diff options
Diffstat (limited to 'g_src')
54 files changed, 20321 insertions, 0 deletions
diff --git a/g_src/KeybindingScreen.cpp b/g_src/KeybindingScreen.cpp new file mode 100755 index 0000000..02cbd81 --- /dev/null +++ b/g_src/KeybindingScreen.cpp @@ -0,0 +1,409 @@ +#ifdef __APPLE__ +# include "osx_messagebox.h" +#elif defined(unix) +# include <gtk/gtk.h> +#endif + +#include "GL/glew.h" + +#ifdef WIN32 + +#ifndef INTEGER_TYPES + #define INTEGER_TYPES + typedef short int16_t; + typedef int int32_t; + typedef long long int64_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; +#endif + +typedef int32_t VIndex; +typedef int32_t Ordinal; + +#endif + +#include "graphics.h" +#include "init.h" +#include "keybindings.h" +#include "KeybindingScreen.h" + +#include <list> +#include <map> +#include <iostream> +#include <sstream> +#include <ctype.h> + +using namespace std; + +struct BindingGroup { + string name; + InterfaceKey start, end; +}; + +const BindingGroup groups[] = { + {"General" , INTERFACEKEY_NONE, WORLDKEY_START-1}, + {"World" , WORLDKEY_START, ADVENTURERKEY_START-1}, + {"Adventurer" , ADVENTURERKEY_START, EMBARKKEY_START-1}, + {"Dwarf mode" , DWARFMAINKEY_START, MILITIAKEY_START-1}, + {"Embark" , EMBARKKEY_START, BUILDINGKEY_START-1}, + {"Building" , BUILDINGKEY_START, WORKSHOPKEY_START-1}, + {"Workshop" , WORKSHOPKEY_START, PILEZONEKEY_START-1}, + {"Pilezone" , PILEZONEKEY_START, STOCKORDERKEY_START-1}, + {"Stockorder" , STOCKORDERKEY_START, DWARFMAINKEY_START-1}, + {"Militia" , MILITIAKEY_START, INTERFACEKEY_STRING_A000-1}, + {"Text entry" , INTERFACEKEY_STRING_A000, INTERFACEKEY_STRING_A255} +}; + +KeybindingScreen::KeybindingScreen() { + gview.addscreen(this, INTERFACE_PUSH_AT_BACK, NULL); // HACK + mode = mode_main; + + main.add("Macros", sel_macros); + for (int i = 0; i < ARRSZ(groups); i++) + main.set(i+2, groups[i].name, sel_first_group + i); + main.set(ARRSZ(groups)+3, "Save and exit", sel_save_exit); + main.add("Exit, discard changes when DF quits", sel_just_exit); + enabler.flag |= ENABLERFLAG_RENDER; +} + +void KeybindingScreen::feed(set<InterfaceKey> &input) { + enabler.flag|=ENABLERFLAG_RENDER; + if (input.count(INTERFACEKEY_KEYBINDING_COMPLETE)) { + list<RegisteredKey> keys = enabler.getRegisteredKey(); + if (keys.size() == 0) { + puts("No keys registered ?!"); + mode = mode_keyR; + } else { + keyRegister.clear(); + list<RegisteredKey> keys = enabler.getRegisteredKey(); + for (list<RegisteredKey>::iterator it = keys.begin(); it != keys.end(); ++it) { + string display; + switch (it->type) { + case type_button: display = "Mouse button: "; break; + case type_key: display = "By position: "; break; + case type_unicode: display = "By letter: "; break; + } + keyRegister.add(display + it->display, it->type); + } + } + } else if (input.count(INTERFACEKEY_STANDARDSCROLL_PAGEUP) || + input.count(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN) || + input.count(INTERFACEKEY_STANDARDSCROLL_UP) || + input.count(INTERFACEKEY_STANDARDSCROLL_DOWN)) { + switch (mode) { + case mode_main: main.feed(input); break; + case mode_keyL: keyL.feed(input); reset_keyR(); break; + case mode_keyR: keyR.feed(input); break; + case mode_macro: macro.feed(input); break; + case mode_register: keyRegister.feed(input); break; + } + } else if (mode == mode_keyL && input.count(INTERFACEKEY_STANDARDSCROLL_RIGHT)) + mode = mode_keyR; + else if (mode == mode_main && input.count(INTERFACEKEY_STANDARDSCROLL_RIGHT)) { + if (main.get_selection() == sel_macros) enter_macros(); + if (main.get_selection() >= sel_first_group) + enter_key(main.get_selection() - sel_first_group); + } else if (mode == mode_keyR && input.count(INTERFACEKEY_STANDARDSCROLL_LEFT)) + mode = mode_keyL; + else if ((mode == mode_keyL || mode == mode_macro) && input.count(INTERFACEKEY_STANDARDSCROLL_LEFT)) + mode = mode_main; + else if (input.count(INTERFACEKEY_STRING_A000)) { // Backspace: Delete something. + switch (mode) { + case mode_macro: + if (macro.get_selection() != "") { + enabler.delete_macro(macro.get_selection()); + macro.del_selection(); + if (!macro.size()) + macro.add("No macros!", ""); + } + break; + case mode_keyR: + keyR_selector sel = keyR.get_selection(); + if (sel.sel == sel_event) { + enabler.remove_key(keyL.get_selection(), sel.event); + reset_keyR(); + } + break; + } + } else if (input.count(INTERFACEKEY_SELECT)) { + switch (mode) { + case mode_main: + if (main.get_selection() == sel_macros) { // Macros + enter_macros(); + } else if (main.get_selection() == sel_save_exit) { // Save and exit + enabler.save_keybindings(); + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else if (main.get_selection() == sel_just_exit) { // Just exit + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else { // Some key-binding group + enter_key(main.get_selection() - sel_first_group); + } + break; + case mode_keyR: { + InterfaceKey key = keyL.get_selection(); + switch (keyR.get_selection().sel) { + case sel_add: + enabler.register_key(); + mode = mode_register; + break; + case sel_rep_none: + enabler.key_repeat(key, REPEAT_NOT); + reset_keyR(); + break; + case sel_rep_slow: + enabler.key_repeat(key, REPEAT_SLOW); + reset_keyR(); + break; + case sel_rep_fast: + enabler.key_repeat(key, REPEAT_FAST); + reset_keyR(); + break; + }} + break; + case mode_register: + enabler.bindRegisteredKey(keyRegister.get_selection(), keyL.get_selection()); + mode = mode_keyR; + reset_keyR(); + break; + } + } else if (input.count(INTERFACEKEY_LEAVESCREEN) || input.count(INTERFACEKEY_OPTIONS)) { + if (mode == mode_register) + mode = mode_keyR; + else + mode = mode_main; + } +} + +void KeybindingScreen::logic() { + if (mode == mode_register) + enabler.flag|=ENABLERFLAG_RENDER; +} + +void KeybindingScreen::enter_macros() { + mode = mode_macro; + macro.clear(); + list<string> macros = enabler.list_macros(); + for (list<string>::iterator it = macros.begin(); it != macros.end(); ++it) + macro.add(*it, *it); + if (!macros.size()) + macro.add("No macros!", ""); +} + +void KeybindingScreen::enter_key(int group) { + mode = mode_keyL; + keyL.clear(); + for (InterfaceKey i = groups[group].start; i <= groups[group].end; i++) { + if (i != INTERFACEKEY_NONE) + keyL.add(enabler.GetBindingTextDisplay(i), i); + } + reset_keyR(); +} + +void KeybindingScreen::reset_keyR() { + int lastpos = keyR.get_pos(); + keyR.clear(); + struct keyR_selector sel; + sel.sel = sel_add; + keyR.add("Add binding", sel); + InterfaceKey key = keyL.get_selection(); + list<EventMatch> matchers = enabler.list_keys(key); + Repeat rep = enabler.key_repeat(key); + sel.sel = sel_rep_none; + keyR.set(2, "Don't repeat", sel); + if (rep == REPEAT_NOT) keyR.set_color(2, 4, 0); + sel.sel = sel_rep_slow; + keyR.set(3, "Delayed repeat", sel); + if (rep == REPEAT_SLOW) keyR.set_color(3, 4, 0); + sel.sel = sel_rep_fast; + keyR.set(4, "Immediate repeat", sel); + if (rep == REPEAT_FAST) keyR.set_color(4, 4, 0); + int i = 6; + for (list<EventMatch>::iterator it = matchers.begin(); it != matchers.end(); ++it, ++i) { + ostringstream desc; + switch (it->type) { + case type_unicode: + desc << "By letter: "; + if (it->unicode < 256 && isgraph(it->unicode)) // Is it printable? + desc << (char)it->unicode; + else + desc << "U+" << hex << uppercase << it->unicode; + break; + case type_key: + desc << "By position: " << translate_mod(it->mod) << sdlNames.left[it->key]; + break; + case type_button: + desc << "Mouse: " << (int)it->button; + break; + } + sel.sel = sel_event; + sel.event = *it; + keyR.set(i, desc.str(), sel); + } + keyR.set_pos(lastpos); +} + +void KeybindingScreen::render_macro() { + drawborder("Macros"); + gps.locate(3, 3); + gps.changecolor(4,0,1); + gps.addst("Select a macro, then press " + enabler.GetKeyDisplay(INTERFACEKEY_STRING_A000) + " to delete."); + macro.render(6, init.display.grid_x-2, 5, init.display.grid_y-2); +} + +void KeybindingScreen::render_key() { + if (enabler.is_registering()) { + gps.changecolor(4,0,1); + drawborder("Keybinding - currently registering new key"); + } else + drawborder("Keybinding"); + gps.locate(3, 6); + gps.changecolor(4,0,1); + gps.addst("Select a binding, then press " + enabler.GetKeyDisplay(INTERFACEKEY_STRING_A000) + " to delete."); + keyL.render(6, init.display.grid_x/2 - 1, 5, init.display.grid_y-2); + if (mode == mode_keyL || mode == mode_register) + keyR.bleach(true); + else + keyR.bleach(false); + keyR.render(init.display.grid_x/2 + 1, init.display.grid_x-2, 5, init.display.grid_y-2); +} + +void KeybindingScreen::render_register() { + int x1 = init.display.grid_x / 2 - 20, + x2 = init.display.grid_x / 2 + 20, + y1 = init.display.grid_y / 2 - 1, + y2 = init.display.grid_y / 2 + 1; + if (!enabler.is_registering()) { + y2 = y1 + keyRegister.size() + 1; + } + gps.erasescreen_rect(x1, x2, y1, y2); + gps.changecolor(1,1,1); + for (int x = x1; x <= x2; x++) { + gps.locate(y1, x); gps.addchar(' '); + gps.locate(y2, x); gps.addchar(' '); + } + for (int y = y1 + 1; y < y2; y++) { + gps.locate(y, x1); gps.addchar(' '); + gps.locate(y, x2); gps.addchar(' '); + } + if (enabler.is_registering()) { + gps.changecolor(7,0,1); + gps.locate(y1+1, x1+2); + gps.addst(translate_mod(getModState())); + } else { + keyRegister.render(x1+1, x2-1, y1+1, y2-1); + gps.locate(y2, x1+2); + gps.changecolor(7,1,1); + gps.addst("Select binding, or press " + enabler.GetKeyDisplay(INTERFACEKEY_LEAVESCREEN) + " to abort"); + } +} + +// Render the main menu +void KeybindingScreen::render_main() { + drawborder("Key binding & macro center"); + main.render(6, init.display.grid_x - 3, 3, init.display.grid_y - 4); +} + +void KeybindingScreen::render() { + switch(mode) { + case mode_main: render_main(); break; + case mode_keyL: case mode_keyR: render_key(); break; + case mode_macro: render_macro(); break; + case mode_register: + render_key(); + render_register(); + break; + } +} + +void KeybindingScreen::help() { +} + + +MacroScreenLoad::MacroScreenLoad() { + list<string> macros = enabler.list_macros(); + width = 10; + if (!macros.size()) { + menu.add("No macros!", ""); + height = 1; + } else + height = macros.size(); + + for (list<string>::iterator it = macros.begin(); it != macros.end(); ++it) { + if (it->length() > width) width = it->length(); + menu.add(*it, *it); + } + enabler.flag |= ENABLERFLAG_RENDER; + // render(); + // gps.renewscreen(); +} + +void MacroScreenLoad::feed(set<InterfaceKey> &input) { + enabler.flag|=ENABLERFLAG_RENDER; + if (input.count(INTERFACEKEY_SELECT)) { + string id = menu.get_selection(); + if (id != "") enabler.load_macro(id); + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else if (input.count(INTERFACEKEY_LEAVESCREEN)) { + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } else { + menu.feed(input); + } + if (input.count(INTERFACEKEY_OPTIONS)) { + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + } +} + +void MacroScreenLoad::logic() { +} + +void MacroScreenLoad::render() { + if (parent) parent->render(); + const int x1 = MAX(init.display.grid_x/2 - ((width + 2) / 2), 0); + const int x2 = MIN(x1+width+1, init.display.grid_x-1); + const int y1 = MAX(init.display.grid_y/2 - ((height + 2) / 2), 0); + const int y2 = MIN(y1 + height + 1, init.display.grid_y-1); + gps.changecolor(0,3,1); + gps.draw_border(x1, x2, y1, y2); + menu.render(x1+1, x2-1, y1+1, y2-1); + // gps.renewscreen(); +} + +MacroScreenSave::MacroScreenSave() { + enabler.flag |= ENABLERFLAG_RENDER; +} + +void MacroScreenSave::logic() { +} + +void MacroScreenSave::feed(set<InterfaceKey> &input) { + enabler.flag|=ENABLERFLAG_RENDER; + id.feed(input); + if (input.count(INTERFACEKEY_SELECT)) { + string n = id.get_text(); + if (n.length()) + enabler.save_macro(n); + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } + if (input.count(INTERFACEKEY_OPTIONS)) { + breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN; + } +} + +void MacroScreenSave::render() { + if (parent) parent->render(); + const int x1 = 3, + x2 = init.display.grid_x-4, + y1 = init.display.grid_y/2-1, + y2 = init.display.grid_y/2+1; + gps.changecolor(0,3,1); + gps.draw_border(x1, x2, y1, y2); + id.render(x1+1,x2-1,y1+1,y2-1); + // gps.renewscreen(); +} + diff --git a/g_src/KeybindingScreen.h b/g_src/KeybindingScreen.h new file mode 100755 index 0000000..fc29f2e --- /dev/null +++ b/g_src/KeybindingScreen.h @@ -0,0 +1,69 @@ +#ifndef KEYBINDINGSCREEN_H +#define KEYBINDINGSCREEN_H + +#include "interface.h" +#include "ViewBase.h" +#include "enabler.h" + +#include <set> +#include <string> + +class KeybindingScreen : public viewscreenst { + enum { mode_main, mode_keyL, mode_keyR, mode_macro, mode_register } mode; + enum keyR_type { sel_add, sel_rep_none, sel_rep_slow, sel_rep_fast, sel_event }; + enum main_selector { sel_macros, sel_just_exit, sel_save_exit, sel_first_group }; + + struct keyR_selector { + keyR_type sel; + EventMatch event; // Uninitialized if sel != sel_event + }; + + widgets::menu<int> main; // Representing main_selector + widgets::menu<InterfaceKey> keyL; + widgets::menu<keyR_selector> keyR; + widgets::menu<std::string> macro; + widgets::menu<MatchType> keyRegister; + + void render_main(); + void render_macro(); + void render_key(); + void render_register(); + + void reset_keyR(); + + void enter_key(int group); + void enter_macros(); + +public: + KeybindingScreen(); + virtual void feed(std::set<InterfaceKey> &events); + virtual void render(); + virtual void help(); + virtual void logic(); + virtual char is_option_screen() { return 2; } +}; + +class MacroScreenLoad : public viewscreenst { + widgets::menu<string> menu; + int width, height; + + public: + MacroScreenLoad(); + virtual void logic(); + virtual void render(); + virtual void feed(std::set<InterfaceKey> &events); + virtual char is_option_screen() { return 1; } +}; + +class MacroScreenSave : public viewscreenst { + widgets::textbox id; +public: + MacroScreenSave(); + virtual void logic(); + virtual void render(); + virtual void feed(std::set<InterfaceKey> &events); + virtual char is_option_screen() { return 1; } +}; + + +#endif diff --git a/g_src/ViewBase.cpp b/g_src/ViewBase.cpp new file mode 100755 index 0000000..6063732 --- /dev/null +++ b/g_src/ViewBase.cpp @@ -0,0 +1,38 @@ +#include <assert.h> +#include <iostream> +#include "ViewBase.h" + +using namespace std; +using namespace widgets; + +void textbox::feed(set<InterfaceKey> &input) { + // Backspace + if (input.count(INTERFACEKEY_STRING_A000) && text.size()) + text.resize(text.size() - 1); + // Hopefully we'll never get multiple characters in one input set, + // but it's possible. We deal with this by inserting them in + // alphabetical order. + for (set<InterfaceKey>::iterator it = input.lower_bound(INTERFACEKEY_STRING_A001); + it != input.end() && *it <= INTERFACEKEY_STRING_A255; + ++it) { + if (keep == false) { + keep = true; + text.clear(); + } + char c = *it - INTERFACEKEY_STRING_A000; + text += c; + } +} + +void textbox::render(int x1, int x2, int y1, int y2) { + // We need to do some kind of line-breaking for multi-line text + // entry boxes. This shall be implemented at need, and there is none + // yet. + assert(y1 == y2); + gps.erasescreen_rect(x1,x2,y1,y2); + gps.locate(y1,x1); + gps.changecolor(7,0,keep); + int width = x2 - x1 + 1; + int start = text.length() - width; + gps.addst(text.substr(MAX(start,0))); +} diff --git a/g_src/ViewBase.h b/g_src/ViewBase.h new file mode 100755 index 0000000..315abf3 --- /dev/null +++ b/g_src/ViewBase.h @@ -0,0 +1,197 @@ +#ifndef VIEWBASE_H +#define VIEWBASE_H + +#include <set> +#include <map> +#include <string> + +#include "keybindings.h" +#include "graphics.h" + +enum InterfaceBreakdownTypes +{ + INTERFACE_BREAKDOWN_NONE, + INTERFACE_BREAKDOWN_QUIT, + INTERFACE_BREAKDOWN_STOPSCREEN, + INTERFACE_BREAKDOWN_TOFIRST, + INTERFACE_BREAKDOWNNUM +}; + +class viewscreenst +{ + public: + viewscreenst *child; + viewscreenst *parent; + char breakdownlevel; + + char option_key_pressed; + virtual void feed(std::set<InterfaceKey> &events){} + virtual void logic(){} + virtual void render(){} + virtual void resize(int w, int h){} + + virtual void help(); + virtual char movies_okay(){return 1;} + virtual char is_option_screen(){return 0;} + virtual char is_save_screen(){return 0;} + viewscreenst() + { + child=0; + parent=0; + breakdownlevel=INTERFACE_BREAKDOWN_NONE; + option_key_pressed=0; + } + virtual ~viewscreenst(){} + + virtual bool key_conflict(InterfaceKey test_key); +}; + +namespace widgets { + + using namespace std; + + template <typename T> + class menu { + typedef map<int,pair<string, T> > dict; + dict lines; + int selection; + int last_displayheight; + bool bleached; + map<int, pair<int,int> > colors; + + // Given 'total' lines, with 'sel' selected, and 'space' to draw in, + // returns the first line that should be drawn. + int first_line(int total, int sel, int space) { + // There is no doubt some clever math to do this, but I'm tired and don't care. + for (int start = 0;; start += space / 2) { + if (start + space/2 >= sel) return start; + if (start + space >= total) return start; + } + } + pair<string,T> mp(string s, T t) { return make_pair(s,t); } + + // Scrolls N lines up/down; positive = down + void scroll(int n) { + typename dict::iterator it = lines.find(selection); + for (int i = 0; i < abs(n); i++) { + if (n < 0 && it == lines.begin()) { // We've hit the top + if (i) break; + else { + it = --(lines.end()); + break; + } + } + if (n < 0) --it; else ++it; // Scroll one line + if (it == lines.end()) { // We've hit the bottom + if (i) { + --it; + break; + } + else { + it = lines.begin(); + break; + } + } + // If we hit neither the top nor bottom, loop. + } + + selection = it->first; + } + + public: + menu() { clear(); } + int size() { return lines.size(); } + // Adds a line just past the last taken position + void add(string text, T token) { + if (!lines.size()) { + lines[0] = mp(text,token); + } else { + typename dict::iterator it = --(lines.end()); + lines[it->first + 1] = mp(text,token); + } + } + // (Re)sets the text of the given line + void set(int line, string text, T token) { + lines[line] = mp(text,token); + } + // Set the color of a line + void set_color(int line, int fg, int bg) { + colors[line] = make_pair(fg,bg); + } + // Handles (page) up/down + void feed(std::set<InterfaceKey> &input) { + if (!lines.size()) return; + if (input.count(INTERFACEKEY_STANDARDSCROLL_UP)) scroll(-1); + if (input.count(INTERFACEKEY_STANDARDSCROLL_DOWN)) scroll(1); + if (input.count(INTERFACEKEY_STANDARDSCROLL_PAGEUP)) scroll(-(last_displayheight / 2)); + if (input.count(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN)) scroll(last_displayheight / 2); + } + void render(int x1, int x2, int y1, int y2) { + gps.erasescreen_rect(x1,x2,y1,y2); + int h = y2 - y1 + 1, + w = x2 - x1 + 1, + x = x1, y = y1; + last_displayheight = h; + if (!lines.size()) return; + int total = (--lines.end())->first + 1; + int first = first_line(total, selection, h); + typename dict::iterator it = lines.lower_bound(first); + for (; it != lines.end() && it->first - first < h; ++it) { + gps.locate(it->first - first + y, x); + map<int,pair<int,int> >::iterator color = colors.find(it->first - first); + int fg = 7, bg = 0; + if (color != colors.end()) { + fg = color->second.first; + bg = color->second.second; + } + gps.changecolor(fg, bg, it->first == selection && !bleached); + gps.addst(it->second.first.substr(0, w)); + } + } + // Read out the current selection + T get_selection() { return lines[selection].second; } + int get_pos() { return selection; } + // Set the position by line + void set_pos(int pos) { + if (pos < size()) + selection = pos; + } + // Delete the currently selected line + void del_selection() { + typename dict::iterator it = lines.find(selection); + typename dict::iterator newsel = it; + ++newsel; + if (newsel == lines.end()) { + newsel = it; + --newsel; + } + lines.erase(it); + if (lines.size()) selection = newsel->first; + } + // If true, don't draw a highlight + void bleach(bool b) { bleached = b; } + // Reset the menu + void clear() { + selection = 0; + lines.clear(); + last_displayheight = 10; + bleached = false; + colors.clear(); + } + }; + + class textbox { + string text; + bool keep; + public: + textbox() { textbox("", false); } + textbox(string initializer, bool keep) { this->keep = keep; text = initializer; } + string get_text() { return text; } + // Only cares about INTERFACEKEY_STRING events + void feed(std::set<InterfaceKey> &input); + void render(int x1, int x2, int y1, int y2); + }; + +} + +#endif diff --git a/g_src/basics.cpp b/g_src/basics.cpp new file mode 100755 index 0000000..a56145d --- /dev/null +++ b/g_src/basics.cpp @@ -0,0 +1,792 @@ +#include "platform.h" +#include <string.h> +#include <math.h> +#include <iosfwd> +#include <iostream> +#include <ios> +#include <streambuf> +#include <istream> +#include <ostream> +#include <iomanip> +#include <sstream> +#include <cstdlib> +#include <fstream> +#include <zlib.h> + +#include "svector.h" +using std::string; +using std::endl; +using std::ofstream; + +#include "endian.h" + +#ifdef WIN32 + +#ifndef INTEGER_TYPES + #define INTEGER_TYPES + typedef short int16_t; + typedef int int32_t; + typedef long long int64_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; +#endif + +typedef int32_t VIndex; +typedef int32_t Ordinal; + +#endif + +#include "ttf_manager.hpp" +#include "init.h" +#include "basics.h" + +extern string errorlog_prefix; + +void errorlog_string(const string &str) +{ + if(str.empty())return; + + //SAVE AN ERROR TO THE LOG FILE + std::ofstream fseed("errorlog.txt", std::ios::out | std::ios::app); + if(fseed.is_open()) + { + if(!errorlog_prefix.empty()) + { + fseed<<errorlog_prefix.c_str()<<std::endl; + errorlog_prefix.clear(); + } + fseed<<str.c_str()<<std::endl; + } + fseed.close(); +} + +void gamelog_string(const string &str) +{ + if(str.empty())return; + + //SAVE AN ERROR TO THE LOG FILE + std::ofstream fseed("gamelog.txt",std::ios::out | std::ios::app); + if(fseed.is_open()) + { + fseed<<str.c_str()<<std::endl; + } + fseed.close(); +} + +void errorlog_string(const char *ptr) +{ + if(ptr==NULL)return; + + //SAVE AN ERROR TO THE LOG FILE + std::ofstream fseed("errorlog.txt", std::ios::out | std::ios::app); + if(fseed.is_open()) + { + if(!errorlog_prefix.empty()) + { + fseed<<errorlog_prefix.c_str()<<std::endl; + errorlog_prefix.clear(); + } + fseed<<ptr<<std::endl; + } + fseed.close(); +} + +int32_t convert_string_to_long(string &str) +{ + return atoi(str.c_str()); +} + +uint32_t convert_string_to_ulong(string &str) +{ + return strtoul(str.c_str(),NULL,0); +} + +void add_long_to_string(int32_t n,string &str) +{ + string str2; + convert_long_to_string(n,str2); + str+=str2; +} + +void convert_long_to_string(int32_t n,string &str) +{ + std::ostringstream o; + o << n; + str = o.str(); +} + +void convert_ulong_to_string(uint32_t n,string &str) +{ + std::ostringstream o; + o << n; + str = o.str(); +} + +char grab_variable_token(string &str,string &token,char sec_comp,int32_t &pos,int32_t i_pos) +{ + token.erase(); + + for(pos=i_pos;pos<str.length();pos++) + { + if((str[pos]=='['&&pos+1<str.length())||sec_comp) + { + if(str[pos]=='['&&!sec_comp)pos++; + grab_token_string_pos(token,str,pos,':'); + pos--; + + if(token.length()>0)return 1; + } + } + + return 0; +} + +bool grab_token_expression(string &dest,string &source,int32_t &pos,char compc) +{ + dest.erase(); + dest+="["; + + string token1; + while(grab_token_string(token1,source,pos)) + { + if(dest.length()>1)dest+=":"; + dest+=token1; + + if(pos<source.length()) + { + if(source[pos]==']')break;//grab_token_string CAN'T HANDLE THESE + } + } + dest+="]"; + + return (dest.length()>2); +} + +bool grab_token_list_as_string(string &dest,string &source,int32_t &pos,char compc) +{ + dest.erase(); + + string token1; + while(grab_token_string(token1,source,pos)) + { + if(dest.length()>0)dest+=":"; + dest+=token1; + + if(pos<source.length()) + { + if(source[pos]==']')break;//grab_token_string CAN'T HANDLE THESE + } + } + + return (dest.length()>0); +} + +bool grab_token_string(string &dest,string &source,int32_t &pos,char compc) +{ + dest.erase(); + if(source.length()==0)return false; + + pos++;//GET RID OF FIRST [ OR compc THAT IS ASSUMED TO BE THERE + if(pos>source.size())return false; + + //GO UNTIL YOU HIT A compc, ], or the end + auto s=source.begin(),e=source.end(); + s+=pos; + for(;s<e;++s) + { + if((*s)==compc||(*s)==']')break; + dest+=(*s); + pos++; + } + return (dest.length()>0); +} + +bool grab_token_string(string &dest,string &source,char compc) +{ + dest.erase(); + if(source.length()==0)return false; + + //GO UNTIL YOU HIT A :, ], or the end + auto s=source.begin(),e=source.end(); + for(;s<e;++s) + { + if((*s)==compc||(*s)==']')break; + dest+=(*s); + } + return (dest.length()>0); +} + +bool grab_token_string_pos(string &dest,string &source,int32_t pos,char compc) +{ + dest.erase(); + if(source.length()==0)return false; + if(pos>source.length())return false; + + //GO UNTIL YOU HIT A :, ], or the end + auto s=source.begin(),e=source.end(); + s+=pos; + for(;s<e;++s) + { + if((*s)==compc||(*s)==']')break; + dest+=(*s); + } + return (dest.length()>0); +} + +bool grab_token_string(string &dest,const char *source,char compc) +{ + dest.erase(); + int32_t sz=strlen(source); + if(sz==0)return false; + + //GO UNTIL YOU HIT A :, ], or the end + int32_t s; + for(s=0;s<sz;s++) + { + if(source[s]==compc||source[s]==']')break; + dest+=source[s]; + } + return (dest.length()>0); +} + + +void replace_token_string(string &token,string &str,int32_t pos,char compc,string &nw,char repc) +{ + string rep; + if(repc!=0)rep=repc; + rep+=token; + if(compc!=0)rep+=compc; + + string::size_type wpos; + + if ((wpos = str.find(rep)) != string::npos) + { + str.replace(wpos,rep.size(),nw); + } +} + +void simplify_string(string &str) +{ + int32_t s; + for(s=0;s<str.length();s++) + { + //CAPITALIZE + if(str[s]>='A'&&str[s]<='Z') + { + str[s]-='A'; + str[s]+='a'; + } + switch(str[s]) + { + case (char)129: + case (char)150: + case (char)151: + case (char)154: + case (char)163: + str[s]='u'; + break; + case (char)152: + str[s]='y'; + break; + case (char)164: + case (char)165: + str[s]='n'; + break; + case (char)131: + case (char)132: + case (char)133: + case (char)134: + case (char)142: + case (char)143: + case (char)145: + case (char)146: + case (char)160: + str[s]='a'; + break; + case (char)130: + case (char)136: + case (char)137: + case (char)138: + case (char)144: + str[s]='e'; + break; + case (char)139: + case (char)140: + case (char)141: + case (char)161: + str[s]='i'; + break; + case (char)147: + case (char)148: + case (char)149: + case (char)153: + case (char)162: + str[s]='o'; + break; + case (char)128: + case (char)135: + str[s]='c'; + break; + } + } +} + +void lower_case_string(string &str) +{ + int32_t s; + for(s=0;s<str.length();s++) + { + //CAPITALIZE + if(str[s]>='A'&&str[s]<='Z') + { + str[s]-='A'; + str[s]+='a'; + } + switch(str[s]) + { + case (char)154:str[s]=(char)129;break; + case (char)165:str[s]=(char)164;break; + case (char)142:str[s]=(char)132;break; + case (char)143:str[s]=(char)134;break; + case (char)144:str[s]=(char)130;break; + case (char)153:str[s]=(char)148;break; + case (char)128:str[s]=(char)135;break; + case (char)146:str[s]=(char)145;break; + } + } +} + +void upper_case_string(string &str) +{ + int32_t s; + for(s=0;s<str.length();s++) + { + //CAPITALIZE + if(str[s]>='a'&&str[s]<='z') + { + str[s]-='a'; + str[s]+='A'; + } + switch(str[s]) + { + case (char)129:str[s]=(char)154;break; + case (char)164:str[s]=(char)165;break; + case (char)132:str[s]=(char)142;break; + case (char)134:str[s]=(char)143;break; + case (char)130:str[s]=(char)144;break; + case (char)148:str[s]=(char)153;break; + case (char)135:str[s]=(char)128;break; + case (char)145:str[s]=(char)146;break; + } + } +} + +void capitalize_string_words(string &str) +{ + char conf; + int32_t s; + for(s=0;s<str.length();s++) + { + conf=0; + if(s>0) + { + if(str[s-1]==' '|| + str[s-1]=='\"')conf=1; + if(str[s-1]=='\'') + { + //DISCOUNT SINGLE QUOTE IF IT ISN'T PRECEDED BY SPACE, COMMA OR NOTHING + if(s<=0)conf=1; + else if(s>=2) + { + if(str[s-2]==' '|| + str[s-2]==',')conf=1; + } + } + } + if(s==0||conf) + { + //CAPITALIZE + if(str[s]>='a'&&str[s]<='z') + { + str[s]-='a'; + str[s]+='A'; + } + switch(str[s]) + { + case (char)129:str[s]=(char)154;break; + case (char)164:str[s]=(char)165;break; + case (char)132:str[s]=(char)142;break; + case (char)134:str[s]=(char)143;break; + case (char)130:str[s]=(char)144;break; + case (char)148:str[s]=(char)153;break; + case (char)135:str[s]=(char)128;break; + case (char)145:str[s]=(char)146;break; + } + } + } +} + +void capitalize_string_first_word(string &str) +{ + char conf; + int32_t s; + for(s=0;s<str.length();s++) + { + conf=0; + if(s>0) + { + if(str[s-1]==' '|| + str[s-1]=='\"')conf=1; + if(str[s-1]=='\'') + { + //DISCOUNT SINGLE QUOTE IF IT ISN'T PRECEDED BY SPACE, COMMA OR NOTHING + if(s<=0)conf=1; + else if(s>=2) + { + if(str[s-2]==' '|| + str[s-2]==',')conf=1; + } + } + } + if(s==0||conf) + { + //CAPITALIZE + if(str[s]>='a'&&str[s]<='z') + { + str[s]-='a'; + str[s]+='A'; + return; + } + switch(str[s]) + { + case (char)129:str[s]=(char)154;return; + case (char)164:str[s]=(char)165;return; + case (char)132:str[s]=(char)142;return; + case (char)134:str[s]=(char)143;return; + case (char)130:str[s]=(char)144;return; + case (char)148:str[s]=(char)153;return; + case (char)135:str[s]=(char)128;return; + case (char)145:str[s]=(char)146;return; + } + if(str[s]!=' '&&str[s]!='\"')return; + } + } +} + +static void abbreviate_string_helper(string &str, int len) { + if(str.length()>=2) + { + if((str[0]=='A'||str[0]=='a')&& + str[1]==' ') + { + str.erase(str.begin()+1); + str.erase(str.begin()); + + if(str.length()<=len)return; + } + + if(str.length()>=3) + { + if((str[0]=='A'||str[0]=='a')&& + (str[1]=='N'||str[1]=='n')&& + str[2]==' ') + { + str.erase(str.begin()+2); + str.erase(str.begin()+1); + str.erase(str.begin()); + + if(str.length()<=len)return; + } + + if(str.length()>=4) + { + if((str[0]=='T'||str[0]=='t')&& + (str[1]=='H'||str[1]=='h')&& + (str[2]=='E'||str[2]=='e')&& + str[3]==' ') + { + str.erase(str.begin()+3); + str.erase(str.begin()+2); + str.erase(str.begin()+1); + str.erase(str.begin()); + + if(str.length()<=len)return; + } + } + } + } + + int32_t l; + for(l=(int32_t)str.length()-1;l>=1;l--) + { + if(str[l-1]==' ')continue; + + if(str[l]=='a'|| + str[l]=='e'|| + str[l]=='i'|| + str[l]=='o'|| + str[l]=='u'|| + str[l]=='A'|| + str[l]=='E'|| + str[l]=='I'|| + str[l]=='O'|| + str[l]=='U') + { + str.erase(str.begin()+l); + if(str.length()<=len)return; + } + } + + if(str.length()>len)str.resize(len); +} + + +void abbreviate_string(string &str, int32_t len) +{ + if (ttf_manager.ttf_active()) { + // We'll need to use TTF-aware text shrinking. + while (ttf_manager.size_text(str) > len) + abbreviate_string_helper(str, str.length() - 1); + } else if(str.length()>len){ + // 1 letter = 1 tile. + abbreviate_string_helper(str, len); + } +} + + + +void get_number(int32_t number,string &str) +{ + str.erase(); + + if(number<0) + { + number*=-1; + str="negative "; + } + switch(number) + { + case 0:str="zero";break; + case 1:str="one";break; + case 2:str="two";break; + case 3:str="three";break; + case 4:str="four";break; + case 5:str="five";break; + case 6:str="six";break; + case 7:str="seven";break; + case 8:str="eight";break; + case 9:str="nine";break; + case 10:str="ten";break; + case 11:str="eleven";break; + case 12:str="twelve";break; + case 13:str="thirteen";break; + case 14:str="fourteen";break; + case 15:str="fifteen";break; + case 16:str="sixteen";break; + case 17:str="seventeen";break; + case 18:str="eighteen";break; + case 19:str="nineteen";break; + default: + { + if(number>=1000000000) + { + string nm; + get_number(number/1000000000,nm); + str+=nm; + str+=" billion"; + if(number%1000000000!=0) + { + str+=" "; + get_number(number%1000000000,nm); + str+=nm; + } + return; + } + if(number>=1000000&&number<1000000000) + { + string nm; + get_number(number/1000000,nm); + str+=nm; + str+=" million"; + if(number%1000000!=0) + { + str+=" "; + get_number(number%1000000,nm); + str+=nm; + } + return; + } + if(number>=1000&&number<1000000) + { + string nm; + get_number(number/1000,nm); + str+=nm; + str+=" thousand"; + if(number%1000!=0) + { + str+=" "; + get_number(number%1000,nm); + str+=nm; + } + return; + } + if(number>=100&&number<1000) + { + string nm; + get_number(number/100,nm); + str+=nm; + str+=" hundred"; + if(number%100!=0) + { + str+=" "; + get_number(number%100,nm); + str+=nm; + } + return; + } + if(number>=20&&number<100) + { + switch(number/10) + { + case 2:str="twenty";break; + case 3:str="thirty";break; + case 4:str="forty";break; + case 5:str="fifty";break; + case 6:str="sixty";break; + case 7:str="seventy";break; + case 8:str="eighty";break; + case 9:str="ninety";break; + } + if(number%10!=0) + { + str+="-"; + string nm; + get_number(number%10,nm); + str+=nm; + } + return; + } + add_long_to_string(number,str); + break; + } + } +} + +void get_ordinal(int32_t number,string &str,bool shorten) +{ + str.erase(); + + if(shorten) + { + if(number<0) + { + number*=-1; + str="-"; + } + add_long_to_string(number,str); + switch(number%10) + { + case 1: + if(number%100==11)str+="th"; + else str+="st"; + break; + case 2: + if(number%100==12)str+="th"; + else str+="nd"; + break; + case 3: + if(number%100==13)str+="th"; + else str+="rd"; + break; + default: + str+="th"; + break; + } + return; + } + + + if(number<0) + { + number*=-1; + str="Negative "; + } + switch(number) + { + case 0:str="Zeroth";break; + case 1:str="First";break; + case 2:str="Second";break; + case 3:str="Third";break; + case 4:str="Fourth";break; + case 5:str="Fifth";break; + case 6:str="Sixth";break; + case 7:str="Seventh";break; + case 8:str="Eighth";break; + case 9:str="Ninth";break; + case 10:str="Tenth";break; + case 11:str="Eleventh";break; + case 12:str="Twelfth";break; + case 13:str="Thirteenth";break; + case 14:str="Fourteenth";break; + case 15:str="Fifteenth";break; + case 16:str="Sixteenth";break; + case 17:str="Seventeenth";break; + case 18:str="Eighteenth";break; + case 19:str="Nineteenth";break; + default: + add_long_to_string(number,str); + switch(number%10) + { + case 1: + if(number%100==11)str+="th"; + else str+="st"; + break; + case 2: + if(number%100==12)str+="th"; + else str+="nd"; + break; + case 3: + if(number%100==13)str+="th"; + else str+="rd"; + break; + default: + str+="th"; + break; + } + break; + } +} + +// Map DF's CP437 to Unicode +// see: http://dwarffortresswiki.net/index.php/Character_table +int charmap[256] = { + ' ', 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022, + 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C, + 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8, + 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC, + /* 0x20 */ + 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, + 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, + 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f, + 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, + 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x2302, + /* 0x80 */ + 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7, + 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5, + 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9, + 0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x20A7, 0x192, + 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA, + 0xBF, 0x2310, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB, + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510, + 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F, + 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567, + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B, + 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580, + 0x3B1, 0xDF/*yay*/, 0x393, 0x3C0, 0x3A3, 0x3C3, 0xB5, 0x3C4, + 0x3A6, 0x398, 0x3A9, 0x3B4, 0x221E, 0x3C6, 0x3B5, 0x2229, + 0x2261, 0xB1, 0x2265, 0x2264, 0x2320, 0x2321, 0xF7, 0x2248, + 0xB0, 0x2219, 0xB7, 0x221A, 0x207F, 0xB2, 0x25A0, 0xA0 +}; diff --git a/g_src/basics.h b/g_src/basics.h new file mode 100755 index 0000000..ce3a3a2 --- /dev/null +++ b/g_src/basics.h @@ -0,0 +1,117 @@ +#ifndef BASICS_H +#define BASICS_H + +#ifndef WIN32 +#include <stdint.h> +#endif +#include <string> +using std::string; + +#ifndef BITS + +#define BITS + +#define BIT1 1 +#define BIT2 2 +#define BIT3 4 +#define BIT4 8 +#define BIT5 16 +#define BIT6 32 +#define BIT7 64 +#define BIT8 128 +#define BIT9 256 +#define BIT10 512 +#define BIT11 1024 +#define BIT12 2048 +#define BIT13 4096 +#define BIT14 8192 +#define BIT15 16384 +#define BIT16 32768 +#define BIT17 65536UL +#define BIT18 131072UL +#define BIT19 262144UL +#define BIT20 524288UL +#define BIT21 1048576UL +#define BIT22 2097152UL +#define BIT23 4194304UL +#define BIT24 8388608UL +#define BIT25 16777216UL +#define BIT26 33554432UL +#define BIT27 67108864UL +#define BIT28 134217728UL +#define BIT29 268435456UL +#define BIT30 536870912UL +#define BIT31 1073741824UL +#define BIT32 2147483648UL + +#endif + +void gamelog_string(const string &str); +void errorlog_string(const string &str); +void errorlog_string(const char *ptr); + +bool grab_token_string(string &dest,string &source,char compc=':'); +bool grab_token_string(string &dest,string &source,int32_t &pos,char compc=':'); +bool grab_token_string_pos(string &dest,string &source,int32_t pos,char compc=':'); +void replace_token_string(string &token,string &str,int32_t pos,char compc,string &nw,char repc); +bool grab_token_list_as_string(string &dest,string &source,int32_t &pos,char compc=':'); +bool grab_token_expression(string &dest,string &source,int32_t &pos,char compc=':'); +char grab_variable_token(string &str,string &token,char sec_comp,int32_t &pos,int32_t i_pos); + +int32_t convert_string_to_long(string &str); +uint32_t convert_string_to_ulong(string &str); +void add_long_to_string(int32_t n,string &str); +void convert_long_to_string(int32_t n,string &str); +void convert_ulong_to_string(uint32_t n,string &str); + +void lower_case_string(string &str); +void upper_case_string(string &str); +void simplify_string(string &str); +void capitalize_string_words(string &str); +void capitalize_string_first_word(string &str); +void abbreviate_string(string &str,int32_t len); + +void get_number(int32_t number,string &str); +void get_ordinal(int32_t number,string &str,bool shorten); + +enum GameMode +{ + GAMEMODE_DWARF, + GAMEMODE_ADVENTURE, + GAMEMODENUM, + GAMEMODE_NONE +}; + +enum GameType +{ + GAMETYPE_DWARF_MAIN,
+ GAMETYPE_ADVENTURE_MAIN,
+ GAMETYPE_VIEW_LEGENDS,
+ GAMETYPE_DWARF_RECLAIM,
+ GAMETYPE_DWARF_ARENA,
+ GAMETYPE_ADVENTURE_ARENA,
+ GAMETYPE_ADVENTURE_DUNGEON,
+ GAMETYPE_DWARF_TUTORIAL,
+ GAMETYPE_DWARF_UNRETIRE,
+ GAMETYPE_ADVENTURE_WORLD_DEBUG,
+ GAMETYPENUM, + GAMETYPE_NONE +}; + +enum Song +{ + SONG_TITLE, + SONG_GAME, + SONGNUM +}; + + +enum justification : unsigned char { + justify_left, justify_center, justify_right, + justify_cont, + not_truetype +}; + +extern int charmap[256]; + +#endif diff --git a/g_src/bimap.h b/g_src/bimap.h new file mode 100755 index 0000000..968f770 --- /dev/null +++ b/g_src/bimap.h @@ -0,0 +1,17 @@ +#ifndef BIMAP_H +#define BIMAP_H + +#include <map> + +template<typename A, typename B> +struct bimap { + std::map<A,B> left; + std::map<B,A> right; + + void insert(A a, B b) { + left.insert(std::pair<A,B>(a,b)); + right.insert(std::pair<B,A>(b,a)); + } +}; + +#endif diff --git a/g_src/command_line.cpp b/g_src/command_line.cpp new file mode 100755 index 0000000..422f88f --- /dev/null +++ b/g_src/command_line.cpp @@ -0,0 +1,132 @@ +#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "basics.h"
+
+#include "command_line.h"
+
+void command_linest::init(const string &str)
+{
+ original=str;
+
+ //BUILD THE TOKEN LIST
+ long pos=0;
+ while(grab_arg(original,pos));
+
+ //HANDLE EACH TOKEN
+ long l;
+ for(l=0;l<arg_vect.str.size();l++)
+ {
+ handle_arg(arg_vect.str[l]->dat);
+ }
+}
+
+char command_linest::grab_arg(string &source,long &pos)
+{
+ string dest;
+
+ while(pos<source.length())
+ {
+ //HIT A NEW ARGUMENT? RETURN, OTHERWISE SKIP AND START UP
+ if(source[pos]=='-')
+ {
+ if(dest.empty()){pos++;continue;}
+ else
+ {
+ pos++;
+ arg_vect.add_string(dest);
+ return 1;
+ }
+ }
+
+ dest+=source[pos];
+
+ pos++;
+ }
+
+ if(!dest.empty())arg_vect.add_string(dest);
+ return 0;
+}
+
+void command_linest::handle_arg(string &arg)
+{
+ long pos=0;
+ string dest;
+
+ grab_token_string_pos(dest,arg,pos,' ');
+ pos+=dest.length();
+
+ short arg_pos=0;
+ if(dest=="gen")
+ {
+ //KEEP GOING FOR A NUMBER
+ while(pos+1<arg.length())
+ {
+ dest.erase();
+ pos++;
+ auto s=arg.begin(),e=arg.end();
+ s+=pos;
+ bool quote=false;
+ for(;s<e;++s)
+ {
+ if((*s)=='"')
+ {
+ if(quote)break;
+ else quote=true;
+ ++pos;
+ continue;
+ }
+ else if((*s)==' '&&!quote)break;
+ dest+=(*s);
+ }
+ pos+=dest.length();
+
+
+ if(!dest.empty())
+ {
+ if(arg_pos==0)gen_id=convert_string_to_long(dest);
+ if(arg_pos==1)
+ {
+ if(dest!="RANDOM")
+ {
+ world_seed=convert_string_to_ulong(dest);
+ use_seed=1;
+ }
+ }
+ if(arg_pos==2)
+ {
+ if(dest!="NONE")
+ {
+ world_param=dest;
+ use_param=1;
+ }
+ }
+
+ arg_pos++;
+ }
+ }
+ }
+}
\ No newline at end of file diff --git a/g_src/command_line.h b/g_src/command_line.h new file mode 100755 index 0000000..e2606fb --- /dev/null +++ b/g_src/command_line.h @@ -0,0 +1,25 @@ +class command_linest +{ + public: + string original; + stringvectst arg_vect; + + long gen_id; + unsigned long world_seed; + char use_seed; + string world_param; + char use_param; + + + + void init(const string &str); + char grab_arg(string &source,long &pos); + void handle_arg(string &arg); + + command_linest() + { + gen_id=-1; + use_seed=0; + use_param=0; + } +};
\ No newline at end of file diff --git a/g_src/curses.h b/g_src/curses.h new file mode 100755 index 0000000..1253f60 --- /dev/null +++ b/g_src/curses.h @@ -0,0 +1,28 @@ +#ifndef DF_CURSES_H
+#define DF_CURSES_H
+
+extern "C" {
+#include "GL/glew.h"
+#if defined(__unix__) || defined(__APPLE__)
+#ifdef __APPLE__
+# include "ncursesw/curses.h"
+#else
+# include <ncursesw/curses.h>
+#endif
+# undef COLOR_BLUE
+# undef COLOR_CYAN
+# undef COLOR_RED
+# undef COLOR_YELLOW
+# include <dlfcn.h>
+#endif
+}
+
+#if defined(__unix__) || defined(__APPLE__)
+extern "C" {
+ void init_curses();
+ extern WINDOW **stdscr_p;
+};
+#endif
+
+
+#endif
diff --git a/g_src/enabler.cpp b/g_src/enabler.cpp new file mode 100755 index 0000000..282eb34 --- /dev/null +++ b/g_src/enabler.cpp @@ -0,0 +1,968 @@ +#ifdef __APPLE__ +# include "osx_messagebox.h" +#elif defined(unix) +# include <gtk/gtk.h> +#endif + +#include <cassert> + +#include "platform.h" +#include "enabler.h" +#include "random.h" +#include "init.h" +#include "music_and_sound_g.h" + +#ifdef unix +# include <locale.h> +#endif + +using namespace std; + +enablerst enabler; + + +// For the printGLError macro +int glerrorcount = 0; + +// Set to 0 when the game wants to quit +static int loopvar = 1; + +// Reports an error to the user, using a MessageBox and stderr. +void report_error(const char *error_preface, const char *error_message) +{ + char *buf = NULL; + // +4 = +colon +space +newline +nul + buf = new char[strlen(error_preface) + strlen(error_message) + 4]; + sprintf(buf, "%s: %s\n", error_preface, error_message); + MessageBox(NULL, buf, "Error", MB_OK); + fprintf(stderr, "%s", buf); + delete [] buf; +} + +Either<texture_fullid,texture_ttfid> renderer::screen_to_texid(int x, int y) { + const int tile = x * gps.dimy + y; + const unsigned char *s = screen + tile*4; + + struct texture_fullid ret; + int ch; + int bold; + int fg; + int bg; + + // TTF text does not get the full treatment. + if (s[3] == GRAPHICSTYPE_TTF) { + texture_ttfid texpos = *((unsigned int *)s) & 0xffffff; + return Either<texture_fullid,texture_ttfid>(texpos); + } else if (s[3] == GRAPHICSTYPE_TTFCONT) { + // TTFCONT means this is a tile that does not have TTF anchored on it, but is covered by TTF. + // Since this may actually be stale information, we'll draw it as a blank space, + ch = 32; + fg = bg = bold = 0; + } else { + // Otherwise, it's a normal (graphical?) tile. + ch = s[0]; + bold = (s[3] != 0) * 8; + fg = (s[1] + bold) % 16; + bg = s[2] % 16; + } + + static bool use_graphics = init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS); + + if (use_graphics) { + const long texpos = screentexpos[tile]; + const char addcolor = screentexpos_addcolor[tile]; + const unsigned char grayscale = screentexpos_grayscale[tile]; + const unsigned char cf = screentexpos_cf[tile]; + const unsigned char cbr = screentexpos_cbr[tile]; + + if (texpos) { + ret.texpos = texpos; + if (grayscale) { + ret.r = enabler.ccolor[cf][0]; + ret.g = enabler.ccolor[cf][1]; + ret.b = enabler.ccolor[cf][2]; + ret.br = enabler.ccolor[cbr][0]; + ret.bg = enabler.ccolor[cbr][1]; + ret.bb = enabler.ccolor[cbr][2]; + } else if (addcolor) { + goto use_ch; + } else { + ret.r = ret.g = ret.b = 1; + ret.br = ret.bg = ret.bb = 0; + } + goto skip_ch; + } + } + + ret.texpos = enabler.is_fullscreen() ? + init.font.large_font_texpos[ch] : + init.font.small_font_texpos[ch]; + use_ch: + ret.r = enabler.ccolor[fg][0]; + ret.g = enabler.ccolor[fg][1]; + ret.b = enabler.ccolor[fg][2]; + ret.br = enabler.ccolor[bg][0]; + ret.bg = enabler.ccolor[bg][1]; + ret.bb = enabler.ccolor[bg][2]; + + skip_ch: + + return Either<texture_fullid,texture_ttfid>(ret); +} + + +#ifdef CURSES +# include "renderer_curses.cpp" +#endif +#include "renderer_2d.hpp" +#include "renderer_opengl.hpp" + + +enablerst::enablerst() { + fullscreen = false; + sync = NULL; + renderer = NULL; + calculated_fps = calculated_gfps = frame_sum = gframe_sum = frame_last = gframe_last = 0; + fps = 100; gfps = 20; + fps_per_gfps = fps / gfps; + last_tick = 0; +} + +void renderer::display() +{ + const int dimx = init.display.grid_x; + const int dimy = init.display.grid_y; + static bool use_graphics = init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS); + if (gps.force_full_display_count) { + // Update the entire screen + update_all(); + } else { + Uint32 *screenp = (Uint32*)screen, *oldp = (Uint32*)screen_old; + if (use_graphics) { + int off = 0; + for (int x2=0; x2 < dimx; x2++) { + for (int y2=0; y2 < dimy; y2++, ++off, ++screenp, ++oldp) { + // We don't use pointers for the non-screen arrays because we mostly fail at the + // *first* comparison, and having pointers for the others would exceed register + // count. + // Partial printing (and color-conversion): Big-ass if. + if (*screenp == *oldp && + screentexpos[off] == screentexpos_old[off] && + screentexpos_addcolor[off] == screentexpos_addcolor_old[off] && + screentexpos_grayscale[off] == screentexpos_grayscale_old[off] && + screentexpos_cf[off] == screentexpos_cf_old[off] && + screentexpos_cbr[off] == screentexpos_cbr_old[off]) + { + // Nothing's changed, this clause deliberately empty + } else { + update_tile(x2, y2); + } + } + } + } else { + for (int x2=0; x2 < dimx; ++x2) { + for (int y2=0; y2 < dimy; ++y2, ++screenp, ++oldp) { + if (*screenp != *oldp) { + update_tile(x2, y2); + } + } + } + } + } + if (gps.force_full_display_count > 0) gps.force_full_display_count--; +} + +void renderer::cleanup_arrays() { + if (screen) delete[] screen; + if (screentexpos) delete[] screentexpos; + if (screentexpos_addcolor) delete[] screentexpos_addcolor; + if (screentexpos_grayscale) delete[] screentexpos_grayscale; + if (screentexpos_cf) delete[] screentexpos_cf; + if (screentexpos_cbr) delete[] screentexpos_cbr; + if (screen_old) delete[] screen_old; + if (screentexpos_old) delete[] screentexpos_old; + if (screentexpos_addcolor_old) delete[] screentexpos_addcolor_old; + if (screentexpos_grayscale_old) delete[] screentexpos_grayscale_old; + if (screentexpos_cf_old) delete[] screentexpos_cf_old; + if (screentexpos_cbr_old) delete[] screentexpos_cbr_old; +} + +void renderer::gps_allocate(int x, int y) { + cleanup_arrays(); + + gps.screen = screen = new unsigned char[x*y*4]; + memset(screen, 0, x*y*4); + gps.screentexpos = screentexpos = new long[x*y]; + memset(screentexpos, 0, x*y*sizeof(long)); + gps.screentexpos_addcolor = screentexpos_addcolor = new char[x*y]; + memset(screentexpos_addcolor, 0, x*y); + gps.screentexpos_grayscale = screentexpos_grayscale = new unsigned char[x*y]; + memset(screentexpos_grayscale, 0, x*y); + gps.screentexpos_cf = screentexpos_cf = new unsigned char[x*y]; + memset(screentexpos_cf, 0, x*y); + gps.screentexpos_cbr = screentexpos_cbr = new unsigned char[x*y]; + memset(screentexpos_cbr, 0, x*y); + + screen_old = new unsigned char[x*y*4]; + memset(screen_old, 0, x*y*4); + screentexpos_old = new long[x*y]; + memset(screentexpos_old, 0, x*y*sizeof(long)); + screentexpos_addcolor_old = new char[x*y]; + memset(screentexpos_addcolor_old, 0, x*y); + screentexpos_grayscale_old = new unsigned char[x*y]; + memset(screentexpos_grayscale_old, 0, x*y); + screentexpos_cf_old = new unsigned char[x*y]; + memset(screentexpos_cf_old, 0, x*y); + screentexpos_cbr_old = new unsigned char[x*y]; + memset(screentexpos_cbr_old, 0, x*y); + + gps.resize(x,y); +} + +void renderer::swap_arrays() { + screen = screen_old; screen_old = gps.screen; gps.screen = screen; + screentexpos = screentexpos_old; screentexpos_old = gps.screentexpos; gps.screentexpos = screentexpos; + screentexpos_addcolor = screentexpos_addcolor_old; screentexpos_addcolor_old = gps.screentexpos_addcolor; gps.screentexpos_addcolor = screentexpos_addcolor; + screentexpos_grayscale = screentexpos_grayscale_old; screentexpos_grayscale_old = gps.screentexpos_grayscale; gps.screentexpos_grayscale = screentexpos_grayscale; + screentexpos_cf = screentexpos_cf_old; screentexpos_cf_old = gps.screentexpos_cf; gps.screentexpos_cf = screentexpos_cf; + screentexpos_cbr = screentexpos_cbr_old; screentexpos_cbr_old = gps.screentexpos_cbr; gps.screentexpos_cbr = screentexpos_cbr; + + gps.screen_limit = gps.screen + gps.dimx * gps.dimy * 4; +} + +void enablerst::pause_async_loop() { + struct async_cmd cmd; + cmd.cmd = async_cmd::pause; + async_tobox.write(cmd); + async_wait(); +} + +// Wait until the previous command has been acknowledged, /or/ +// async_loop has quit. Incidentally execute any requests in the +// meantime. +void enablerst::async_wait() { + if (loopvar == 0) return; + async_msg r; + bool reset_textures = false; + for (;;) { + async_frombox.read(r); + switch (r.msg) { + case async_msg::quit: + loopvar = 0; + return; + case async_msg::complete: + if (reset_textures) { + puts("Resetting textures"); + textures.remove_uploaded_textures(); + textures.upload_textures(); + } + return; + case async_msg::set_fps: + set_fps(r.fps); + async_fromcomplete.write(); + break; + case async_msg::set_gfps: + set_gfps(r.fps); + async_fromcomplete.write(); + break; + case async_msg::push_resize: + override_grid_size(r.x, r.y); + async_fromcomplete.write(); + break; + case async_msg::pop_resize: + release_grid_size(); + async_fromcomplete.write(); + break; + case async_msg::reset_textures: + reset_textures = true; + break; + default: + puts("EMERGENCY: Unknown case in async_wait"); + abort(); + } + } +} + +void enablerst::async_loop() { + async_paused = false; + async_frames = 0; + int total_frames = 0; + int fps = 100; // Just a thread-local copy + for (;;) { + // cout << "FRAMES: " << frames << endl; + // Check for commands + async_cmd cmd; + bool have_cmd = true; + do { + if (async_paused || (async_frames == 0 && !(enabler.flag & ENABLERFLAG_MAXFPS))) + async_tobox.read(cmd); + else + have_cmd = async_tobox.try_read(cmd); + // Obey the command, would you kindly. + if (have_cmd) { + switch (cmd.cmd) { + case async_cmd::pause: + async_paused = true; + // puts("Paused"); + async_frombox.write(async_msg(async_msg::complete)); + break; + case async_cmd::start: + async_paused = false; + async_frames = 0; + // puts("UNpaused"); + break; + case async_cmd::render: + if (flag & ENABLERFLAG_RENDER) { + total_frames++; + renderer->swap_arrays(); + if (total_frames % 1800 == 0) + ttf_manager.gc(); + render_things(); + flag &= ~ENABLERFLAG_RENDER; + update_gfps(); + } + async_frombox.write(async_msg(async_msg::complete)); + break; + case async_cmd::inc: + async_frames += cmd.val; + if (async_frames > fps*3) async_frames = fps*3; // Just in case + break; + case async_cmd::set_fps: + fps = cmd.val; + break; + } + } + } while (have_cmd); + // Run the main-loop, maybe + if (!async_paused && (async_frames || (enabler.flag & ENABLERFLAG_MAXFPS))) { + if (mainloop()) { + async_frombox.write(async_msg(async_msg::quit)); + return; // We're done. + } + simticks.lock(); + simticks.val++; + simticks.unlock(); + async_frames--; + if (async_frames < 0) async_frames = 0; + update_fps(); + } + SDL_NumJoysticks(); // Hook for dfhack + } +} + +void enablerst::do_frame() { + // Check how long it's been, exactly + const Uint32 now = SDL_GetTicks(); + const Uint32 interval = CLAMP(now - last_tick, 0, 1000); // Anything above a second doesn't count + // cout << last_tick << " + " << interval << " = " << now << endl; + last_tick = now; + + // Update outstanding-frame counts + outstanding_frames += interval * fps / 1000; + outstanding_gframes += interval * gfps / 1000; + if (outstanding_gframes > 3) { + outstanding_gframes = 3; + } + // cout << outstanding_frames << " " << outstanding_gframes << endl; + + // Update the loop's tick-counter suitably + if (outstanding_frames >= 1) { + async_cmd cmd(async_cmd::inc); + cmd.val = outstanding_frames; + outstanding_frames -= cmd.val; + async_tobox.write(cmd); + } + + // Store the current time, for things that are fine with approximations + enabler.clock = SDL_GetTicks(); + + // If it's time to render.. + if (outstanding_gframes >= 1 && + (!sync || glClientWaitSync(sync, 0, 0) == GL_ALREADY_SIGNALED)) { + // Get the async-loop to render_things + async_cmd cmd(async_cmd::render); + async_tobox.write(cmd); + async_wait(); + // Then finish here + renderer->display(); + renderer->render(); + gputicks.lock(); + gputicks.val++; + gputicks.unlock(); + outstanding_gframes--; + } + + // Sleep until the next gframe + if (outstanding_gframes < 1) { + float fragment = 1 - outstanding_gframes; + float milliseconds = fragment / gfps * 1000; + // cout << milliseconds << endl; + SDL_Delay(milliseconds); + } +} + +void enablerst::eventLoop_SDL() +{ + + SDL_Event event; + const SDL_Surface *screen = SDL_GetVideoSurface(); + Uint32 mouse_lastused = 0; + SDL_ShowCursor(SDL_DISABLE); + + // Initialize the grid + renderer->resize(screen->w, screen->h); + + while (loopvar) { + Uint32 now = SDL_GetTicks(); + bool paused_loop = false; + + // Check for zoom commands + zoom_commands zoom; + while (async_zoom.try_read(zoom)) { + if (overridden_grid_sizes.size()) + continue; // No zooming in movies + if (!paused_loop) { + pause_async_loop(); + paused_loop = true; + } + if (zoom == zoom_fullscreen) + renderer->set_fullscreen(); + else + renderer->zoom(zoom); + } + + // Check for SDL events + while (SDL_PollEvent(&event)) { + // Make sure mainloop isn't running while we're processing input + if (!paused_loop) { + pause_async_loop(); + paused_loop = true; + } + // Handle SDL events + switch (event.type) { + case SDL_KEYDOWN: + // Disable mouse if it's been long enough + if (mouse_lastused + 5000 < now) { + if(init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_PICTURE)) { + // hide the mouse picture + // enabler.set_tile(0, TEXTURE_MOUSE, enabler.mouse_x, enabler.mouse_y); + } + SDL_ShowCursor(SDL_DISABLE); + } + case SDL_KEYUP: + case SDL_QUIT: + enabler.add_input(event, now); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + if (!init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_OFF)) { + int isdown = (event.type == SDL_MOUSEBUTTONDOWN); + if (event.button.button == SDL_BUTTON_LEFT) { + enabler.mouse_lbut = isdown; + enabler.mouse_lbut_down = isdown; + if (!isdown) + enabler.mouse_lbut_lift = 0; + } else if (event.button.button == SDL_BUTTON_RIGHT) { + enabler.mouse_rbut = isdown; + enabler.mouse_rbut_down = isdown; + if (!isdown) + enabler.mouse_rbut_lift = 0; + } else + enabler.add_input(event, now); + } + break; + case SDL_MOUSEMOTION: + // Deal with the mouse hiding bit + mouse_lastused = now; + if(init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_PICTURE)) { + // turn on mouse picture + // enabler.set_tile(gps.tex_pos[TEXTURE_MOUSE], TEXTURE_MOUSE,enabler.mouse_x, enabler.mouse_y); + } else { + SDL_ShowCursor(SDL_ENABLE); + } + break; + case SDL_ACTIVEEVENT: + enabler.clear_input(); + if (event.active.state & SDL_APPACTIVE) { + if (event.active.gain) { + enabler.flag|=ENABLERFLAG_RENDER; + gps.force_full_display_count++; + } + } + break; + case SDL_VIDEOEXPOSE: + gps.force_full_display_count++; + enabler.flag|=ENABLERFLAG_RENDER; + break; + case SDL_VIDEORESIZE: + if (is_fullscreen()); + //errorlog << "Caught resize event in fullscreen??\n"; + else { + //gamelog << "Resizing window to " << event.resize.w << "x" << event.resize.h << endl << flush; + renderer->resize(event.resize.w, event.resize.h); + } + break; + } // switch (event.type) + } //while have event + + // Update mouse state + if (!init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_OFF)) { + int mouse_x = -1, mouse_y = -1, mouse_state; + // Check whether the renderer considers this valid input or not, and write it to gps + if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && + renderer->get_mouse_coords(mouse_x, mouse_y)) { + mouse_state = 1; + } else { + mouse_state = 0; + } + if (mouse_x != gps.mouse_x || mouse_y != gps.mouse_y || + mouse_state != enabler.tracking_on) { + // Pause rendering loop and update values + if (!paused_loop) { + pause_async_loop(); + paused_loop = true; + } + enabler.tracking_on = mouse_state; + gps.mouse_x = mouse_x; + gps.mouse_y = mouse_y; + } + } + + if (paused_loop) + unpause_async_loop(); + + do_frame(); +#if !defined(NO_FMOD) + // Call FMOD::System.update(). Manages a bunch of sound stuff. + musicsound.update(); +#endif + } +} + +int enablerst::loop(string cmdline) { + command_line = cmdline; + + // Initialize the tick counters + simticks.write(0); + gputicks.write(0); + + // Call DF's initialization routine + if (!beginroutine()) + exit(EXIT_FAILURE); + + // Allocate a renderer + if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) { +#ifdef CURSES + renderer = new renderer_curses(); +#else + report_error("PRINT_MODE", "TEXT not supported on windows"); + exit(EXIT_FAILURE); +#endif + } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_2D)) { + renderer = new renderer_2d(); + } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_ACCUM_BUFFER)) { + renderer = new renderer_accum_buffer(); + } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_FRAME_BUFFER)) { + renderer = new renderer_framebuffer(); + } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT)) { + if (init.display.partial_print_count) + renderer = new renderer_partial(); + else + renderer = new renderer_once(); + } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_VBO)) { + renderer = new renderer_vbo(); + } else { + renderer = new renderer_opengl(); + } + + // At this point we should have a window that is setup to render DF. + if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) { +#ifdef CURSES + eventLoop_ncurses(); +#endif + } else { + SDL_EnableUNICODE(1); + eventLoop_SDL(); + } + + endroutine(); + + // Clean up graphical resources + delete renderer; +} + +void enablerst::override_grid_size(int x, int y) { + if (SDL_ThreadID() != renderer_threadid) { + // Ask the renderer to do it + async_msg m(async_msg::push_resize); + m.x = x; m.y = y; + async_frombox.write(m); + async_fromcomplete.read(); + } else { + // We are the renderer; do it. + overridden_grid_sizes.push(make_pair(init.display.grid_x,init.display.grid_y)); + renderer->grid_resize(x, y); + } +} + +void enablerst::release_grid_size() { + if (SDL_ThreadID() != renderer_threadid) { + async_frombox.write(async_msg(async_msg::pop_resize)); + async_fromcomplete.read(); + } else { + if (!overridden_grid_sizes.size()) return; + // FIXME: Find out whatever is causing release to be called too rarely; right now + // we're overriding once per movie but apparently only releasing for the last one. + pair<int,int> sz; + while (overridden_grid_sizes.size()) { + sz = overridden_grid_sizes.top(); + overridden_grid_sizes.pop(); + } + zoom_display(zoom_resetgrid); + } +} + +void enablerst::zoom_display(zoom_commands command) { + async_zoom.write(command); +} + +int enablerst::calculate_fps() { + if (frame_timings.size() < 50) + return get_fps(); + else + return calculated_fps; +} +int enablerst::calculate_gfps() { + if (gframe_timings.size() < 50) + return get_gfps(); + else + return calculated_gfps; +} + +void enablerst::do_update_fps(queue<int> &q, int &sum, int &last, int &calc) { + while (q.size() > 50 && sum > 10000) { + sum -= q.front(); + q.pop(); + } + const int now = SDL_GetTicks(); + const int interval = now - last; + q.push(interval); + sum += interval; + last = now; + if (sum) + calc = q.size() * 1000 / sum; +} + +void enablerst::clear_fps() { + while (frame_timings.size()) + frame_timings.pop(); + frame_sum = 0; + frame_last = SDL_GetTicks(); + calculated_fps = get_fps(); +} + +void enablerst::update_fps() { + do_update_fps(frame_timings, frame_sum, frame_last, calculated_fps); +} + +void enablerst::update_gfps() { + do_update_fps(gframe_timings, gframe_sum, gframe_last, calculated_gfps); +} + +void enablerst::set_fps(int fps) { + if (SDL_ThreadID() != renderer_threadid) { + async_msg m(async_msg::set_fps); + m.fps = fps; + async_paused = true; + async_frombox.write(m); + async_fromcomplete.read(); + } else { + if (fps == 0) + fps = 1048576; + this->fps = fps; + fps_per_gfps = fps / gfps; + struct async_cmd cmd; + cmd.cmd = async_cmd::set_fps; + cmd.val = fps; + async_tobox.write(cmd); + async_tobox.write(async_cmd(async_cmd::start)); + } +} + +void enablerst::set_gfps(int gfps) { + if (SDL_ThreadID() != renderer_threadid) { + async_msg m(async_msg::set_gfps); + m.fps = gfps; + async_frombox.write(m); + async_fromcomplete.read(); + } else { + if (gfps == 0) + gfps = 50; + this->gfps = gfps; + fps_per_gfps = fps / gfps; + } +} + +int call_loop(void *dummy) { + enabler.async_loop(); + return 0; +} + +int main (int argc, char* argv[]) { +#ifdef unix + setlocale(LC_ALL, ""); +#endif +#if !defined(__APPLE__) && defined(unix) + bool gtk_ok = false; + if (getenv("DISPLAY")) + gtk_ok = gtk_init_check(&argc, &argv); +#endif + + // Initialise minimal SDL subsystems. + int retval = SDL_Init(SDL_INIT_TIMER); + // Report failure? + if (retval != 0) { + report_error("SDL initialization failure", SDL_GetError()); + return false; + } + enabler.renderer_threadid = SDL_ThreadID(); + + // Spawn simulation thread + SDL_CreateThread(call_loop, NULL); + + init.begin(); // Load init.txt settings + +#if !defined(__APPLE__) && defined(unix) + if (!gtk_ok && !init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) { + puts("Display not found and PRINT_MODE not set to TEXT, aborting."); + exit(EXIT_FAILURE); + } + if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT) && + init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS)) { + puts("Graphical tiles are not compatible with text output, sorry"); + exit(EXIT_FAILURE); + } +#endif + + // Initialize video, if we /use/ video + retval = SDL_InitSubSystem(init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT) ? 0 : SDL_INIT_VIDEO); + if (retval != 0) { + report_error("SDL initialization failure", SDL_GetError()); + return false; + } + +#ifdef linux + if (!init.media.flag.has_flag(INIT_MEDIA_FLAG_SOUND_OFF)) { + // Initialize OpenAL + if (!musicsound.initsound()) { + puts("Initializing OpenAL failed, no sound will be played"); + init.media.flag.add_flag(INIT_MEDIA_FLAG_SOUND_OFF); + } + } +#endif + +#ifdef WIN32 + // Attempt to get as good a timer as possible + int ms = 1; + while (timeBeginPeriod(ms) != TIMERR_NOERROR) ms++; +#endif + + // Load keyboard map + keybinding_init(); + enabler.load_keybindings("data/init/interface.txt"); + + string cmdLine; + for (int i = 1; i < argc; ++i) { + char *option = argv[i]; + string opt=option; + if(opt.length()>=1) + { + //main removes quotes, unlike the winmain version, so it has to be rebuilt + if(opt[0]=='-') + { + cmdLine += opt; + cmdLine += " "; + } + else + { + cmdLine += "\""; + cmdLine += opt; + cmdLine += "\""; + cmdLine += " "; + } + } + } + int result = enabler.loop(cmdLine); + + SDL_Quit(); + +#ifdef WIN32 + timeEndPeriod(ms); +#endif + + return result; +} + +void text_system_file_infost::initialize_info() +{ + std::ifstream fseed(filename.c_str()); + if(fseed.is_open()) + { + string str; + + while(std::getline(fseed,str)) + { + if(str.length()>0)number++; + } + } + else + { + string str; + str="Error Initializing Text: "; + str+=filename; + errorlog_string(str); + } + fseed.close(); +} + +void text_system_file_infost::get_text(text_infost &text) +{ + text.clean(); + + if(number==0)return; + + std::ifstream fseed(filename.c_str()); + if(fseed.is_open()) + { + string str; + + int num=trandom(number); + + //SKIP AHEAD TO THE RIGHT SPOT + while(num>0) + { + std::getline(fseed,str); + num--; + } + + //PROCESS THE STRING INTO TEXT ELEMENTS + if(std::getline(fseed,str)) + { + int curpos; + string nextstr; + char doing_long=0; + + text_info_elementst *newel; + long end=str.length(); + + while(end>0) + { + if(isspace(str[end-1]))end--; + else break; + } + + str.resize(end); + + for(curpos=0;curpos<end;curpos++) + { + //HANDLE TOKEN OR ENDING + //TWO FILE TOKENS IN A ROW MEANS LONG + //ONE MEANS STRING + if(str[curpos]==file_token || curpos==end-1) + { + if(str[curpos]!=file_token)nextstr+=str[curpos]; + + //HAVE SOMETHING == SAVE IT + if(!nextstr.empty()) + { + if(doing_long) + { + newel=new text_info_element_longst(atoi(nextstr.c_str())); + text.element.push_back(newel); + doing_long=0; + } + else + { + newel=new text_info_element_stringst(nextstr); + text.element.push_back(newel); + } + + nextstr.erase(); + } + //STARTING A LONG + else + { + doing_long=1; + } + } + //JUST ADD IN ANYTHING ELSE + else + { + nextstr+=str[curpos]; + } + } + } + } + fseed.close(); +} + +void curses_text_boxst::add_paragraph(const string &src,int32_t para_width) +{ + stringvectst sp; + sp.add_string(src); + add_paragraph(sp,para_width); +} + +void curses_text_boxst::add_paragraph(stringvectst &src,int32_t para_width) +{ + bool skip_leading_spaces=false; + + //ADD EACH OF THE STRINGS ON IN TURN + string curstr; + long strlength=0; + long s,pos; + for(s=0;s<src.str.size();s++) + { + //GRAB EACH WORD, AND SEE IF IT FITS, IF NOT START A NEW LINE + for(pos=0;pos<src.str[s]->dat.size();pos++) + { + if(skip_leading_spaces) + { + if(src.str[s]->dat[pos]==' ')continue; + else skip_leading_spaces=false; + } + + //ADD TO WORD + curstr+=src.str[s]->dat[pos]; + + //IF TOO LONG, CUT BACK TO FIRST SPACE + if(curstr.length()>para_width) + { + long opos=pos; + + long minus=0; + do + { + pos--; + minus++; + }while(src.str[s]->dat[pos]!=' '&&pos>0); + + //IF WENT ALL THE WAY BACK, INTRODUCE A SPACE + if(minus==curstr.size()) + { + src.str[s]->dat.insert(opos-1," "); + } + else + { + curstr.resize(curstr.size()-minus); + text.add_string(curstr); + skip_leading_spaces=true; + } + curstr.erase(); + } + } + } + + //FLUSH FINAL BIT + if(!curstr.empty())text.add_string(curstr); +} diff --git a/g_src/enabler.h b/g_src/enabler.h new file mode 100755 index 0000000..f524e1d --- /dev/null +++ b/g_src/enabler.h @@ -0,0 +1,1027 @@ +//some of this stuff is based on public domain code from nehe or opengl books over the years
+//additions and modifications Copyright (c) 2008, Tarn Adams
+//All rights reserved. See game.cpp or license.txt for more information.
+
+#ifndef ENABLER_H
+#define ENABLER_H
+
+#include "platform.h"
+#include <SDL/SDL.h>
+#include <SDL/SDL_thread.h>
+#ifdef __APPLE__
+# include <SDL_ttf/SDL_ttf.h>
+# include <SDL_image/SDL_image.h>
+#else
+# include <SDL/SDL_ttf.h>
+# include <SDL/SDL_image.h>
+#endif
+
+#include "GL/glew.h"
+
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <utility>
+#include <list>
+#include <iostream>
+#include <sstream>
+#include <stack>
+#include <queue>
+#include <set>
+#include <functional>
+
+using std::vector;
+using std::pair;
+using std::map;
+using std::set;
+using std::list;
+using std::stack;
+using std::queue;
+
+#include "basics.h"
+#include "svector.h"
+#include "endian.h"
+#include "files.h"
+#include "enabler_input.h"
+#include "mail.hpp"
+
+#define ENABLER
+
+#ifndef BITS
+
+#define BITS
+
+#define BIT1 1
+#define BIT2 2
+#define BIT3 4
+#define BIT4 8
+#define BIT5 16
+#define BIT6 32
+#define BIT7 64
+#define BIT8 128
+#define BIT9 256
+#define BIT10 512
+#define BIT11 1024
+#define BIT12 2048
+#define BIT13 4096
+#define BIT14 8192
+#define BIT15 16384
+#define BIT16 32768
+#define BIT17 65536UL
+#define BIT18 131072UL
+#define BIT19 262144UL
+#define BIT20 524288UL
+#define BIT21 1048576UL
+#define BIT22 2097152UL
+#define BIT23 4194304UL
+#define BIT24 8388608UL
+#define BIT25 16777216UL
+#define BIT26 33554432UL
+#define BIT27 67108864UL
+#define BIT28 134217728UL
+#define BIT29 268435456UL
+#define BIT30 536870912UL
+#define BIT31 1073741824UL
+#define BIT32 2147483648UL
+
+#endif
+
+#define GAME_TITLE_STRING "Dwarf Fortress"
+
+class pstringst
+{
+ public:
+ string dat;
+};
+
+class stringvectst
+{
+ public:
+ svector<pstringst *> str;
+
+ void add_string(const string &st)
+ {
+ pstringst *newp=new pstringst;
+ newp->dat=st;
+ str.push_back(newp);
+ }
+
+ long add_unique_string(const string &st)
+ {
+ long i;
+ for(i=(long)str.size()-1;i>=0;i--)
+ {
+ if(str[i]->dat==st)return i;
+ }
+ add_string(st);
+ return (long)str.size()-1;
+ }
+
+ void add_string(const char *st)
+ {
+ if(st!=NULL)
+ {
+ pstringst *newp=new pstringst;
+ newp->dat=st;
+ str.push_back(newp);
+ }
+ }
+
+ void insert_string(long k,const string &st)
+ {
+ pstringst *newp=new pstringst;
+ newp->dat=st;
+ if(str.size()>k)str.insert(k,newp);
+ else str.push_back(newp);
+ }
+
+ ~stringvectst()
+ {
+ clean();
+ }
+
+ void clean()
+ {
+ while(str.size()>0)
+ {
+ delete str[0];
+ str.erase(0);
+ }
+ }
+
+ void read_file(file_compressorst &filecomp,long loadversion)
+ {
+ long dummy;
+ filecomp.read_file(dummy);
+ str.resize(dummy);
+
+ long s;
+ for(s=0;s<dummy;s++)
+ {
+ str[s]=new pstringst;
+ filecomp.read_file(str[s]->dat);
+ }
+ }
+ void write_file(file_compressorst &filecomp)
+ {
+ long dummy=str.size();
+ filecomp.write_file(dummy);
+
+ long s;
+ for(s=0;s<dummy;s++)
+ {
+ filecomp.write_file(str[s]->dat);
+ }
+ }
+
+ void copy_from(stringvectst &src)
+ {
+ clean();
+
+ str.resize(src.str.size());
+
+ long s;
+ for(s=(long)src.str.size()-1;s>=0;s--)
+ {
+ str[s]=new pstringst;
+ str[s]->dat=src.str[s]->dat;
+ }
+ }
+
+ bool has_string(const string &st)
+ {
+ long i;
+ for(i=(long)str.size()-1;i>=0;i--)
+ {
+ if(str[i]->dat==st)return true;
+ }
+ return false;
+ }
+
+ void remove_string(const string &st)
+ {
+ long i;
+ for(i=(long)str.size()-1;i>=0;i--)
+ {
+ if(str[i]->dat==st)
+ {
+ delete str[i];
+ str.erase(i);
+ }
+ }
+ }
+
+ void operator=(stringvectst &two);
+};
+
+class flagarrayst
+{
+ public:
+ flagarrayst()
+ {
+ slotnum=0;
+ array=NULL;
+ }
+ ~flagarrayst()
+ {
+ if(array!=NULL)delete[] array;
+ array=NULL;
+ slotnum=0;
+ }
+
+ void set_size_on_flag_num(long flagnum)
+ {
+ if(flagnum<=0)return;
+
+ set_size(((flagnum-1)>>3)+1);
+ }
+
+ void set_size(long newsize)
+ {
+ if(newsize<=0)return;
+
+ if(array!=NULL)delete[] array;
+ array=new unsigned char[newsize];
+ memset(array,0,sizeof(unsigned char)*newsize);
+
+ slotnum=newsize;
+ }
+
+ void clear_all()
+ {
+ if(slotnum<=0)return;
+
+ if(array!=NULL)memset(array,0,sizeof(unsigned char)*slotnum);
+ }
+
+ void copy_from(flagarrayst &src)
+ {
+ clear_all();
+
+ if(src.slotnum>0)
+ {
+ set_size(src.slotnum);
+ memmove(array,src.array,sizeof(unsigned char)*slotnum);
+ }
+ }
+
+ bool has_flag(long checkflag)
+ {
+ if(checkflag<0)return false;
+ long slot=checkflag>>3;
+ return (slot>=0&&slot<slotnum&&((array[slot] & (1<<(checkflag&7)))!=0));
+ }
+
+ void add_flag(long checkflag)
+ {
+ if(checkflag<0)return;
+ long slot=checkflag>>3;
+ if(slot>=0&&slot<slotnum)array[slot]|=(1<<(checkflag&7));
+ }
+
+ void toggle_flag(long checkflag)
+ {
+ if(checkflag<0)return;
+ long slot=checkflag>>3;
+ if(slot>=0&&slot<slotnum)array[slot]^=(1<<(checkflag&7));
+ }
+
+ void remove_flag(long checkflag)
+ {
+ if(checkflag<0)return;
+ long slot=checkflag>>3;
+ if(slot>=0&&slot<slotnum)array[slot]&=~(1<<(checkflag&7));
+ }
+
+ void write_file(file_compressorst &filecomp)
+ {
+ filecomp.write_file(slotnum);
+ if(slotnum>0)
+ {
+ long ind;
+ for(ind=0;ind<slotnum;ind++)filecomp.write_file(array[ind]);
+ }
+ }
+
+ void read_file(file_compressorst &filecomp,long loadversion)
+ {
+ long newsl;
+ filecomp.read_file(newsl);
+ if(newsl>0)
+ {
+ //AVOID UNNECESSARY DELETE/NEW
+ if(array!=NULL&&slotnum!=newsl)
+ {
+ delete[] array;
+ array=new unsigned char[newsl];
+ }
+ if(array==NULL)array=new unsigned char[newsl];
+
+ long ind;
+ for(ind=0;ind<newsl;ind++)filecomp.read_file(array[ind]);
+
+ slotnum=newsl;
+ }
+ else if(array!=NULL)
+ {
+ delete[] array;
+ array=NULL;
+
+ slotnum=0;
+ }
+ }
+
+ private:
+ unsigned char *array;
+ long slotnum;
+};
+
+#ifdef ENABLER
+
+#define COLOR_BLACK 0
+#define COLOR_BLUE 1
+#define COLOR_GREEN 2
+#define COLOR_CYAN 3
+#define COLOR_RED 4
+#define COLOR_MAGENTA 5
+#define COLOR_YELLOW 6
+#define COLOR_WHITE 7
+
+enum ColorData
+ {
+ COLOR_DATA_WHITE_R,
+ COLOR_DATA_WHITE_G,
+ COLOR_DATA_WHITE_B,
+ COLOR_DATA_RED_R,
+ COLOR_DATA_RED_G,
+ COLOR_DATA_RED_B,
+ COLOR_DATA_GREEN_R,
+ COLOR_DATA_GREEN_G,
+ COLOR_DATA_GREEN_B,
+ COLOR_DATA_BLUE_R,
+ COLOR_DATA_BLUE_G,
+ COLOR_DATA_BLUE_B,
+ COLOR_DATA_YELLOW_R,
+ COLOR_DATA_YELLOW_G,
+ COLOR_DATA_YELLOW_B,
+ COLOR_DATA_MAGENTA_R,
+ COLOR_DATA_MAGENTA_G,
+ COLOR_DATA_MAGENTA_B,
+ COLOR_DATA_CYAN_R,
+ COLOR_DATA_CYAN_G,
+ COLOR_DATA_CYAN_B,
+ COLOR_DATANUM
+ };
+
+#define TILEFLAG_DEAD BIT1
+#define TILEFLAG_ROTATE BIT2
+#define TILEFLAG_PIXRECT BIT3
+#define TILEFLAG_HORFLIP BIT4
+#define TILEFLAG_VERFLIP BIT5
+#define TILEFLAG_LINE BIT6
+#define TILEFLAG_RECT BIT7
+#define TILEFLAG_BUFFER_DRAW BIT8
+#define TILEFLAG_MODEL_PERSPECTIVE BIT9
+#define TILEFLAG_MODEL_ORTHO BIT10
+#define TILEFLAG_MODEL_TRANSLATE BIT11
+#define TILEFLAG_LINE_3D BIT12
+
+#define TRIMAX 9999
+
+enum render_phase {
+ setup, // 0
+ complete,
+ phase_count
+};
+
+class texture_bo {
+ GLuint bo, tbo;
+ public:
+ texture_bo() { bo = tbo = 0; }
+ void reset() {
+ if (bo) {
+ glDeleteBuffers(1, &bo);
+ glDeleteTextures(1, &tbo);
+ bo = tbo = 0;
+ printGLError();
+ }
+ }
+ void buffer(GLvoid *ptr, GLsizeiptr sz) {
+ if (bo) reset();
+ glGenBuffersARB(1, &bo);
+ glGenTextures(1, &tbo);
+ glBindBufferARB(GL_TEXTURE_BUFFER_ARB, bo);
+ glBufferDataARB(GL_TEXTURE_BUFFER_ARB, sz, ptr, GL_STATIC_DRAW_ARB);
+ printGLError();
+ }
+ void bind(GLenum texture_unit, GLenum type) {
+ glActiveTexture(texture_unit);
+ glBindTexture(GL_TEXTURE_BUFFER_ARB, tbo);
+ glTexBufferARB(GL_TEXTURE_BUFFER_ARB, type, bo);
+ printGLError();
+ }
+ GLuint texnum() { return tbo; }
+};
+
+
+class shader {
+ string filename;
+ std::ostringstream lines;
+ public:
+ std::ostringstream header;
+ void load(const string &filename) {
+ this->filename = filename;
+ std::ifstream file(filename.c_str());
+ string version;
+ getline(file, version);
+ header << version << std::endl;
+ while (file.good()) {
+ string line;
+ getline(file, line);
+ lines << line << std::endl;
+ }
+ file.close();
+ }
+ GLuint upload(GLenum type) {
+ GLuint shader = glCreateShader(type);
+ string lines_done = lines.str(), header_done = header.str();
+ const char *ptrs[3];
+ ptrs[0] = header_done.c_str();
+ ptrs[1] = "#line 1 0\n";
+ ptrs[2] = lines_done.c_str();
+ glShaderSource(shader, 3, ptrs, NULL);
+ glCompileShader(shader);
+ // Let's see if this compiled correctly..
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE) { // ..no. Check the compilation log.
+ GLint log_size;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_size);
+ //errorlog << filename << " preprocessed source:" << std::endl;
+ std::cerr << filename << " preprocessed source:" << std::endl;
+ //errorlog << header_done << "#line 1 0\n" << lines_done;
+ std::cerr << header_done << "#line 1 0\n" << lines_done;
+ //errorlog << filename << " shader compilation log (" << log_size << "):" << std::endl;
+ std::cerr << filename << " shader compilation log (" << log_size << "):" << std::endl;
+ char *buf = new char[log_size];
+ glGetShaderInfoLog(shader, log_size, NULL, buf);
+ //errorlog << buf << std::endl;
+ std::cerr << buf << std::endl;
+ //errorlog.flush();
+ delete[] buf;
+ MessageBox(NULL, "Shader compilation failed; details in errorlog.txt", "Critical error", MB_OK);
+ abort();
+ }
+ printGLError();
+ return shader;
+ }
+};
+
+
+class text_info_elementst
+{
+ public:
+ virtual string get_string()
+ {
+ string empty;
+ return empty;
+ }
+ virtual long get_long()
+ {
+ return 0;
+ }
+
+ virtual ~text_info_elementst(){}
+};
+
+class text_info_element_stringst : public text_info_elementst
+{
+ public:
+ virtual string get_string()
+ {
+ return str;
+ }
+ text_info_element_stringst(const string &newstr)
+ {
+ str=newstr;
+ }
+
+ protected:
+ string str;
+};
+
+class text_info_element_longst : public text_info_elementst
+{
+ public:
+ virtual long get_long()
+ {
+ return val;
+ }
+ text_info_element_longst(long nval)
+ {
+ val=nval;
+ }
+
+ protected:
+ long val;
+};
+
+class text_infost
+{
+ public:
+ svector<text_info_elementst *> element;
+
+ void clean()
+ {
+ while(element.size()>0)
+ {
+ delete element[0];
+ element.erase(0);
+ }
+ }
+
+ string get_string(int e)
+ {
+ if(e<0||e>=element.size())
+ {
+ string empty;
+ return empty;
+ }
+ if(element[e]==NULL)
+ {
+ string empty;
+ return empty;
+ }
+ return element[e]->get_string();
+ }
+
+ long get_long(int e)
+ {
+ if(e<0||e>=element.size())
+ {
+ return 0;
+ }
+ if(element[e]==NULL)
+ {
+ return 0;
+ }
+ return element[e]->get_long();
+ }
+
+ ~text_infost()
+ {
+ clean();
+ }
+};
+
+class text_system_file_infost
+{
+ public:
+ long index;
+ string filename;
+
+ static text_system_file_infost *add_file_info(const string &newf,long newi,char newft)
+ {
+ return new text_system_file_infost(newf,newi,newft);
+ }
+
+ void initialize_info();
+ void get_text(text_infost &text);
+ void get_specific_text(text_infost &text,long num);
+
+ protected:
+ char file_token;
+ long number;
+
+ text_system_file_infost(const string &newf,long newi,char newft)
+ {
+ filename=newf;
+ file_token=newft;
+ index=newi;
+ number=0;
+ }
+};
+
+class text_systemst
+{
+ public:
+ void register_file_fixed(const string &file_name,int32_t index,char token,char initialize)
+ {
+ text_system_file_infost *tsfi=text_system_file_infost::add_file_info(file_name,index,token);
+ if(initialize)tsfi->initialize_info();
+ file_info.push_back(tsfi);
+ }
+ void register_file(const string &file_name,int32_t &index,char token,char initialize)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->filename==file_name)
+ {
+ //RESET CALLING INDEX AND BAIL IF THIS FILE IS ALREADY IN THE SYSTEM
+ index=file_info[t]->index;
+ return;
+ }
+ }
+
+ text_system_file_infost *tsfi=text_system_file_infost::add_file_info(file_name,index,token);
+ if(initialize)tsfi->initialize_info();
+ file_info.push_back(tsfi);
+ }
+ void initialize_system()
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)file_info[t]->initialize_info();
+ }
+ void get_text(int32_t index,text_infost &text)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->index==index)
+ {
+ file_info[t]->get_text(text);
+ return;
+ }
+ }
+ }
+ void get_text(const string &file_name,text_infost &text)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->filename==file_name)
+ {
+ file_info[t]->get_text(text);
+ return;
+ }
+ }
+ }
+ void get_specific_text(int32_t index,text_infost &text,int32_t num)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->index==index)
+ {
+ file_info[t]->get_specific_text(text,num);
+ return;
+ }
+ }
+ }
+
+ ~text_systemst()
+ {
+ while(file_info.size()>0)
+ {
+ delete file_info[0];
+ file_info.erase(0);
+ }
+ }
+
+ protected:
+ svector<text_system_file_infost *> file_info;
+};
+
+class curses_text_boxst
+{
+ public:
+ stringvectst text;
+
+ void add_paragraph(stringvectst &src,int32_t para_width);
+ void add_paragraph(const string &src,int32_t para_width);
+
+ void read_file(file_compressorst &filecomp,int32_t loadversion)
+ {
+ text.read_file(filecomp,loadversion);
+ }
+ void write_file(file_compressorst &filecomp)
+ {
+ text.write_file(filecomp);
+ }
+ void clean()
+ {
+ text.clean();
+ }
+};
+
+#define COPYTEXTUREFLAG_HORFLIP BIT1
+#define COPYTEXTUREFLAG_VERFLIP BIT2
+
+#define ENABLERFLAG_RENDER BIT1
+#define ENABLERFLAG_MAXFPS BIT2
+
+// GL texture positions
+struct gl_texpos {
+ GLfloat left, right, top, bottom;
+};
+
+// Covers every allowed permutation of text
+struct ttf_id {
+ std::string text;
+ unsigned char fg, bg, bold;
+
+ bool operator< (const ttf_id &other) const {
+ if (fg != other.fg) return fg < other.fg;
+ if (bg != other.bg) return bg < other.bg;
+ if (bold != other.bold) return bold < other.bold;
+ return text < other.text;
+ }
+
+ bool operator== (const ttf_id &other) const {
+ return fg == other.fg && bg == other.bg && bold == other.bold && text == other.text;
+ }
+};
+
+namespace std {
+ template<> struct hash<ttf_id> {
+ size_t operator()(ttf_id val) const {
+ // Not the ideal hash function, but it'll do. And it's better than GCC's. id? Seriously?
+ return hash<string>()(val.text) + val.fg + (val.bg << 4) + (val.bold << 8);
+ }
+ };
+};
+
+// Being a texture catalog interface, with opengl, sdl and truetype capability
+class textures
+{
+ friend class enablerst;
+ friend class renderer_opengl;
+ private:
+ vector<SDL_Surface *> raws;
+ bool uploaded;
+ long add_texture(SDL_Surface*);
+ protected:
+ GLuint gl_catalog; // texture catalog gennum
+ struct gl_texpos *gl_texpos; // Texture positions in the GL catalog, if any
+ public:
+ // Initialize state variables
+ textures() {
+ uploaded = false;
+ gl_texpos = NULL;
+ }
+ ~textures() {
+ for (auto it = raws.cbegin(); it != raws.cend(); ++it)
+ SDL_FreeSurface(*it);
+}
+ int textureCount() {
+ return raws.size();
+ }
+ // Upload in-memory textures to the GPU
+ // When textures are uploaded, any alteration to a texture
+ // is automatically reflected in the uploaded copy - eg. it's replaced.
+ // This is very expensive in opengl mode. Don't do it often.
+ void upload_textures();
+ // Also, you really should try to remove uploaded textures before
+ // deleting a window, in case of driver memory leaks.
+ void remove_uploaded_textures();
+ // Returns the most recent texture data
+ SDL_Surface *get_texture_data(long pos);
+ // Clone a texture
+ long clone_texture(long src);
+ // Remove all color, but not transparency
+ void grayscale_texture(long pos);
+ // Loads dimx*dimy textures from a file, assuming all tiles
+ // are equally large and arranged in a grid
+ // Texture positions are saved in row-major order to tex_pos
+ // If convert_magenta is true and the file does not have built-in transparency,
+ // any magenta (255,0,255 RGB) is converted to full transparency
+ // The calculated size of individual tiles is saved to disp_x, disp_y
+ void load_multi_pdim(const string &filename,long *tex_pos,long dimx,long dimy,
+ bool convert_magenta,
+ long *disp_x, long *disp_y);
+ // Loads a single texture from a file, returning the handle
+ long load(const string &filename, bool convert_magenta);
+ // To delete a texture..
+ void delete_texture(long pos);
+};
+
+struct tile {
+ int x, y;
+ long tex;
+};
+
+typedef struct { // Window Creation Info
+ char* title; // Window Title
+ int width; // Width
+ int height; // Height
+ int bitsPerPixel; // Bits Per Pixel
+ BOOL isFullScreen; // FullScreen?
+} GL_WindowInit; // GL_WindowInit
+
+typedef struct { // Contains Information Vital To A Window
+ GL_WindowInit init; // Window Init
+ BOOL isVisible; // Window Visible?
+} GL_Window; // GL_Window
+
+enum zoom_commands { zoom_in, zoom_out, zoom_reset, zoom_fullscreen, zoom_resetgrid };
+
+
+struct texture_fullid {
+ int texpos;
+ float r, g, b;
+ float br, bg, bb;
+
+ bool operator< (const struct texture_fullid &other) const {
+ if (texpos != other.texpos) return texpos < other.texpos;
+ if (r != other.r) return r < other.r;
+ if (g != other.g) return g < other.g;
+ if (b != other.b) return b < other.b;
+ if (br != other.br) return br < other.br;
+ if (bg != other.bg) return bg < other.bg;
+ return bb < other.bb;
+ }
+};
+
+typedef int texture_ttfid; // Just the texpos
+
+class renderer {
+ void cleanup_arrays();
+ protected:
+ unsigned char *screen;
+ long *screentexpos;
+ char *screentexpos_addcolor;
+ unsigned char *screentexpos_grayscale;
+ unsigned char *screentexpos_cf;
+ unsigned char *screentexpos_cbr;
+ // For partial printing:
+ unsigned char *screen_old;
+ long *screentexpos_old;
+ char *screentexpos_addcolor_old;
+ unsigned char *screentexpos_grayscale_old;
+ unsigned char *screentexpos_cf_old;
+ unsigned char *screentexpos_cbr_old;
+
+ void gps_allocate(int x, int y);
+ Either<texture_fullid,texture_ttfid> screen_to_texid(int x, int y);
+ public:
+ void display();
+ virtual void update_tile(int x, int y) = 0;
+ virtual void update_all() = 0;
+ virtual void render() = 0;
+ virtual void set_fullscreen() {} // Should read from enabler.is_fullscreen()
+ virtual void zoom(zoom_commands cmd) {};
+ virtual void resize(int w, int h) = 0;
+ virtual void grid_resize(int w, int h) = 0;
+ void swap_arrays();
+ renderer() {
+ screen = NULL;
+ screentexpos = NULL;
+ screentexpos_addcolor = NULL;
+ screentexpos_grayscale = NULL;
+ screentexpos_cf = NULL;
+ screentexpos_cbr = NULL;
+ screen_old = NULL;
+ screentexpos_old = NULL;
+ screentexpos_addcolor_old = NULL;
+ screentexpos_grayscale_old = NULL;
+ screentexpos_cf_old = NULL;
+ screentexpos_cbr_old = NULL;
+ }
+ virtual ~renderer() {
+ cleanup_arrays();
+ }
+ virtual bool get_mouse_coords(int &x, int &y) = 0;
+ virtual bool uses_opengl() { return false; };
+};
+
+class enablerst : public enabler_inputst
+{
+ friend class initst;
+ friend class renderer_2d_base;
+ friend class renderer_2d;
+ friend class renderer_opengl;
+ friend class renderer_curses;
+
+ bool fullscreen;
+ stack<pair<int,int> > overridden_grid_sizes;
+
+ class renderer *renderer;
+ void eventLoop_SDL();
+#ifdef CURSES
+ void eventLoop_ncurses();
+#endif
+
+ // Framerate calculations
+ int calculated_fps, calculated_gfps;
+ queue<int> frame_timings, gframe_timings; // Milisecond lengths of the last few frames
+ int frame_sum, gframe_sum;
+ int frame_last, gframe_last; // SDL_GetTick returns
+ void do_update_fps(queue<int> &q, int &sum, int &last, int &calc);
+
+ public:
+ void clear_fps();
+ private:
+ void update_fps();
+ void update_gfps();
+
+ // Frame timing calculations
+ float fps, gfps;
+ float fps_per_gfps;
+ Uint32 last_tick;
+ float outstanding_frames, outstanding_gframes;
+
+ // Async rendering
+ struct async_cmd {
+ enum cmd_t { pause, start, render, inc, set_fps } cmd;
+ int val; // If async_inc, number of extra frames to run. If set_fps, current value of fps.
+ async_cmd() {}
+ async_cmd(cmd_t c) { cmd = c; }
+ };
+
+ struct async_msg {
+ enum msg_t { quit, complete, set_fps, set_gfps, push_resize, pop_resize, reset_textures } msg;
+ union {
+ int fps; // set_fps, set_gfps
+ struct { // push_resize
+ int x, y;
+ };
+ };
+ async_msg() {}
+ async_msg(msg_t m) { msg = m; }
+ };
+
+ unsigned int async_frames; // Number of frames the async thread has been asked to run
+ bool async_paused;
+ Chan<async_cmd> async_tobox; // Messages to the simulation thread
+ Chan<async_msg> async_frombox; // Messages from the simulation thread, and acknowledgements of those to
+ Chan<zoom_commands> async_zoom; // Zoom commands (from the simulation thread)
+ Chan<void> async_fromcomplete; // Barrier for async_msg requests that require acknowledgement
+ public:
+ Uint32 renderer_threadid;
+ private:
+
+ void pause_async_loop();
+ void async_wait();
+ void unpause_async_loop() {
+ struct async_cmd cmd;
+ cmd.cmd = async_cmd::start;
+ async_tobox.write(cmd);
+ }
+
+ public:
+
+ string command_line;
+
+ float ccolor[16][3]; // The curses-RGB mapping used for non-curses display modes
+
+ enablerst();
+ unsigned long flag; // ENABLERFLAG_RENDER, ENABLERFLAG_MAXFPS
+
+ int loop(string cmdline);
+ void async_loop();
+ void do_frame();
+
+ // Framerate interface
+ void set_fps(int fps);
+ void set_gfps(int gfps);
+ int get_fps() { return (int)fps; }
+ int get_gfps() { return (int)gfps; }
+ int calculate_fps(); // Calculate the actual provided (G)FPS
+ int calculate_gfps();
+
+ // Mouse interface, such as it is
+ char mouse_lbut,mouse_rbut,mouse_lbut_down,mouse_rbut_down,mouse_lbut_lift,mouse_rbut_lift;
+ char tracking_on; // Whether we're tracking the mouse or not
+
+ // OpenGL state (wrappers)
+ class textures textures; // Font/graphics texture catalog
+ GLsync sync; // Rendering barrier
+ void reset_textures() {
+ async_frombox.write(async_msg(async_msg::reset_textures));
+ }
+ bool uses_opengl() {
+ if (!renderer) return false;
+ return renderer->uses_opengl();
+ }
+
+ // Grid-size interface
+ void override_grid_size(int w, int h); // Pick a /particular/ grid-size
+ void release_grid_size(); // Undoes override_grid_size
+ void zoom_display(zoom_commands command);
+
+
+ // Window management
+ bool is_fullscreen() { return fullscreen; }
+ void toggle_fullscreen() {
+ fullscreen = !fullscreen;
+ async_zoom.write(zoom_fullscreen);
+ }
+
+ // Conversations
+ text_systemst text_system;
+
+ // TOADY: MOVE THESE TO "FRAMERATE INTERFACE"
+ MVar<int> simticks, gputicks;
+ Uint32 clock; // An *approximation* of the current time for use in garbage collection thingies, updated every frame or so.
+};
+#endif
+
+// Function prototypes for deep-DF calls
+char beginroutine();
+char mainloop();
+void endroutine();
+
+extern enablerst enabler;
+
+#endif //ENABLER_H
diff --git a/g_src/enabler_input.cpp b/g_src/enabler_input.cpp new file mode 100755 index 0000000..e16486d --- /dev/null +++ b/g_src/enabler_input.cpp @@ -0,0 +1,1095 @@ +#include <SDL/SDL.h> +#include <map> +#include <vector> +#include <iostream> +#include <sstream> +#include <algorithm> +#include <stdlib.h> +#include <math.h> +using namespace std; + +#include "enabler_input.h" +#include "init.h" +extern initst init; +#include "platform.h" +#include "files.h" +#include "find_files.h" +#include "svector.h" +#include "curses.h" + +// The timeline events we actually pass back from get_input. Well, no, +// that's just k, but.. +struct Event { + Repeat r; + InterfaceKey k; + int repeats; // Starts at 0, increments once per repeat + int serial; + int time; + int tick; // The sim-tick at which we last returned this event + bool macro; // Created as part of macro playback. + + bool operator== (const Event &other) const { + if (r != other.r) return false; + if (k != other.k) return false; + if (repeats != other.repeats) return false; + if (serial != other.serial) return false; + if (time != other.time) return false; + if (macro != other.macro) return false; + return true; + } + + // We sort by time first, and then serial number. + // The order of the other bits is unimportant. + bool operator< (const Event &o) const { + if (time != o.time) return time < o.time; + if (serial != o.serial) return serial < o.serial; + if (r != o.r) return r < o.r; + if (k != o.k) return k < o.k; + if (repeats != o.repeats) return repeats < o.repeats; + if (macro != o.macro) return macro < o.macro; + return false; + } +}; + +// Used to decide which key-binding to display. As a heuristic, we +// prefer whichever display string is shortest. +struct less_sz { + bool operator() (const string &a, const string &b) const { + if (a.size() < b.size()) return true; + if (a.size() > b.size()) return false; + return a < b; + } +}; + +// These change dynamically in the normal process of DF +static int last_serial = 0; // Input serial number, to differentiate distinct physical presses +static set<Event> timeline; // A timeline of pending key events (for next get_input) +static set<EventMatch> pressed_keys; // Keys we consider "pressed" +static int modState; // Modifier state + +// These do not change as part of the normal dynamics of DF, only at startup/when editing. +static multimap<EventMatch,InterfaceKey> keymap; +static map<InterfaceKey,Repeat> repeatmap; +static map<InterfaceKey,set<string,less_sz> > keydisplay; // Used only for display, not for meaning + +// Macro recording +static bool macro_recording = false; +static macro active_macro; // Active macro +static map<string,macro> macros; +static Time macro_end = 0; // Time at which the currently playing macro will end + +// Prefix command state +static bool in_prefix_command = false; +static string prefix_command; + +// Keybinding editing +static bool key_registering = false; +static list<EventMatch> stored_keys; + +// Interface-file last loaded +static string interfacefile; + + +// Returns an unused serial number +static Time next_serial() { + return ++last_serial; +} + +static void update_keydisplay(InterfaceKey binding, string display) { + // Need to filter out space/tab, for obvious reasons. + if (display == " ") display = "Space"; + if (display == "\t") display = "Tab"; + map<InterfaceKey,set<string,less_sz> >::iterator it = keydisplay.find(binding); + if (it == keydisplay.end()) { + set<string,less_sz> s; s.insert(display); + keydisplay[binding] = s; + } else { + keydisplay[binding].insert(display); + } +} + +static void assertgood(ifstream &s) { + if (s.eof()) + MessageBox(NULL, "EOF while parsing keyboard bindings", 0, 0); + else if (!s.good()) + MessageBox(NULL, "I/O error while parsing keyboard bindings", 0, 0); + else + return; + abort(); +} + +// Decodes an UTF-8 encoded string into a /single/ UTF-8 character, +// discarding any overflow. Returns 0 on parse error. +int decode_utf8(const string &s) { + int unicode = 0, length, i; + if (s.length() == 0) return 0; + length = decode_utf8_predict_length(s[0]); + switch (length) { + case 1: unicode = s[0]; break; + case 2: unicode = s[0] & 0x1f; break; + case 3: unicode = s[0] & 0x0f; break; + case 4: unicode = s[0] & 0x07; break; + default: return 0; + } + + // Concatenate the follow-up bytes + if (s.length() < length) return 0; + for (i = 1; i < length; i++) { + if ((s[i] & 0xc0) != 0x80) return 0; + unicode = (unicode << 6) | (s[i] & 0x3f); + } + return unicode; +} + +// Returns the length of an utf-8 sequence, based on its first byte +int decode_utf8_predict_length(char byte) { + if ((byte & 0x80) == 0) return 1; + if ((byte & 0xe0) == 0xc0) return 2; + if ((byte & 0xf0) == 0xe0) return 3; + if ((byte & 0xf8) == 0xf0) return 4; + return 0; // Invalid start byte +} + +// Encode an arbitrary unicode value as a string. Returns an empty +// string if the value is out of range. +string encode_utf8(int unicode) { + string s; + int i; + if (unicode < 0 || unicode > 0x10ffff) return ""; // Out of range for utf-8 + else if (unicode <= 0x007f) { // 1-byte utf-8 + s.resize(1, 0); + } + else if (unicode <= 0x07ff) { // 2-byte utf-8 + s.resize(2, 0); + s[0] = 0xc0; + } + else if (unicode <= 0xffff) { // 3-byte utf-8 + s.resize(3, 0); + s[0] = 0xe0; + } + else { // 4-byte utf-8 + s.resize(4, 0); + s[0] = 0xf0; + } + + // Build up the string, right to left + for (i = s.length()-1; i > 0; i--) { + s[i] = 0x80 | (unicode & 0x3f); + unicode >>= 6; + } + // Finally, what's left goes in the low bits of s[0] + s[0] |= unicode; + return s; +} + +string translate_mod(Uint8 mod) { + string ret; + if (mod & 1) ret += "Shift+"; + if (mod & 2) ret += "Ctrl+"; + if (mod & 4) ret += "Alt+"; + return ret; +} + +static string display(const EventMatch &match) { + ostringstream ret; + ret << translate_mod(match.mod); + switch (match.type) { + case type_unicode: ret << (char)match.unicode; break; + case type_key: { + map<SDLKey,string>::iterator it = sdlNames.left.find(match.key); + if (it != sdlNames.left.end()) + ret << it->second; + else + ret << "SDL+" << (int)match.key; + break; + } + case type_button: + ret << "Button " << (int)match.button; + break; + } + return ret.str(); +} + +static string translate_repeat(Repeat r) { + switch (r) { + case REPEAT_NOT: return "REPEAT_NOT"; + case REPEAT_SLOW: return "REPEAT_SLOW"; + case REPEAT_FAST: return "REPEAT_FAST"; + default: return "REPEAT_BROKEN"; + } +} + +// Update the modstate, since SDL_getModState doesn't /work/ for alt +static void update_modstate(const SDL_Event &e) { + if (e.type == SDL_KEYUP) { + switch (e.key.keysym.sym) { + case SDLK_RSHIFT: + case SDLK_LSHIFT: + modState &= ~1; + break; + case SDLK_RCTRL: + case SDLK_LCTRL: + modState &= ~2; + break; + case SDLK_RALT: + case SDLK_LALT: + modState &= ~4; + break; + } + } else if (e.type == SDL_KEYDOWN) { + switch (e.key.keysym.sym) { + case SDLK_RSHIFT: + case SDLK_LSHIFT: + modState |= 1; + break; + case SDLK_RCTRL: + case SDLK_LCTRL: + modState |= 2; + break; + case SDLK_RALT: + case SDLK_LALT: + modState |= 4; + break; + } + } +} + +// Converts SDL mod states to ours, collapsing left/right shift/alt/ctrl +Uint8 getModState() { + return modState; +} + +// Not sure what to call this, but it ain't using regexes. +static bool parse_line(const string &line, const string ®ex, vector<string> &parts) { + parts.clear(); + parts.push_back(line); + int bytes; + for (int l = 0, r = 0; r < regex.length();) { + switch (regex[r]) { + case '*': // Read until ], : or the end of the line, but at least one character. + { + const int start = l; + for (; l < line.length() && (l == start || (line[l] != ']' && line[l] != ':')); l++) + ; + parts.push_back(line.substr(start, l - start)); + r++; + } + break; + default: + if (line[l] != regex[r]) return false; + r++; l++; + break; + } + } + // We've made it this far, clearly the string parsed + return true; +} + +void enabler_inputst::load_keybindings(const string &file) { + cout << "Loading bindings from " << file << endl; + interfacefile = file; + ifstream s(file.c_str()); + if (!s.good()) { + MessageBox(NULL, (file + " not found, or I/O error encountered").c_str(), 0, 0); + abort(); + } + + list<string> lines; + while (s.good()) { + string line; + getline(s, line); + lines.push_back(line); + } + + static const string bind("[BIND:*:*]"); + static const string sym("[SYM:*:*]"); + static const string key("[KEY:*]"); + static const string button("[BUTTON:*:*]"); + + list<string>::iterator line = lines.begin(); + vector<string> match; + + while (line != lines.end()) { + if (parse_line(*line, bind, match)) { + map<string,InterfaceKey>::iterator it = bindingNames.right.find(match[1]); + if (it != bindingNames.right.end()) { + InterfaceKey binding = it->second; + // Parse repeat data + if (match[2] == "REPEAT_FAST") + repeatmap[(InterfaceKey)binding] = REPEAT_FAST; + else if (match[2] == "REPEAT_SLOW") + repeatmap[(InterfaceKey)binding] = REPEAT_SLOW; + else if (match[2] == "REPEAT_NOT") + repeatmap[(InterfaceKey)binding] = REPEAT_NOT; + else { + repeatmap[(InterfaceKey)binding] = REPEAT_NOT; + cout << "Broken repeat request: " << match[2] << endl; + } + ++line; + // Add symbols/keys/buttons + while (line != lines.end()) { + EventMatch matcher; + // SDL Keys + if (parse_line(*line, sym, match)) { + map<string,SDLKey>::iterator it = sdlNames.right.find(match[2]); + if (it != sdlNames.right.end()) { + matcher.mod = atoi(string(match[1]).c_str()); + matcher.type = type_key; + matcher.key = it->second; + keymap.insert(pair<EventMatch,InterfaceKey>(matcher, (InterfaceKey)binding)); + update_keydisplay(binding, display(matcher)); + } else { + cout << "Unknown SDLKey: " << match[2] << endl; + } + ++line; + } // Unicode + else if (parse_line(*line, key, match)) { + matcher.type = type_unicode; + matcher.unicode = decode_utf8(match[1]); + matcher.mod = KMOD_NONE; + if (matcher.unicode) { + keymap.insert(make_pair(matcher, (InterfaceKey)binding)); + if (matcher.unicode < 256) { + // This unicode key is part of the latin-1 mapped portion of unicode, so we can + // actually display it. Nice. + char c[2] = {char(matcher.unicode), 0}; + update_keydisplay(binding, display(matcher)); + } + } else { + cout << "Broken unicode: " << *line << endl; + } + ++line; + } // Mouse buttons + else if (parse_line(*line, button, match)) { + matcher.type = type_button; + string str = match[2]; + matcher.button = atoi(str.c_str()); + if (matcher.button) { + matcher.mod = atoi(string(match[1]).c_str()); + keymap.insert(pair<EventMatch,InterfaceKey>(matcher, (InterfaceKey)binding)); + update_keydisplay(binding, display(matcher)); + } else { + cout << "Broken button (should be [BUTTON:#:#]): " << *line << endl; + } + ++line; + } else { + break; + } + } + } else { + cout << "Unknown binding: " << match[1] << endl; + ++line; + } + } else { + // Retry with next line + ++line; + } + } +} + +void enabler_inputst::save_keybindings(const string &file) { + cout << "Saving bindings to " << file << endl; + string temporary = file + ".partial"; + ofstream s(temporary.c_str()); + multimap<InterfaceKey,EventMatch> map; + InterfaceKey last_key = INTERFACEKEY_NONE; + + if (!s.good()) { + string t = "Failed to open " + temporary + " for writing"; + MessageBox(NULL, t.c_str(), 0, 0); + s.close(); + return; + } + // Invert keyboard map + for (multimap<EventMatch,InterfaceKey>::iterator it = keymap.begin(); it != keymap.end(); ++it) + map.insert(pair<InterfaceKey,EventMatch>(it->second,it->first)); + // Insert an empty line for the benefit of note/wordpad + s << endl; + // And write. + for (multimap<InterfaceKey,EventMatch>::iterator it = map.begin(); it != map.end(); ++it) { + if (!s.good()) { + MessageBox(NULL, "I/O error while writing keyboard mapping", 0, 0); + s.close(); + return; + } + if (it->first != last_key) { + last_key = it->first; + s << "[BIND:" << bindingNames.left[it->first] << ":" + << translate_repeat(repeatmap[it->first]) << "]" << endl; + } + switch (it->second.type) { + case type_unicode: + s << "[KEY:" << encode_utf8(it->second.unicode) << "]" << endl; + break; + case type_key: + s << "[SYM:" << (int)it->second.mod << ":" << sdlNames.left[it->second.key] << "]" << endl; + break; + case type_button: + s << "[BUTTON:" << (int)it->second.mod << ":" << (int)it->second.button << "]" << endl; + break; + } + } + s.close(); + replace_file(temporary, file); +} + +void enabler_inputst::save_keybindings() { + save_keybindings(interfacefile); +} + +void enabler_inputst::add_input(SDL_Event &e, Uint32 now) { + // Before we can use this input, there are some issues to deal with: + // - SDL provides unicode translations only for key-press events, not + // releases. We need to keep track of pressed keys, and generate + // unicode release events whenever any modifiers are hit, or if + // that raw keycode is released. + // - Generally speaking, when modifiers are hit/released, we discard those + // events and generate press/release events for all pressed non-modifiers. + // - It's possible for multiple events to be generated on the same tick. + // These are of course separate keypresses, and must be kept separate. + // That's what the serial is for. + + set<EventMatch>::iterator pkit; + list<pair<KeyEvent, int> > synthetics; + update_modstate(e); + + // Convert modifier state changes + if ((e.type == SDL_KEYUP || e.type == SDL_KEYDOWN) && + (e.key.keysym.sym == SDLK_RSHIFT || + e.key.keysym.sym == SDLK_LSHIFT || + e.key.keysym.sym == SDLK_RCTRL || + e.key.keysym.sym == SDLK_LCTRL || + e.key.keysym.sym == SDLK_RALT || + e.key.keysym.sym == SDLK_LALT )) { + for (pkit = pressed_keys.begin(); pkit != pressed_keys.end(); ++pkit) { + // Release currently pressed keys + KeyEvent synth; + synth.release = true; + synth.match = *pkit; + synthetics.push_back(make_pair(synth, next_serial())); + // Re-press them, with new modifiers, if they aren't unicode. We can't re-translate unicode. + if (synth.match.type != type_unicode) { + synth.release = false; + synth.match.mod = getModState(); + if (!key_registering) // We don't want extras when registering keys + synthetics.push_back(make_pair(synth, next_serial())); + } + } + } else { + // It's not a modifier. If this is a key release, then we still need + // to find and release pressed unicode keys with this scancode + if (e.type == SDL_KEYUP) { + for (pkit = pressed_keys.begin(); pkit != pressed_keys.end(); ++pkit) { + if (pkit->type == type_unicode && pkit->scancode == e.key.keysym.scancode) { + KeyEvent synth; + synth.release = true; + synth.match = *pkit; + synthetics.push_back(make_pair(synth, next_serial())); + } + } + } + // Since it's not a modifier, we also pass on symbolic/button + // (always) and unicode (if defined) events + // + // However, since SDL ignores(?) ctrl and alt when translating to + // unicode, we want to ignore unicode events if those are set. + const int serial = next_serial(); + + KeyEvent real; + real.release = (e.type == SDL_KEYUP || e.type == SDL_MOUSEBUTTONUP) ? true : false; + real.match.mod = getModState(); + if (e.type == SDL_MOUSEBUTTONUP || e.type == SDL_MOUSEBUTTONDOWN) { + real.match.type = type_button; + real.match.scancode = 0; + real.match.button = e.button.button; + synthetics.push_back(make_pair(real, serial)); + } + if (e.type == SDL_KEYUP || e.type == SDL_KEYDOWN) { + real.match.type = type_key; + real.match.scancode = e.key.keysym.scancode; + real.match.key = e.key.keysym.sym; + synthetics.push_back(make_pair(real, serial)); + } + if (e.type == SDL_KEYDOWN && e.key.keysym.unicode && getModState() < 2) { + real.match.mod = KMOD_NONE; + real.match.type = type_unicode; + real.match.scancode = e.key.keysym.scancode; + real.match.unicode = e.key.keysym.unicode; + synthetics.push_back(make_pair(real, serial)); + } + if (e.type == SDL_QUIT) { + // This one, we insert directly into the timeline. + Event e = {REPEAT_NOT, (InterfaceKey)INTERFACEKEY_OPTIONS, 0, next_serial(), now, 0}; + timeline.insert(e); + } + } + + list<pair<KeyEvent, int> >::iterator lit; + for (lit = synthetics.begin(); lit != synthetics.end(); ++lit) { + // Add or remove the key from pressed_keys, keeping that up to date + if (lit->first.release) pressed_keys.erase(lit->first.match); + else pressed_keys.insert(lit->first.match); + // And pass the event on deeper. + add_input_refined(lit->first, now, lit->second); + } +} + +// Input encoding: +// 1 and up are ncurses symbols, as returned by getch. +// -1 and down are unicode values. +// esc is true if this key was part of an escape sequence. +#ifdef CURSES +void enabler_inputst::add_input_ncurses(int key, Time now, bool esc) { + // TODO: Deal with shifted arrow keys, etc. See man 5 terminfo and tgetent. + + EventMatch sdl, uni; // Each key may provoke an unicode event, an "SDL-key" event, or both + const int serial = next_serial(); + sdl.type = type_key; + uni.type = type_unicode; + sdl.scancode = uni.scancode = 0; // We don't use this.. hang on, who does? ..nobody. FIXME! + sdl.mod = uni.mod = 0; + sdl.key = SDLK_UNKNOWN; + uni.unicode = 0; + + if (esc) { // Escape sequence, meaning alt was held. I hope. + sdl.mod = uni.mod = DFMOD_ALT; + } + + if (key == -10) { // Return + sdl.key = SDLK_RETURN; + uni.unicode = '\n'; + } else if (key == -9) { // Tab + sdl.key = SDLK_TAB; + uni.unicode = '\t'; + } else if (key == -27) { // If we see esc here, it's the actual esc key. Hopefully. + sdl.key = SDLK_ESCAPE; + } else if (key == -127) { // Backspace/del + sdl.key = SDLK_BACKSPACE; + } else if (key < 0 && key >= -26) { // Control-a through z (but not ctrl-j, or ctrl-i) + sdl.mod |= DFMOD_CTRL; + sdl.key = (SDLKey)(SDLK_a + (-key) - 1); + } else if (key <= -32 && key >= -126) { // ASCII character set + uni.unicode = -key; + sdl.key = (SDLKey)-key; // Most of this maps directly to SDL keys, except.. + if (sdl.key > 64 && sdl.key < 91) { // Uppercase + sdl.key = (SDLKey)(sdl.key + 32); // Maps to lowercase, and + sdl.mod |= DFMOD_SHIFT; // Add shift. + } + } else if (key < -127) { // Unicode, no matching SDL keys + uni.unicode = -key; + } else if (key > 0) { // Symbols such as arrow-keys, etc, no matching unicode. + switch (key) { + case KEY_DOWN: sdl.key = SDLK_DOWN; break; + case KEY_UP: sdl.key = SDLK_UP; break; + case KEY_LEFT: sdl.key = SDLK_LEFT; break; + case KEY_RIGHT: sdl.key = SDLK_RIGHT; break; + case KEY_BACKSPACE: sdl.key = SDLK_BACKSPACE; break; + case KEY_F(1): sdl.key = SDLK_F1; break; + case KEY_F(2): sdl.key = SDLK_F2; break; + case KEY_F(3): sdl.key = SDLK_F3; break; + case KEY_F(4): sdl.key = SDLK_F4; break; + case KEY_F(5): sdl.key = SDLK_F5; break; + case KEY_F(6): sdl.key = SDLK_F6; break; + case KEY_F(7): sdl.key = SDLK_F7; break; + case KEY_F(8): sdl.key = SDLK_F8; break; + case KEY_F(9): sdl.key = SDLK_F9; break; + case KEY_F(10): sdl.key = SDLK_F10; break; + case KEY_F(11): sdl.key = SDLK_F11; break; + case KEY_F(12): sdl.key = SDLK_F12; break; + case KEY_F(13): sdl.key = SDLK_F13; break; + case KEY_F(14): sdl.key = SDLK_F14; break; + case KEY_F(15): sdl.key = SDLK_F15; break; + case KEY_DC: sdl.key = SDLK_DELETE; break; + case KEY_NPAGE: sdl.key = SDLK_PAGEDOWN; break; + case KEY_PPAGE: sdl.key = SDLK_PAGEUP; break; + case KEY_ENTER: sdl.key = SDLK_RETURN; break; + } + } + + // We may be registering a new mapping, in which case we skip the + // rest of this function. + if (key_registering) { + if (uni.unicode) { + stored_keys.push_back(uni); + } + if (sdl.key) { + stored_keys.push_back(sdl); + } + Event e; e.r = REPEAT_NOT; e.repeats = 0; e.time = now; e.serial = serial; e.k = INTERFACEKEY_KEYBINDING_COMPLETE; e.tick = enabler.simticks.read(); + timeline.insert(e); + key_registering = false; + return; + } + + // Key repeat is handled by the terminal, and we don't get release + // events anyway. + KeyEvent kev; kev.release = false; + Event e; e.r = REPEAT_NOT; e.repeats = 0; e.time = now; + if (sdl.key) { + set<InterfaceKey> events = key_translation(sdl); + for (set<InterfaceKey>::iterator k = events.begin(); k != events.end(); ++k) { + e.serial = serial; + e.k = *k; + timeline.insert(e); + } + } + if (uni.unicode) { + set<InterfaceKey> events = key_translation(uni); + for (set<InterfaceKey>::iterator k = events.begin(); k != events.end(); ++k) { + e.serial = serial; + e.k = *k; + timeline.insert(e); + } + } +} +#endif + +void enabler_inputst::add_input_refined(KeyEvent &e, Uint32 now, int serial) { + // We may be registering a new mapping, in which case we skip the + // rest of this function. + if (key_registering && !e.release) { + stored_keys.push_back(e.match); + Event e; e.r = REPEAT_NOT; e.repeats = 0; e.time = now; e.serial = serial; e.k = INTERFACEKEY_KEYBINDING_COMPLETE; e.tick = enabler.simticks.read(); + timeline.insert(e); + return; + } + + // If this is a key-press event, we add it to the timeline. If it's + // a release, we remove any pending repeats, but not those that + // haven't repeated yet (which are on their first cycle); those we + // just set to non-repeating. + set<InterfaceKey> keys = key_translation(e.match); + if (e.release) { + set<Event>::iterator it = timeline.begin(); + while (it != timeline.end()) { + set<Event>::iterator el = it++; + if (keys.count(el->k)) { + if (el->repeats) { + timeline.erase(el); + } else { + Event new_el = *el; + new_el.r = REPEAT_NOT; + timeline.erase(el); + timeline.insert(new_el); + } + } + } + } else { + set<InterfaceKey>::iterator key; + // As policy, when the user hits a non-repeating key we'd want to + // also cancel any keys that are currently repeating. This allows + // for easy recovery from stuck keys. + // + // Unfortunately, each key may be bound to multiple + // commands. So, lacking information on which commands are + // accepted at the moment, there is no way we can know if it's + // okay to cancel repeats unless /all/ the bindings are + // non-repeating. + for (set<InterfaceKey>::iterator k = keys.begin(); k != keys.end(); ++k) { + Event e = {key_repeat(*k), *k, 0, serial, now, enabler.simticks.read()}; + timeline.insert(e); + } + // if (cancel_ok) { + // // Set everything on the timeline to non-repeating + // multimap<Time,Event>::iterator it; + // for (it = timeline.begin(); it != timeline.end(); ++it) { + // it->second.r = REPEAT_NOT; + // } + } +} + + +void enabler_inputst::clear_input() { + timeline.clear(); + pressed_keys.clear(); + modState = 0; + last_serial = 0; +} + +set<InterfaceKey> enabler_inputst::get_input(Time now) { + // We walk the timeline, returning all events corresponding to a + // single physical keypress, and inserting repeats relative to the + // current time, not when the events we're now returning were + // *supposed* to happen. + + set<InterfaceKey> input; + set<Event>::iterator ev = timeline.begin(); + if (ev == timeline.end() || ev->time > now) { + return input; // No input (yet). + } + + const Time first_time = ev->time; + const int first_serial = ev->serial; + int simtick = enabler.simticks.read(); + bool event_from_macro = false; + while (ev != timeline.end() && ev->time == first_time && ev->serial == first_serial) { + // Avoid recording macro-sources events as macro events. + if (ev->macro) event_from_macro = true; + // To make sure the user had a chance to cancel (by lifting the key), we require there + // to be at least three simulation ticks before the first repeat. + if (ev->repeats == 1 && ev->tick > simtick - 3) { + } else { + input.insert(ev->k); + } + // Schedule a repeat + Event next = *ev; + next.repeats++; + switch (next.r) { + case REPEAT_NOT: + break; + case REPEAT_SLOW: + if (ev->repeats == 0) { + next.time = now + init.input.hold_time; + timeline.insert(next); + break; + } + case REPEAT_FAST: + double accel = 1; + if (ev->repeats >= init.input.repeat_accel_start) { + // Compute acceleration + accel = MIN(init.input.repeat_accel_limit, + sqrt(double(next.repeats - init.input.repeat_accel_start) + 16) - 3); + } + next.time = now + double(init.input.repeat_time) / accel; + timeline.insert(next); + break; + } + // Delete the event from the timeline and iterate + timeline.erase(ev++); + } +#ifdef DEBUG + if (input.size() && !init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) { + cout << "Returning input:\n"; + set<InterfaceKey>::iterator it; + for (it = input.begin(); it != input.end(); ++it) + cout << " " << GetKeyDisplay(*it) << ": " << GetBindingDisplay(*it) << endl; + } +#endif + // It could be argued that the "record event" step of recording + // belongs in add_input, not here. I don't hold with this + // argument. The whole point is to record events as the user seems + // them happen. + if (macro_recording && !event_from_macro) { + set<InterfaceKey> macro_input = input; + macro_input.erase(INTERFACEKEY_RECORD_MACRO); + macro_input.erase(INTERFACEKEY_PLAY_MACRO); + macro_input.erase(INTERFACEKEY_SAVE_MACRO); + macro_input.erase(INTERFACEKEY_LOAD_MACRO); + if (macro_input.size()) + active_macro.push_back(macro_input); + } + return input; +} + +set<InterfaceKey> enabler_inputst::key_translation(EventMatch &match) { + set<InterfaceKey> bindings; + pair<multimap<EventMatch,InterfaceKey>::iterator,multimap<EventMatch,InterfaceKey>::iterator> its; + + for (its = keymap.equal_range(match); its.first != its.second; ++its.first) + bindings.insert((its.first)->second); + + return bindings; +} + +string enabler_inputst::GetKeyDisplay(int binding) { + map<InterfaceKey,set<string,less_sz> >::iterator it = keydisplay.find(binding); + if (it != keydisplay.end() && it->second.size()) + return *it->second.begin(); + else { + cout << "Missing binding displayed: " + bindingNames.left[binding] << endl; + return "?"; + } +} + +string enabler_inputst::GetBindingDisplay(int binding) { + map<InterfaceKey,string>::iterator it = bindingNames.left.find(binding); + if (it != bindingNames.left.end()) + return it->second; + else + return "NO BINDING"; +} + +string enabler_inputst::GetBindingTextDisplay(int binding) { + map<InterfaceKey,string>::iterator it = displayNames.left.find(binding); + if (it !=displayNames.left.end()) + return it->second; + else + return "NO BINDING"; +} + +Repeat enabler_inputst::key_repeat(InterfaceKey binding) { + map<InterfaceKey,Repeat>::iterator it = repeatmap.find(binding); + if (it != repeatmap.end()) + return it->second; + else + return REPEAT_NOT; +} + +void enabler_inputst::key_repeat(InterfaceKey binding, Repeat repeat) { + repeatmap[binding] = repeat; +} + +void enabler_inputst::record_input() { + active_macro.clear(); + macro_recording = true; +} + +void enabler_inputst::record_stop() { + macro_recording = false; +} + +bool enabler_inputst::is_recording() { + return macro_recording; +} + +void enabler_inputst::play_macro() { + Time now = SDL_GetTicks(); + for_each(timeline.begin(), timeline.end(), [&](Event e){ + now = MAX(now, e.time); + }); + for (macro::iterator sim = active_macro.begin(); sim != active_macro.end(); ++sim) { + Event e; e.r = REPEAT_NOT; e.repeats = 0; e.serial = next_serial(); e.time = now; + e.macro = true; // Avoid exponential macro blowup. + for (set<InterfaceKey>::iterator k = sim->begin(); k != sim->end(); ++k) { + e.k = *k; + timeline.insert(e); + now += init.input.macro_time; + } + } + macro_end = MAX(macro_end, now); +} + +bool enabler_inputst::is_macro_playing() { + return SDL_GetTicks() <= macro_end; +} + +// Replaces any illegal letters. +static string filter_filename(string name, char replacement) { + for (int i = 0; i < name.length(); i++) { + switch (name[i]) { + case '<': name[i] = replacement; break; + case '>': name[i] = replacement; break; + case ':': name[i] = replacement; break; + case '"': name[i] = replacement; break; + case '/': name[i] = replacement; break; + case '\\': name[i] = replacement; break; + case '|': name[i] = replacement; break; + case '?': name[i] = replacement; break; + case '*': name[i] = replacement; break; + } + if (name[i] <= 31) name[i] = replacement; + } + return name; +} + +void enabler_inputst::load_macro_from_file(const string &file) { + ifstream s(file.c_str()); + char buf[100]; + s.getline(buf, 100); + string name(buf); + if (macros.find(name) != macros.end()) return; // Already got it. + + macro macro; + set<InterfaceKey> group; + for(;;) { + s.getline(buf, 100); + if (!s.good()) { + MessageBox(NULL, "I/O error while loading macro", 0, 0); + s.close(); + return; + } + string line(buf); + if (line == "End of macro") { + if (group.size()) macro.push_back(group); + break; + } else if (line == "\tEnd of group") { + if (group.size()) macro.push_back(group); + group.clear(); + } else if (line.substr(0,2) != "\t\t" ) { + if( line.substr(1).find("\t") != string::npos) { + // expecting /t##/tCMD for a repeated command + istringstream ss(line.substr(1)); + int count; + string remainingline; + + if(ss >> count) { + ss >> remainingline; + if(remainingline.size()) { + for(int i=0; i < count; i++) { + map<string,InterfaceKey>::iterator it = bindingNames.right.find(remainingline); + if (it == bindingNames.right.end()) { + cout << "Binding name unknown while loading macro: " << line.substr(1) << endl; + } else { + group.insert(it->second); + if (group.size()) macro.push_back(group); + group.clear(); + } + } + } + else { + cout << "Binding missing while loading macro: " << line.substr(1) << endl; + } + } else { + cout << "Quantity not numeric or Unexpected tab(s) while loading macro: " << line.substr(1) << endl; + } + } + else + { + // expecting /tCMD for a non-grouped command + map<string,InterfaceKey>::iterator it = bindingNames.right.find(line.substr(1)); + if (it == bindingNames.right.end()) { + cout << "Binding name unknown while loading macro: " << line.substr(1) << endl; + } else { + group.insert(it->second); + if (group.size()) macro.push_back(group); + group.clear(); + } + } + } else { + map<string,InterfaceKey>::iterator it = bindingNames.right.find(line.substr(2)); + if (it == bindingNames.right.end()) + cout << "Binding name unknown while loading macro: " << line.substr(2) << endl; + else + group.insert(it->second); + } + } + if (s.good()) + macros[name] = macro; + else + MessageBox(NULL, "I/O error while loading macro", 0, 0); + s.close(); +} + +void enabler_inputst::save_macro_to_file(const string &file, const string &name, const macro ¯o) { + ofstream s(file.c_str()); + s << name << endl; + for (macro::const_iterator group = macro.begin(); group != macro.end(); ++group) { + for (set<InterfaceKey>::const_iterator key = group->begin(); key != group->end(); ++key) + s << "\t\t" << bindingNames.left[*key] << endl; + s << "\tEnd of group" << endl; + } + s << "End of macro" << endl; + s.close(); +} + +list<string> enabler_inputst::list_macros() { + // First, check for unloaded macros + svector<char*> files; + find_files_by_pattern("data/init/macros/*.mak", files); + for (int i = 0; i < files.size(); i++) { + string file(files[i]); + delete files[i]; + file = "data/init/macros/" + file; + load_macro_from_file(file); + } + // Then return all in-memory macros + list<string> ret; + for (map<string,macro>::iterator it = macros.begin(); it != macros.end(); ++it) + ret.push_back(it->first); + return ret; +} + +void enabler_inputst::load_macro(string name) { + if (macros.find(name) != macros.end()) + active_macro = macros[name]; + else + macros.clear(); +} + +void enabler_inputst::save_macro(string name) { + macros[name] = active_macro; + save_macro_to_file("data/init/macros/" + filter_filename(name, '_') + ".mak", name, active_macro); +} + +void enabler_inputst::delete_macro(string name) { + map<string,macro>::iterator it = macros.find(name); + if (it != macros.end()) macros.erase(it); + // TODO: Store the filename it was loaded from instead + string filename = "data/init/macros/" + filter_filename(name, '_') + ".mak"; + remove(filename.c_str()); +} + + +// Sets the next key-press to be stored instead of executed. +void enabler_inputst::register_key() { + key_registering = true; + stored_keys.clear(); +} + +// Returns a description of stored keys. Max one of each type. +list<RegisteredKey> enabler_inputst::getRegisteredKey() { + key_registering = false; + list<RegisteredKey> ret; + for (list<EventMatch>::iterator it = stored_keys.begin(); it != stored_keys.end(); ++it) { + struct RegisteredKey r = {it->type, display(*it)}; + ret.push_back(r); + } + return ret; +} + +// Binds one of the stored keys to key +void enabler_inputst::bindRegisteredKey(MatchType type, InterfaceKey key) { + for (list<EventMatch>::iterator it = stored_keys.begin(); it != stored_keys.end(); ++it) { + if (it->type == type) { + keymap.insert(pair<EventMatch,InterfaceKey>(*it, key)); + update_keydisplay(key, display(*it)); + } + } +} + +bool enabler_inputst::is_registering() { + return key_registering; +} + + +list<EventMatch> enabler_inputst::list_keys(InterfaceKey key) { + list<EventMatch> ret; + // Oh, now this is inefficient. + for (multimap<EventMatch,InterfaceKey>::iterator it = keymap.begin(); it != keymap.end(); ++it) + if (it->second == key) ret.push_back(it->first); + return ret; +} + +void enabler_inputst::remove_key(InterfaceKey key, EventMatch ev) { + for (multimap<EventMatch,InterfaceKey>::iterator it = keymap.find(ev); + it != keymap.end() && it->first == ev; + ++it) { + if (it->second == key) keymap.erase(it++); + } + // Also remove the key from key displaying, assuming we can find it + map<InterfaceKey,set<string,less_sz> >::iterator it = keydisplay.find(key); + if (it != keydisplay.end()) + it->second.erase(display(ev)); +} + +bool enabler_inputst::prefix_building() { + return in_prefix_command; +} + +void enabler_inputst::prefix_toggle() { + in_prefix_command = !in_prefix_command; + prefix_command.clear(); +} + +void enabler_inputst::prefix_add_digit(char digit) { + prefix_command.push_back(digit); +#ifdef DEBUG + cout << "Built prefix to " << prefix_command << endl; +#endif + if (atoi(prefix_command.c_str()) > 99) + prefix_command = "99"; // Let's not go overboard here. +} + +int enabler_inputst::prefix_end() { + if (prefix_command.size()) { + int repeats = atoi(prefix_command.c_str()); + prefix_toggle(); + return repeats; + } else { + return 1; + } +} + +string enabler_inputst::prefix() { + return prefix_command; +} diff --git a/g_src/enabler_input.h b/g_src/enabler_input.h new file mode 100755 index 0000000..be5f94b --- /dev/null +++ b/g_src/enabler_input.h @@ -0,0 +1,137 @@ +#ifndef ENABLER_INPUT_H
+#define ENABLER_INPUT_H
+
+#ifdef __APPLE__
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+
+#include <SDL/SDL.h>
+#include <string>
+#include <set>
+#include <list>
+
+#include "ViewBase.h"
+#include "keybindings.h"
+#include "curses.h"
+
+typedef Uint32 Time;
+
+enum Repeat {
+ REPEAT_NOT, // Don't repeat at all. Furthermore, cancel other repeats.
+ REPEAT_SLOW, // Repeat normally.
+ REPEAT_FAST // Repeat instantly, without waiting for the first-repeat interval.
+};
+
+enum MatchType { type_unicode, type_key, type_button };
+
+Uint8 getModState();
+std::string translate_mod(Uint8 mod);
+int decode_utf8(const std::string &s);
+int decode_utf8_predict_length(char byte);
+std::string encode_utf8(int unicode);
+
+#define DFMOD_SHIFT 1
+#define DFMOD_CTRL 2
+#define DFMOD_ALT 4
+
+struct EventMatch {
+ MatchType type;
+ Uint8 mod; // not defined for type=unicode. 1: shift, 2: ctrl, 4:alt
+ Uint8 scancode; // not defined for type=button
+ union {
+ Uint16 unicode;
+ SDLKey key;
+ Uint8 button;
+ };
+
+ bool operator== (const EventMatch &other) const {
+ if (mod != other.mod) return false;
+ if (type != other.type) return false;
+ switch (type) {
+ case type_unicode: return unicode == other.unicode;
+ case type_key: return key == other.key;
+ case type_button: return button == other.button;
+ default: return false;
+ }
+ }
+
+ bool operator< (const EventMatch &other) const {
+ if (mod != other.mod) return mod < other.mod;
+ if (type != other.type) return type < other.type;
+ switch (type) {
+ case type_unicode: return unicode < other.unicode;
+ case type_key: return key < other.key;
+ case type_button: return button < other.button;
+ default: return false;
+ }
+ }
+};
+
+struct KeyEvent {
+ bool release;
+ EventMatch match;
+};
+
+typedef std::list<std::set<InterfaceKey> > macro;
+
+struct RegisteredKey {
+ MatchType type;
+ string display;
+};
+
+class enabler_inputst {
+ std::set<InterfaceKey> key_translation(EventMatch &match);
+ public:
+ Repeat key_repeat(InterfaceKey);
+ void key_repeat(InterfaceKey, Repeat);
+ void load_macro_from_file(const std::string &file);
+ void save_macro_to_file(const std::string &file, const std::string &name, const macro &);
+
+ // In practice.. do not use this one.
+ void add_input(SDL_Event &e, Time now);
+ // Use this one. It's much nicer.
+ void add_input_refined(KeyEvent &e, Time now, int serial);
+ // Made specifically for curses. <0 = unicode, >0 = ncurses symbols.
+#ifdef CURSES
+ void add_input_ncurses(int key, Time now, bool esc);
+#endif
+ std::set<InterfaceKey> get_input(Time now);
+ void clear_input();
+
+ void load_keybindings(const std::string &file);
+ void save_keybindings(const std::string &file);
+ void save_keybindings();
+ std::string GetKeyDisplay(int binding);
+ std::string GetBindingDisplay(int binding);
+ std::string GetBindingTextDisplay(int binding);
+
+ // Macros
+ void record_input(); // Records input until such a time as you say stop
+ void record_stop(); // Stops recording, saving it as the active macro
+ bool is_recording();
+ void play_macro(); // Runs the active macro, if any
+ bool is_macro_playing();
+ std::list<string> list_macros();
+ void load_macro(string name); // Loads some macro as the active one
+ void save_macro(string name); // Saves the active macro under some name
+ void delete_macro(string name);
+
+ // Prefix commands
+ bool prefix_building();
+ void prefix_toggle();
+ void prefix_add_digit(char digit);
+ int prefix_end();
+ string prefix();
+
+ // Updating the key-bindings
+ void register_key(); // Sets the next key-press to be stored instead of executed.
+ list<RegisteredKey> getRegisteredKey(); // Returns a description of stored keys. Max one of each type.
+ void bindRegisteredKey(MatchType type, InterfaceKey key); // Binds one of the stored keys to key
+ bool is_registering(); // Returns true if we're still waiting for a key-hit
+
+ std::list<EventMatch> list_keys(InterfaceKey key); // Returns a list of events matching this interfacekey
+ void remove_key(InterfaceKey key, EventMatch ev); // Removes a particular matcher from the keymap.
+};
+
+
+#endif
diff --git a/g_src/endian.h b/g_src/endian.h new file mode 100755 index 0000000..b56dee4 --- /dev/null +++ b/g_src/endian.h @@ -0,0 +1,42 @@ +#ifndef ENDIAN_H +#define ENDIAN_H + +inline unsigned short byteswap(unsigned short x) +{ +#if defined(__ppc__) || defined(__ppc64__) + return (x << 8 | x >> 8); +#else + return x; +#endif +} + +inline unsigned long byteswap(unsigned long x) +{ +#if defined(__ppc__) || defined(__ppc64__) + return + ( (x << 24) & 0xFF000000) | + ( (x << 8) & 0x00FF0000) | + ( (x >> 8) & 0x0000FF00) | + ( (x >> 24) & 0x000000FF) ; +#else + return x; +#endif +} + +inline unsigned int byteswap(unsigned int x) +{ +#if defined(__ppc__) || defined(__ppc64__) + return + ( (x << 24) & 0xFF000000) | + ( (x << 8) & 0x00FF0000) | + ( (x >> 8) & 0x0000FF00) | + ( (x >> 24) & 0x000000FF) ; +#else + return x; +#endif +} + +inline short byteswap(short x) { return byteswap( (unsigned short) x ); } +inline long byteswap(long x) { return byteswap( (unsigned long) x ); } +inline int byteswap(int x) { return byteswap( (unsigned int) x ); } +#endif diff --git a/g_src/files.cpp b/g_src/files.cpp new file mode 100755 index 0000000..581e024 --- /dev/null +++ b/g_src/files.cpp @@ -0,0 +1,428 @@ +#include "platform.h"
+#include <cerrno>
+#include <string>
+#include <cstring>
+#include <cmath>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <algorithm>
+#include <map>
+#include <set>
+#include <stdio.h>
+//#include <unistd.h>
+
+extern "C" {
+#include <zlib.h>
+#ifndef WIN32
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/time.h>
+# include <signal.h>
+#endif
+}
+#include "svector.h"
+
+#ifdef WIN32
+
+#ifndef INTEGER_TYPES
+ #define INTEGER_TYPES
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned long long uint64_t;
+#endif
+
+typedef int32_t VIndex;
+typedef int32_t Ordinal;
+
+#endif
+
+#include "random.h"
+
+using std::string;
+
+#include "basics.h"
+#include "endian.h"
+#include "files.h"
+#include "enabler.h"
+#include "find_files.h"
+
+inline void CHECK_ERR(int err, const char* msg)
+{
+ if (err != Z_OK)
+ {
+ MessageBox(NULL, "One of the compressed files on disk has errors in it. Restore from backup if you are able.", 0, 0);
+ exit(1);
+ }
+}
+
+using std::fstream;
+
+char file_compressorst::def_ibuff[FILE_IN_BUFF];
+char file_compressorst::def_obuff[FILE_OUT_BUFF];
+
+char file_compressorst::load_posnull_pointer()
+{
+ char dummy;
+ read_file(dummy);
+
+ if(!dummy)return 0;
+ else return 1;
+}
+
+char file_compressorst::save_posnull_pointer(void *ptr)
+{
+ char dummy;
+
+ if(ptr==NULL)
+ {
+ dummy=0;
+ write_file(dummy);
+ return 0;
+ }
+ else
+ {
+ dummy=1;
+ write_file(dummy);
+ return 1;
+ }
+}
+
+char file_compressorst::write_file(string &str)
+{
+ short ln=str.length();
+ if(ln>=10000||ln<0)ln=0;
+
+ if(!write_file(ln))return 0;
+
+ if(ln==0)return 1;
+
+ if(!write_file((void *)str.c_str(),sizeof(char)*ln))return 0;
+
+ return 1;
+}
+
+char file_compressorst::read_file(string &str)
+{
+ str.erase();
+
+ short ln;
+
+ if(!read_file(ln))return 0;
+
+ if(ln==0)return 1;
+
+ char *strar=new char[ln+1];
+
+ if(!read_file(strar,sizeof(char)*ln))
+ {
+ delete[] strar;
+ return 0;
+ }
+ strar[ln]='\x0';
+
+ str=strar;
+
+ delete[] strar;
+ return 1;
+}
+
+char file_compressorst::write_file(void *write_var,long write_size)
+{
+ if (!f.is_open())return 0;
+
+ if(!compressed)
+ {
+ f.write((char *)write_var,write_size);
+ return 1;
+ }
+
+ //WRITE OUT THE VARIABLE CHUNK BY CHUNK
+ while(write_size>0)
+ {
+ //FLUSH THE BUFFER IF NECESSARY
+ if(in_buffer_amount_loaded>=in_buffersize)
+ {
+ if(!flush_in_buffer())return 0;
+ }
+
+ //SET THE AMOUNT TO COPY
+ long copy_size=in_buffersize-in_buffer_amount_loaded;
+ if(write_size<copy_size)copy_size=write_size;
+
+ //COPY THE NEXT CHUNK INTO THE BUFFER
+ memmove(in_buffer+in_buffer_amount_loaded,write_var,copy_size);
+
+ write_var=((char *)write_var) + copy_size;
+ write_size-=copy_size;
+ in_buffer_amount_loaded+=copy_size;
+ }
+
+ return 1;
+}
+
+char file_compressorst::flush_in_buffer()
+{
+ if (!f.is_open())return 0;
+ if(!compressed)return 1;
+ if(in_buffer_amount_loaded==0)return 1;//EXTRA CALLS TO FLUSH SHOULDN'T KILL YOU
+
+ //TARN: adapted from zlib example files
+
+ //SET UP THE COMPRESSOR
+ z_stream c_stream;
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, 9);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = (Bytef*)out_buffer;
+ c_stream.avail_out = out_buffersize;
+
+ //SEND IT TO THE COMPRESSOR
+ c_stream.next_in = (Bytef*)in_buffer;
+ c_stream.avail_in = in_buffer_amount_loaded;
+
+ while (c_stream.total_in != in_buffer_amount_loaded && c_stream.total_out < out_buffersize)
+ {
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+
+ //FINISH UP THE STREAM
+ while(1)
+ {
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ //SAVE THE COMPRESSED BIT AS A GIANT BLOCK
+ if(c_stream.total_out>0)
+ {
+ long compsize=byteswap((long)(c_stream.total_out));
+
+ //WRITE IT
+ f.write((char*)&compsize,sizeof(long));
+ f.write(out_buffer,c_stream.total_out);
+ }
+
+ in_buffer_position=0;
+ in_buffer_amount_loaded=0;
+
+ return 1;
+}
+
+char file_compressorst::read_file(void *read_var,long read_size)
+{
+ if (!f.is_open())return 0;
+
+ if(!compressed)
+ {
+ f.read((char *)read_var,read_size);
+ return 1;
+ }
+
+ //NOW LOAD INTO read_var UNTIL DONE
+ while(read_size>0)
+ {
+ //GET A BUFFER IF NECESSARY
+ if(in_buffer_amount_loaded==0||
+ in_buffer_position>=in_buffer_amount_loaded)
+ {
+ if(!load_new_in_buffer())return 0;
+ }
+
+ //BAIL IF STILL NO BUFFER LEFT
+ if(in_buffer_amount_loaded==0)return 0;
+
+ //SET THE AMOUNT TO COPY
+ long copy_size=in_buffer_amount_loaded-in_buffer_position;
+ if(read_size<copy_size)copy_size=read_size;
+
+ //COPY
+ memmove(read_var,in_buffer+in_buffer_position,copy_size);
+
+ read_var=((char *)read_var) + copy_size;
+ read_size-=copy_size;
+ in_buffer_position+=copy_size;
+ }
+
+ return 1;
+}
+
+char file_compressorst::load_new_in_buffer()
+{
+ if (!f.is_open())return 0;
+ if(!compressed)return 1;
+
+ in_buffer_position=0;
+ in_buffer_amount_loaded=0;
+
+ //LOAD THE BLOCK OF COMPRESSED DATA
+ f.read((char*)&out_buffer_amount_written,sizeof(long));
+ out_buffer_amount_written=byteswap(out_buffer_amount_written);
+ f.read(out_buffer,out_buffer_amount_written);
+
+ int err;
+
+ if(out_buffer_amount_written>0)
+ {
+ //TARN: adapted from zlib example files
+
+ //UNCOMPRESS
+ z_stream d_stream; // decompression stream
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = (Bytef*)out_buffer;
+ d_stream.avail_in = out_buffer_amount_written;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = (Bytef*)in_buffer;
+ d_stream.avail_out = in_buffersize;
+
+ while (d_stream.total_out < in_buffersize && d_stream.total_in < out_buffer_amount_written)
+ {
+ //d_stream.avail_in = d_stream.avail_out = 1; // force small buffers
+ err = inflate(&d_stream, Z_NO_FLUSH);
+
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ in_buffer_amount_loaded=d_stream.total_out;
+
+ return 1;
+ }
+ else return 0;
+}
+
+void file_compressorst::close_file()
+{
+ if (f.is_open())
+ {
+ f.close();
+ }
+}
+
+char file_compressorst::open_file(const string &filename,char existing_only)
+{
+ if(filename.empty())return 0;
+
+ //RESET DATA
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+ out_buffer_amount_written=0;
+
+/*
+ //CHECK IF FILE ALREADY EXISTS
+ f.open(filename.c_str(), fstream::in);
+ char file_exists = f.is_open();
+ if (file_exists)f.close();
+
+ //OPEN FILE
+ if(!existing_only || file_exists)
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
+ else
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
+*/
+ //if(existing_only)h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+ //else h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
+
+ if(f.is_open())f.close();
+ f.clear();
+
+ if(existing_only)
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
+ else
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary | fstream::trunc);
+
+ if (f.is_open())return 1;
+ else return 0;
+}
+
+file_compressorst::file_compressorst(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize)
+{
+ compressed=true;
+
+ in_buffer=new_in_buffer;
+ in_buffersize=new_in_buffersize;
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+
+ out_buffer=new_out_buffer;
+ out_buffersize=new_out_buffersize;
+ out_buffer_amount_written=0;
+
+ f.clear();
+}
+
+void file_compressorst::set_buffer_info(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize)
+{
+ in_buffer=new_in_buffer;
+ in_buffersize=new_in_buffersize;
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+
+ out_buffer=new_out_buffer;
+ out_buffersize=new_out_buffersize;
+ out_buffer_amount_written=0;
+
+ f.clear();
+}
+
+
+file_compressorst::file_compressorst()
+{
+ compressed=true;
+
+ in_buffer=def_ibuff;
+ in_buffersize=FILE_IN_BUFF;
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+
+ out_buffer=def_obuff;
+ out_buffersize=FILE_OUT_BUFF;
+ out_buffer_amount_written=0;
+
+ f.clear();
+}
+
+void copy_file(const string &src,const string &dst)
+{
+ std::ifstream in_stream(src.c_str(),std::ios_base::binary);
+ std::ofstream out_stream(dst.c_str(),std::ios_base::binary);
+ if(in_stream.is_open()&&out_stream.is_open())
+ {
+ out_stream<<in_stream.rdbuf();
+ }
+ in_stream.close();
+ out_stream.close();
+}
+
+void replace_file(const string &src, const string &dst) {
+#ifdef WIN32
+ remove(dst.c_str());
+#endif
+ rename(src.c_str(), dst.c_str());
+}
diff --git a/g_src/files.h b/g_src/files.h new file mode 100755 index 0000000..2f11c72 --- /dev/null +++ b/g_src/files.h @@ -0,0 +1,368 @@ +//Copyright (c) 2006, Tarn Adams
+//All rights reserved. See game.cpp or license.txt for more information.
+#ifndef FILES_H
+#define FILES_H
+
+#define FILE_IN_BUFF 1000000
+#define FILE_OUT_BUFF 2000000
+
+#include <string>
+using std::string;
+
+#include <fstream>
+#include "endian.h"
+#include "svector.h"
+
+class file_compressorst
+{
+ public:
+ bool compressed;
+ std::fstream f;
+
+
+ char open_file(const string &filename,char existing_only);
+ void close_file();
+ char write_file(string &str);
+ char read_file(string &str);
+
+ char load_posnull_pointer();
+ char save_posnull_pointer(void *ptr);
+
+ void write_file_fixedlength(char *var)
+ {
+ short len=strlen(var);
+ write_file(len);
+ if(len>0)write_file(var,len*sizeof(char));
+ }
+ void read_file_fixedlength(char *var)
+ {
+ short len;
+ read_file(len);//DO NOT NEED TO ALLOCATE SPACE
+ if(len>0)read_file(var,len*sizeof(char));
+ var[len]='\x0';
+ }
+ char write_file(long var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(long));
+ }
+ char read_file(long &var)
+ {
+ char ret = read_file(&var,sizeof(long));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(int var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(int));
+ }
+ char read_file(int &var)
+ {
+ char ret = read_file(&var,sizeof(int));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(short var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(short));
+ }
+ char read_file(short &var)
+ {
+ char ret = read_file(&var,sizeof(short));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(char var)
+ {
+ return write_file(&var,sizeof(char));
+ }
+ char read_file(char &var)
+ {
+ return read_file(&var,sizeof(char));
+ }
+ char write_file(bool var)
+ {
+ char temp;
+ if(var)temp=1;
+ else temp=0;
+ return write_file(&temp,sizeof(char));
+ }
+ char read_file(bool &var)
+ {
+ char temp;
+ if(!read_file(&temp,sizeof(char)))return 0;
+ var=(temp!=0);
+ return 1;
+ }
+ char write_file(unsigned long var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(unsigned long));
+ }
+ char read_file(unsigned long &var)
+ {
+ char ret = read_file(&var,sizeof(unsigned long));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(unsigned int var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(unsigned int));
+ }
+ char read_file(unsigned int &var)
+ {
+ char ret = read_file(&var,sizeof(unsigned int));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(unsigned short var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(unsigned short));
+ }
+ char read_file(unsigned short &var)
+ {
+ char ret = read_file(&var,sizeof(unsigned short));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(unsigned char var)
+ {
+ return write_file(&var,sizeof(unsigned char));
+ }
+ char read_file(unsigned char &var)
+ {
+ return read_file(&var,sizeof(unsigned char));
+ }
+ void write_file(svector<bool> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ bool bl;//JUST FOR PARITY WITH read BELOW
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ bl=(*i_b);
+ write_file(bl);
+ }
+ }
+ void read_file(svector<bool> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ bool bl;//NO IDEA WHY IT CAN'T JUST TAKE vect[i]
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file(bl);
+ (*i_b)=bl;
+ }
+ }
+ void write_file(svector<short> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<short> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned short> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned short> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned char> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned char> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<char> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<char> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<long> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<long> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned long> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned long> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<int> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<int> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned int> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned int> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+
+
+ char load_new_in_buffer();
+ char flush_in_buffer();
+
+ file_compressorst();
+ file_compressorst(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize);
+ ~file_compressorst()
+ {
+ close_file();
+ }
+ void set_buffer_info(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize);
+
+ private:
+ char write_file(void *write_var,long write_size);
+ char read_file(void *read_var,long read_size);
+
+ char *in_buffer;
+ long in_buffersize;
+ long in_buffer_amount_loaded;
+ long in_buffer_position;
+
+ char *out_buffer;
+ long out_buffersize;
+ long out_buffer_amount_written;
+
+ static char def_ibuff[FILE_IN_BUFF];
+ static char def_obuff[FILE_OUT_BUFF];
+};
+
+void copy_file(const string &src,const string &dst);
+// Replaces dst with src, removing src in the process. Atomic if possible.
+void replace_file(const string &src, const string &dst);
+#endif
diff --git a/g_src/find_files.cpp b/g_src/find_files.cpp new file mode 100755 index 0000000..059dcc7 --- /dev/null +++ b/g_src/find_files.cpp @@ -0,0 +1,180 @@ +#include "../game_g.h" +#include "../game_extv.h" + +void find_files_by_pattern(const char* pattern, svector<char *>& filenames) +{ + HANDLE h; + WIN32_FIND_DATA finddata; + char *c; + + h=FindFirstFile(pattern,&finddata); + + if(h!=INVALID_HANDLE_VALUE) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + c=new char[strlen(finddata.cFileName)+1]; + strcpy(c,finddata.cFileName); + filenames.push_back(c); + } + } + + while(FindNextFile(h,&finddata)) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + c=new char[strlen(finddata.cFileName)+1]; + strcpy(c,finddata.cFileName); + filenames.push_back(c); + } + } + } + + FindClose(h); + } +} + +void find_files_by_pattern_with_exception(const char* pattern, svector<char *>& filenames,const char *exception) +{ + HANDLE h; + WIN32_FIND_DATA finddata; + char *c; + + h=FindFirstFile(pattern,&finddata); + + if(h!=INVALID_HANDLE_VALUE) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception)) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + c=new char[strlen(finddata.cFileName)+1]; + strcpy(c,finddata.cFileName); + filenames.push_back(c); + } + } + + while(FindNextFile(h,&finddata)) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception)) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + c=new char[strlen(finddata.cFileName)+1]; + strcpy(c,finddata.cFileName); + filenames.push_back(c); + } + } + } + + FindClose(h); + } +} + +void find_files_by_pattern(const char* pattern, stringvectst &filenames) +{ + HANDLE h; + WIN32_FIND_DATA finddata; + + h=FindFirstFile(pattern,&finddata); + + if(h!=INVALID_HANDLE_VALUE) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName); + } + + while(FindNextFile(h,&finddata)) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName); + } + } + + FindClose(h); + } +} + +void find_files_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception) +{ + HANDLE h; + WIN32_FIND_DATA finddata; + + h=FindFirstFile(pattern,&finddata); + + if(h!=INVALID_HANDLE_VALUE) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception)) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName); + } + + while(FindNextFile(h,&finddata)) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception)) + { + if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName); + } + } + + FindClose(h); + } +} + +void find_directories_by_pattern(const char* pattern, stringvectst &filenames) +{ + HANDLE h; + WIN32_FIND_DATA finddata; + + h=FindFirstFile(pattern,&finddata); + + if(h!=INVALID_HANDLE_VALUE) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")) + { + if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName); + } + + while(FindNextFile(h,&finddata)) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")) + { + if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName); + } + } + + FindClose(h); + } +} + +void find_directories_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception) +{ + HANDLE h; + WIN32_FIND_DATA finddata; + + h=FindFirstFile(pattern,&finddata); + + if(h!=INVALID_HANDLE_VALUE) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception)) + { + if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName); + } + + while(FindNextFile(h,&finddata)) + { + if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception)) + { + if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName); + } + } + + FindClose(h); + } +}
\ No newline at end of file diff --git a/g_src/find_files.h b/g_src/find_files.h new file mode 100755 index 0000000..3f93e9f --- /dev/null +++ b/g_src/find_files.h @@ -0,0 +1,6 @@ +void find_files_by_pattern(const char* pattern, svector<char *>& vec); +void find_files_by_pattern_with_exception(const char* pattern, svector<char *>& vec, const char* exception); +void find_files_by_pattern(const char* pattern, stringvectst &vec); +void find_files_by_pattern_with_exception(const char* pattern, stringvectst &vec, const char* exception); +void find_directories_by_pattern(const char* pattern, stringvectst &filenames); +void find_directories_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception);
\ No newline at end of file diff --git a/g_src/find_files_posix.cpp b/g_src/find_files_posix.cpp new file mode 100755 index 0000000..bda787b --- /dev/null +++ b/g_src/find_files_posix.cpp @@ -0,0 +1,185 @@ +#include "platform.h" +#include <cerrno> +#include <string> +#include <cstring> +#include <cmath> +#include <iostream> +#include <sstream> +#include <fstream> +#include <algorithm> +#include <map> +#include <set> + +extern "C" { +#include <zlib.h> +#ifndef WIN32 +# include <sys/types.h> +# include <sys/stat.h> +# include <sys/time.h> +# include <signal.h> +#endif +} +#include "svector.h" +#include "random.h" + +using std::string; + +#include "basics.h" +#include "endian.h" +#include "files.h" +#include "enabler.h" +#include "find_files.h" + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <glob.h> +#include <string.h> + +void find_files_by_pattern(const char* pattern, svector<char *>& filenames) +{ + glob_t g; + if (!glob(pattern, 0, NULL, &g)) + { + for (int i = 0; i < g.gl_pathc; ++i) + { + struct stat cstat; + stat(g.gl_pathv[i],&cstat); + if(!S_ISREG(cstat.st_mode))continue; + + // don't include the path + char* src = strrchr(g.gl_pathv[i], '/'); + if (src) + { + int len = strlen(++src); + char* c = new char[len + 1]; // caller will free this + strcpy(c, src); + filenames.push_back(c); + } + } + } + globfree(&g); +} + +void find_files_by_pattern_with_exception(const char* pattern, svector<char *>& filenames,const char *exception) +{ + glob_t g; + if (!glob(pattern, 0, NULL, &g)) + { + for (int i = 0; i < g.gl_pathc; ++i) + { + struct stat cstat; + stat(g.gl_pathv[i],&cstat); + if(!S_ISREG(cstat.st_mode))continue; + + // don't include the path + char* src = strrchr(g.gl_pathv[i], '/'); + if (src) + { + int len = strlen(++src); + if(!strcmp(src,exception))continue; + + char* c = new char[len + 1]; // caller will free this + strcpy(c, src); + filenames.push_back(c); + } + } + } + globfree(&g); +} + +void find_files_by_pattern(const char* pattern, stringvectst& filenames) +{ + glob_t g; + if (!glob(pattern, 0, NULL, &g)) + { + for (int i = 0; i < g.gl_pathc; ++i) + { + struct stat cstat; + stat(g.gl_pathv[i],&cstat); + if(!S_ISREG(cstat.st_mode))continue; + + // don't include the path + char* src = strrchr(g.gl_pathv[i], '/'); + if (src) + { + ++src; + filenames.add_string(src); + } + } + } + globfree(&g); +} + +void find_files_by_pattern_with_exception(const char* pattern, stringvectst& filenames,const char *exception) +{ + glob_t g; + if (!glob(pattern, 0, NULL, &g)) + { + for (int i = 0; i < g.gl_pathc; ++i) + { + struct stat cstat; + stat(g.gl_pathv[i],&cstat); + if(!S_ISREG(cstat.st_mode))continue; + + // don't include the path + char* src = strrchr(g.gl_pathv[i], '/'); + if (src) + { + ++src; + if(!strcmp(src,exception))continue; + + filenames.add_string(src); + } + } + } + globfree(&g); +} + +void find_directories_by_pattern(const char* pattern, stringvectst &filenames) +{ + glob_t g; + if (!glob(pattern, 0, NULL, &g)) + { + for (int i = 0; i < g.gl_pathc; ++i) + { + struct stat cstat; + stat(g.gl_pathv[i],&cstat); + if(!S_ISDIR(cstat.st_mode))continue; + + // don't include the path + char* src = strrchr(g.gl_pathv[i], '/'); + if (src) + { + ++src; + filenames.add_string(src); + } + } + } + globfree(&g); +} + +void find_directories_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception) +{ + glob_t g; + if (!glob(pattern, 0, NULL, &g)) + { + for (int i = 0; i < g.gl_pathc; ++i) + { + struct stat cstat; + stat(g.gl_pathv[i],&cstat); + if(!S_ISDIR(cstat.st_mode))continue; + + // don't include the path + char* src = strrchr(g.gl_pathv[i], '/'); + if (src) + { + ++src; + if(!strcmp(src,exception))continue; + + filenames.add_string(src); + } + } + } + globfree(&g); +} diff --git a/g_src/g_basics.h b/g_src/g_basics.h new file mode 100755 index 0000000..eca424c --- /dev/null +++ b/g_src/g_basics.h @@ -0,0 +1,33 @@ +#ifndef G_BASICS_H +#define G_BASICS_H + +#define MAX_GRID_X 256 +#define MAX_GRID_Y 256 +#define MIN_GRID_X 80 +#define MIN_GRID_Y 25 + +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef ARRSZ +# define ARRSZ(arr) (sizeof (arr) / sizeof ((arr)[0])) +#endif +#ifndef CLAMP +#define CLAMP(x,a,b) MIN(MAX((x),(a)),(b)) +#endif + +// GL error macro +extern int glerrorcount; + +#ifdef DEBUG +# define printGLError() do { GLenum err; do { err = glGetError(); if (err && glerrorcount < 40) { printf("GL error: 0x%x in %s:%d\n", err, __FILE__ , __LINE__); glerrorcount++; } } while(err); } while(0); +# define deputs(str) puts(str) +#else +# define printGLError() +# define deputs(str) +#endif + +#endif diff --git a/g_src/graphics.cpp b/g_src/graphics.cpp new file mode 100755 index 0000000..2f3237a --- /dev/null +++ b/g_src/graphics.cpp @@ -0,0 +1,566 @@ +#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+#include <cassert>
+
+#include "svector.h"
+#include "ttf_manager.hpp"
+
+#ifdef WIN32
+
+/*
+#ifndef INTEGER_TYPES
+ #define INTEGER_TYPES
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned long long uint64_t;
+#endif
+*/
+
+typedef int32_t VIndex;
+typedef int32_t Ordinal;
+
+#endif
+
+#include "random.h"
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "find_files.h"
+
+#include "basics.h"
+
+#include "g_basics.h"
+
+#include "texture_handler.h"
+
+#include "graphics.h"
+
+#include "music_and_sound_g.h"
+
+#include "init.h"
+
+#include "interface.h"
+
+#ifdef __APPLE__
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+
+#include "curses.h"
+
+using namespace std;
+
+
+#pragma comment( lib, "opengl32.lib" ) // Search For OpenGL32.lib While Linking
+#pragma comment( lib, "glu32.lib" ) // Search For GLu32.lib While Linking
+
+extern enablerst enabler;
+extern texture_handlerst texture;
+graphicst gps;
+extern interfacest gview;
+
+extern string errorlog_prefix;
+
+void process_object_lines(textlinesst &lines,string &chktype,string &graphics_dir);
+
+// Add, then increment to the (possible) PBO alignment requirement
+static void align(size_t &sz, off_t inc) {
+ sz += inc;
+ while (sz%64) sz++; // So.. tired.. FIXME.
+}
+
+void graphicst::resize(int x, int y) {
+ dimx = x; dimy = y;
+ init.display.grid_x = x;
+ init.display.grid_y = y;
+ setclipping(0, x-1, 0, y-1);
+ force_full_display_count++;
+ screen_limit = screen + dimx * dimy * 4;
+}
+
+void graphicst::addcoloredst(const char *str,const char *colorstr)
+{
+ const int slen = strlen(str);
+ int s;
+ for(s=0; s < slen && screenx < init.display.grid_x; s++)
+ {
+ if(screenx<0)
+ {
+ s-=screenx;
+ screenx=0;
+ if (s >= slen) break;
+ }
+
+ changecolor((colorstr[s] & 7),((colorstr[s] & 56))>>3,((colorstr[s] & 64))>>6);
+ addchar(str[s]);
+ }
+}
+
+static list<ttf_id> ttfstr;
+
+static void abbreviate_string_helper_hackaroundmissingcode(string &str, int len) {
+ if(str.length()>=2)
+ {
+ if((str[0]=='A'||str[0]=='a')&&
+ str[1]==' ')
+ {
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+
+ if(str.length()>=3)
+ {
+ if((str[0]=='A'||str[0]=='a')&&
+ (str[1]=='N'||str[1]=='n')&&
+ str[2]==' ')
+ {
+ str.erase(str.begin()+2);
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+
+ if(str.length()>=4)
+ {
+ if((str[0]=='T'||str[0]=='t')&&
+ (str[1]=='H'||str[1]=='h')&&
+ (str[2]=='E'||str[2]=='e')&&
+ str[3]==' ')
+ {
+ str.erase(str.begin()+3);
+ str.erase(str.begin()+2);
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+ }
+ }
+ }
+
+ int32_t l;
+ for(l=(int32_t)str.length()-1;l>=1;l--)
+ {
+ if(str[l-1]==' ')continue;
+
+ if(str[l]=='a'||
+ str[l]=='e'||
+ str[l]=='i'||
+ str[l]=='o'||
+ str[l]=='u'||
+ str[l]=='A'||
+ str[l]=='E'||
+ str[l]=='I'||
+ str[l]=='O'||
+ str[l]=='U')
+ {
+ str.erase(str.begin()+l);
+ if(str.length()<=len)return;
+ }
+ }
+
+ if(str.length()>len)str.resize(len);
+}
+
+
+static void abbreviate_string_hackaroundmissingcode(string &str, int32_t len)
+{
+ if (ttf_manager.ttf_active()) {
+ // We'll need to use TTF-aware text shrinking.
+ while (ttf_manager.size_text(str) > len)
+ abbreviate_string_helper_hackaroundmissingcode(str, str.length() - 1);
+ } else if(str.length()>len){
+ // 1 letter = 1 tile.
+ abbreviate_string_helper_hackaroundmissingcode(str, len);
+ }
+}
+
+
+void graphicst::addst(const string &str_orig, justification just, int space)
+{
+ if (!str_orig.size())
+ return;
+ string str = str_orig;
+ if (space)
+ abbreviate_string_hackaroundmissingcode(str, space);
+ if (just == not_truetype || !ttf_manager.ttf_active()) {
+ int s;
+ for(s=0;s<str.length()&&screenx<init.display.grid_x;s++)
+ {
+ if(screenx<0)
+ {
+ s-=screenx;
+ screenx=0;
+ if(s>=str.length())break;
+ }
+
+ addchar(str[s]);
+ }
+ } else {
+ // Truetype
+ if (str.size() > 2 && str[0] == ':' && str[1] == ' ')
+ str[1] = '\t'; // EVIL HACK
+ struct ttf_id id = {str, screenf, screenb, screenbright};
+ ttfstr.push_back(id);
+ // if (str.size() == 80) {
+ // cout << "(" << int(str[0]) << ") ";
+ // }
+ // cout << screeny << "," << str.size() << ":" << str;
+ // if (just == justify_cont)
+ // cout << "|";
+ // else
+ // cout << endl;
+ if (just == justify_cont)
+ return; // More later
+ // This string is done. Time to render.
+ ttf_details details = ttf_manager.get_handle(ttfstr, just);
+ const int handle = details.handle;
+ const int offset = details.offset;
+ int width = details.width;
+ const int ourx = screenx + offset;
+ unsigned int * const s = ((unsigned int*)screen + ourx*dimy + screeny);
+ if (s < (unsigned int*)screen_limit)
+ s[0] = (((unsigned int)GRAPHICSTYPE_TTF) << 24) | handle;
+ // Also set the other tiles this text covers, but don't write past the end.
+ if (width + ourx >= dimx)
+ width = dimx - ourx - 1;
+ for (int x = 1; x < width; ++x)
+ s[x * dimy] = (((unsigned int)GRAPHICSTYPE_TTFCONT) << 24) | handle;
+ // Clean up, prepare for next string.
+ screenx = ourx + width;
+ ttfstr.clear();
+ }
+}
+
+void graphicst::erasescreen_clip()
+{
+ changecolor(0,0,0);
+ short x2,y2;
+ for(x2=clipx[0];x2<=clipx[1];x2++)
+ {
+ for(y2=clipy[0];y2<=clipy[1];y2++)
+ {
+ locate(y2,x2);
+ addchar(' ');
+ }
+ }
+}
+
+void graphicst::erasescreen_rect(int x1, int x2, int y1, int y2)
+{
+ changecolor(0,0,0);
+ for (int x = x1; x <= x2; x++) {
+ for (int y = y1; y <= y2; y++) {
+ locate(y, x);
+ addchar(' ');
+ }
+ }
+}
+
+void graphicst::erasescreen()
+{
+ memset(screen, 0, dimx*dimy*4);
+
+ memset(screentexpos, 0, dimx*dimy*sizeof(long));
+}
+
+void graphicst::setclipping(long x1,long x2,long y1,long y2)
+{
+ if(x1<0)x1=0;
+ if(x2>init.display.grid_x-1)x2=init.display.grid_x-1;
+ if(y1<0)y1=0;
+ if(y2>init.display.grid_y-1)y2=init.display.grid_y-1;
+
+ clipx[0]=x1;
+ clipx[1]=x2;
+ clipy[0]=y1;
+ clipy[1]=y2;
+}
+
+void graphicst::dim_colors(long x,long y,char dim)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ switch(dim)
+ {
+ case 4:
+ switch(screen[x*dimy*4 + y*4 + 2])
+ {
+ case 4:
+ case 5:
+ case 6:
+ screen[x*dimy*4 + y*4 + 2]=1;
+ break;
+ case 2:
+ case 7:
+ screen[x*dimy*4 + y*4 + 2]=3;
+ break;
+ }
+ switch(screen[x*dimy*4 + y*4 + 1])
+ {
+ case 4:
+ case 5:
+ case 6:
+ screen[x*dimy*4 + y*4 + 1]=1;
+ break;
+ case 2:
+ case 7:
+ screen[x*dimy*4 + y*4 + 1]=3;
+ break;
+ }
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2])screen[x*dimy*4 + y*4 + 1]=0;
+ screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ case 3:
+ switch(screen[x*dimy*4 + y*4 + 2])
+ {
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 2]=6;
+ break;
+ case 2:
+ case 7:
+ screen[x*dimy*4 + y*4 + 2]=3;
+ break;
+ }
+ switch(screen[x*dimy*4 + y*4 + 1])
+ {
+ case 1:
+ screen[x*dimy*4 + y*4 + 3]=0;
+ break;
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 1]=6;
+ break;
+ case 2:
+ screen[x*dimy*4 + y*4 + 1]=3;
+ break;
+ case 7:
+ screen[x*dimy*4 + y*4 + 1]=3;
+ break;
+ }
+ if(screen[x*dimy*4 + y*4 + 1]!=7)screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2]&&
+ screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 1]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ case 2:
+ switch(screen[x*dimy*4 + y*4 + 2])
+ {
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 2]=6;
+ break;
+ }
+ switch(screen[x*dimy*4 + y*4 + 1])
+ {
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 1]=6;
+ break;
+ }
+ if(screen[x*dimy*4 + y*4 + 1]!=7)screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2]&&
+ screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 1]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ case 1:
+ if(screen[x*dimy*4 + y*4 + 1]!=7)screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2]&&
+ screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 1]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ }
+ }
+}
+
+void graphicst::rain_color_square(long x,long y)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ screen[x*dimy*4 + y*4 + 1]=1;
+ screen[x*dimy*4 + y*4 + 2]=0;
+ screen[x*dimy*4 + y*4 + 3]=1;
+ }
+}
+
+void graphicst::snow_color_square(long x,long y)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ screen[x*dimy*4 + y*4 + 1]=7;
+ screen[x*dimy*4 + y*4 + 2]=0;
+ screen[x*dimy*4 + y*4 + 3]=1;
+ }
+}
+
+void graphicst::color_square(long x,long y,unsigned char f,unsigned char b,unsigned char br)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ screen[x*dimy*4 + y*4 + 1]=f;
+ screen[x*dimy*4 + y*4 + 2]=b;
+ screen[x*dimy*4 + y*4 + 3]=br;
+ }
+}
+
+void graphicst::prepare_graphics(string &src_dir)
+{
+ if(!init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS))return;
+
+ texture.clean();
+
+ //GET READY TO LOAD
+ svector<char *> processfilename;
+ long f;
+ textlinesst setuplines;
+ char str[400];
+
+ //LOAD THE OBJECT FILES UP INTO MEMORY
+ //MUST INSURE THAT THEY ARE LOADED IN THE PROPER ORDER, IN CASE THEY REFER TO EACH OTHER
+ string chk=src_dir;
+ chk+="graphics/graphics_*";
+#ifdef WIN32
+ chk+=".*";
+#endif
+ find_files_by_pattern_with_exception(chk.c_str(),processfilename,"text");
+
+ string chktype="GRAPHICS";
+ for(f=0;f<processfilename.size();f++)
+ {
+ strcpy(str,src_dir.c_str());
+ strcat(str,"graphics/");
+ strcat(str,processfilename[f]);
+ setuplines.load_raw_to_lines(str);
+
+ errorlog_prefix="*** Error(s) found in the file \"";
+ errorlog_prefix+=str;
+ errorlog_prefix+='\"';
+ process_object_lines(setuplines,chktype,src_dir);
+ errorlog_prefix.clear();
+
+
+ delete[] processfilename[f];
+ }
+ processfilename.clear();
+
+ enabler.reset_textures();
+}
+
+void graphicst::add_tile(long texp,char addcolor)
+{
+ if(screenx>=clipx[0]&&screenx<=clipx[1]&&
+ screeny>=clipy[0]&&screeny<=clipy[1])
+ {
+ screentexpos[screenx*dimy + screeny]=texp;
+ screentexpos_addcolor[screenx*dimy + screeny]=addcolor;
+ screentexpos_grayscale[screenx*dimy + screeny]=0;
+ }
+}
+
+void graphicst::add_tile_grayscale(long texp,char cf,char cbr)
+{
+ if(screenx>=clipx[0]&&screenx<=clipx[1]&&
+ screeny>=clipy[0]&&screeny<=clipy[1])
+ {
+ screentexpos[screenx*dimy + screeny]=texp;
+ screentexpos_addcolor[screenx*dimy + screeny]=0;
+ screentexpos_grayscale[screenx*dimy + screeny]=1;
+ screentexpos_cf[screenx*dimy + screeny]=cf;
+ screentexpos_cbr[screenx*dimy + screeny]=cbr;
+ }
+}
+
+void graphicst::draw_border(int x1, int x2, int y1, int y2) {
+ // Upper and lower
+ for (int x = x1; x <= x2; x++) {
+ locate(y1, x);
+ addchar(' ');
+ locate(y2, x);
+ addchar(' ');
+ }
+ // Left and right
+ for (int y = y1+1; y < y2; y++) {
+ locate(y, x1);
+ addchar(' ');
+ locate(y, x2);
+ addchar(' ');
+ }
+}
+
+void graphicst::get_mouse_text_coords(int32_t &mx, int32_t &my) {
+ mx = mouse_x; my = mouse_y;
+}
+
+void render_things()
+{
+ //GRAB CURRENT SCREEN AT THE END OF THE LIST
+ viewscreenst *currentscreen=&gview.view;
+ while(currentscreen->child!=NULL)currentscreen=currentscreen->child;
+
+ //NO INTERFACE LEFT, LEAVE
+ if(currentscreen==&gview.view)return;
+
+ if(currentscreen->breakdownlevel==INTERFACE_BREAKDOWN_NONE)
+ {
+ currentscreen->render();
+ }
+ else gps.erasescreen();
+
+ // Render REC when recording macros. Definitely want this screen-specific. Or do we?
+ const Time now = SDL_GetTicks();
+ if (enabler.is_recording() && now % 1000 > 500) {
+ gps.locate(0, 20);
+ gps.changecolor(4,1,1);
+ gps.addst("REC");
+ }
+ // Render PLAY when playing a macro
+ if (enabler.is_macro_playing() && now % 1000 <= 500) {
+ gps.locate(0,20);
+ gps.changecolor(2,1,1);
+ gps.addst("PLAY");
+ }
+ // Render # <i> when building a repetition prefix
+ if (enabler.prefix_building()) {
+ gps.locate(0,20);
+ gps.changecolor(3,1,1);
+ gps.addst("#" + enabler.prefix());
+ }
+ if (gps.display_frames) {
+ ostringstream fps_stream;
+ fps_stream << "FPS: " << setw(3) << enabler.calculate_fps() << " (" << enabler.calculate_gfps() << ")";
+ string fps = fps_stream.str();
+ gps.changecolor(7,3,1);
+ static gps_locator fps_locator(0, 25);
+ fps_locator(fps.size());
+ gps.addst(fps);
+ }
+}
diff --git a/g_src/graphics.h b/g_src/graphics.h new file mode 100755 index 0000000..cf3ffee --- /dev/null +++ b/g_src/graphics.h @@ -0,0 +1,252 @@ +#ifndef GRAPHICS_H +#define GRAPHICS_H + +#include <string> +#include <map> +#include <cassert> +using std::string; + +#include "GL/glew.h" +#include "g_basics.h" +#include "platform.h" +#include "basics.h" + +enum Texture +{ + TEXTURE_MOUSE, + TEXTURENUM +}; + +/* screen array layout + * + * + * X*Y tiles of 4 bytes each in column-major order (FIXME: This is inefficient! It should be row-major!) + * For each tile, byte 0 is the character, 1 is foreground color, 2 is bacground, and 3 denotes bold. + * + * As there are only 8 different colors and bold is a boolean, this leaves a lot of free space. Therefore, + * without involving the graphics arrays, out-of-gamut values can be used for designating TTF objects. + * + * This means setting the bold byte to all 1s (0xff), and then using the other three bytes as a designator. + * + * Time will tell whether this was a good idea or not. + */ + +// So yeah, we store "type" in the previously bold byte. This means we have quite a lot of free types yet. +#define GRAPHICSTYPE_TTF 0xff +// This type denotes a tile that is covered by truetype, but is not the tile it starts on. +#define GRAPHICSTYPE_TTFCONT 0xfe + + +class graphicst +{ + int lookup_pair(std::pair<int,int> color); + long calculate_old_fps(); + public: + long screenx,screeny; + char screenf,screenb; + char screenbright; + + unsigned char *screen; + long *screentexpos; + char *screentexpos_addcolor; + unsigned char *screentexpos_grayscale; + unsigned char *screentexpos_cf; + unsigned char *screentexpos_cbr; + + // Calling this is not enough in itself. You also need to call swap_front/back. + void resize(int x, int y); + + long clipx[2],clipy[2]; + long tex_pos[TEXTURENUM]; + + long rect_id; + + LARGE_INTEGER print_time[100]; + long print_index; + char display_frames; + + short force_full_display_count; + + char original_rect; + + int dimx, dimy; + + graphicst() + { + print_index=0; + display_frames=0; + rect_id=-1; + force_full_display_count=4; + original_rect=1; + + screentexpos = NULL; + screentexpos_addcolor = NULL; + screentexpos_grayscale = NULL; + screentexpos_cf = NULL; + screentexpos_cbr = NULL; + screen = NULL; + } + + void locate(long y,long x) + { + // No point in clamping here, addchar clamps too. + screenx=x; + screeny=y; + } + void changecolor(short f,short b,char bright) + { + screenf=f; + screenb=b; + screenbright=bright; + } + void addchar(unsigned char c,char advance=1) + { + /* assert (screen_limit == screen + dimy * dimx * 4); */ + unsigned char *s = screen + screenx*dimy*4 + screeny*4; + if (s < screen_limit) { + if(screenx>=clipx[0]&&screenx<=clipx[1]&& + screeny>=clipy[0]&&screeny<=clipy[1]) + { + *s++ = c; + *s++ = screenf; + *s++ = screenb; + *s++ = screenbright; + screentexpos[screenx*dimy + screeny]=0; + } + } + screenx += advance; + } + void addchar(unsigned int x, unsigned int y, unsigned char c, + unsigned char f, unsigned char b, unsigned char bright) { + /* assert (screen_limit == screen + dimy * dimx * 4); */ + unsigned char *s = screen + x*dimy*4 + y*4; + if (s >= screen && s < screen_limit) { + if(x>=clipx[0]&&x<=clipx[1]&& + y>=clipy[0]&&y<=clipy[1]) + { + *s++ = c; + *s++ = f; + *s++ = b; + *s++ = bright; + } + } + } + void addcoloredst(const char *str,const char *colorstr); + void addst(const string &str, justification just = justify_left, int space=0); + void erasescreen_clip(); + void erasescreen(); + void erasescreen_rect(int x1, int x2, int y1, int y2); + void setclipping(long x1,long x2,long y1,long y2); + + void add_tile(long texp,char addcolor); + void add_tile_grayscale(long texp,char cf,char cbr); + + void prepare_graphics(string &src_dir); + + void gray_out_rect(long sx,long ex,long sy,long ey) + { + long x,y; + for(x=sx;x<=ex;x++) + { + for(y=sy;y<=ey;y++) + { + screen[x*dimy*4 + y*4 + 1]=0; + screen[x*dimy*4 + y*4 + 2]=7; + screen[x*dimy*4 + y*4 + 3]=0; + } + } + } + void dim_colors(long x,long y,char dim); + + void rain_color_square(long x,long y); + void snow_color_square(long x,long y); + void color_square(long x,long y,unsigned char f,unsigned char b,unsigned char br); + + long border_start_x(){return 1;} + long border_start_y(){return 1;} + long border_end_x(){return 78;} + long border_end_y(){return 23;} + long text_width(){return 1;} + long text_height(){return 1;} + long window_element_height(long minus,char border) + { + long height=25; + if(border)height-=2; + height-=text_height()*minus; + return height; + } + + int mouse_x, mouse_y; + void get_mouse_text_coords(int32_t &mx, int32_t &my); + void draw_border(int x1, int x2, int y1, int y2); + + // Instead of doing costly bounds-checking calculations, we cache the end + // of the arrays.. + unsigned char *screen_limit; +}; + +extern graphicst gps; +// From graphics.cpp +void render_things(); + +// Locates some area of the screen with free space for writing +class gps_locator { + int y, last_x; +public: + gps_locator(int y, int x) { + this->y = y; + last_x = x; + } + bool is_free(int x) { + unsigned char c = gps.screen[x*gps.dimy*4 + y*4]; + switch (c) { + case 0: + case 20: + case 176: + case 177: + case 178: + case 219: + case 254: + case 255: + return true; + default: + return false; + } + } + void operator()(int sz) { + // First, check if our cached slot will still do + bool ok = true; + for (int x = last_x; x < last_x + sz; x++) + if (!is_free(x)) { + ok = false; + break; + } + if (ok) { + // Yeah, okay + gps.locate(y, last_x); + } else { + // Not so okay. Find a new spot. + int run = 0, x = 0; + for (; x < gps.dimx; x++) { + if (is_free(x)) + run++; + else run = 0; + if (run > sz + 2) { // We pad things a bit for cleanliness. + ok = true; + x -= sz + 1; + break; + } + } + if (ok) { + // Found a new spot. + last_x = x; + gps.locate(y, x); + } else { + // Damn it. + gps.locate(y, last_x); + } + } + } +}; + +#endif diff --git a/g_src/init.cpp b/g_src/init.cpp new file mode 100755 index 0000000..f60b653 --- /dev/null +++ b/g_src/init.cpp @@ -0,0 +1,685 @@ +#include "platform.h" +#include <string.h> +#include <math.h> +#include <iosfwd> +#include <iostream> +#include <ios> +#include <streambuf> +#include <istream> +#include <ostream> +#include <iomanip> +#include <sstream> +#include <cstdlib> +#include <fstream> +#include <zlib.h> + +#include "svector.h" +using std::string; + +#include "endian.h" + +#include "files.h" + +#include "enabler.h" + +#include "textlines.h" + +#include "basics.h" + +#include "g_basics.h" + +#include "texture_handler.h" + +#include "graphics.h" + +#include "init.h" + +extern enablerst enabler; +extern graphicst gps; + +init_displayst::init_displayst() +{ + flag.set_size_on_flag_num(INIT_DISPLAY_FLAGNUM); + windowed=INIT_DISPLAY_WINDOW_PROMPT; + + partial_print_count=0; +} + +void initst::begin() +{ + static bool called = false; + if (called) return; + called = true; + + string small_font="data/art/curses_640x300.png"; + string large_font="data/art/curses_640x300.png"; + std::ifstream fseed("data/init/init.txt"); + if(fseed.is_open()) + { + string str; + + while(std::getline(fseed,str)) + { + if(str.length()>1) + { + string token; + string token2; + + grab_token_string_pos(token,str,1); + if(str.length()>=token.length()+2) + { + grab_token_string_pos(token2,str,token.length()+2); + } + if(!token.compare("TRUETYPE")) { + const char *str = token2.c_str(); + char *endptr; + int limit = strtol(str, &endptr, 10); + font.ttf_limit = 0; + if (endptr != str) { + font.use_ttf = ttf_auto; + font.ttf_limit = limit; + } else if (token2 == "YES") { + font.use_ttf = ttf_on; + } else { + font.use_ttf = ttf_off; + } + } + + if(!token.compare("FONT")) + { + small_font="data/art/"; + small_font+=token2; + } + if(!token.compare("FULLFONT")) + { + large_font="data/art/"; + large_font+=token2; + } + if(!token.compare("WINDOWEDX")) + { + display.desired_windowed_width=convert_string_to_long(token2); + } + if(!token.compare("WINDOWEDY")) + { + display.desired_windowed_height=convert_string_to_long(token2); + } + if(!token.compare("RESIZABLE")) { + if (token2=="NO") + display.flag.add_flag(INIT_DISPLAY_FLAG_NOT_RESIZABLE); + } + if(!token.compare("FULLSCREENX")) + { + display.desired_fullscreen_width=convert_string_to_long(token2); + } + if(!token.compare("FULLSCREENY")) + { + display.desired_fullscreen_height=convert_string_to_long(token2); + } + + if(token=="PRINT_MODE") + { + if(token2=="PARTIAL") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + + string token3; + if(str.length()>=token.length()+token2.length()+3) + { + grab_token_string_pos(token3,str,token.length()+token2.length()+3); + } + long l=convert_string_to_long(token3); + if(l<0)l=0; + if(l>100)l=100; + display.partial_print_count=(char)l; + } + if(token2=="PROMPT") + { + int answer = MessageBox(NULL, "Using only 2D (Click no) is more reliable, but means you lose features and, often, speed. Edit data/init/init.txt PRINT_MODE to avoid this dialog box.", "Use OpenGL?", MB_YESNO); + if (answer == IDYES) + token2 = "STANDARD"; + else + token2 = "2D"; + } + if(token2=="TEXT") { +#ifdef CURSES + display.flag.add_flag(INIT_DISPLAY_FLAG_TEXT); + display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + display.partial_print_count=0; +#else + MessageBox(NULL, "Text mode not supported on your platform, using 2D", 0, 0); + token2 = "2D"; +#endif + } + if(token2=="FRAME_BUFFER") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_FRAME_BUFFER); + display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + display.partial_print_count=0; + } + if(token2=="ACCUM_BUFFER") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_ACCUM_BUFFER); + display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + display.partial_print_count=0; + } + if(token2=="VBO") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_VBO); + // display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + display.partial_print_count=0; + } + if(token2=="2DSW") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_2D); + display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + display.partial_print_count=0; + } + if(token2=="2D" || token2=="2DHW") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_2D); + display.flag.add_flag(INIT_DISPLAY_FLAG_2DHW); + display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + display.partial_print_count=0; + } + if(token2=="2DASYNC") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_2D); + display.flag.add_flag(INIT_DISPLAY_FLAG_2DHW); + display.flag.add_flag(INIT_DISPLAY_FLAG_2DASYNC); + display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT); + display.partial_print_count=0; + } + if(token2=="SHADER") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_SHADER); + } + } + + if(token=="SINGLE_BUFFER") + { + if(token2=="YES") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_SINGLE_BUFFER); + } + } + + if(display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS)) + { + if(!token.compare("GRAPHICS_FONT")) + { + small_font="data/art/"; + small_font+=token2; + } + if(!token.compare("GRAPHICS_FULLFONT")) + { + large_font="data/art/"; + large_font+=token2; + } + if(!token.compare("GRAPHICS_WINDOWEDX")) + { + display.desired_windowed_width=convert_string_to_long(token2); + } + if(!token.compare("GRAPHICS_WINDOWEDY")) + { + display.desired_windowed_height=convert_string_to_long(token2); + } + if(!token.compare("GRAPHICS_FULLSCREENX")) + { + display.desired_fullscreen_width=convert_string_to_long(token2); + } + if(!token.compare("GRAPHICS_FULLSCREENY")) + { + display.desired_fullscreen_height=convert_string_to_long(token2); + } + if(!token.compare("GRAPHICS_BLACK_SPACE")) + { + if(token2=="YES") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_BLACK_SPACE); + } + else display.flag.remove_flag(INIT_DISPLAY_FLAG_BLACK_SPACE); + } + } + + if(!token.compare("GRAPHICS")) + { + if(token2=="YES") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS); + } + } + + if(!token.compare("BLACK_SPACE")) + { + if(token2=="YES") + { + display.flag.add_flag(INIT_DISPLAY_FLAG_BLACK_SPACE); + } + } + + if(token=="ZOOM_SPEED") + { + input.zoom_speed = convert_string_to_long(token2); + } + if(token=="MOUSE") + { + if(token2=="NO") + { + input.flag.add_flag(INIT_INPUT_FLAG_MOUSE_OFF); + } + } + if(token=="VSYNC") + { + if(token2=="YES") + { + window.flag.add_flag(INIT_WINDOW_FLAG_VSYNC_ON); + } + if(token2=="NO") + { + window.flag.add_flag(INIT_WINDOW_FLAG_VSYNC_OFF); + } + } + if(token=="ARB_SYNC") { + if (token2 == "YES") + display.flag.add_flag(INIT_DISPLAY_FLAG_ARB_SYNC); + } + +#ifdef WIN32 + if(token=="PRIORITY") + { + if(token2=="REALTIME") + { + SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS); + } + if(token2=="HIGH") + { + SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); + } + if(token2=="ABOVE_NORMAL") + { + SetPriorityClass(GetCurrentProcess(),ABOVE_NORMAL_PRIORITY_CLASS); + } + if(token2=="NORMAL") + { + SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS); + } + if(token2=="BELOW_NORMAL") + { + SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS); + } + if(token2=="IDLE") + { + SetPriorityClass(GetCurrentProcess(),IDLE_PRIORITY_CLASS); + } + } +#endif + + if(token=="TEXTURE_PARAM") + { + if(token2=="LINEAR") + { + window.flag.add_flag(INIT_WINDOW_FLAG_TEXTURE_LINEAR); + } + } + if(token=="TOPMOST") + { + if(token2=="YES") + { + window.flag.add_flag(INIT_WINDOW_FLAG_TOPMOST); + } + } + if(token=="FPS") + { + if(token2=="YES") + { + gps.display_frames=1; + } + } + if(token=="MOUSE_PICTURE") + { + if(token2=="YES") + { + input.flag.add_flag(INIT_INPUT_FLAG_MOUSE_PICTURE); + } + } + if(!token.compare("FPS_CAP")) + { + enabler.set_fps(convert_string_to_long(token2)); + } + if(!token.compare("G_FPS_CAP")) + { + enabler.set_gfps(convert_string_to_long(token2)); + } + if(token=="WINDOWED") + { + if(token2=="YES") + { + display.windowed=INIT_DISPLAY_WINDOW_TRUE; + } + if(token2=="NO") + { + display.windowed=INIT_DISPLAY_WINDOW_FALSE; + } + if(token2=="PROMPT") + { + display.windowed=INIT_DISPLAY_WINDOW_PROMPT; + } + } + if(!token.compare("SOUND")) + { + if(token2!="YES") + { + media.flag.add_flag(INIT_MEDIA_FLAG_SOUND_OFF); + } + } + if(!token.compare("INTRO")) + { + if(token2!="YES") + { + media.flag.add_flag(INIT_MEDIA_FLAG_INTRO_OFF); + } + } + if(!token.compare("VOLUME")) + { + media.volume=convert_string_to_long(token2); + } + if(!token.compare("KEY_HOLD_MS")) + { + input.hold_time=convert_string_to_long(token2); + + if(input.hold_time<100)input.hold_time=100; + } + if(token=="KEY_REPEAT_MS") + { + input.repeat_time=convert_string_to_long(token2); + + if(input.repeat_time<100)input.repeat_time=100; + } + if(token=="KEY_REPEAT_ACCEL_LIMIT") { + input.repeat_accel_limit = convert_string_to_long(token2); + if (input.repeat_accel_limit < 1) input.repeat_accel_limit = 1; + } + if(token=="KEY_REPEAT_ACCEL_START") { + input.repeat_accel_start = convert_string_to_long(token2); + } + if(token=="MACRO_MS") + { + input.macro_time=convert_string_to_long(token2); + + if(input.macro_time<1)input.macro_time=1; + } + if(token=="RECENTER_INTERFACE_SHUTDOWN_MS") + { + input.pause_zoom_no_interface_ms=convert_string_to_long(token2); + + if(input.pause_zoom_no_interface_ms<0)input.pause_zoom_no_interface_ms=0; + } + if(token=="COMPRESSED_SAVES") + { + if(token2=="YES") + { + media.flag.add_flag(INIT_MEDIA_FLAG_COMPRESS_SAVES); + } + } + } + } + } + fseed.close(); + + std::ifstream fseed2("data/init/colors.txt"); + if(fseed2.is_open()) + { + string str; + + while(std::getline(fseed2,str)) + { + if(str.length()>1) + { + string token; + string token2; + + grab_token_string_pos(token,str,1); + if(str.length()>=token.length()+2) + { + grab_token_string_pos(token2,str,token.length()+2); + } + + if(!token.compare("BLACK_R")) + { + enabler.ccolor[0][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BLACK_G")) + { + enabler.ccolor[0][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BLACK_B")) + { + enabler.ccolor[0][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BLUE_R")) + { + enabler.ccolor[1][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BLUE_G")) + { + enabler.ccolor[1][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BLUE_B")) + { + enabler.ccolor[1][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("GREEN_R")) + { + enabler.ccolor[2][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("GREEN_G")) + { + enabler.ccolor[2][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("GREEN_B")) + { + enabler.ccolor[2][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("CYAN_R")) + { + enabler.ccolor[3][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("CYAN_G")) + { + enabler.ccolor[3][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("CYAN_B")) + { + enabler.ccolor[3][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("RED_R")) + { + enabler.ccolor[4][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("RED_G")) + { + enabler.ccolor[4][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("RED_B")) + { + enabler.ccolor[4][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("MAGENTA_R")) + { + enabler.ccolor[5][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("MAGENTA_G")) + { + enabler.ccolor[5][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("MAGENTA_B")) + { + enabler.ccolor[5][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BROWN_R")) + { + enabler.ccolor[6][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BROWN_G")) + { + enabler.ccolor[6][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("BROWN_B")) + { + enabler.ccolor[6][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LGRAY_R")) + { + enabler.ccolor[7][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LGRAY_G")) + { + enabler.ccolor[7][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LGRAY_B")) + { + enabler.ccolor[7][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("DGRAY_R")) + { + enabler.ccolor[8][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("DGRAY_G")) + { + enabler.ccolor[8][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("DGRAY_B")) + { + enabler.ccolor[8][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LBLUE_R")) + { + enabler.ccolor[9][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LBLUE_G")) + { + enabler.ccolor[9][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LBLUE_B")) + { + enabler.ccolor[9][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LGREEN_R")) + { + enabler.ccolor[10][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LGREEN_G")) + { + enabler.ccolor[10][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LGREEN_B")) + { + enabler.ccolor[10][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LCYAN_R")) + { + enabler.ccolor[11][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LCYAN_G")) + { + enabler.ccolor[11][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LCYAN_B")) + { + enabler.ccolor[11][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LRED_R")) + { + enabler.ccolor[12][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LRED_G")) + { + enabler.ccolor[12][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LRED_B")) + { + enabler.ccolor[12][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LMAGENTA_R")) + { + enabler.ccolor[13][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LMAGENTA_G")) + { + enabler.ccolor[13][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("LMAGENTA_B")) + { + enabler.ccolor[13][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("YELLOW_R")) + { + enabler.ccolor[14][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("YELLOW_G")) + { + enabler.ccolor[14][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("YELLOW_B")) + { + enabler.ccolor[14][2]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("WHITE_R")) + { + enabler.ccolor[15][0]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("WHITE_G")) + { + enabler.ccolor[15][1]=(float)convert_string_to_long(token2)/255.0f; + } + if(!token.compare("WHITE_B")) + { + enabler.ccolor[15][2]=(float)convert_string_to_long(token2)/255.0f; + } + } + } + } + fseed2.close(); + +#ifdef _DEBUG + enabler.window.isFullScreen = FALSE; +#else + + //FULL SCREEN QUERY, UNLESS IT'S ALREADY SET IN INIT + + if (!display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) { + if(enabler.command_line.empty()) + { + if(display.windowed==INIT_DISPLAY_WINDOW_TRUE) + { + enabler.fullscreen = false; + } + else if(display.windowed==INIT_DISPLAY_WINDOW_FALSE) + { + enabler.fullscreen = true; + } + else + { + if (MessageBox (NULL, "Run in Fullscreen Mode? You can set your preferences in data\\init\\init.txt.\rUnless you've changed your bindings, you can press F11 to toggle this setting any time.", "Start FullScreen?", MB_YESNO | MB_ICONQUESTION) == IDNO) { + enabler.fullscreen = false; // If Not, Run In Windowed Mode + } else { + enabler.fullscreen = true; + } + } + } + else enabler.fullscreen = false; + } +#endif + + + enabler.textures.load_multi_pdim(small_font,font.small_font_texpos,16,16,true,&font.small_font_dispx,&font.small_font_dispy); + enabler.textures.load_multi_pdim(large_font,font.large_font_texpos,16,16,true,&font.large_font_dispx,&font.large_font_dispy); + + // compute the desired window size, if set to auto + if (display.desired_windowed_width < MAX_GRID_X && display.desired_windowed_height < MAX_GRID_Y) { + int dimx = MAX(display.desired_windowed_width,80); + int dimy = MAX(display.desired_windowed_height,25); + display.desired_windowed_width = font.small_font_dispx * dimx; + display.desired_windowed_height = font.small_font_dispy * dimy; + } +} diff --git a/g_src/init.h b/g_src/init.h new file mode 100755 index 0000000..243c5d1 --- /dev/null +++ b/g_src/init.h @@ -0,0 +1,166 @@ +#ifndef INIT_H +#define INIT_H + +#include "enabler.h" +#ifdef __APPLE__ +#include <SDL_ttf/SDL_ttf.h> +#else +#include <SDL/SDL_ttf.h> +#endif + +enum ttf_flag { + ttf_off, ttf_on, ttf_auto +}; + +class init_fontst +{ + public: + long small_font_texpos[256]; + long large_font_texpos[256]; + long small_font_datapos[256]; + long large_font_datapos[256]; + float small_font_adjx; + float small_font_adjy; + float large_font_adjx; + float large_font_adjy; + long small_font_dispx; + long small_font_dispy; + long large_font_dispx; + long large_font_dispy; + ttf_flag use_ttf; + int ttf_limit; +}; + +enum InitDisplayFlag +{ + INIT_DISPLAY_FLAG_USE_GRAPHICS, + INIT_DISPLAY_FLAG_BLACK_SPACE, + INIT_DISPLAY_FLAG_PARTIAL_PRINT, + INIT_DISPLAY_FLAG_FRAME_BUFFER, + INIT_DISPLAY_FLAG_SINGLE_BUFFER, + INIT_DISPLAY_FLAG_ACCUM_BUFFER, + INIT_DISPLAY_FLAG_VBO, + INIT_DISPLAY_FLAG_2D, + INIT_DISPLAY_FLAG_2DHW, + INIT_DISPLAY_FLAG_2DASYNC, + INIT_DISPLAY_FLAG_UNUSED_01_08,// + INIT_DISPLAY_FLAG_TEXT, + INIT_DISPLAY_FLAG_SHADER, + INIT_DISPLAY_FLAG_NOT_RESIZABLE, + INIT_DISPLAY_FLAG_ARB_SYNC, + INIT_DISPLAY_FLAGNUM +}; + +enum InitDisplayWindow +{ + INIT_DISPLAY_WINDOW_TRUE, + INIT_DISPLAY_WINDOW_FALSE, + INIT_DISPLAY_WINDOW_PROMPT, + INIT_DISPLAY_WINDOWNUM +}; + +class init_displayst +{ + public: + flagarrayst flag; + InitDisplayWindow windowed; + + int grid_x, grid_y; // The *current* display grid size, kept up to date + + int desired_fullscreen_width, desired_fullscreen_height; + int desired_windowed_width, desired_windowed_height; + + + char partial_print_count; + + init_displayst(); +}; + +enum InitMediaFlag +{ + INIT_MEDIA_FLAG_SOUND_OFF, + INIT_MEDIA_FLAG_INTRO_OFF, + INIT_MEDIA_FLAG_COMPRESS_SAVES, + INIT_MEDIA_FLAGNUM +}; + +class init_mediast +{ + public: + flagarrayst flag; + int32_t volume; + + init_mediast() + { + flag.set_size_on_flag_num(INIT_MEDIA_FLAGNUM); + volume=255; + } +}; + +enum InitInputFlag +{ + INIT_INPUT_FLAG_MOUSE_OFF, + INIT_INPUT_FLAG_MOUSE_PICTURE, + INIT_INPUT_FLAGNUM +}; + +class init_inputst +{ + public: + long hold_time; + long repeat_time; + long macro_time; + long pause_zoom_no_interface_ms; + flagarrayst flag; + long zoom_speed; + int repeat_accel_start; + int repeat_accel_limit; + + init_inputst() + { + hold_time=150; + repeat_time=150; + macro_time=75; + pause_zoom_no_interface_ms=0; + flag.set_size_on_flag_num(INIT_INPUT_FLAGNUM); + zoom_speed = 10; + repeat_accel_start = 10; + repeat_accel_limit = 1; + } +}; + +enum InitWindowFlag +{ + INIT_WINDOW_FLAG_TOPMOST, + INIT_WINDOW_FLAG_VSYNC_ON, + INIT_WINDOW_FLAG_VSYNC_OFF, + INIT_WINDOW_FLAG_TEXTURE_LINEAR, + INIT_WINDOW_FLAGNUM +}; + +class init_windowst +{ + public: + flagarrayst flag; + + init_windowst() + { + flag.set_size_on_flag_num(INIT_WINDOW_FLAGNUM); + } +}; + +class initst +{ + public: + init_displayst display; + init_mediast media; + init_inputst input; + init_fontst font; + init_windowst window; + + void begin(); +}; + +extern initst init; + +#endif diff --git a/g_src/interface.cpp b/g_src/interface.cpp new file mode 100755 index 0000000..11d0464 --- /dev/null +++ b/g_src/interface.cpp @@ -0,0 +1,1777 @@ +#include "platform.h" +#include <string.h> +#include <math.h> +#include <iosfwd> +#include <iostream> +#include <ios> +#include <streambuf> +#include <istream> +#include <ostream> +#include <iomanip> +#include <sstream> +#include <cstdlib> +#include <fstream> +#include <zlib.h> + +#include "svector.h" +using std::string; + +#include "endian.h" + +#include "files.h" + +#include "enabler.h" + +#include "textlines.h" + +#include "find_files.h" + +#include "basics.h" + +#include "g_basics.h" + +#include "music_and_sound_g.h" + +#include "graphics.h" + +#include "init.h" + +#include "keybindings.h" +#include "interface.h" +#include "KeybindingScreen.h" +#include "ttf_manager.hpp" + +#include <list> +#include <set> + +void dwarf_end_announcements(); +void dwarf_remove_screen(); +void dwarf_option_screen(); +void drawborder(const char *str,char style,const char *colorstr); + + +inline void CHECK_ERR(int err, const char* msg) +{ + if (err != Z_OK) + { + MessageBox(NULL, "One of the compressed files on disk has errors in it. Restore from backup if you are able.", 0, 0); + exit(1); + } +} + +using std::fstream; +using std::ios; +using std::list; +using std::set; + +extern interfacest gview; +extern enablerst enabler; +extern graphicst gps; +extern initst init; +#ifndef NO_FMOD +extern musicsoundst musicsound; +#endif + +extern GameMode gamemode; +extern GameType gametype; + +extern int32_t movie_version; + + + + +void viewscreen_movieplayerst::help() +{ + if(is_playing)return; + + viewscreenst::help(); +} + +void interfacest::finish_movie() +{ + supermovie_on=0; + currentblocksize=0; + nextfilepos=0; + supermovie_pos=0; + viewscreen_movieplayerst::create(INTERFACE_PUSH_AT_BACK); +} + +void interfacest::use_movie_input() +{ + if(supermovie_on)handlemovie(1); + finish_movie(); +} + +viewscreen_movieplayerst *viewscreen_movieplayerst::create(char pushtype,viewscreenst *scr) +{ + viewscreen_movieplayerst *newv=new viewscreen_movieplayerst(); + gview.addscreen(newv,pushtype,scr); + + return newv; +} + +void viewscreen_movieplayerst::force_play(const string &file) +{ + force_file=file; + is_forced_play=1; +} + +void viewscreen_movieplayerst::logic() +{ + enabler.flag&=~ENABLERFLAG_MAXFPS; + + enabler.flag|=ENABLERFLAG_RENDER; + + if(!force_file.empty()&&!is_playing&&!quit_if_no_play&&is_forced_play) + { + is_playing=1; + quit_if_no_play=1; + gview.movie_file=force_file; + gview.supermovie_on=0; + gview.currentblocksize=0; + gview.nextfilepos=0; + gview.supermovie_pos=0; + maxmoviepos=0; + } + + if(!is_playing&&quit_if_no_play) + { + breakdownlevel=INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } + + //LOAD A MOVIE BUFFER BY BUFFER + if(is_playing) + { + if(gview.supermovie_pos>=MOVIEBUFFSIZE||gview.currentblocksize==0) + { + gview.read_movie_chunk(maxmoviepos,is_playing); + } + + if(is_playing) + { + int half_frame_size=init.display.grid_x*init.display.grid_y; + +#ifndef NO_FMOD + //PLAY ANY RELEVANT SOUNDS + if(gview.supermovie_delaystep==gview.supermovie_delayrate) + { + int fr=gview.supermovie_pos/(half_frame_size*2); + if(fr>=0&&fr<200) + { + int c,sd; + for(c=0;c<16;c++) + { + sd=gview.supermovie_sound_time[fr][c]; + if(sd>=0&&sd<gview.supermovie_sound.str.size()) + { + musicsound.playsound(sd,c); + } + } + } + } +#endif + + //PRINT THE NEXT FRAME AND ADVANCE POSITION + short x2,y2; + for(x2=0;x2<init.display.grid_x;x2++) + { + for(y2=0;y2<init.display.grid_y;y2++) + { + gview.supermovie_pos++; + } + } + if(gview.supermovie_delaystep==0) + { + gview.supermovie_pos+=half_frame_size; + gview.supermovie_delaystep=gview.supermovie_delayrate; + } + else + { + gview.supermovie_pos-=half_frame_size;//RETURN TO LAST FRAME + gview.supermovie_delaystep--; + } + + //DONE + if(gview.supermovie_pos>=maxmoviepos&& + maxmoviepos+half_frame_size*2<MOVIEBUFFSIZE) + { + is_playing=0; + //NOTE: THIS CAUSES IT TO LOSE THE LAST FRAME DUE TO CLEARING + } + } + } +} + +void viewscreen_movieplayerst::render() +{ + if(breakdownlevel!=INTERFACE_BREAKDOWN_NONE)return; + + if(!is_playing&&is_forced_play)return; + + if(!quit_if_no_play) + { + if(editing)drawborder(NULL); + else drawborder(" Moving Records "); + } + + //LOAD A MOVIE BUFFER BY BUFFER + if(is_playing) + { + if(gview.currentblocksize>0) + { + int32_t half_frame_size=init.display.grid_x*init.display.grid_y; + + //PRINT THE NEXT FRAME AND ADVANCE POSITION + drawborder(NULL,-1); + + int32_t curp=gview.supermovie_pos; + //HANG ON THE LAST FRAME TO AVOID POSSIBLE OVERRUNS + if(gview.supermovie_pos>=MOVIEBUFFSIZE-half_frame_size*2) + { + curp=MOVIEBUFFSIZE-half_frame_size*4; + } + short x2,y2; + for(x2=0;x2<init.display.grid_x;x2++) + { + for(y2=0;y2<init.display.grid_y;y2++,++curp) + { + gps.locate(y2,x2); + + gps.changecolor((gview.supermoviebuffer[curp+half_frame_size] & 7), + (gview.supermoviebuffer[curp+half_frame_size] & 56)>>3, + (gview.supermoviebuffer[curp+half_frame_size] & 64)); + + gps.addchar(gview.supermoviebuffer[curp]); + } + } + } + } + else if(loading) + { + int scroll=selfile/21*21; + int l; + for(l=scroll;l<filelist.size() && l<scroll+21;l++) + { + if(l==selfile)gps.changecolor(7,0,1); + else gps.changecolor(7,0,0); + gps.locate(l-scroll+2,2); + gps.addst(filelist[l]); + } + } +#ifdef DEBUG_MOVIE_EDIT + else if(editing) + { + if(editing_menu) + { + int tx,ty; + unsigned char c=0; + for(ty=0;ty<16;ty++) + { + for(tx=0;tx<16;tx++) + { + gps.locate(ty,tx); + gps.changecolor(editing_screenf,editing_screenb,editing_screenbright); + gps.addchar(c); + c++; + } + } + gps.locate(18,0); + gps.changecolor(editing_screenf,editing_screenb,editing_screenbright); + gps.addchar(editing_char); + for(ty=0;ty<16;ty++) + { + for(tx=0;tx<8;tx++) + { + gps.locate(ty,tx+16); + gps.changecolor(ty%8,tx,ty/8); + gps.addchar('A'); + } + } + + gps.changecolor(7,0,1); + gps.locate(20,0); + string str; + gps.addst("1/100 sec per frame: ");convert_long_to_string(gview.supermovie_delayrate,str); + gps.addst(str); + + int scroll=(editing_selected_sound/25)*25; + int e; + for(e=scroll;e<scroll+25&&e<gview.supermovie_sound.str.size();e++) + { + if(e==editing_selected_sound)gps.changecolor(7,0,1); + else gps.changecolor(7,0,0); + gps.locate(e-scroll,26); + gps.addst(gview.supermovie_sound.str[e]->dat); + } + + int frame=gview.supermovie_pos/4000,sd; + for(e=0;e<SOUND_CHANNELNUM;e++) + { + gps.changecolor(2,0,1); + gps.locate(e-scroll,52); + sd=gview.supermovie_sound_time[frame][e]; + if(sd>=0&&sd<gview.supermovie_sound.str.size())gps.addst(gview.supermovie_sound.str[sd]->dat); + else + { + gps.addst("-----------------"); + } + gps.changecolor(4,0,1); + gps.locate(e-scroll,(init.display.grid_x-1)); + gps.addst("X"); + } + } + else + { + drawborder(NULL,-1); + + int curp=gview.supermovie_pos; + int x2,y2; + for(x2=0;x2<80;x2++) + { + for(y2=0;y2<25;y2++) + { + gps.locate(y2,x2); + + gps.changecolor((gview.supermoviebuffer[curp+2000] & 7), + (gview.supermoviebuffer[curp+2000] & 56)>>3, + (gview.supermoviebuffer[curp+2000] & 64)); + + gps.addchar(gview.supermoviebuffer[curp]); + + curp++; + } + } + + if(enabler.mouse_y<150)gps.locate(24,0); + else gps.locate(0,0); + gps.changecolor(2,0,1); + gps.addst("Frame: "); + string num; + convert_long_to_string(gview.supermovie_pos/4000+1,num); + gps.addst(num); + + if(enabler.mouse_y<150)gps.locate(24,20); + else gps.locate(0,20); + gps.changecolor(3,0,1); + gps.addst("Copy From: "); + convert_long_to_string(editing_copy_from/4000+1,num); + gps.addst(num); + + if(enabler.mouse_y<150)gps.locate(24,40); + else gps.locate(0,40); + gps.changecolor(4,0,1); + gps.addst("Ends At: "); + convert_long_to_string(end_frame_pos/4000+1,num); + gps.addst(num); + + if(enabler.mouse_y<150)gps.locate(24,60); + else gps.locate(0,60); + int sx,sy; + gps.get_mouse_text_coords(sx,sy); + gps.changecolor(7,0,1); + gps.addst("("); + convert_long_to_string(sx,num); + gps.addst(num); + gps.addst(","); + convert_long_to_string(sy,num); + gps.addst(num); + gps.addst(")"); + } + } +#endif + else + { + gps.changecolor(7,0,1); + gps.locate(2,2); + gview.print_interface_token(INTERFACEKEY_MOVIE_RECORD); + gps.addst(": Start recording (active record is erased, stops when you return here)"); + gps.locate(3,2); + gview.print_interface_token(INTERFACEKEY_MOVIE_PLAY); + gps.addst(": Play the active moving record"); + gps.locate(4,2); + gview.print_interface_token(INTERFACEKEY_MOVIE_SAVE); + gps.addst(": Save the active moving record (you will be prompted for a name)"); + gps.locate(5,2); + gview.print_interface_token(INTERFACEKEY_MOVIE_LOAD); + gps.addst(": Load a moving record"); + +#ifdef DEBUG_MOVIE_EDIT + gps.locate(7,2); + gps.addst("E: Edit"); +#endif + + if(saving) + { + gps.locate(10,2); + gps.addst("Name: "); + gps.addst(savename); + } + } +} + +void viewscreen_movieplayerst::feed(std::set<InterfaceKey> &events) +{ + if(events.count(INTERFACEKEY_LEAVESCREEN)) + { + events.clear(); + + if(is_playing) + { + is_playing=0; + enabler.release_grid_size(); + if (gview.original_fps) + enabler.set_fps(gview.original_fps); + gview.supermovie_on=0; + gview.currentblocksize=0; + gview.nextfilepos=0; + gview.supermovie_pos=0; + maxmoviepos=0; + +#ifndef NO_FMOD + musicsound.stop_sound(); +#endif + } + else if(saving)saving=0; + else if(loading)loading=0; +#ifdef DEBUG_MOVIE_EDIT + else if(editing)editing=0; +#endif + else + { + is_playing=0; + enabler.release_grid_size(); + if (gview.original_fps) + enabler.set_fps(gview.original_fps); + gview.supermovie_on=0; + gview.currentblocksize=0; + gview.nextfilepos=0; + gview.supermovie_pos=0; + maxmoviepos=0; + + breakdownlevel=INTERFACE_BREAKDOWN_STOPSCREEN; + return; + } + } + else if(saving) + { + standardstringentry(savename,39,STRINGENTRY_LETTERS|STRINGENTRY_SPACE|STRINGENTRY_NUMBERS|STRINGENTRY_SYMBOLS,events); + + if(events.count(INTERFACEKEY_SELECT)) + { + string filename; + filename="data/movies/"; + filename+=savename; + filename+=".cmv"; + + copy_file(gview.movie_file,filename); + saving=0; + } + } + else if(loading) + { + if(events.count(INTERFACEKEY_SELECT)) + { + string filename; + filename="data/movies/"; + filename+=filelist[selfile]; + + if(filename!=gview.movie_file) + { + copy_file(filename,gview.movie_file); + } + loading=0; + } + + standardscrolling(events,selfile,0,filelist.size()-1,21); + } +#ifdef DEBUG_MOVIE_EDIT + else if(editing) + { + char entering=0; + + if(editing_menu) + { + if(enabler.mouse_lbut&&enabler.tracking_on) + { + int sx,sy; + gps.get_mouse_text_coords(sx,sy); + + if(sx>=0&&sx<80&&sy>=0&&sy<25) + { + if(sx>=0&&sx<16&&sy>=0&&sy<16) + { + editing_char=sx+sy*16; + } + if(sx>=16&&sx<24&&sy>=0&&sy<16) + { + editing_screenf=sy%8; + editing_screenb=sx-16; + editing_screenbright=sy/8; + } + if(sx>=26&&sx<=51&&sy>=0&&sy<SOUND_CHANNELNUM) + { + editing_selected_sound=sy; + } + int frame=gview.supermovie_pos/4000; + if(sx>=52&&sx<=78&&sy>=0&&sy<SOUND_CHANNELNUM) + { + gview.supermovie_sound_time[frame][sy]=editing_selected_sound; + } + if(sx==(init.display.grid_x-1)&&sy>=0&&sy<SOUND_CHANNELNUM) + { + gview.supermovie_sound_time[frame][sy]=-1; + } + } + + enabler.mouse_lbut=0; + } + + if(enabler.mouse_rbut&&enabler.tracking_on) + { + editing_menu=0; + enabler.mouse_rbut=0; + } + + if(editing_selected_sound>=0&&editing_selected_sound<gview.supermovie_sound.str.size()) + { + if(gview.c== '%') + { + delete gview.supermovie_sound.str[editing_selected_sound]; + gview.supermovie_sound.str.erase(editing_selected_sound); + } + else + { + standardstringentry(events,gview.supermovie_sound.str[editing_selected_sound]->dat,26,STRINGENTRY_LETTERS|STRINGENTRY_SPACE|STRINGENTRY_NUMBERS|STRINGENTRY_SYMBOLS); + entering=1; + } + } + else + { + if(gview.c== '#')gview.supermovie_sound.add_string("new_sound"); + if(gview.c== '+')gview.supermovie_delayrate++; + if(gview.c== '-')gview.supermovie_delayrate--; + if(gview.c== 'T')text_mode=1-text_mode; + } + if(gview.supermovie_delayrate<0)gview.supermovie_delayrate=0; + if(gview.supermovie_delayrate>10)gview.supermovie_delayrate=10; + } + else + { + if(text_mode) + { + if(gview.c!=0) + { + int sx,sy; + gps.get_mouse_text_coords(sx,sy); + + if(sx>=0&&sx<80&&sy>=0&&sy<25) + { + int curpos=gview.supermovie_pos+sy+sx*25; + gview.supermoviebuffer[curpos]=gview.c; + gview.supermoviebuffer[curpos+2000]=(editing_screenf&7)+((editing_screenb&7)<<3); + if(editing_screenbright)gview.supermoviebuffer[curpos+2000]+=64; + } + } + } + else + { + if(gview.c== 'a') + { + int x2,y2; + for(x2=0;x2<80;x2++) + { + for(y2=0;y2<25;y2++) + { + if(x2>0) + { + gview.supermoviebuffer[gview.supermovie_pos+y2+(x2-1)*25]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25]; + gview.supermoviebuffer[gview.supermovie_pos+y2+(x2-1)*25+2000]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25+2000]; + } + if(x2==(init.display.grid_x-1))gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25]=0; + } + } + } + if(gview.c== 'd') + { + int x2,y2; + for(x2=(init.display.grid_x-1);x2>=0;x2--) + { + for(y2=0;y2<(init.display.grid_y-1);y2++) + { + if(x2<(init.display.grid_x-1)) + { + gview.supermoviebuffer[gview.supermovie_pos+y2+(x2+1)*25]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25]; + gview.supermoviebuffer[gview.supermovie_pos+y2+(x2+1)*25+2000]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25+2000]; + } + if(x2==0)gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25]=0; + } + } + } + if(gview.c== 'E')end_frame_pos=gview.supermovie_pos; + if(gview.c== 'c')editing_copy_from=gview.supermovie_pos; + if(gview.c== 'p') + { + int i; + for(i=0;i<4000;i++) + { + gview.supermoviebuffer[gview.supermovie_pos+i]=gview.supermoviebuffer[editing_copy_from+i]; + } + } + if(gview.c== '+')gview.supermovie_pos+=4000; + if(gview.c== '-')gview.supermovie_pos-=4000; + if(gview.c== '/')gview.supermovie_pos-=40000; + if(gview.c== '*')gview.supermovie_pos+=40000; + if(gview.supermovie_pos<0)gview.supermovie_pos=0; + if(gview.supermovie_pos>=MOVIEBUFFSIZE)gview.supermovie_pos=MOVIEBUFFSIZE-4000; + } + + if(enabler.mouse_lbut&&enabler.tracking_on) + { + int sx,sy; + gps.get_mouse_text_coords(sx,sy); + + if(sx>=0&&sx<80&&sy>=0&&sy<25) + { + int curpos=gview.supermovie_pos+sy+sx*25; + gview.supermoviebuffer[curpos]=editing_char; + gview.supermoviebuffer[curpos+2000]=(editing_screenf&7)+((editing_screenb&7)<<3); + if(editing_screenbright)gview.supermoviebuffer[curpos+2000]+=64; + } + } + if(enabler.mouse_rbut&&enabler.tracking_on) + { + editing_menu=1; + enabler.mouse_rbut=0; + } + } + + if(!entering&&gview.c== 'S') + { + int opos=gview.supermovie_pos; + gview.first_movie_write=1; + gview.supermovie_pos=end_frame_pos+4000; + + gview.write_movie_chunk(); + + gview.supermovie_pos=opos; + } + } +#endif + else + { + if(is_playing) + { + } + else + { +#ifdef DEBUG_MOVIE_EDIT + if(gview.c== 'E') + { + editing=1; + gview.supermovie_pos=0; + } +#endif + + if(events.count(INTERFACEKEY_MOVIE_RECORD)) + { + //TURN ON THE MOVIE RECORDER + is_playing=0; + enabler.release_grid_size(); + if (gview.original_fps) + enabler.set_fps(gview.original_fps); + gview.supermovie_on=1; + gview.currentblocksize=0; + gview.nextfilepos=0; + gview.supermovie_pos=0; + gview.supermovie_delayrate=0; + gview.first_movie_write=1; + maxmoviepos=0; + + breakdownlevel=INTERFACE_BREAKDOWN_STOPSCREEN; + } + if(events.count(INTERFACEKEY_MOVIE_PLAY)) + { + is_playing=1; + gview.supermovie_on=0; + gview.currentblocksize=0; + gview.nextfilepos=0; + gview.supermovie_pos=0; + maxmoviepos=0; + } + if(events.count(INTERFACEKEY_MOVIE_SAVE)) + { + savename.erase(); + saving=1; + } + if(events.count(INTERFACEKEY_MOVIE_LOAD)) + { + selfile=0; + + clearfilelist(); + + find_files_by_pattern("data/movies/*.cmv",filelist); + + if(filelist.size()>0)loading=1; + } + } + } +} + +void viewscreen_movieplayerst::clearfilelist() +{ + int f; + for(f=0;f<filelist.size();f++)delete[] filelist[f]; + filelist.clear(); +} + +viewscreen_movieplayerst::viewscreen_movieplayerst() +{ + force_file.erase(); + gview.movie_file="data/movies/last_record.cmv"; + is_playing=0; + enabler.release_grid_size(); + if (gview.original_fps) + enabler.set_fps(gview.original_fps); + is_forced_play=0; + quit_if_no_play=0; + gview.supermovie_on=0; + gview.currentblocksize=0; + gview.nextfilepos=0; + gview.supermovie_pos=0; + maxmoviepos=0; + saving=0; + loading=0; + editing=0; + text_mode=0; + editing_copy_from=0; + editing_char=219; + editing_screenf=7; + editing_screenb=0; + editing_screenbright=0; + editing_menu=0; + editing_selected_sound=0; + end_frame_pos=0; + gview.supermovie_sound.clean(); +#ifndef NO_FMOD + int i,c; + for(i=0;i<200;i++) + { + for(c=0;c<SOUND_CHANNELNUM;c++)gview.supermovie_sound_time[i][c]=-1; + } +#endif +} + +interfacest::interfacest() +{ + original_fps = 0; + shutdown_interface_for_ms=0; + shutdown_interface_tickcount=0; + flag=0; + supermovie_on=0; + supermovie_pos=0; + supermovie_delayrate=0; +} + +interfacest::~interfacest() +{ + //GO AHEAD + while(view.child!=NULL) + { + removescreen(view.child); + } +} + +void interfacest::addscreen(viewscreenst *scr,char pushtype,viewscreenst *relate) +{ + gps.force_full_display_count+=2; + + switch(pushtype) + { + case INTERFACE_PUSH_AS_PARENT:insertscreen_as_parent(scr,relate);break; + case INTERFACE_PUSH_AS_CHILD:insertscreen_as_child(scr,relate);break; + case INTERFACE_PUSH_AT_FRONT:insertscreen_at_front(scr);break; + default:insertscreen_at_back(scr);break; + } + + //WHENEVER A SCREEN IS ADDED, END ANNOUNCEMENTS + if(gamemode==GAMEMODE_DWARF)dwarf_end_announcements(); +} + +void interfacest::insertscreen_as_parent(viewscreenst *scr,viewscreenst *child) +{ + if(child==NULL) + { + insertscreen_at_back(scr); + return; + } + + scr->child=child; + scr->parent=child->parent; + + if(scr->parent!=NULL)scr->parent->child=scr; + child->parent=scr; +} + +void interfacest::insertscreen_as_child(viewscreenst *scr,viewscreenst *parent) +{ + if(parent==NULL) + { + insertscreen_at_back(scr); + return; + } + + scr->child=parent->child; + scr->parent=parent; + + if(scr->child!=NULL)scr->child->parent=scr; + parent->child=scr; +} + +void interfacest::insertscreen_at_back(viewscreenst *scr) +{ + //GRAB CURRENT SCREEN AT THE END OF THE LIST + viewscreenst *currentscreen=&view; + while(currentscreen->child!=NULL)currentscreen=currentscreen->child; + + //PUT IT ON TO THE BACK SCREEN + insertscreen_as_child(scr,currentscreen); +} + +void interfacest::insertscreen_at_front(viewscreenst *scr) +{ + //PUT IT ON TO THE BASE + insertscreen_as_child(scr,&view); +} + +viewscreenst *interfacest::grab_lastscreen() { + viewscreenst *currentscreen = &view; + while (currentscreen->child) currentscreen = currentscreen->child; + return currentscreen; +} + +char interfacest::loop() { + //NO INTERFACE LEFT, QUIT + if(view.child==0)return 1; + + //GRAB CURRENT SCREEN AT THE END OF THE LIST + viewscreenst *currentscreen = grab_lastscreen(); + //MOVE SCREENS BACK + switch(currentscreen->breakdownlevel) { + case INTERFACE_BREAKDOWN_NONE: { + + currentscreen->logic(); + + if(currentscreen->movies_okay()) + { + //HANDLE MOVIES + handlemovie(0); + } + + const Time now = SDL_GetTicks(); + // Process as much input as possible. Some screens can't handle multiple input events + // per logic call (retain_nonzero_input, and any alteration to the window setup + // requires us to stop until the next logic call. + for (;;) { + if (currentscreen->child || currentscreen->breakdownlevel != INTERFACE_BREAKDOWN_NONE) + break; // Some previous input or logic had the effect of switching screens + + if (flag & INTERFACEFLAG_RETAIN_NONZERO_INPUT) { + flag&=~INTERFACEFLAG_RETAIN_NONZERO_INPUT; + break; + } else { + set<InterfaceKey> era = enabler.get_input(now); + if (era.size() == 0) { + if(enabler.mouse_lbut || enabler.mouse_rbut) currentscreen->feed(era); + break; + } + + if (era.count(INTERFACEKEY_OPTIONS)&&!currentscreen->key_conflict(INTERFACEKEY_OPTIONS)) { + //PEEL BACK ALL SCREENS TO THE CURRENT OPTION SCREEN IF THERE IS ONE + //UNLESS THERE IS A BLOCKING SCREEN LIKE THE REGION MAKER + viewscreenst *opscreen=&view; + while(opscreen!=NULL) { + if(opscreen->is_option_screen()) { + opscreen->option_key_pressed=1; + while(opscreen->child!=NULL) { + if(opscreen->child->is_option_screen()==2) { + opscreen->child->option_key_pressed=1; + opscreen->option_key_pressed=0; + break; + } + removescreen(opscreen->child); + } + break; + } + opscreen = opscreen->child; + } + //NEED A NEW OPTIONS SCREEN? + if(opscreen==NULL) dwarf_option_screen(); + + era.clear(); + continue; + } + //DO MOVIE COMMANDS + if (era.count(INTERFACEKEY_MOVIES)&&!currentscreen->key_conflict(INTERFACEKEY_MOVIES)) + if(currentscreen->movies_okay()) use_movie_input(); + if (era.count(INTERFACEKEY_HELP)&&!currentscreen->key_conflict(INTERFACEKEY_HELP)) + currentscreen->help(); + // Prefix commands + // Most prefix commands we don't want to touch game management commands, + // i.e. what's in here. Macro playback is a notable exception. + if (era.count(INTERFACEKEY_PREFIX)) + enabler.prefix_toggle(); + int repeats = 1; // If this input ends a prefix command, we'll want to repeat it. + if (enabler.prefix_building()) { + // TODO: OMGWTFBBQ + char c = 0; + if (era.count(INTERFACEKEY_STRING_A048)) c = '0'; + else if (era.count(INTERFACEKEY_STRING_A049)) c = '1'; + else if (era.count(INTERFACEKEY_STRING_A050)) c = '2'; + else if (era.count(INTERFACEKEY_STRING_A051)) c = '3'; + else if (era.count(INTERFACEKEY_STRING_A052)) c = '4'; + else if (era.count(INTERFACEKEY_STRING_A053)) c = '5'; + else if (era.count(INTERFACEKEY_STRING_A054)) c = '6'; + else if (era.count(INTERFACEKEY_STRING_A055)) c = '7'; + else if (era.count(INTERFACEKEY_STRING_A056)) c = '8'; + else if (era.count(INTERFACEKEY_STRING_A057)) c = '9'; + + if (c) { + enabler.prefix_add_digit(c); + era.clear(); + } else { + repeats = enabler.prefix_end(); + } + } + // TTF toggle + if (era.count(INTERFACEKEY_TOGGLE_TTF)) { + if (init.font.use_ttf == ttf_auto) { + // Do whatever produces a visible result. + if (ttf_manager.ttf_active()) + init.font.use_ttf = ttf_off; + else + init.font.use_ttf = ttf_on; + } else if (init.font.use_ttf == ttf_on) { + init.font.use_ttf = ttf_off; + } else { + init.font.use_ttf = ttf_on; + } + gps.force_full_display_count++; + } + // Zoom commands + if (era.count(INTERFACEKEY_ZOOM_IN)) + enabler.zoom_display(zoom_in); + if (era.count(INTERFACEKEY_ZOOM_OUT)) + enabler.zoom_display(zoom_out); + if (era.count(INTERFACEKEY_ZOOM_RESET)) + enabler.zoom_display(zoom_reset); + // Macro commands + if (era.count(INTERFACEKEY_RECORD_MACRO)) { + if (enabler.is_recording()) + enabler.record_stop(); + else + enabler.record_input(); + } + if (era.count(INTERFACEKEY_PLAY_MACRO)) { + for (int i = 0; i < repeats; i++) + enabler.play_macro(); + } + if (era.count(INTERFACEKEY_SAVE_MACRO)) + gview.addscreen(new MacroScreenSave(), INTERFACE_PUSH_AT_BACK, NULL); + if (era.count(INTERFACEKEY_LOAD_MACRO)) + gview.addscreen(new MacroScreenLoad(), INTERFACE_PUSH_AT_BACK, NULL); + // Feed input + for (int i = 0; i < repeats; i++) + currentscreen->feed(era); + if (era.count(INTERFACEKEY_TOGGLE_FULLSCREEN)) { + enabler.toggle_fullscreen(); + } + if (era.count(INTERFACEKEY_FPS_UP)) { + int fps = enabler.get_fps(); + enabler.set_fps(fps + fps/10); + enabler.clear_fps(); + } + if (era.count(INTERFACEKEY_FPS_DOWN)) { + int fps = enabler.get_fps(); + enabler.set_fps(fps - fps/10); + enabler.clear_fps(); + } + } + } + break; + } // case INTERFACE_BREAKDOWN_NONE + + case INTERFACE_BREAKDOWN_QUIT: + { + handlemovie(1); + return 1; + } + case INTERFACE_BREAKDOWN_STOPSCREEN: + if(currentscreen->movies_okay()) + { + //HANDLE MOVIES + handlemovie(0); + } + + removescreen(currentscreen); + break; + case INTERFACE_BREAKDOWN_TOFIRST: + if(currentscreen->movies_okay()) + { + //HANDLE MOVIES + handlemovie(0); + } + + remove_to_first(); + break; + } + + return 0; +} + +void interfacest::remove_to_first() +{ + //GRAB LAST SCREEN AT THE END OF THE LIST + viewscreenst *lastscreen=&view; + while(lastscreen->child!=NULL)lastscreen=lastscreen->child; + + //NO INTERFACE LEFT + if(lastscreen==&view)return; + + //GO AHEAD + while(lastscreen->parent!=&view) + { + viewscreenst *par=lastscreen->parent; + removescreen(lastscreen); + lastscreen=par; + } +} + +void interfacest::removescreen(viewscreenst *scr) +{ + //THE MINIMAP IS EXPENSIVE, SO WE REFRESH IT WHENEVER INTERFACE GETS IN THE WAY + if(gamemode==GAMEMODE_DWARF)dwarf_remove_screen(); + + //FIX LINKS + if(scr->parent!=NULL)scr->parent->child=scr->child; + if(scr->child!=NULL)scr->child->parent=scr->parent; + + //WASTE SCREEN + delete scr; +} + +int interfacest::write_movie_chunk() +{ + int inputsize=supermovie_pos; + if(inputsize>MOVIEBUFFSIZE)inputsize=MOVIEBUFFSIZE; + + //DUMP CURRENT BUFFER INTO A COMPRESSION STREAM + z_stream c_stream; + int err; + + c_stream.zalloc = (alloc_func)0; + c_stream.zfree = (free_func)0; + c_stream.opaque = (voidpf)0; + + err = deflateInit(&c_stream, 9); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = (Bytef*)supermoviebuffer_comp; + c_stream.avail_out = COMPMOVIEBUFFSIZE; + + c_stream.next_in = (Bytef*)supermoviebuffer; + c_stream.avail_in = inputsize; + + while (c_stream.total_in != inputsize && c_stream.total_out < COMPMOVIEBUFFSIZE) { + //c_stream.avail_in = c_stream.avail_out = 1; // force small buffers + err = deflate(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + // Finish the stream, still forcing small buffers: + for (;;) { + err = deflate(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = deflateEnd(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + int length=0; + + if(c_stream.total_out>0) + { + if(first_movie_write) + { + //GET RID OF ANY EXISTING MOVIES IF THIS IS THE FIRST TIME THROUGH + unlink(movie_file.c_str()); + } + + //OPEN UP THE MOVIE FILE AND APPEND + std::fstream f; + f.open(movie_file.c_str(), fstream::out | fstream::binary | fstream::app); + + if(f.is_open()) + { + //WRITE A HEADER + if(first_movie_write) + { + int swp_l=byteswap(movie_version); + f.write((const char *)&swp_l,sizeof(int)); + + + cursesmovie_headerst cmh; + cmh.dimx=init.display.grid_x; + cmh.dimy=init.display.grid_y; + cmh.delayrate=supermovie_delayrate; + cmh.dimx=byteswap(cmh.dimx); + cmh.dimy=byteswap(cmh.dimy); + cmh.delayrate=byteswap(cmh.delayrate); + f.write((const char *)&cmh,sizeof(cursesmovie_headerst)); + + int s; + s=byteswap(gview.supermovie_sound.str.size()); + f.write((const char *)&s,sizeof(int)); + char buf[50]; + for(s=0;s<gview.supermovie_sound.str.size();s++) + { + strcpy(buf,gview.supermovie_sound.str[s]->dat.c_str()); + f.write(buf,sizeof(char)*50); + } + + int i1,i2; + for(i1=0;i1<200;i1++) + { + for(i2=0;i2<SOUND_CHANNELNUM;i2++) + { +#ifndef NO_FMOD + swp_l=byteswap(gview.supermovie_sound_time[i1][i2]); +#else + swp_l=-1; +#endif + f.write((const char *)&swp_l,sizeof(int)); + } + } + } + + //WRITE IT + int compsize=byteswap(c_stream.total_out); + f.write((const char *)&compsize,sizeof(int)); + f.write((const char *)supermoviebuffer_comp,c_stream.total_out); + + f.seekg(0,ios::beg); + int beg=f.tellg(); + f.seekg(0,ios::end); + int end=f.tellg(); + length=end-beg; + + f.close(); + } + else supermovie_on=0; + + first_movie_write=0; + } + + return length; +} + +void interfacest::read_movie_chunk(int &maxmoviepos,char &is_playing) +{ + //OPEN UP THE MOVIE FILE AND MOVE TO CORRECT POSITION + std::fstream f; + f.open(movie_file.c_str(), fstream::in | fstream::binary); + + if(f.is_open()) + { + f.seekg(0,ios::beg); + int beg=f.tellg(); + f.seekg(0,ios::end); + int end=f.tellg(); + int file_size=end-beg; + + if(gview.nextfilepos<file_size) + { + f.seekg(gview.nextfilepos,ios::beg); + + //LOAD THE HEADER + char fail=0; + if(gview.nextfilepos==0) + { + int loadversion; + f.read((char *)&loadversion,sizeof(int)); + loadversion=byteswap(loadversion); + + if(loadversion>movie_version)fail=1; + + cursesmovie_headerst cmh; + f.read((char *)&cmh,sizeof(cursesmovie_headerst)); + cmh.dimx=byteswap(cmh.dimx); + cmh.dimy=byteswap(cmh.dimy); + cmh.delayrate=byteswap(cmh.delayrate); + + enabler.override_grid_size(cmh.dimx, cmh.dimy); + if (!gview.original_fps) + gview.original_fps = enabler.get_fps(); + enabler.set_fps(100); + + gview.supermovie_delayrate=cmh.delayrate; + gview.supermovie_delaystep=cmh.delayrate; + + gview.supermovie_sound.clean(); + if(loadversion>=10001) + { + int num; + f.read((char *)&num,sizeof(int)); + num=byteswap(num); + gview.nextfilepos+=sizeof(int); + char buf[50]; + int s; + for(s=0;s<num;s++) + { + f.read(buf,sizeof(char)*50); + string str=buf; + gview.supermovie_sound.add_string(str); + gview.nextfilepos+=sizeof(char)*50; + } + + int i1,i2,swp_l; + for(i1=0;i1<200;i1++) + { + for(i2=0;i2<SOUND_CHANNELNUM;i2++) + { + f.read((char *)&swp_l,sizeof(int)); +#ifndef NO_FMOD + gview.supermovie_sound_time[i1][i2]=byteswap(swp_l); +#endif + } + } + + gview.nextfilepos+=sizeof(int)*200*SOUND_CHANNELNUM; + } + else + { +#ifndef NO_FMOD + int i,c; + for(i=0;i<200;i++) + { + for(c=0;c<SOUND_CHANNELNUM;c++)gview.supermovie_sound_time[i][c]=-1; + } +#endif + } + + gview.nextfilepos+=sizeof(int)+sizeof(cursesmovie_headerst); + +#ifndef NO_FMOD + //HANDLE SOUND LOADING + int s; + for(s=0;s<gview.supermovie_sound.str.size();s++) + { + string filename="data/sound/"; + filename+=gview.supermovie_sound.str[s]->dat; + filename+=".ogg"; + + musicsound.set_sound(filename,s); + } +#endif + } + + if(!fail) + { + //READ IT + f.read((char *)&gview.currentblocksize,sizeof(int)); + gview.currentblocksize=byteswap(gview.currentblocksize); + f.read((char *)gview.supermoviebuffer_comp,gview.currentblocksize); + + gview.nextfilepos+=gview.currentblocksize+sizeof(int); + + //UNCOMPRESS IT + z_stream d_stream; // decompression stream + + d_stream.zalloc = (alloc_func)0; + d_stream.zfree = (free_func)0; + d_stream.opaque = (voidpf)0; + + d_stream.next_in = (Bytef*)gview.supermoviebuffer_comp; + d_stream.avail_in = gview.currentblocksize; + + int err = inflateInit(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = gview.supermoviebuffer; + d_stream.avail_out = MOVIEBUFFSIZE; + + while (d_stream.total_out < MOVIEBUFFSIZE && d_stream.total_in < gview.currentblocksize) { + //d_stream.avail_in = d_stream.avail_out = 1; // force small buffers + err = inflate(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = inflateEnd(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + gview.supermovie_pos=0; + maxmoviepos=d_stream.total_out; + } + else + { + is_playing=0; + enabler.release_grid_size(); + if (gview.original_fps) + enabler.set_fps(gview.original_fps); + } + } + else + { + is_playing=0; + enabler.release_grid_size(); + if (gview.original_fps) + enabler.set_fps(gview.original_fps); + } + + f.close(); + } + else + { + is_playing=0; + enabler.release_grid_size(); + if (gview.original_fps) + enabler.set_fps(gview.original_fps); + } +} + +void interfacest::handlemovie(char flushall) +{ + //SAVE A MOVIE FRAME INTO THE CURRENT MOVIE BUFFER + if(supermovie_on==1) + { + if(supermovie_delaystep>0&&!flushall)supermovie_delaystep--; + else + { + if(!flushall)supermovie_delaystep=supermovie_delayrate; + + if(!flushall||supermovie_delaystep==0) + { + //SAVING CHARACTERS, THEN COLORS + short x2,y2; + for(x2=0;x2<init.display.grid_x;x2++) + { + for(y2=0;y2<init.display.grid_y;y2++) + { + supermoviebuffer[supermovie_pos]=gps.screen[x2*gps.dimy*4 + y2*4 + 0]; + + supermovie_pos++; + } + } + char frame_col; + for(x2=0;x2<init.display.grid_x;x2++) + { + for(y2=0;y2<init.display.grid_y;y2++) + { + frame_col=gps.screen[x2*gps.dimy*4 + y2*4 + 1]; + frame_col|=(gps.screen[x2*gps.dimy*4 + y2*4 + 2]<<3); + if(gps.screen[x2*gps.dimy*4 + y2*4 + 3])frame_col|=64; + supermoviebuffer[supermovie_pos]=frame_col; + + supermovie_pos++; + } + } + } + + int frame_size=init.display.grid_x*init.display.grid_y*2; + if(supermovie_pos+frame_size>=MOVIEBUFFSIZE||flushall) + { + int length=write_movie_chunk(); + + if(length>5000000) + { + finish_movie(); + } + else supermovie_pos=0; + } + } + } +} + +void interfacest::print_interface_token(InterfaceKey key,justification just) +{ + short o_screenf=gps.screenf,o_screenb=gps.screenb,o_screenbright=gps.screenbright; + gps.changecolor(2,0,1); + string tok = enabler.GetKeyDisplay(key); + gps.addst(tok,just); + gps.changecolor(o_screenf,o_screenb,o_screenbright); +} + +char standardstringentry(char *str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events) +{ + string str2; + str2=str; + char ret=standardstringentry(str2,maxlen,flag,events); + strcpy(str,str2.c_str()); + return ret; +} + +char standardstringentry(string &str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events) +{ + unsigned char entry=255; + if(flag & STRINGENTRY_LETTERS) + { + if(events.count(INTERFACEKEY_STRING_A097))entry='a'; + if(events.count(INTERFACEKEY_STRING_A098))entry='b'; + if(events.count(INTERFACEKEY_STRING_A099))entry='c'; + if(events.count(INTERFACEKEY_STRING_A100))entry='d'; + if(events.count(INTERFACEKEY_STRING_A101))entry='e'; + if(events.count(INTERFACEKEY_STRING_A102))entry='f'; + if(events.count(INTERFACEKEY_STRING_A103))entry='g'; + if(events.count(INTERFACEKEY_STRING_A104))entry='h'; + if(events.count(INTERFACEKEY_STRING_A105))entry='i'; + if(events.count(INTERFACEKEY_STRING_A106))entry='j'; + if(events.count(INTERFACEKEY_STRING_A107))entry='k'; + if(events.count(INTERFACEKEY_STRING_A108))entry='l'; + if(events.count(INTERFACEKEY_STRING_A109))entry='m'; + if(events.count(INTERFACEKEY_STRING_A110))entry='n'; + if(events.count(INTERFACEKEY_STRING_A111))entry='o'; + if(events.count(INTERFACEKEY_STRING_A112))entry='p'; + if(events.count(INTERFACEKEY_STRING_A113))entry='q'; + if(events.count(INTERFACEKEY_STRING_A114))entry='r'; + if(events.count(INTERFACEKEY_STRING_A115))entry='s'; + if(events.count(INTERFACEKEY_STRING_A116))entry='t'; + if(events.count(INTERFACEKEY_STRING_A117))entry='u'; + if(events.count(INTERFACEKEY_STRING_A118))entry='v'; + if(events.count(INTERFACEKEY_STRING_A119))entry='w'; + if(events.count(INTERFACEKEY_STRING_A120))entry='x'; + if(events.count(INTERFACEKEY_STRING_A121))entry='y'; + if(events.count(INTERFACEKEY_STRING_A122))entry='z'; + if(events.count(INTERFACEKEY_STRING_A065))entry='A'; + if(events.count(INTERFACEKEY_STRING_A066))entry='B'; + if(events.count(INTERFACEKEY_STRING_A067))entry='C'; + if(events.count(INTERFACEKEY_STRING_A068))entry='D'; + if(events.count(INTERFACEKEY_STRING_A069))entry='E'; + if(events.count(INTERFACEKEY_STRING_A070))entry='F'; + if(events.count(INTERFACEKEY_STRING_A071))entry='G'; + if(events.count(INTERFACEKEY_STRING_A072))entry='H'; + if(events.count(INTERFACEKEY_STRING_A073))entry='I'; + if(events.count(INTERFACEKEY_STRING_A074))entry='J'; + if(events.count(INTERFACEKEY_STRING_A075))entry='K'; + if(events.count(INTERFACEKEY_STRING_A076))entry='L'; + if(events.count(INTERFACEKEY_STRING_A077))entry='M'; + if(events.count(INTERFACEKEY_STRING_A078))entry='N'; + if(events.count(INTERFACEKEY_STRING_A079))entry='O'; + if(events.count(INTERFACEKEY_STRING_A080))entry='P'; + if(events.count(INTERFACEKEY_STRING_A081))entry='Q'; + if(events.count(INTERFACEKEY_STRING_A082))entry='R'; + if(events.count(INTERFACEKEY_STRING_A083))entry='S'; + if(events.count(INTERFACEKEY_STRING_A084))entry='T'; + if(events.count(INTERFACEKEY_STRING_A085))entry='U'; + if(events.count(INTERFACEKEY_STRING_A086))entry='V'; + if(events.count(INTERFACEKEY_STRING_A087))entry='W'; + if(events.count(INTERFACEKEY_STRING_A088))entry='X'; + if(events.count(INTERFACEKEY_STRING_A089))entry='Y'; + if(events.count(INTERFACEKEY_STRING_A090))entry='Z'; + } + if(flag & STRINGENTRY_SPACE) + { + if(events.count(INTERFACEKEY_STRING_A032))entry=' '; + } + if(events.count(INTERFACEKEY_STRING_A000))entry='\x0'; + if(flag & STRINGENTRY_NUMBERS) + { + if(events.count(INTERFACEKEY_STRING_A048))entry='0'; + if(events.count(INTERFACEKEY_STRING_A049))entry='1'; + if(events.count(INTERFACEKEY_STRING_A050))entry='2'; + if(events.count(INTERFACEKEY_STRING_A051))entry='3'; + if(events.count(INTERFACEKEY_STRING_A052))entry='4'; + if(events.count(INTERFACEKEY_STRING_A053))entry='5'; + if(events.count(INTERFACEKEY_STRING_A054))entry='6'; + if(events.count(INTERFACEKEY_STRING_A055))entry='7'; + if(events.count(INTERFACEKEY_STRING_A056))entry='8'; + if(events.count(INTERFACEKEY_STRING_A057))entry='9'; + } + if(flag & STRINGENTRY_SYMBOLS) + { + if(events.count(INTERFACEKEY_STRING_A000))entry=0; + if(events.count(INTERFACEKEY_STRING_A001))entry=1; + if(events.count(INTERFACEKEY_STRING_A002))entry=2; + if(events.count(INTERFACEKEY_STRING_A003))entry=3; + if(events.count(INTERFACEKEY_STRING_A004))entry=4; + if(events.count(INTERFACEKEY_STRING_A005))entry=5; + if(events.count(INTERFACEKEY_STRING_A006))entry=6; + if(events.count(INTERFACEKEY_STRING_A007))entry=7; + if(events.count(INTERFACEKEY_STRING_A008))entry=8; + if(events.count(INTERFACEKEY_STRING_A009))entry=9; + if(events.count(INTERFACEKEY_STRING_A010))entry=10; + if(events.count(INTERFACEKEY_STRING_A011))entry=11; + if(events.count(INTERFACEKEY_STRING_A012))entry=12; + if(events.count(INTERFACEKEY_STRING_A013))entry=13; + if(events.count(INTERFACEKEY_STRING_A014))entry=14; + if(events.count(INTERFACEKEY_STRING_A015))entry=15; + if(events.count(INTERFACEKEY_STRING_A016))entry=16; + if(events.count(INTERFACEKEY_STRING_A017))entry=17; + if(events.count(INTERFACEKEY_STRING_A018))entry=18; + if(events.count(INTERFACEKEY_STRING_A019))entry=19; + if(events.count(INTERFACEKEY_STRING_A020))entry=20; + if(events.count(INTERFACEKEY_STRING_A021))entry=21; + if(events.count(INTERFACEKEY_STRING_A022))entry=22; + if(events.count(INTERFACEKEY_STRING_A023))entry=23; + if(events.count(INTERFACEKEY_STRING_A024))entry=24; + if(events.count(INTERFACEKEY_STRING_A025))entry=25; + if(events.count(INTERFACEKEY_STRING_A026))entry=26; + if(events.count(INTERFACEKEY_STRING_A027))entry=27; + if(events.count(INTERFACEKEY_STRING_A028))entry=28; + if(events.count(INTERFACEKEY_STRING_A029))entry=29; + if(events.count(INTERFACEKEY_STRING_A030))entry=30; + if(events.count(INTERFACEKEY_STRING_A031))entry=31; + if(events.count(INTERFACEKEY_STRING_A032))entry=32; + if(events.count(INTERFACEKEY_STRING_A033))entry=33; + if(events.count(INTERFACEKEY_STRING_A034))entry=34; + if(events.count(INTERFACEKEY_STRING_A035))entry=35; + if(events.count(INTERFACEKEY_STRING_A036))entry=36; + if(events.count(INTERFACEKEY_STRING_A037))entry=37; + if(events.count(INTERFACEKEY_STRING_A038))entry=38; + if(events.count(INTERFACEKEY_STRING_A039))entry=39; + if(events.count(INTERFACEKEY_STRING_A040))entry=40; + if(events.count(INTERFACEKEY_STRING_A041))entry=41; + if(events.count(INTERFACEKEY_STRING_A042))entry=42; + if(events.count(INTERFACEKEY_STRING_A043))entry=43; + if(events.count(INTERFACEKEY_STRING_A044))entry=44; + if(events.count(INTERFACEKEY_STRING_A045))entry=45; + if(events.count(INTERFACEKEY_STRING_A046))entry=46; + if(events.count(INTERFACEKEY_STRING_A047))entry=47; + if(events.count(INTERFACEKEY_STRING_A048))entry=48; + if(events.count(INTERFACEKEY_STRING_A049))entry=49; + if(events.count(INTERFACEKEY_STRING_A050))entry=50; + if(events.count(INTERFACEKEY_STRING_A051))entry=51; + if(events.count(INTERFACEKEY_STRING_A052))entry=52; + if(events.count(INTERFACEKEY_STRING_A053))entry=53; + if(events.count(INTERFACEKEY_STRING_A054))entry=54; + if(events.count(INTERFACEKEY_STRING_A055))entry=55; + if(events.count(INTERFACEKEY_STRING_A056))entry=56; + if(events.count(INTERFACEKEY_STRING_A057))entry=57; + if(events.count(INTERFACEKEY_STRING_A058))entry=58; + if(events.count(INTERFACEKEY_STRING_A059))entry=59; + if(events.count(INTERFACEKEY_STRING_A060))entry=60; + if(events.count(INTERFACEKEY_STRING_A061))entry=61; + if(events.count(INTERFACEKEY_STRING_A062))entry=62; + if(events.count(INTERFACEKEY_STRING_A063))entry=63; + if(events.count(INTERFACEKEY_STRING_A064))entry=64; + if(events.count(INTERFACEKEY_STRING_A065))entry=65; + if(events.count(INTERFACEKEY_STRING_A066))entry=66; + if(events.count(INTERFACEKEY_STRING_A067))entry=67; + if(events.count(INTERFACEKEY_STRING_A068))entry=68; + if(events.count(INTERFACEKEY_STRING_A069))entry=69; + if(events.count(INTERFACEKEY_STRING_A070))entry=70; + if(events.count(INTERFACEKEY_STRING_A071))entry=71; + if(events.count(INTERFACEKEY_STRING_A072))entry=72; + if(events.count(INTERFACEKEY_STRING_A073))entry=73; + if(events.count(INTERFACEKEY_STRING_A074))entry=74; + if(events.count(INTERFACEKEY_STRING_A075))entry=75; + if(events.count(INTERFACEKEY_STRING_A076))entry=76; + if(events.count(INTERFACEKEY_STRING_A077))entry=77; + if(events.count(INTERFACEKEY_STRING_A078))entry=78; + if(events.count(INTERFACEKEY_STRING_A079))entry=79; + if(events.count(INTERFACEKEY_STRING_A080))entry=80; + if(events.count(INTERFACEKEY_STRING_A081))entry=81; + if(events.count(INTERFACEKEY_STRING_A082))entry=82; + if(events.count(INTERFACEKEY_STRING_A083))entry=83; + if(events.count(INTERFACEKEY_STRING_A084))entry=84; + if(events.count(INTERFACEKEY_STRING_A085))entry=85; + if(events.count(INTERFACEKEY_STRING_A086))entry=86; + if(events.count(INTERFACEKEY_STRING_A087))entry=87; + if(events.count(INTERFACEKEY_STRING_A088))entry=88; + if(events.count(INTERFACEKEY_STRING_A089))entry=89; + if(events.count(INTERFACEKEY_STRING_A090))entry=90; + if(events.count(INTERFACEKEY_STRING_A091))entry=91; + if(events.count(INTERFACEKEY_STRING_A092))entry=92; + if(events.count(INTERFACEKEY_STRING_A093))entry=93; + if(events.count(INTERFACEKEY_STRING_A094))entry=94; + if(events.count(INTERFACEKEY_STRING_A095))entry=95; + if(events.count(INTERFACEKEY_STRING_A096))entry=96; + if(events.count(INTERFACEKEY_STRING_A097))entry=97; + if(events.count(INTERFACEKEY_STRING_A098))entry=98; + if(events.count(INTERFACEKEY_STRING_A099))entry=99; + if(events.count(INTERFACEKEY_STRING_A100))entry=100; + if(events.count(INTERFACEKEY_STRING_A101))entry=101; + if(events.count(INTERFACEKEY_STRING_A102))entry=102; + if(events.count(INTERFACEKEY_STRING_A103))entry=103; + if(events.count(INTERFACEKEY_STRING_A104))entry=104; + if(events.count(INTERFACEKEY_STRING_A105))entry=105; + if(events.count(INTERFACEKEY_STRING_A106))entry=106; + if(events.count(INTERFACEKEY_STRING_A107))entry=107; + if(events.count(INTERFACEKEY_STRING_A108))entry=108; + if(events.count(INTERFACEKEY_STRING_A109))entry=109; + if(events.count(INTERFACEKEY_STRING_A110))entry=110; + if(events.count(INTERFACEKEY_STRING_A111))entry=111; + if(events.count(INTERFACEKEY_STRING_A112))entry=112; + if(events.count(INTERFACEKEY_STRING_A113))entry=113; + if(events.count(INTERFACEKEY_STRING_A114))entry=114; + if(events.count(INTERFACEKEY_STRING_A115))entry=115; + if(events.count(INTERFACEKEY_STRING_A116))entry=116; + if(events.count(INTERFACEKEY_STRING_A117))entry=117; + if(events.count(INTERFACEKEY_STRING_A118))entry=118; + if(events.count(INTERFACEKEY_STRING_A119))entry=119; + if(events.count(INTERFACEKEY_STRING_A120))entry=120; + if(events.count(INTERFACEKEY_STRING_A121))entry=121; + if(events.count(INTERFACEKEY_STRING_A122))entry=122; + if(events.count(INTERFACEKEY_STRING_A123))entry=123; + if(events.count(INTERFACEKEY_STRING_A124))entry=124; + if(events.count(INTERFACEKEY_STRING_A125))entry=125; + if(events.count(INTERFACEKEY_STRING_A126))entry=126; + if(events.count(INTERFACEKEY_STRING_A128))entry=128; + if(events.count(INTERFACEKEY_STRING_A129))entry=129; + if(events.count(INTERFACEKEY_STRING_A130))entry=130; + if(events.count(INTERFACEKEY_STRING_A131))entry=131; + if(events.count(INTERFACEKEY_STRING_A132))entry=132; + if(events.count(INTERFACEKEY_STRING_A133))entry=133; + if(events.count(INTERFACEKEY_STRING_A134))entry=134; + if(events.count(INTERFACEKEY_STRING_A135))entry=135; + if(events.count(INTERFACEKEY_STRING_A136))entry=136; + if(events.count(INTERFACEKEY_STRING_A137))entry=137; + if(events.count(INTERFACEKEY_STRING_A138))entry=138; + if(events.count(INTERFACEKEY_STRING_A139))entry=139; + if(events.count(INTERFACEKEY_STRING_A140))entry=140; + if(events.count(INTERFACEKEY_STRING_A141))entry=141; + if(events.count(INTERFACEKEY_STRING_A142))entry=142; + if(events.count(INTERFACEKEY_STRING_A143))entry=143; + if(events.count(INTERFACEKEY_STRING_A144))entry=144; + if(events.count(INTERFACEKEY_STRING_A145))entry=145; + if(events.count(INTERFACEKEY_STRING_A146))entry=146; + if(events.count(INTERFACEKEY_STRING_A147))entry=147; + if(events.count(INTERFACEKEY_STRING_A148))entry=148; + if(events.count(INTERFACEKEY_STRING_A149))entry=149; + if(events.count(INTERFACEKEY_STRING_A150))entry=150; + if(events.count(INTERFACEKEY_STRING_A151))entry=151; + if(events.count(INTERFACEKEY_STRING_A152))entry=152; + if(events.count(INTERFACEKEY_STRING_A153))entry=153; + if(events.count(INTERFACEKEY_STRING_A154))entry=154; + if(events.count(INTERFACEKEY_STRING_A155))entry=155; + if(events.count(INTERFACEKEY_STRING_A156))entry=156; + if(events.count(INTERFACEKEY_STRING_A157))entry=157; + if(events.count(INTERFACEKEY_STRING_A158))entry=158; + if(events.count(INTERFACEKEY_STRING_A159))entry=159; + if(events.count(INTERFACEKEY_STRING_A160))entry=160; + if(events.count(INTERFACEKEY_STRING_A161))entry=161; + if(events.count(INTERFACEKEY_STRING_A162))entry=162; + if(events.count(INTERFACEKEY_STRING_A163))entry=163; + if(events.count(INTERFACEKEY_STRING_A164))entry=164; + if(events.count(INTERFACEKEY_STRING_A165))entry=165; + if(events.count(INTERFACEKEY_STRING_A166))entry=166; + if(events.count(INTERFACEKEY_STRING_A167))entry=167; + if(events.count(INTERFACEKEY_STRING_A168))entry=168; + if(events.count(INTERFACEKEY_STRING_A169))entry=169; + if(events.count(INTERFACEKEY_STRING_A170))entry=170; + if(events.count(INTERFACEKEY_STRING_A171))entry=171; + if(events.count(INTERFACEKEY_STRING_A172))entry=172; + if(events.count(INTERFACEKEY_STRING_A173))entry=173; + if(events.count(INTERFACEKEY_STRING_A174))entry=174; + if(events.count(INTERFACEKEY_STRING_A175))entry=175; + if(events.count(INTERFACEKEY_STRING_A176))entry=176; + if(events.count(INTERFACEKEY_STRING_A177))entry=177; + if(events.count(INTERFACEKEY_STRING_A178))entry=178; + if(events.count(INTERFACEKEY_STRING_A179))entry=179; + if(events.count(INTERFACEKEY_STRING_A180))entry=180; + if(events.count(INTERFACEKEY_STRING_A181))entry=181; + if(events.count(INTERFACEKEY_STRING_A182))entry=182; + if(events.count(INTERFACEKEY_STRING_A183))entry=183; + if(events.count(INTERFACEKEY_STRING_A184))entry=184; + if(events.count(INTERFACEKEY_STRING_A185))entry=185; + if(events.count(INTERFACEKEY_STRING_A186))entry=186; + if(events.count(INTERFACEKEY_STRING_A187))entry=187; + if(events.count(INTERFACEKEY_STRING_A188))entry=188; + if(events.count(INTERFACEKEY_STRING_A189))entry=189; + if(events.count(INTERFACEKEY_STRING_A190))entry=190; + if(events.count(INTERFACEKEY_STRING_A191))entry=191; + if(events.count(INTERFACEKEY_STRING_A192))entry=192; + if(events.count(INTERFACEKEY_STRING_A193))entry=193; + if(events.count(INTERFACEKEY_STRING_A194))entry=194; + if(events.count(INTERFACEKEY_STRING_A195))entry=195; + if(events.count(INTERFACEKEY_STRING_A196))entry=196; + if(events.count(INTERFACEKEY_STRING_A197))entry=197; + if(events.count(INTERFACEKEY_STRING_A198))entry=198; + if(events.count(INTERFACEKEY_STRING_A199))entry=199; + if(events.count(INTERFACEKEY_STRING_A200))entry=200; + if(events.count(INTERFACEKEY_STRING_A201))entry=201; + if(events.count(INTERFACEKEY_STRING_A202))entry=202; + if(events.count(INTERFACEKEY_STRING_A203))entry=203; + if(events.count(INTERFACEKEY_STRING_A204))entry=204; + if(events.count(INTERFACEKEY_STRING_A205))entry=205; + if(events.count(INTERFACEKEY_STRING_A206))entry=206; + if(events.count(INTERFACEKEY_STRING_A207))entry=207; + if(events.count(INTERFACEKEY_STRING_A208))entry=208; + if(events.count(INTERFACEKEY_STRING_A209))entry=209; + if(events.count(INTERFACEKEY_STRING_A210))entry=210; + if(events.count(INTERFACEKEY_STRING_A211))entry=211; + if(events.count(INTERFACEKEY_STRING_A212))entry=212; + if(events.count(INTERFACEKEY_STRING_A213))entry=213; + if(events.count(INTERFACEKEY_STRING_A214))entry=214; + if(events.count(INTERFACEKEY_STRING_A215))entry=215; + if(events.count(INTERFACEKEY_STRING_A216))entry=216; + if(events.count(INTERFACEKEY_STRING_A217))entry=217; + if(events.count(INTERFACEKEY_STRING_A218))entry=218; + if(events.count(INTERFACEKEY_STRING_A219))entry=219; + if(events.count(INTERFACEKEY_STRING_A220))entry=220; + if(events.count(INTERFACEKEY_STRING_A221))entry=221; + if(events.count(INTERFACEKEY_STRING_A222))entry=222; + if(events.count(INTERFACEKEY_STRING_A223))entry=223; + if(events.count(INTERFACEKEY_STRING_A224))entry=224; + if(events.count(INTERFACEKEY_STRING_A225))entry=225; + if(events.count(INTERFACEKEY_STRING_A226))entry=226; + if(events.count(INTERFACEKEY_STRING_A227))entry=227; + if(events.count(INTERFACEKEY_STRING_A228))entry=228; + if(events.count(INTERFACEKEY_STRING_A229))entry=229; + if(events.count(INTERFACEKEY_STRING_A230))entry=230; + if(events.count(INTERFACEKEY_STRING_A231))entry=231; + if(events.count(INTERFACEKEY_STRING_A232))entry=232; + if(events.count(INTERFACEKEY_STRING_A233))entry=233; + if(events.count(INTERFACEKEY_STRING_A234))entry=234; + if(events.count(INTERFACEKEY_STRING_A235))entry=235; + if(events.count(INTERFACEKEY_STRING_A236))entry=236; + if(events.count(INTERFACEKEY_STRING_A237))entry=237; + if(events.count(INTERFACEKEY_STRING_A238))entry=238; + if(events.count(INTERFACEKEY_STRING_A239))entry=239; + if(events.count(INTERFACEKEY_STRING_A240))entry=240; + if(events.count(INTERFACEKEY_STRING_A241))entry=241; + if(events.count(INTERFACEKEY_STRING_A242))entry=242; + if(events.count(INTERFACEKEY_STRING_A243))entry=243; + if(events.count(INTERFACEKEY_STRING_A244))entry=244; + if(events.count(INTERFACEKEY_STRING_A245))entry=245; + if(events.count(INTERFACEKEY_STRING_A246))entry=246; + if(events.count(INTERFACEKEY_STRING_A247))entry=247; + if(events.count(INTERFACEKEY_STRING_A248))entry=248; + if(events.count(INTERFACEKEY_STRING_A249))entry=249; + if(events.count(INTERFACEKEY_STRING_A250))entry=250; + if(events.count(INTERFACEKEY_STRING_A251))entry=251; + if(events.count(INTERFACEKEY_STRING_A252))entry=252; + if(events.count(INTERFACEKEY_STRING_A253))entry=253; + if(events.count(INTERFACEKEY_STRING_A254))entry=254; + if(events.count(INTERFACEKEY_STRING_A255))entry=255; + } + + if(entry!=255) + { + if(entry=='\x0') + { + if(str.length()>0)str.resize(str.length()-1); + } + else + { + int cursor=str.length(); + if(cursor>=maxlen)cursor=maxlen-1; + if(cursor<0)cursor=0; + + if(str.length()<cursor+1)str.resize(cursor+1); + + if(entry>='a'&&entry<='z'&&(flag & STRINGENTRY_CAPS))str[cursor]=entry+'A'-'a'; + else str[cursor]=entry; + } + + + return 1; + } + + return 0; +} + +//To Do +//get the gview.c references inside the DEBUG_MOVIE defines +//make scrolling and stringentry use newer pressed functions for better speed diff --git a/g_src/interface.h b/g_src/interface.h new file mode 100755 index 0000000..6df8fdd --- /dev/null +++ b/g_src/interface.h @@ -0,0 +1,149 @@ +#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include <string>
+using std::string;
+#include <set>
+#include "svector.h"
+#include "ViewBase.h"
+#include "keybindings.h"
+#include "enabler.h"
+#include "music_and_sound_g.h"
+
+struct cursesmovie_headerst
+{
+ int dimx,dimy;
+ int delayrate;
+};
+
+class viewscreen_movieplayerst : viewscreenst
+{
+ public:
+ static viewscreen_movieplayerst *create(char pushtype,viewscreenst *scr=NULL);
+ virtual void help();
+ virtual void feed(std::set<InterfaceKey> &events);
+ virtual void logic();
+ virtual void render();
+ virtual char movies_okay(){return 0;}
+ void clearfilelist();
+ void force_play(const string &file);
+
+ virtual char is_option_screen(){if(is_playing)return 2;else return 0;}
+
+ protected:
+ char saving;
+ char loading;
+ char editing;
+ char text_mode;
+ unsigned char editing_char;
+ int editing_copy_from;
+ short editing_screenf;
+ short editing_screenb;
+ short editing_screenbright;
+ int editing_selected_sound;
+ char editing_menu;
+ string savename;
+ string force_file;
+ char is_playing;
+ char is_forced_play;
+ char quit_if_no_play;
+ int maxmoviepos;
+ int end_frame_pos;
+
+ int32_t selfile;
+ svector<char *> filelist;
+
+ viewscreen_movieplayerst();
+ virtual ~viewscreen_movieplayerst(){clearfilelist();};
+};
+
+enum InterfacePushType
+{
+ INTERFACE_PUSH_AS_PARENT,
+ INTERFACE_PUSH_AS_CHILD,
+ INTERFACE_PUSH_AT_BACK,
+ INTERFACE_PUSH_AT_FRONT,
+ INTERFACE_PUSHNUM
+};
+
+#define INTERFACEFLAG_RETAIN_NONZERO_INPUT BIT1
+
+#define MOVIEBUFFSIZE 800000
+#define COMPMOVIEBUFFSIZE 1000000
+
+class interfacest
+{
+ int original_fps;
+ viewscreenst *grab_lastscreen();
+ friend class viewscreen_movieplayerst;
+
+ public:
+ viewscreenst view;
+ unsigned int flag;
+
+ int shutdown_interface_tickcount;
+ int shutdown_interface_for_ms;
+
+ char loop();
+ void remove_to_first();
+ void removescreen(viewscreenst *scr);
+ void addscreen(viewscreenst *scr,char pushtype,viewscreenst *relate);
+ char is_supermovie_on()
+ {
+ return supermovie_on;
+ }
+
+ void print_interface_token(InterfaceKey key,justification just=justify_left);
+
+ interfacest();
+ ~interfacest();
+
+ protected:
+ char supermovie_on;
+ int supermovie_pos;
+ int supermovie_delayrate;
+ int supermovie_delaystep;
+ stringvectst supermovie_sound;
+#ifndef NO_FMOD
+ int supermovie_sound_time[200][SOUND_CHANNELNUM];
+#endif
+ unsigned char supermoviebuffer[MOVIEBUFFSIZE];
+ unsigned char supermoviebuffer_comp[COMPMOVIEBUFFSIZE];
+ int currentblocksize;
+ int nextfilepos;
+ char first_movie_write;
+ string movie_file;
+
+ void insertscreen_as_parent(viewscreenst *scr,viewscreenst *child);
+ void insertscreen_as_child(viewscreenst *scr,viewscreenst *parent);
+ void insertscreen_at_back(viewscreenst *scr);
+ void insertscreen_at_front(viewscreenst *scr);
+ void handlemovie(char flushall);
+ void finish_movie();
+ void use_movie_input();
+
+ int write_movie_chunk();
+ void read_movie_chunk(int &maxmoviepos,char &is_playing);
+};
+
+#define SCROLLING_NOSELECT BIT1
+#define SCROLLING_NO_WRAP BIT2
+#define SCROLLING_REVERSE BIT3
+void finishscrolling(int32_t &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag,char littlekey);
+char standardscrolling(std::set<InterfaceKey> &events,short &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+char standardscrolling(std::set<InterfaceKey> &events,int32_t &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+char secondaryscrolling(std::set<InterfaceKey> &events,short &scroll,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+char secondaryscrolling(std::set<InterfaceKey> &events,int32_t &scroll,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+#define STRINGENTRY_LETTERS BIT1
+#define STRINGENTRY_SPACE BIT2
+#define STRINGENTRY_NUMBERS BIT3
+#define STRINGENTRY_CAPS BIT4
+#define STRINGENTRY_SYMBOLS BIT5
+char standardstringentry(char *str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events);
+char standardstringentry(string &str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events);
+
+void drawborder(const char *str,char style=0,const char *colorstr=NULL);
+
+extern interfacest gview;
+
+#endif
diff --git a/g_src/keybindings.cpp b/g_src/keybindings.cpp new file mode 100755 index 0000000..d22b035 --- /dev/null +++ b/g_src/keybindings.cpp @@ -0,0 +1,3115 @@ +#include "keybindings.h"
+
+#include <SDL/SDL.h>
+
+using namespace std;
+
+bimap<InterfaceKey,std::string> bindingNames;
+bimap<InterfaceKey,std::string> displayNames;
+bimap<SDLKey,std::string> sdlNames;
+
+void keybinding_init() {
+ bindingNames.insert(INTERFACEKEY_NONE, "NONE");
+ bindingNames.insert(INTERFACEKEY_SELECT, "SELECT");
+ bindingNames.insert(INTERFACEKEY_SEC_SELECT, "SEC_SELECT");
+ bindingNames.insert(INTERFACEKEY_DESELECT, "DESELECT");
+ bindingNames.insert(INTERFACEKEY_SELECT_ALL, "SELECT_ALL");
+ bindingNames.insert(INTERFACEKEY_DESELECT_ALL, "DESELECT_ALL");
+ bindingNames.insert(INTERFACEKEY_LEAVESCREEN, "LEAVESCREEN");
+ bindingNames.insert(INTERFACEKEY_LEAVESCREEN_ALL, "LEAVESCREEN_ALL");
+ bindingNames.insert(INTERFACEKEY_CLOSE_MEGA_ANNOUNCEMENT, "CLOSE_MEGA_ANNOUNCEMENT");
+ bindingNames.insert(INTERFACEKEY_TOGGLE_FULLSCREEN, "TOGGLE_FULLSCREEN");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_ADD, "WORLD_PARAM_ADD");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_COPY, "WORLD_PARAM_COPY");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DELETE, "WORLD_PARAM_DELETE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_TITLE, "WORLD_PARAM_TITLE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_RANDOM, "WORLD_PARAM_NAME_RANDOM");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_ENTER, "WORLD_PARAM_NAME_ENTER");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_RANDOM, "WORLD_PARAM_SEED_RANDOM");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_ENTER, "WORLD_PARAM_SEED_ENTER");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_LOAD, "WORLD_PARAM_LOAD");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SAVE, "WORLD_PARAM_SAVE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_UP, "WORLD_PARAM_DIM_X_UP");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_DOWN, "WORLD_PARAM_DIM_X_DOWN");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_UP, "WORLD_PARAM_DIM_Y_UP");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_DOWN, "WORLD_PARAM_DIM_Y_DOWN");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SET, "WORLD_PARAM_SET");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_INCREASE, "WORLD_PARAM_INCREASE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DECREASE, "WORLD_PARAM_DECREASE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_ENTER_VALUE, "WORLD_PARAM_ENTER_VALUE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_NULLIFY, "WORLD_PARAM_NULLIFY");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_PRESET, "WORLD_PARAM_PRESET");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_CONTINUE, "WORLD_PARAM_REJECT_CONTINUE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ABORT, "WORLD_PARAM_REJECT_ABORT");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_THIS, "WORLD_PARAM_REJECT_ALLOW_THIS");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_ALL, "WORLD_PARAM_REJECT_ALLOW_ALL");
+ bindingNames.insert(INTERFACEKEY_WORLD_GEN_CONTINUE, "WORLD_GEN_CONTINUE");
+ bindingNames.insert(INTERFACEKEY_WORLD_GEN_USE, "WORLD_GEN_USE");
+ bindingNames.insert(INTERFACEKEY_WORLD_GEN_ABORT, "WORLD_GEN_ABORT");
+ bindingNames.insert(INTERFACEKEY_SETUP_EMBARK, "SETUP_EMBARK");
+ bindingNames.insert(INTERFACEKEY_SETUP_NAME_FORT, "SETUP_NAME_FORT");
+ bindingNames.insert(INTERFACEKEY_SETUP_NAME_GROUP, "SETUP_NAME_GROUP");
+ bindingNames.insert(INTERFACEKEY_SETUP_RECLAIM, "SETUP_RECLAIM");
+ bindingNames.insert(INTERFACEKEY_SETUP_FIND, "SETUP_FIND");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES, "SETUP_NOTES");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_TAKE_NOTES, "SETUP_NOTES_TAKE_NOTES");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_DELETE_NOTE, "SETUP_NOTES_DELETE_NOTE");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_CHANGE_SYMBOL_SELECTION, "SETUP_NOTES_CHANGE_SYMBOL_SELECTION");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_ADOPT_SYMBOL, "SETUP_NOTES_ADOPT_SYMBOL");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_UP, "SETUP_LOCAL_Y_UP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_DOWN, "SETUP_LOCAL_Y_DOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_UP, "SETUP_LOCAL_X_UP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_DOWN, "SETUP_LOCAL_X_DOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MUP, "SETUP_LOCAL_Y_MUP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MDOWN, "SETUP_LOCAL_Y_MDOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MUP, "SETUP_LOCAL_X_MUP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MDOWN, "SETUP_LOCAL_X_MDOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_1, "SETUP_BIOME_1");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_2, "SETUP_BIOME_2");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_3, "SETUP_BIOME_3");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_4, "SETUP_BIOME_4");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_5, "SETUP_BIOME_5");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_6, "SETUP_BIOME_6");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_7, "SETUP_BIOME_7");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_8, "SETUP_BIOME_8");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_9, "SETUP_BIOME_9");
+ bindingNames.insert(INTERFACEKEY_CHOOSE_NAME_RANDOM, "CHOOSE_NAME_RANDOM");
+ bindingNames.insert(INTERFACEKEY_CHOOSE_NAME_CLEAR, "CHOOSE_NAME_CLEAR");
+ bindingNames.insert(INTERFACEKEY_CHOOSE_NAME_TYPE, "CHOOSE_NAME_TYPE");
+ bindingNames.insert(INTERFACEKEY_ITEM_DESCRIPTION, "ITEM_DESCRIPTION");
+ bindingNames.insert(INTERFACEKEY_ITEM_FORBID, "ITEM_FORBID");
+ bindingNames.insert(INTERFACEKEY_ITEM_MELT, "ITEM_MELT");
+ bindingNames.insert(INTERFACEKEY_ITEM_DUMP, "ITEM_DUMP");
+ bindingNames.insert(INTERFACEKEY_ITEM_HIDE, "ITEM_HIDE");
+ bindingNames.insert(INTERFACEKEY_HELP, "HELP");
+ bindingNames.insert(INTERFACEKEY_MOVIES, "MOVIES");
+ bindingNames.insert(INTERFACEKEY_OPTIONS, "OPTIONS");
+ bindingNames.insert(INTERFACEKEY_OPTION_EXPORT, "OPTION_EXPORT");
+ bindingNames.insert(INTERFACEKEY_CHANGETAB, "CHANGETAB");
+ bindingNames.insert(INTERFACEKEY_SEC_CHANGETAB, "SEC_CHANGETAB");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_LEFT, "STANDARDSCROLL_LEFT");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_RIGHT, "STANDARDSCROLL_RIGHT");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_UP, "STANDARDSCROLL_UP");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_DOWN, "STANDARDSCROLL_DOWN");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEUP, "STANDARDSCROLL_PAGEUP");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN, "STANDARDSCROLL_PAGEDOWN");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_UP, "SECONDSCROLL_UP");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_DOWN, "SECONDSCROLL_DOWN");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEUP, "SECONDSCROLL_PAGEUP");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEDOWN, "SECONDSCROLL_PAGEDOWN");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP, "CURSOR_UP");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN, "CURSOR_DOWN");
+ bindingNames.insert(INTERFACEKEY_CURSOR_LEFT, "CURSOR_LEFT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_RIGHT, "CURSOR_RIGHT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPLEFT, "CURSOR_UPLEFT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPRIGHT, "CURSOR_UPRIGHT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT, "CURSOR_DOWNLEFT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT, "CURSOR_DOWNRIGHT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP_FAST, "CURSOR_UP_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN_FAST, "CURSOR_DOWN_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_LEFT_FAST, "CURSOR_LEFT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_RIGHT_FAST, "CURSOR_RIGHT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPLEFT_FAST, "CURSOR_UPLEFT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPRIGHT_FAST, "CURSOR_UPRIGHT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT_FAST, "CURSOR_DOWNLEFT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT_FAST, "CURSOR_DOWNRIGHT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP_Z, "CURSOR_UP_Z");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN_Z, "CURSOR_DOWN_Z");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP_Z_AUX, "CURSOR_UP_Z_AUX");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN_Z_AUX, "CURSOR_DOWN_Z_AUX");
+ bindingNames.insert(INTERFACEKEY_A_RETURN_TO_ARENA, "A_RETURN_TO_ARENA");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_N, "A_MOVE_N");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_S, "A_MOVE_S");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_E, "A_MOVE_E");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_W, "A_MOVE_W");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NW, "A_MOVE_NW");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NE, "A_MOVE_NE");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SW, "A_MOVE_SW");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SE, "A_MOVE_SE");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SAME_SQUARE, "A_MOVE_SAME_SQUARE");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_N, "A_CARE_MOVE_N");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_S, "A_CARE_MOVE_S");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_E, "A_CARE_MOVE_E");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_W, "A_CARE_MOVE_W");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_NW, "A_CARE_MOVE_NW");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_NE, "A_CARE_MOVE_NE");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_SW, "A_CARE_MOVE_SW");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_SE, "A_CARE_MOVE_SE");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_UPDOWN, "A_CARE_MOVE_UPDOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_N_UP, "A_MOVE_N_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_S_UP, "A_MOVE_S_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_E_UP, "A_MOVE_E_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_W_UP, "A_MOVE_W_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NW_UP, "A_MOVE_NW_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NE_UP, "A_MOVE_NE_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SW_UP, "A_MOVE_SW_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SE_UP, "A_MOVE_SE_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_UP, "A_MOVE_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_N_DOWN, "A_MOVE_N_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_S_DOWN, "A_MOVE_S_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_E_DOWN, "A_MOVE_E_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_W_DOWN, "A_MOVE_W_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NW_DOWN, "A_MOVE_NW_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NE_DOWN, "A_MOVE_NE_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SW_DOWN, "A_MOVE_SW_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SE_DOWN, "A_MOVE_SE_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_DOWN, "A_MOVE_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_UP_AUX, "A_MOVE_UP_AUX");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_DOWN_AUX, "A_MOVE_DOWN_AUX");
+ bindingNames.insert(INTERFACEKEY_WORLDGEN_EXPORT_MAP, "WORLDGEN_EXPORT_MAP");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_EXPORT_MAP, "LEGENDS_EXPORT_MAP");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_EXPORT_XML, "LEGENDS_EXPORT_XML");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_EXPORT_DETAILED_MAP, "LEGENDS_EXPORT_DETAILED_MAP");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_TOGGLE_CIVSITE, "LEGENDS_TOGGLE_CIVSITE");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_STRING_FILTER, "LEGENDS_STRING_FILTER");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT_ATTACK, "A_COMBAT_ATTACK");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT_DODGE, "A_COMBAT_DODGE");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT_CHARGEDEF, "A_COMBAT_CHARGEDEF");
+ bindingNames.insert(INTERFACEKEY_A_STATUS, "A_STATUS");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_WRESTLE, "A_STATUS_WRESTLE");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_CUSTOMIZE, "A_STATUS_CUSTOMIZE");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_KILLS, "A_STATUS_KILLS");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_HEALTH, "A_STATUS_HEALTH");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_ATT_SKILL, "A_STATUS_ATT_SKILL");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_DESC, "A_STATUS_DESC");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_CUSTOMIZE, "UNITVIEW_CUSTOMIZE");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_HEALTH, "UNITVIEW_HEALTH");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS, "UNITVIEW_RELATIONSHIPS");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_ZOOM, "UNITVIEW_RELATIONSHIPS_ZOOM");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_VIEW, "UNITVIEW_RELATIONSHIPS_VIEW");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_KILLS, "UNITVIEW_KILLS");
+ bindingNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_NICKNAME, "CUSTOMIZE_UNIT_NICKNAME");
+ bindingNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_PROFNAME, "CUSTOMIZE_UNIT_PROFNAME");
+ bindingNames.insert(INTERFACEKEY_A_CLEAR_ANNOUNCEMENTS, "A_CLEAR_ANNOUNCEMENTS");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP, "A_SLEEP");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP_SLEEP, "A_SLEEP_SLEEP");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP_WAIT, "A_SLEEP_WAIT");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP_DAWN, "A_SLEEP_DAWN");
+ bindingNames.insert(INTERFACEKEY_A_WAIT, "A_WAIT");
+ bindingNames.insert(INTERFACEKEY_A_SHORT_WAIT, "A_SHORT_WAIT");
+ bindingNames.insert(INTERFACEKEY_A_ATTACK, "A_ATTACK");
+ bindingNames.insert(INTERFACEKEY_A_ATTACK_CONFIRM, "A_ATTACK_CONFIRM");
+ bindingNames.insert(INTERFACEKEY_QUICK_ATTACK, "QUICK_ATTACK");
+ bindingNames.insert(INTERFACEKEY_HEAVY_ATTACK, "HEAVY_ATTACK");
+ bindingNames.insert(INTERFACEKEY_WILD_ATTACK, "WILD_ATTACK");
+ bindingNames.insert(INTERFACEKEY_PRECISE_ATTACK, "PRECISE_ATTACK");
+ bindingNames.insert(INTERFACEKEY_CHARGE_ATTACK, "CHARGE_ATTACK");
+ bindingNames.insert(INTERFACEKEY_MULTI_ATTACK, "MULTI_ATTACK");
+ bindingNames.insert(INTERFACEKEY_A_LOOK, "A_LOOK");
+ bindingNames.insert(INTERFACEKEY_A_SEARCH, "A_SEARCH");
+ bindingNames.insert(INTERFACEKEY_A_ODOR,"A_ODOR");
+ bindingNames.insert(INTERFACEKEY_A_DISPLAY_ODOR,"A_DISPLAY_ODOR");
+ bindingNames.insert(INTERFACEKEY_A_YIELD,"A_YIELD");
+ bindingNames.insert(INTERFACEKEY_A_DISPLAY_TRACKS,"A_DISPLAY_TRACKS");
+ bindingNames.insert(INTERFACEKEY_A_FRESHEST_TRACK,"A_FRESHEST_TRACK");
+ bindingNames.insert(INTERFACEKEY_A_INV_DRAW_WEAPON,"A_INV_DRAW_WEAPON");
+ bindingNames.insert(INTERFACEKEY_A_JUMP,"A_JUMP");
+ bindingNames.insert(INTERFACEKEY_A_HOLD,"A_HOLD");
+ bindingNames.insert(INTERFACEKEY_A_TALK, "A_TALK");
+ bindingNames.insert(INTERFACEKEY_A_INTERACT, "A_INTERACT");
+ bindingNames.insert(INTERFACEKEY_A_ACTION, "A_ACTION");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_CREATE, "A_ACTION_CREATE");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_BUTCHER, "A_ACTION_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_ABILITY, "A_ACTION_ABILITY");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_POWER, "A_ACTION_POWER");
+ bindingNames.insert(INTERFACEKEY_A_INV_LOOK, "A_INV_LOOK");
+ bindingNames.insert(INTERFACEKEY_A_INV_REMOVE, "A_INV_REMOVE");
+ bindingNames.insert(INTERFACEKEY_A_INV_WEAR, "A_INV_WEAR");
+ bindingNames.insert(INTERFACEKEY_A_INV_EATDRINK, "A_INV_EATDRINK");
+ bindingNames.insert(INTERFACEKEY_A_INV_PUTIN, "A_INV_PUTIN");
+ bindingNames.insert(INTERFACEKEY_A_INV_DROP, "A_INV_DROP");
+ bindingNames.insert(INTERFACEKEY_A_GROUND, "A_GROUND");
+ bindingNames.insert(INTERFACEKEY_A_THROW, "A_THROW");
+ bindingNames.insert(INTERFACEKEY_A_SHOOT, "A_SHOOT");
+ bindingNames.insert(INTERFACEKEY_A_ANNOUNCEMENTS, "A_ANNOUNCEMENTS");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT, "A_COMBAT");
+ bindingNames.insert(INTERFACEKEY_A_MOVEMENT, "A_MOVEMENT");
+ bindingNames.insert(INTERFACEKEY_A_MOVEMENT_SWIM, "A_MOVEMENT_SWIM");
+ bindingNames.insert(INTERFACEKEY_A_SNEAK, "A_SNEAK");
+ bindingNames.insert(INTERFACEKEY_A_SPEED_SNEAK, "A_SPEED_SNEAK");
+ bindingNames.insert(INTERFACEKEY_A_CENTER, "A_CENTER");
+ bindingNames.insert(INTERFACEKEY_A_COMPANIONS, "A_COMPANIONS");
+ bindingNames.insert(INTERFACEKEY_A_BUILDING, "A_BUILDING");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL, "A_TRAVEL");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_SLEEP, "A_TRAVEL_SLEEP");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_MAP, "A_TRAVEL_MAP");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_HIDE_INSTRUCTIONS, "A_TRAVEL_HIDE_INSTRUCTIONS");
+ bindingNames.insert(INTERFACEKEY_A_DATE, "A_DATE");
+ bindingNames.insert(INTERFACEKEY_A_WEATHER, "A_WEATHER");
+ bindingNames.insert(INTERFACEKEY_A_TEMPERATURE, "A_TEMPERATURE");
+ bindingNames.insert(INTERFACEKEY_A_STANCE, "A_STANCE");
+ bindingNames.insert(INTERFACEKEY_OPTION1, "OPTION1");
+ bindingNames.insert(INTERFACEKEY_OPTION2, "OPTION2");
+ bindingNames.insert(INTERFACEKEY_OPTION3, "OPTION3");
+ bindingNames.insert(INTERFACEKEY_OPTION4, "OPTION4");
+ bindingNames.insert(INTERFACEKEY_OPTION5, "OPTION5");
+ bindingNames.insert(INTERFACEKEY_OPTION6, "OPTION6");
+ bindingNames.insert(INTERFACEKEY_OPTION7, "OPTION7");
+ bindingNames.insert(INTERFACEKEY_OPTION8, "OPTION8");
+ bindingNames.insert(INTERFACEKEY_OPTION9, "OPTION9");
+ bindingNames.insert(INTERFACEKEY_OPTION10, "OPTION10");
+ bindingNames.insert(INTERFACEKEY_OPTION11, "OPTION11");
+ bindingNames.insert(INTERFACEKEY_OPTION12, "OPTION12");
+ bindingNames.insert(INTERFACEKEY_OPTION13, "OPTION13");
+ bindingNames.insert(INTERFACEKEY_OPTION14, "OPTION14");
+ bindingNames.insert(INTERFACEKEY_OPTION15, "OPTION15");
+ bindingNames.insert(INTERFACEKEY_OPTION16, "OPTION16");
+ bindingNames.insert(INTERFACEKEY_OPTION17, "OPTION17");
+ bindingNames.insert(INTERFACEKEY_OPTION18, "OPTION18");
+ bindingNames.insert(INTERFACEKEY_OPTION19, "OPTION19");
+ bindingNames.insert(INTERFACEKEY_OPTION20, "OPTION20");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION1, "SEC_OPTION1");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION2, "SEC_OPTION2");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION3, "SEC_OPTION3");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION4, "SEC_OPTION4");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION5, "SEC_OPTION5");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION6, "SEC_OPTION6");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION7, "SEC_OPTION7");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION8, "SEC_OPTION8");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION9, "SEC_OPTION9");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION10, "SEC_OPTION10");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION11, "SEC_OPTION11");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION12, "SEC_OPTION12");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION13, "SEC_OPTION13");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION14, "SEC_OPTION14");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION15, "SEC_OPTION15");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION16, "SEC_OPTION16");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION17, "SEC_OPTION17");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION18, "SEC_OPTION18");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION19, "SEC_OPTION19");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION20, "SEC_OPTION20");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MAKE_ASH, "HOTKEY_MAKE_ASH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MAKE_CHARCOAL, "HOTKEY_MAKE_CHARCOAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MELT_OBJECT, "HOTKEY_MELT_OBJECT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_GREEN, "HOTKEY_GLASS_GREEN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CLEAR, "HOTKEY_GLASS_CLEAR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CRYSTAL, "HOTKEY_GLASS_CRYSTAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_COLLECT_SAND, "HOTKEY_COLLECT_SAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_COLLECT_CLAY, "HOTKEY_COLLECT_CLAY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_ROUGH, "HOTKEY_GLASS_ROUGH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_ARMORSTAND, "HOTKEY_GLASS_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_BOX, "HOTKEY_GLASS_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CABINET, "HOTKEY_GLASS_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_COFFIN, "HOTKEY_GLASS_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLOODGATE, "HOTKEY_GLASS_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_HATCH_COVER, "HOTKEY_GLASS_HATCH_COVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_GRATE, "HOTKEY_GLASS_GRATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_GOBLET, "HOTKEY_GLASS_GOBLET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_TOY, "HOTKEY_GLASS_TOY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_INSTRUMENT, "HOTKEY_GLASS_INSTRUMENT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_DOOR, "HOTKEY_GLASS_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_STATUE, "HOTKEY_GLASS_STATUE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_TABLE, "HOTKEY_GLASS_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CAGE, "HOTKEY_GLASS_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CHAIR, "HOTKEY_GLASS_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_BLOCKS, "HOTKEY_GLASS_BLOCKS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLASK, "HOTKEY_GLASS_FLASK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_WEAPONRACK, "HOTKEY_GLASS_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_WINDOW, "HOTKEY_GLASS_WINDOW");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ASHERY_LYE, "HOTKEY_ASHERY_LYE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH, "HOTKEY_ASHERY_POTASH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH_DIRECT, "HOTKEY_ASHERY_POTASH_DIRECT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BARREL, "HOTKEY_CARPENTER_BARREL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BLOCKS, "HOTKEY_CARPENTER_BLOCKS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BUCKET, "HOTKEY_CARPENTER_BUCKET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TRAP_ANIMAL, "HOTKEY_CARPENTER_TRAP_ANIMAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CAGE, "HOTKEY_CARPENTER_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_ARMORSTAND, "HOTKEY_CARPENTER_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BED, "HOTKEY_CARPENTER_BED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CHAIR, "HOTKEY_CARPENTER_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_COFFIN, "HOTKEY_CARPENTER_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_DOOR, "HOTKEY_CARPENTER_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_FLOODGATE, "HOTKEY_CARPENTER_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_HATCH_COVER, "HOTKEY_CARPENTER_HATCH_COVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_GRATE, "HOTKEY_CARPENTER_GRATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CABINET, "HOTKEY_CARPENTER_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BIN, "HOTKEY_CARPENTER_BIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BOX, "HOTKEY_CARPENTER_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_WEAPONRACK, "HOTKEY_CARPENTER_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TABLE, "HOTKEY_CARPENTER_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SIEGE_BALLISTA, "HOTKEY_SIEGE_BALLISTA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SIEGE_CATAPULT, "HOTKEY_SIEGE_CATAPULT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BOX, "HOTKEY_LEATHER_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_FLASK, "HOTKEY_LEATHER_FLASK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_SHIRT, "HOTKEY_LEATHER_SHIRT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_CLOAK, "HOTKEY_LEATHER_CLOAK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BACKPACK, "HOTKEY_LEATHER_BACKPACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_QUIVER, "HOTKEY_LEATHER_QUIVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_IMAGE, "HOTKEY_LEATHER_IMAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_PLANT, "HOTKEY_CLOTHES_MAT_PLANT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_SILK, "HOTKEY_CLOTHES_MAT_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_YARN, "HOTKEY_CLOTHES_MAT_YARN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_SHIRT, "HOTKEY_CLOTHES_SHIRT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CLOAK, "HOTKEY_CLOTHES_CLOAK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_BOX, "HOTKEY_CLOTHES_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CHAIN, "HOTKEY_CLOTHES_CHAIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_IMAGE, "HOTKEY_CLOTHES_IMAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_STONE, "HOTKEY_CRAFTS_MAT_STONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_WOOD, "HOTKEY_CRAFTS_MAT_WOOD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_BONE, "HOTKEY_CRAFTS_DEC_BONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_SHELL, "HOTKEY_CRAFTS_DEC_SHELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_TOOTH, "HOTKEY_CRAFTS_DEC_TOOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_HORN, "HOTKEY_CRAFTS_DEC_HORN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_PEARL, "HOTKEY_CRAFTS_DEC_PEARL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOTEM, "HOTKEY_CRAFTS_TOTEM");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_CLOTH, "HOTKEY_CRAFTS_CLOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SILK, "HOTKEY_CRAFTS_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_YARN, "HOTKEY_CRAFTS_YARN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_WOOD, "HOTKEY_CRAFTS_SEL_WOOD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_BONE, "HOTKEY_CRAFTS_SEL_BONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_SHELL, "HOTKEY_CRAFTS_SEL_SHELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SHELL, "HOTKEY_CRAFTS_SHELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOOTH, "HOTKEY_CRAFTS_TOOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_HORN, "HOTKEY_CRAFTS_HORN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_PEARL, "HOTKEY_CRAFTS_PEARL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_BONE, "HOTKEY_CRAFTS_BONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_LEATHER, "HOTKEY_CRAFTS_LEATHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SLAB, "HOTKEY_CRAFTS_SLAB");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_CRAFTS, "HOTKEY_CRAFTS_MAT_CRAFTS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_GOBLET, "HOTKEY_CRAFTS_MAT_GOBLET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_INSTRUMENT, "HOTKEY_CRAFTS_MAT_INSTRUMENT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_TOY, "HOTKEY_CRAFTS_MAT_TOY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_WEAPON, "HOTKEY_SMITH_WEAPON");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_ARMOR, "HOTKEY_SMITH_ARMOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_FURNITURE, "HOTKEY_SMITH_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_SIEGE, "HOTKEY_SMITH_SIEGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_TRAP, "HOTKEY_SMITH_TRAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_OTHER, "HOTKEY_SMITH_OTHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_METAL, "HOTKEY_SMITH_METAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARMORSTAND, "HOTKEY_BUILDING_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BED, "HOTKEY_BUILDING_BED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRACTION_BENCH, "HOTKEY_BUILDING_TRACTION_BENCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SLAB, "HOTKEY_BUILDING_SLAB");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_NEST_BOX, "HOTKEY_BUILDING_NEST_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HIVE, "HOTKEY_BUILDING_HIVE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIR, "HOTKEY_BUILDING_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_COFFIN, "HOTKEY_BUILDING_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_DOOR, "HOTKEY_BUILDING_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FLOODGATE, "HOTKEY_BUILDING_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HATCH, "HOTKEY_BUILDING_HATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_WALL, "HOTKEY_BUILDING_GRATE_WALL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_FLOOR, "HOTKEY_BUILDING_GRATE_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_VERTICAL, "HOTKEY_BUILDING_BARS_VERTICAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_FLOOR, "HOTKEY_BUILDING_BARS_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CABINET, "HOTKEY_BUILDING_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BOX, "HOTKEY_BUILDING_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_KENNEL, "HOTKEY_BUILDING_KENNEL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FARMPLOT, "HOTKEY_BUILDING_FARMPLOT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WEAPONRACK, "HOTKEY_BUILDING_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_STATUE, "HOTKEY_BUILDING_STATUE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TABLE, "HOTKEY_BUILDING_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_DIRT, "HOTKEY_BUILDING_ROAD_DIRT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_PAVED, "HOTKEY_BUILDING_ROAD_PAVED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BRIDGE, "HOTKEY_BUILDING_BRIDGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WELL, "HOTKEY_BUILDING_WELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE, "HOTKEY_BUILDING_SIEGEENGINE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP, "HOTKEY_BUILDING_WORKSHOP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE, "HOTKEY_BUILDING_FURNACE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GLASS, "HOTKEY_BUILDING_WINDOW_GLASS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GEM, "HOTKEY_BUILDING_WINDOW_GEM");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SHOP, "HOTKEY_BUILDING_SHOP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ANIMALTRAP, "HOTKEY_BUILDING_ANIMALTRAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIN, "HOTKEY_BUILDING_CHAIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CAGE, "HOTKEY_BUILDING_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRADEDEPOT, "HOTKEY_BUILDING_TRADEDEPOT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP, "HOTKEY_BUILDING_TRAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE, "HOTKEY_BUILDING_MACHINE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SUPPORT, "HOTKEY_BUILDING_SUPPORT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARCHERYTARGET, "HOTKEY_BUILDING_ARCHERYTARGET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_SCREW_PUMP, "HOTKEY_BUILDING_MACHINE_SCREW_PUMP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WATER_WHEEL, "HOTKEY_BUILDING_MACHINE_WATER_WHEEL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WINDMILL, "HOTKEY_BUILDING_MACHINE_WINDMILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY, "HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL, "HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL, "HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_ROLLERS, "HOTKEY_BUILDING_MACHINE_ROLLERS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_BALLISTA, "HOTKEY_BUILDING_SIEGEENGINE_BALLISTA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_CATAPULT, "HOTKEY_BUILDING_SIEGEENGINE_CATAPULT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_STONE, "HOTKEY_BUILDING_TRAP_STONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_WEAPON, "HOTKEY_BUILDING_TRAP_WEAPON");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_LEVER, "HOTKEY_BUILDING_TRAP_LEVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_TRIGGER, "HOTKEY_BUILDING_TRAP_TRIGGER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_CAGE, "HOTKEY_BUILDING_TRAP_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_SPIKE, "HOTKEY_BUILDING_TRAP_SPIKE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION, "HOTKEY_BUILDING_CONSTRUCTION");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION, "HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_WALL, "HOTKEY_BUILDING_CONSTRUCTION_WALL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FLOOR, "HOTKEY_BUILDING_CONSTRUCTION_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_RAMP, "HOTKEY_BUILDING_CONSTRUCTION_RAMP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP, "HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN, "HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN, "HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK, "HOTKEY_BUILDING_CONSTRUCTION_TRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP, "HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LEATHER, "HOTKEY_BUILDING_WORKSHOP_LEATHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_QUERN, "HOTKEY_BUILDING_WORKSHOP_QUERN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MILLSTONE, "HOTKEY_BUILDING_WORKSHOP_MILLSTONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LOOM, "HOTKEY_BUILDING_WORKSHOP_LOOM");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CLOTHES, "HOTKEY_BUILDING_WORKSHOP_CLOTHES");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BOWYER, "HOTKEY_BUILDING_WORKSHOP_BOWYER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CARPENTER, "HOTKEY_BUILDING_WORKSHOP_CARPENTER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_METALSMITH, "HOTKEY_BUILDING_WORKSHOP_METALSMITH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LAVAMILL, "HOTKEY_BUILDING_WORKSHOP_LAVAMILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_JEWELER, "HOTKEY_BUILDING_WORKSHOP_JEWELER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MASON, "HOTKEY_BUILDING_WORKSHOP_MASON");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BUTCHER, "HOTKEY_BUILDING_WORKSHOP_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_TANNER, "HOTKEY_BUILDING_WORKSHOP_TANNER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_DYER, "HOTKEY_BUILDING_WORKSHOP_DYER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN, "HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_SIEGE, "HOTKEY_BUILDING_WORKSHOP_SIEGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MECHANIC, "HOTKEY_BUILDING_WORKSHOP_MECHANIC");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_STILL, "HOTKEY_BUILDING_WORKSHOP_STILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FARMER, "HOTKEY_BUILDING_WORKSHOP_FARMER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_KITCHEN, "HOTKEY_BUILDING_WORKSHOP_KITCHEN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FISHERY, "HOTKEY_BUILDING_WORKSHOP_FISHERY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_ASHERY, "HOTKEY_BUILDING_WORKSHOP_ASHERY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_WOOD, "HOTKEY_BUILDING_FURNACE_WOOD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER, "HOTKEY_BUILDING_FURNACE_SMELTER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS, "HOTKEY_BUILDING_FURNACE_GLASS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN, "HOTKEY_BUILDING_FURNACE_KILN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER_LAVA, "HOTKEY_BUILDING_FURNACE_SMELTER_LAVA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS_LAVA, "HOTKEY_BUILDING_FURNACE_GLASS_LAVA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN_LAVA, "HOTKEY_BUILDING_FURNACE_KILN_LAVA");
+ bindingNames.insert(INTERFACEKEY_HIVE_INSTALL_COLONY, "HIVE_INSTALL_COLONY");
+ bindingNames.insert(INTERFACEKEY_HIVE_GATHER_PRODUCTS, "HIVE_GATHER_PRODUCTS");
+ bindingNames.insert(INTERFACEKEY_D_ONESTEP, "D_ONESTEP");
+ bindingNames.insert(INTERFACEKEY_D_PAUSE, "D_PAUSE");
+ bindingNames.insert(INTERFACEKEY_D_DEPOT, "D_DEPOT");
+ bindingNames.insert(INTERFACEKEY_D_HOT_KEYS, "D_HOT_KEYS");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY1, "D_HOTKEY1");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY2, "D_HOTKEY2");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY3, "D_HOTKEY3");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY4, "D_HOTKEY4");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY5, "D_HOTKEY5");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY6, "D_HOTKEY6");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY7, "D_HOTKEY7");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY8, "D_HOTKEY8");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY9, "D_HOTKEY9");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY10, "D_HOTKEY10");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY11, "D_HOTKEY11");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY12, "D_HOTKEY12");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY13, "D_HOTKEY13");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY14, "D_HOTKEY14");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY15, "D_HOTKEY15");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY16, "D_HOTKEY16");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY_CHANGE_NAME, "D_HOTKEY_CHANGE_NAME");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY_ZOOM, "D_HOTKEY_ZOOM");
+ bindingNames.insert(INTERFACEKEY_D_ANNOUNCE, "D_ANNOUNCE");
+ bindingNames.insert(INTERFACEKEY_D_REPORTS, "D_REPORTS");
+ bindingNames.insert(INTERFACEKEY_D_BUILDING, "D_BUILDING");
+ bindingNames.insert(INTERFACEKEY_D_CIVLIST, "D_CIVLIST");
+ bindingNames.insert(INTERFACEKEY_D_DESIGNATE, "D_DESIGNATE");
+ bindingNames.insert(INTERFACEKEY_D_ARTLIST, "D_ARTLIST");
+ bindingNames.insert(INTERFACEKEY_D_NOBLES, "D_NOBLES");
+ bindingNames.insert(INTERFACEKEY_D_ORDERS, "D_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY, "D_MILITARY");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SQUAD, "D_MILITARY_CREATE_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_DISBAND_SQUAD, "D_MILITARY_DISBAND_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SUB_SQUAD, "D_MILITARY_CREATE_SUB_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_CANCEL_ORDERS, "D_MILITARY_CANCEL_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_POSITIONS, "D_MILITARY_POSITIONS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS, "D_MILITARY_ALERTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_ADD, "D_MILITARY_ALERTS_ADD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_DELETE, "D_MILITARY_ALERTS_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET, "D_MILITARY_ALERTS_SET");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_NAME, "D_MILITARY_ALERTS_NAME");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET_RETAIN, "D_MILITARY_ALERTS_SET_RETAIN");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP, "D_MILITARY_EQUIP");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_CUSTOMIZE, "D_MILITARY_EQUIP_CUSTOMIZE");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_UNIFORM, "D_MILITARY_EQUIP_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_PRIORITY, "D_MILITARY_EQUIP_PRIORITY");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_UNIFORMS, "D_MILITARY_UNIFORMS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES, "D_MILITARY_SUPPLIES");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_DOWN, "D_MILITARY_SUPPLIES_WATER_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_UP, "D_MILITARY_SUPPLIES_WATER_UP");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_DOWN, "D_MILITARY_SUPPLIES_FOOD_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_UP, "D_MILITARY_SUPPLIES_FOOD_UP");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION, "D_MILITARY_AMMUNITION");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_ADD_ITEM, "D_MILITARY_AMMUNITION_ADD_ITEM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_REMOVE_ITEM, "D_MILITARY_AMMUNITION_REMOVE_ITEM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT, "D_MILITARY_AMMUNITION_LOWER_AMOUNT");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT, "D_MILITARY_AMMUNITION_RAISE_AMOUNT");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS, "D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS, "D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_MATERIAL, "D_MILITARY_AMMUNITION_MATERIAL");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_COMBAT, "D_MILITARY_AMMUNITION_COMBAT");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_TRAINING, "D_MILITARY_AMMUNITION_TRAINING");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_TRAINING, "D_MILITARY_TRAINING");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SCHEDULE, "D_MILITARY_SCHEDULE");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_UNIFORM, "D_MILITARY_ADD_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_DELETE_UNIFORM, "D_MILITARY_DELETE_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_NAME_UNIFORM, "D_MILITARY_NAME_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_NAME_SQUAD, "D_MILITARY_NAME_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_ARMOR, "D_MILITARY_ADD_ARMOR");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_PANTS, "D_MILITARY_ADD_PANTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_HELM, "D_MILITARY_ADD_HELM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_GLOVES, "D_MILITARY_ADD_GLOVES");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_BOOTS, "D_MILITARY_ADD_BOOTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_SHIELD, "D_MILITARY_ADD_SHIELD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_WEAPON, "D_MILITARY_ADD_WEAPON");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_MATERIAL, "D_MILITARY_ADD_MATERIAL");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_COLOR, "D_MILITARY_ADD_COLOR");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_REPLACE_CLOTHING, "D_MILITARY_REPLACE_CLOTHING");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EXACT_MATCH, "D_MILITARY_EXACT_MATCH");
+ bindingNames.insert(INTERFACEKEY_D_ROOMS, "D_ROOMS");
+ bindingNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_T, "BUILDINGLIST_ZOOM_T");
+ bindingNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_Q, "BUILDINGLIST_ZOOM_Q");
+ bindingNames.insert(INTERFACEKEY_RECENTER_ON_LEVER, "RECENTER_ON_LEVER");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS, "D_SQUADS");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_MOVE, "D_SQUADS_MOVE");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_KILL, "D_SQUADS_KILL");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_KILL_LIST, "D_SQUADS_KILL_LIST");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_KILL_RECT, "D_SQUADS_KILL_RECT");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_SCHEDULE, "D_SQUADS_SCHEDULE");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_CANCEL_ORDER, "D_SQUADS_CANCEL_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_ALERT, "D_SQUADS_ALERT");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_SELECT_INDIVIDUALS, "D_SQUADS_SELECT_INDIVIDUALS");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_CENTER, "D_SQUADS_CENTER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_SLEEP, "D_SQUAD_SCH_SLEEP");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_CIVILIAN_UNIFORM, "D_SQUAD_SCH_CIVILIAN_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_GIVE_ORDER, "D_SQUAD_SCH_GIVE_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_EDIT_ORDER, "D_SQUAD_SCH_EDIT_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_CANCEL_ORDER, "D_SQUAD_SCH_CANCEL_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_COPY_ORDERS, "D_SQUAD_SCH_COPY_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_PASTE_ORDERS, "D_SQUAD_SCH_PASTE_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_MS_NAME, "D_SQUAD_SCH_MS_NAME");
+ bindingNames.insert(INTERFACEKEY_D_STOCKPILES, "D_STOCKPILES");
+ bindingNames.insert(INTERFACEKEY_D_CIVZONE, "D_CIVZONE");
+ bindingNames.insert(INTERFACEKEY_D_VIEWUNIT, "D_VIEWUNIT");
+ bindingNames.insert(INTERFACEKEY_D_JOBLIST, "D_JOBLIST");
+ bindingNames.insert(INTERFACEKEY_D_UNITLIST, "D_UNITLIST");
+ bindingNames.insert(INTERFACEKEY_D_LOOK, "D_LOOK");
+ bindingNames.insert(INTERFACEKEY_D_HAULING, "D_HAULING");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_NEW_ROUTE, "D_HAULING_NEW_ROUTE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_NEW_STOP, "D_HAULING_NEW_STOP");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_REMOVE, "D_HAULING_REMOVE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_PROMOTE, "D_HAULING_PROMOTE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_VEHICLE, "D_HAULING_VEHICLE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_NICKNAME, "D_HAULING_NICKNAME");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_DEPART, "D_HAULING_STOP_NEW_DEPART");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_LINK, "D_HAULING_STOP_NEW_LINK");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_REMOVE, "D_HAULING_STOP_REMOVE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_SELECT_PILE, "D_HAULING_STOP_SL_SELECT_PILE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_TAKE_GIVE, "D_HAULING_STOP_SL_TAKE_GIVE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DIR, "D_HAULING_STOP_LC_DIR");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MODE, "D_HAULING_STOP_LC_MODE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_UP, "D_HAULING_STOP_LC_TIMER_UP");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_DOWN, "D_HAULING_STOP_LC_TIMER_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_UP, "D_HAULING_STOP_LC_FULLNESS_UP");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_DOWN, "D_HAULING_STOP_LC_FULLNESS_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MORE_LESS, "D_HAULING_STOP_LC_MORE_LESS");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DESIRED_TOTAL, "D_HAULING_STOP_LC_DESIRED_TOTAL");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_CHANGE, "D_HAULING_STOP_LC_CHANGE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_ADVANCED, "D_HAULING_STOP_LC_ADVANCED");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS, "D_BURROWS");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_ADD, "D_BURROWS_ADD");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_DELETE, "D_BURROWS_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_DEFINE, "D_BURROWS_DEFINE");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_ADD_UNIT, "D_BURROWS_ADD_UNIT");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_WORKSHOP_LIMIT, "D_BURROWS_WORKSHOP_LIMIT");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_CENTER, "D_BURROWS_CENTER");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_NAME, "D_BURROWS_NAME");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_CHANGE_SELECTION, "D_BURROWS_CHANGE_SELECTION");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_BRUSH, "D_BURROWS_BRUSH");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_REMOVE, "D_BURROWS_REMOVE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE, "D_NOTE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_PLACE, "D_NOTE_PLACE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_DELETE, "D_NOTE_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_NAME, "D_NOTE_NAME");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ENTER, "D_NOTE_ENTER");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ADOPT_SYMBOL, "D_NOTE_ADOPT_SYMBOL");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_CHANGE_SELECTION, "D_NOTE_CHANGE_SELECTION");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_POINTS, "D_NOTE_POINTS");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE, "D_NOTE_ROUTE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_ADD, "D_NOTE_ROUTE_ADD");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_EDIT, "D_NOTE_ROUTE_EDIT");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_DELETE, "D_NOTE_ROUTE_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_CENTER, "D_NOTE_ROUTE_CENTER");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_NAME, "D_NOTE_ROUTE_NAME");
+ bindingNames.insert(INTERFACEKEY_D_BUILDJOB, "D_BUILDJOB");
+ bindingNames.insert(INTERFACEKEY_D_STATUS, "D_STATUS");
+ bindingNames.insert(INTERFACEKEY_D_STATUS_OVERALL_HEALTH_RECENTER, "D_STATUS_OVERALL_HEALTH_RECENTER");
+ bindingNames.insert(INTERFACEKEY_D_BUILDITEM, "D_BUILDITEM");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_FORBID, "D_BITEM_FORBID");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_DUMP, "D_BITEM_DUMP");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_HIDE, "D_BITEM_HIDE");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_MELT, "D_BITEM_MELT");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_FORBID, "D_LOOK_FORBID");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_DUMP, "D_LOOK_DUMP");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_MELT, "D_LOOK_MELT");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_HIDE, "D_LOOK_HIDE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_FOLLOW, "D_LOOK_FOLLOW");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_CREATURE, "D_LOOK_ARENA_CREATURE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_ADV_MODE, "D_LOOK_ARENA_ADV_MODE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_WATER, "D_LOOK_ARENA_WATER");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_MAGMA, "D_LOOK_ARENA_MAGMA");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_DOWN, "ARENA_CREATURE_SIDE_DOWN");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_UP, "ARENA_CREATURE_SIDE_UP");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_NEW_ITEM, "ARENA_CREATURE_NEW_ITEM");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_BLANK_LIST, "ARENA_CREATURE_BLANK_LIST");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_REMOVE_ITEM, "ARENA_CREATURE_REMOVE_ITEM");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_UNDEAD, "ARENA_CREATURE_UNDEAD");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_STRING, "ARENA_CREATURE_STRING");
+ bindingNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_1, "ARENA_CONFLICT_STATE_1");
+ bindingNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_2, "ARENA_CONFLICT_STATE_2");
+ bindingNames.insert(INTERFACEKEY_ARENA_MORALE, "ARENA_MORALE");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER, "ARENA_WEATHER");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER_SNOW, "ARENA_WEATHER_SNOW");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER_MUD, "ARENA_WEATHER_MUD");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER_CLEAR_SPATTER, "ARENA_WEATHER_CLEAR_SPATTER");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_TREE, "D_LOOK_ARENA_TREE");
+ bindingNames.insert(INTERFACEKEY_ARENA_TREE_FILTER, "ARENA_TREE_FILTER");
+ bindingNames.insert(INTERFACEKEY_ARENA_TREE_AGE, "ARENA_TREE_AGE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_MOUNT, "D_LOOK_ARENA_MOUNT");
+ bindingNames.insert(INTERFACEKEY_A_ENTER_NAME, "A_ENTER_NAME");
+ bindingNames.insert(INTERFACEKEY_A_CUST_NAME, "A_CUST_NAME");
+ bindingNames.insert(INTERFACEKEY_A_RANDOM_NAME, "A_RANDOM_NAME");
+ bindingNames.insert(INTERFACEKEY_A_CHANGE_GENDER, "A_CHANGE_GENDER");
+ bindingNames.insert(INTERFACEKEY_A_END_TRAVEL, "A_END_TRAVEL");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_CLOUDS, "A_TRAVEL_CLOUDS");
+ bindingNames.insert(INTERFACEKEY_A_LOG, "A_LOG");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_LOG, "A_TRAVEL_LOG");
+ bindingNames.insert(INTERFACEKEY_A_LOG_TASKS, "A_LOG_TASKS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_ENTITIES, "A_LOG_ENTITIES");
+ bindingNames.insert(INTERFACEKEY_A_LOG_SITES, "A_LOG_SITES");
+ bindingNames.insert(INTERFACEKEY_A_LOG_SUBREGIONS, "A_LOG_SUBREGIONS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_FEATURE_LAYERS, "A_LOG_FEATURE_LAYERS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_PEOPLE, "A_LOG_PEOPLE");
+ bindingNames.insert(INTERFACEKEY_A_LOG_AGREEMENTS, "A_LOG_AGREEMENTS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_EVENTS, "A_LOG_EVENTS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_BESTIARY, "A_LOG_BESTIARY");
+ bindingNames.insert(INTERFACEKEY_A_LOG_FILTER, "A_LOG_FILTER");
+ bindingNames.insert(INTERFACEKEY_A_LOG_ZOOM_CURRENT_LOCATION, "A_LOG_ZOOM_CURRENT_LOCATION");
+ bindingNames.insert(INTERFACEKEY_A_LOG_ZOOM_SELECTED, "A_LOG_ZOOM_SELECTED");
+ bindingNames.insert(INTERFACEKEY_A_LOG_LINE, "A_LOG_LINE");
+ bindingNames.insert(INTERFACEKEY_A_LOG_MAP, "A_LOG_MAP");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTOFORBID, "ORDERS_AUTOFORBID");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_PROJECTILE, "ORDERS_FORBID_PROJECTILE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_CORPSE, "ORDERS_FORBID_YOUR_CORPSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_ITEMS, "ORDERS_FORBID_YOUR_ITEMS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_CORPSE, "ORDERS_FORBID_OTHER_CORPSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_ITEMS, "ORDERS_FORBID_OTHER_ITEMS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_GATHER, "ORDERS_REFUSE_GATHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE, "ORDERS_REFUSE_OUTSIDE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE_VERMIN, "ORDERS_REFUSE_OUTSIDE_VERMIN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_CORPSE, "ORDERS_REFUSE_DUMP_CORPSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKULL, "ORDERS_REFUSE_DUMP_SKULL");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKIN, "ORDERS_REFUSE_DUMP_SKIN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_BONE, "ORDERS_REFUSE_DUMP_BONE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SHELL, "ORDERS_REFUSE_DUMP_SHELL");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_OTHER, "ORDERS_REFUSE_DUMP_OTHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_STRAND_TISSUE, "ORDERS_REFUSE_DUMP_STRAND_TISSUE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_FURNITURE, "ORDERS_GATHER_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_ANIMALS, "ORDERS_GATHER_ANIMALS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_FOOD, "ORDERS_GATHER_FOOD");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_BODIES, "ORDERS_GATHER_BODIES");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE, "ORDERS_REFUSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_STONE, "ORDERS_GATHER_STONE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_WOOD, "ORDERS_GATHER_WOOD");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ALL_HARVEST, "ORDERS_ALL_HARVEST");
+ bindingNames.insert(INTERFACEKEY_ORDERS_SAMEPILE, "ORDERS_SAMEPILE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_MIXFOODS, "ORDERS_MIXFOODS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_EXCEPTIONS, "ORDERS_EXCEPTIONS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_LOOM, "ORDERS_LOOM");
+ bindingNames.insert(INTERFACEKEY_ORDERS_DYED_CLOTH, "ORDERS_DYED_CLOTH");
+ bindingNames.insert(INTERFACEKEY_ORDERS_WORKSHOP, "ORDERS_WORKSHOP");
+ bindingNames.insert(INTERFACEKEY_ORDERS_COLLECT_WEB, "ORDERS_COLLECT_WEB");
+ bindingNames.insert(INTERFACEKEY_ORDERS_SLAUGHTER, "ORDERS_SLAUGHTER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_BUTCHER, "ORDERS_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_TAN, "ORDERS_TAN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_FISHERY, "ORDERS_AUTO_FISHERY");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_KITCHEN, "ORDERS_AUTO_KITCHEN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_KILN, "ORDERS_AUTO_KILN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_SMELTER, "ORDERS_AUTO_SMELTER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_OTHER, "ORDERS_AUTO_OTHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ZONE, "ORDERS_ZONE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ZONE_DRINKING, "ORDERS_ZONE_DRINKING");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ZONE_FISHING, "ORDERS_ZONE_FISHING");
+ bindingNames.insert(INTERFACEKEY_DESTROYBUILDING, "DESTROYBUILDING");
+ bindingNames.insert(INTERFACEKEY_SUSPENDBUILDING, "SUSPENDBUILDING");
+ bindingNames.insert(INTERFACEKEY_MENU_CONFIRM, "MENU_CONFIRM");
+ bindingNames.insert(INTERFACEKEY_SAVE_BINDINGS, "SAVE_BINDINGS");
+ bindingNames.insert(INTERFACEKEY_LOAD_BINDINGS, "LOAD_BINDINGS");
+ bindingNames.insert(INTERFACEKEY_KEYBINDING_COMPLETE, "KEYBINDING_COMPLETE");
+ bindingNames.insert(INTERFACEKEY_ZOOM_IN, "ZOOM_IN");
+ bindingNames.insert(INTERFACEKEY_ZOOM_OUT, "ZOOM_OUT");
+ bindingNames.insert(INTERFACEKEY_ZOOM_TOGGLE, "ZOOM_TOGGLE");
+ bindingNames.insert(INTERFACEKEY_ZOOM_RESET, "ZOOM_RESET");
+ bindingNames.insert(INTERFACEKEY_MACRO_BREAK, "MACRO_BREAK");
+ bindingNames.insert(INTERFACEKEY_RECORD_MACRO, "RECORD_MACRO");
+ bindingNames.insert(INTERFACEKEY_PLAY_MACRO, "PLAY_MACRO");
+ bindingNames.insert(INTERFACEKEY_SAVE_MACRO, "SAVE_MACRO");
+ bindingNames.insert(INTERFACEKEY_LOAD_MACRO, "LOAD_MACRO");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ALCHEMIST_SOAP, "HOTKEY_ALCHEMIST_SOAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_STILL_BREW, "HOTKEY_STILL_BREW");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_STILL_EXTRACT, "HOTKEY_STILL_EXTRACT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_COLLECT_SILK, "HOTKEY_LOOM_COLLECT_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_CLOTH, "HOTKEY_LOOM_WEAVE_CLOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_SILK, "HOTKEY_LOOM_WEAVE_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_YARN, "HOTKEY_LOOM_WEAVE_YARN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_METAL, "HOTKEY_LOOM_WEAVE_METAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_2, "HOTKEY_KITCHEN_COOK_2");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_3, "HOTKEY_KITCHEN_COOK_3");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_4, "HOTKEY_KITCHEN_COOK_4");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_RENDER_FAT, "HOTKEY_KITCHEN_RENDER_FAT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS, "HOTKEY_FARMER_PROCESS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_VIAL, "HOTKEY_FARMER_PROCESS_VIAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BAG, "HOTKEY_FARMER_PROCESS_BAG");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BARREL, "HOTKEY_FARMER_PROCESS_BARREL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_CHEESE, "HOTKEY_FARMER_CHEESE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_MILK, "HOTKEY_FARMER_MILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_SHEAR_CREATURE, "HOTKEY_FARMER_SHEAR_CREATURE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_SPIN_THREAD, "HOTKEY_FARMER_SPIN_THREAD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MILL_MILL, "HOTKEY_MILL_MILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KENNEL_CATCH_VERMIN, "HOTKEY_KENNEL_CATCH_VERMIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KENNEL_TAME_VERMIN, "HOTKEY_KENNEL_TAME_VERMIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FISHERY_PROCESS, "HOTKEY_FISHERY_PROCESS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FISHERY_EXTRACT, "HOTKEY_FISHERY_EXTRACT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FISHERY_CATCH, "HOTKEY_FISHERY_CATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_BUTCHER, "HOTKEY_BUTCHER_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_EXTRACT, "HOTKEY_BUTCHER_EXTRACT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_CATCH, "HOTKEY_BUTCHER_CATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TANNER_TAN, "HOTKEY_TANNER_TAN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_DYER_THREAD, "HOTKEY_DYER_THREAD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_DYER_CLOTH, "HOTKEY_DYER_CLOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FURNITURE, "HOTKEY_JEWELER_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FINISHED, "HOTKEY_JEWELER_FINISHED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_AMMO, "HOTKEY_JEWELER_AMMO");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_CUT, "HOTKEY_JEWELER_CUT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_ENCRUST, "HOTKEY_JEWELER_ENCRUST");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_PARTS, "HOTKEY_MECHANIC_PARTS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_TRACTION_BENCH, "HOTKEY_MECHANIC_TRACTION_BENCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_ARMORSTAND, "HOTKEY_MASON_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_BLOCKS, "HOTKEY_MASON_BLOCKS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_CHAIR, "HOTKEY_MASON_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_COFFIN, "HOTKEY_MASON_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_DOOR, "HOTKEY_MASON_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_FLOODGATE, "HOTKEY_MASON_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_HATCH_COVER, "HOTKEY_MASON_HATCH_COVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_GRATE, "HOTKEY_MASON_GRATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_CABINET, "HOTKEY_MASON_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_BOX, "HOTKEY_MASON_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_STATUE, "HOTKEY_MASON_STATUE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_QUERN, "HOTKEY_MASON_QUERN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_MILLSTONE, "HOTKEY_MASON_MILLSTONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_TABLE, "HOTKEY_MASON_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_WEAPONRACK, "HOTKEY_MASON_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_SLAB, "HOTKEY_MASON_SLAB");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_BRIDGE, "HOTKEY_TRAP_BRIDGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_GEAR_ASSEMBLY, "HOTKEY_TRAP_GEAR_ASSEMBLY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_DOOR, "HOTKEY_TRAP_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_FLOODGATE, "HOTKEY_TRAP_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_SPIKE, "HOTKEY_TRAP_SPIKE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_HATCH, "HOTKEY_TRAP_HATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_WALL, "HOTKEY_TRAP_GRATE_WALL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_FLOOR, "HOTKEY_TRAP_GRATE_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_VERTICAL, "HOTKEY_TRAP_BARS_VERTICAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_FLOOR, "HOTKEY_TRAP_BARS_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_SUPPORT, "HOTKEY_TRAP_SUPPORT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_CHAIN, "HOTKEY_TRAP_CHAIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_CAGE, "HOTKEY_TRAP_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_PULL_LEVER, "HOTKEY_TRAP_PULL_LEVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_TRACK_STOP, "HOTKEY_TRAP_TRACK_STOP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ADD, "BUILDJOB_ADD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CANCEL, "BUILDJOB_CANCEL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_PROMOTE, "BUILDJOB_PROMOTE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_NOW, "BUILDJOB_NOW");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_REPEAT, "BUILDJOB_REPEAT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_SUSPEND, "BUILDJOB_SUSPEND");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_WORKSHOP_PROFILE, "BUILDJOB_WORKSHOP_PROFILE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_WELL_FREE, "BUILDJOB_WELL_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_WELL_SIZE, "BUILDJOB_WELL_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_FREE, "BUILDJOB_TARGET_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_SIZE, "BUILDJOB_TARGET_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_DOWN, "BUILDJOB_TARGET_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_UP, "BUILDJOB_TARGET_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_RIGHT, "BUILDJOB_TARGET_RIGHT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_LEFT, "BUILDJOB_TARGET_LEFT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STATUE_ASSIGN, "BUILDJOB_STATUE_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STATUE_FREE, "BUILDJOB_STATUE_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STATUE_SIZE, "BUILDJOB_STATUE_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_JUSTICE, "BUILDJOB_CAGE_JUSTICE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_FREE, "BUILDJOB_CAGE_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_SIZE, "BUILDJOB_CAGE_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN_OCC, "BUILDJOB_CAGE_ASSIGN_OCC");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_WATER, "BUILDJOB_CAGE_WATER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN, "BUILDJOB_CAGE_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN_OCC, "BUILDJOB_CHAIN_ASSIGN_OCC");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_JUSTICE, "BUILDJOB_CHAIN_JUSTICE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN, "BUILDJOB_CHAIN_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_FREE, "BUILDJOB_CHAIN_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_SIZE, "BUILDJOB_CHAIN_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_FIRING, "BUILDJOB_SIEGE_FIRING");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_ORIENT, "BUILDJOB_SIEGE_ORIENT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DOOR_INTERNAL, "BUILDJOB_DOOR_INTERNAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DOOR_LOCK, "BUILDJOB_DOOR_LOCK");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DOOR_AJAR, "BUILDJOB_DOOR_AJAR");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_ASSIGN, "BUILDJOB_COFFIN_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_FREE, "BUILDJOB_COFFIN_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_SIZE, "BUILDJOB_COFFIN_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_BURIAL, "BUILDJOB_COFFIN_BURIAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_CIV, "BUILDJOB_COFFIN_CIV");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_PET, "BUILDJOB_COFFIN_PET");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_ASSIGN, "BUILDJOB_CHAIR_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_FREE, "BUILDJOB_CHAIR_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_SIZE, "BUILDJOB_CHAIR_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_ASSIGN, "BUILDJOB_TABLE_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_HALL, "BUILDJOB_TABLE_HALL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_FREE, "BUILDJOB_TABLE_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_SIZE, "BUILDJOB_TABLE_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_ASSIGN, "BUILDJOB_BED_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_FREE, "BUILDJOB_BED_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_BARRACKS, "BUILDJOB_BED_BARRACKS");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_DORMITORY, "BUILDJOB_BED_DORMITORY");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_RENT, "BUILDJOB_BED_RENT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_SIZE, "BUILDJOB_BED_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_NAME, "BUILDJOB_BED_NAME");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_SLEEP, "BUILDJOB_BED_SLEEP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_TRAIN, "BUILDJOB_BED_TRAIN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_INDIV_EQ, "BUILDJOB_BED_INDIV_EQ");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_SQUAD_EQ, "BUILDJOB_BED_SQUAD_EQ");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_POSITION, "BUILDJOB_BED_POSITION");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BRING, "BUILDJOB_DEPOT_BRING");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_TRADE, "BUILDJOB_DEPOT_TRADE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_REQUEST_TRADER, "BUILDJOB_DEPOT_REQUEST_TRADER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BROKER_ONLY, "BUILDJOB_DEPOT_BROKER_ONLY");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_NONE, "BUILDJOB_ANIMALTRAP_BAIT_NONE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_MEAT, "BUILDJOB_ANIMALTRAP_BAIT_MEAT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_FISH, "BUILDJOB_ANIMALTRAP_BAIT_FISH");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_GEM, "BUILDJOB_ANIMALTRAP_BAIT_GEM");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_FALLOW, "BUILDJOB_FARM_FALLOW");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_FERTILIZE, "BUILDJOB_FARM_FERTILIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_SEASFERT, "BUILDJOB_FARM_SEASFERT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_SPRING, "BUILDJOB_FARM_SPRING");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_SUMMER, "BUILDJOB_FARM_SUMMER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_AUTUMN, "BUILDJOB_FARM_AUTUMN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_WINTER, "BUILDJOB_FARM_WINTER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_MASTER, "BUILDJOB_STOCKPILE_MASTER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_LINK_ANYWHERE, "BUILDJOB_STOCKPILE_LINK_ANYWHERE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_GIVE_TO, "BUILDJOB_STOCKPILE_GIVE_TO");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_WHEELBARROW, "BUILDJOB_STOCKPILE_WHEELBARROW");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_DELETE_CHILD, "BUILDJOB_STOCKPILE_DELETE_CHILD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_SETTINGS, "BUILDJOB_STOCKPILE_SETTINGS");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_UP, "BUILDJOB_STOCKPILE_BARREL_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_DOWN, "BUILDJOB_STOCKPILE_BARREL_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_ZERO, "BUILDJOB_STOCKPILE_BARREL_ZERO");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_MAX, "BUILDJOB_STOCKPILE_BARREL_MAX");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_UP, "BUILDJOB_STOCKPILE_BIN_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_DOWN, "BUILDJOB_STOCKPILE_BIN_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_ZERO, "BUILDJOB_STOCKPILE_BIN_ZERO");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_MAX, "BUILDJOB_STOCKPILE_BIN_MAX");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BONE, "BUILDJOB_RACK_MAT_BONE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BRONZE, "BUILDJOB_RACK_MAT_BRONZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_COPPER, "BUILDJOB_RACK_MAT_COPPER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_IRON, "BUILDJOB_RACK_MAT_IRON");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_STEEL, "BUILDJOB_RACK_MAT_STEEL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_WOOD, "BUILDJOB_RACK_MAT_WOOD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_METAL, "BUILDJOB_RACK_MAT_METAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BONE, "BUILDJOB_STAND_MAT_BONE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_LEATHER, "BUILDJOB_STAND_MAT_LEATHER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_COPPER, "BUILDJOB_STAND_MAT_COPPER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BRONZE, "BUILDJOB_STAND_MAT_BRONZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_STEEL, "BUILDJOB_STAND_MAT_STEEL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_IRON, "BUILDJOB_STAND_MAT_IRON");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_WOOD, "BUILDJOB_STAND_MAT_WOOD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_METAL, "BUILDJOB_STAND_MAT_METAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ASSIGN, "BUILDJOB_RACKSTAND_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_FREE, "BUILDJOB_RACKSTAND_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_SIZE, "BUILDJOB_RACKSTAND_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ITEM, "BUILDJOB_RACKSTAND_ITEM");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_MAT, "BUILDJOB_RACKSTAND_MAT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS1, "BUILDJOB_RACKSTAND_DEFAULTS1");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL1, "BUILDJOB_RACKSTAND_KILL1");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS2, "BUILDJOB_RACKSTAND_DEFAULTS2");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL2, "BUILDJOB_RACKSTAND_KILL2");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_ENABLE, "STOCKPILE_SETTINGS_ENABLE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_DISABLE, "STOCKPILE_SETTINGS_DISABLE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_ALL, "STOCKPILE_SETTINGS_PERMIT_ALL");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_ALL, "STOCKPILE_SETTINGS_FORBID_ALL");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_SUB, "STOCKPILE_SETTINGS_PERMIT_SUB");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_SUB, "STOCKPILE_SETTINGS_FORBID_SUB");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC1, "STOCKPILE_SETTINGS_SPECIFIC1");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC2, "STOCKPILE_SETTINGS_SPECIFIC2");
+ bindingNames.insert(INTERFACEKEY_MOVIE_RECORD, "MOVIE_RECORD");
+ bindingNames.insert(INTERFACEKEY_MOVIE_PLAY, "MOVIE_PLAY");
+ bindingNames.insert(INTERFACEKEY_MOVIE_SAVE, "MOVIE_SAVE");
+ bindingNames.insert(INTERFACEKEY_MOVIE_LOAD, "MOVIE_LOAD");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_VIEW, "ASSIGNTRADE_VIEW");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_STRING, "ASSIGNTRADE_STRING");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_EXCLUDE_PROHIBITED, "ASSIGNTRADE_EXCLUDE_PROHIBITED");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_PENDING, "ASSIGNTRADE_PENDING");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_SORT, "ASSIGNTRADE_SORT");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_REPLACE, "NOBLELIST_REPLACE");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_SETTINGS, "NOBLELIST_SETTINGS");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_CAPITAL, "NOBLELIST_CAPITAL");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_VIEW_CANDIDATE, "NOBLELIST_VIEW_CANDIDATE");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_VIEW, "A_BARTER_VIEW");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_1, "A_BARTER_CURRENCY_1");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_2, "A_BARTER_CURRENCY_2");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_TRADE, "A_BARTER_TRADE");
+ bindingNames.insert(INTERFACEKEY_TRADE_VIEW, "TRADE_VIEW");
+ bindingNames.insert(INTERFACEKEY_TRADE_TRADE, "TRADE_TRADE");
+ bindingNames.insert(INTERFACEKEY_TRADE_OFFER, "TRADE_OFFER");
+ bindingNames.insert(INTERFACEKEY_TRADE_SEIZE, "TRADE_SEIZE");
+ bindingNames.insert(INTERFACEKEY_STORES_VIEW, "STORES_VIEW");
+ bindingNames.insert(INTERFACEKEY_STORES_ZOOM, "STORES_ZOOM");
+ bindingNames.insert(INTERFACEKEY_STORES_FORBID, "STORES_FORBID");
+ bindingNames.insert(INTERFACEKEY_STORES_MELT, "STORES_MELT");
+ bindingNames.insert(INTERFACEKEY_STORES_DUMP, "STORES_DUMP");
+ bindingNames.insert(INTERFACEKEY_STORES_HIDE, "STORES_HIDE");
+ bindingNames.insert(INTERFACEKEY_MILITARY_ACTIVATE, "MILITARY_ACTIVATE");
+ bindingNames.insert(INTERFACEKEY_MILITARY_VIEW, "MILITARY_VIEW");
+ bindingNames.insert(INTERFACEKEY_MILITARY_WEAPON, "MILITARY_WEAPON");
+ bindingNames.insert(INTERFACEKEY_MILITARY_ZOOM, "MILITARY_ZOOM");
+ bindingNames.insert(INTERFACEKEY_ANNOUNCE_ZOOM, "ANNOUNCE_ZOOM");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_REMOVE_CRE, "UNITJOB_REMOVE_CRE");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_ZOOM_CRE, "UNITJOB_ZOOM_CRE");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_ZOOM_BUILD, "UNITJOB_ZOOM_BUILD");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_VIEW, "UNITJOB_VIEW");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_MANAGER, "UNITJOB_MANAGER");
+ bindingNames.insert(INTERFACEKEY_MANAGER_NEW_ORDER, "MANAGER_NEW_ORDER");
+ bindingNames.insert(INTERFACEKEY_MANAGER_REMOVE, "MANAGER_REMOVE");
+ bindingNames.insert(INTERFACEKEY_MANAGER_PROMOTE, "MANAGER_PROMOTE");
+ bindingNames.insert(INTERFACEKEY_MANAGER_MAX, "MANAGER_MAX");
+ bindingNames.insert(INTERFACEKEY_MANAGER_WAGES, "MANAGER_WAGES");
+ bindingNames.insert(INTERFACEKEY_PET_BUTCHER, "PET_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_PET_GELD, "PET_GELD");
+ bindingNames.insert(INTERFACEKEY_ANIMAL_SELECT_TRAINER, "ANIMAL_SELECT_TRAINER");
+ bindingNames.insert(INTERFACEKEY_ANIMAL_WAR_TRAINING, "ANIMAL_WAR_TRAINING");
+ bindingNames.insert(INTERFACEKEY_ANIMAL_HUNTING_TRAINING, "ANIMAL_HUNTING_TRAINING");
+ bindingNames.insert(INTERFACEKEY_KITCHEN_COOK, "KITCHEN_COOK");
+ bindingNames.insert(INTERFACEKEY_KITCHEN_BREW, "KITCHEN_BREW");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_NEW, "SETUPGAME_NEW");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_VIEW, "SETUPGAME_VIEW");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_CUSTOMIZE_UNIT, "SETUPGAME_CUSTOMIZE_UNIT");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE, "SETUPGAME_SAVE_PROFILE");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_ABORT, "SETUPGAME_SAVE_PROFILE_ABORT");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_GO, "SETUPGAME_SAVE_PROFILE_GO");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_VIEW_PROFILE_PROBLEMS, "SETUPGAME_VIEW_PROFILE_PROBLEMS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_REMOVE, "CIVZONE_REMOVE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_REMOVE_ZONE, "CIVZONE_REMOVE_ZONE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_SHAPE, "CIVZONE_SHAPE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_NEXT, "CIVZONE_NEXT");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_POND_OPTIONS, "CIVZONE_POND_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL_OPTIONS, "CIVZONE_HOSPITAL_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS, "CIVZONE_GATHER_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_TREES, "CIVZONE_GATHER_OPTIONS_PICK_TREES");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_SHRUBS, "CIVZONE_GATHER_OPTIONS_PICK_SHRUBS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_GATHER_FALLEN, "CIVZONE_GATHER_OPTIONS_GATHER_FALLEN");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_WATER_SOURCE, "CIVZONE_WATER_SOURCE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_FISH, "CIVZONE_FISH");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER, "CIVZONE_GATHER");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_DUMP, "CIVZONE_DUMP");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_POND, "CIVZONE_POND");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL, "CIVZONE_HOSPITAL");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_SAND_COLLECT, "CIVZONE_SAND_COLLECT");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_CLAY_COLLECT, "CIVZONE_CLAY_COLLECT");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_ACTIVE, "CIVZONE_ACTIVE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_MEETING, "CIVZONE_MEETING");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_ANIMAL_TRAINING, "CIVZONE_ANIMAL_TRAINING");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_POND_WATER, "CIVZONE_POND_WATER");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_PEN, "CIVZONE_PEN");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_PEN_OPTIONS, "CIVZONE_PEN_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_ANIMAL, "STOCKPILE_ANIMAL");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_FOOD, "STOCKPILE_FOOD");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_WEAPON, "STOCKPILE_WEAPON");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_ARMOR, "STOCKPILE_ARMOR");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM, "STOCKPILE_CUSTOM");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM_SETTINGS, "STOCKPILE_CUSTOM_SETTINGS");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_FURNITURE, "STOCKPILE_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_GRAVEYARD, "STOCKPILE_GRAVEYARD");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_REFUSE, "STOCKPILE_REFUSE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_WOOD, "STOCKPILE_WOOD");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_STONE, "STOCKPILE_STONE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_GEM, "STOCKPILE_GEM");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_BARBLOCK, "STOCKPILE_BARBLOCK");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_CLOTH, "STOCKPILE_CLOTH");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_LEATHER, "STOCKPILE_LEATHER");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_AMMO, "STOCKPILE_AMMO");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_COINS, "STOCKPILE_COINS");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_FINISHED, "STOCKPILE_FINISHED");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_NONE, "STOCKPILE_NONE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_BITEM, "DESIGNATE_BITEM");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_CLAIM, "DESIGNATE_CLAIM");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_UNCLAIM, "DESIGNATE_UNCLAIM");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_MELT, "DESIGNATE_MELT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_NO_MELT, "DESIGNATE_NO_MELT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_DUMP, "DESIGNATE_DUMP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_NO_DUMP, "DESIGNATE_NO_DUMP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_HIDE, "DESIGNATE_HIDE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_NO_HIDE, "DESIGNATE_NO_HIDE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC, "DESIGNATE_TRAFFIC");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_HIGH, "DESIGNATE_TRAFFIC_HIGH");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_NORMAL, "DESIGNATE_TRAFFIC_NORMAL");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_LOW, "DESIGNATE_TRAFFIC_LOW");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_RESTRICTED, "DESIGNATE_TRAFFIC_RESTRICTED");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT, "DESIGNATE_TRAFFIC_INCREASE_WEIGHT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT, "DESIGNATE_TRAFFIC_DECREASE_WEIGHT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE, "DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE, "DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_DIG, "DESIGNATE_DIG");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_DIG_REMOVE_STAIRS_RAMPS, "DESIGNATE_DIG_REMOVE_STAIRS_RAMPS");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UP, "DESIGNATE_STAIR_UP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STAIR_DOWN, "DESIGNATE_STAIR_DOWN");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UPDOWN, "DESIGNATE_STAIR_UPDOWN");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_RAMP, "DESIGNATE_RAMP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_CHANNEL, "DESIGNATE_CHANNEL");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_CHOP, "DESIGNATE_CHOP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_PLANTS, "DESIGNATE_PLANTS");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_SMOOTH, "DESIGNATE_SMOOTH");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_ENGRAVE, "DESIGNATE_ENGRAVE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_FORTIFY, "DESIGNATE_FORTIFY");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRACK, "DESIGNATE_TRACK");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_ENGRAVING, "DESIGNATE_TOGGLE_ENGRAVING");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STANDARD_MARKER, "DESIGNATE_STANDARD_MARKER");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_MINE_MODE, "DESIGNATE_MINE_MODE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_MARKER, "DESIGNATE_TOGGLE_MARKER");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_UNDO, "DESIGNATE_UNDO");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_REMOVE_CONSTRUCTION, "DESIGNATE_REMOVE_CONSTRUCTION");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_Y_UP, "BUILDING_DIM_Y_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_Y_DOWN, "BUILDING_DIM_Y_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_X_UP, "BUILDING_DIM_X_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_X_DOWN, "BUILDING_DIM_X_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_UP, "BUILDING_ORIENT_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_LEFT, "BUILDING_ORIENT_LEFT");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_RIGHT, "BUILDING_ORIENT_RIGHT");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_DOWN, "BUILDING_ORIENT_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_NONE, "BUILDING_ORIENT_NONE");
+ bindingNames.insert(INTERFACEKEY_BUILDING_VIEW_ITEM, "BUILDING_VIEW_ITEM");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ADVANCE_STAGE, "BUILDING_ADVANCE_STAGE");
+ bindingNames.insert(INTERFACEKEY_BUILDING_EXPAND_CONTRACT, "BUILDING_EXPAND_CONTRACT");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_WATER, "BUILDING_TRIGGER_ENABLE_WATER");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_UP, "BUILDING_TRIGGER_MIN_WATER_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_DOWN, "BUILDING_TRIGGER_MIN_WATER_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_UP, "BUILDING_TRIGGER_MAX_WATER_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_DOWN, "BUILDING_TRIGGER_MAX_WATER_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_MAGMA, "BUILDING_TRIGGER_ENABLE_MAGMA");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_UP, "BUILDING_TRIGGER_MIN_MAGMA_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_DOWN, "BUILDING_TRIGGER_MIN_MAGMA_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_UP, "BUILDING_TRIGGER_MAX_MAGMA_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_DOWN, "BUILDING_TRIGGER_MAX_MAGMA_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_TRACK_CART, "BUILDING_TRIGGER_ENABLE_TRACK_CART");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_DOWN, "BUILDING_TRIGGER_MIN_TRACK_CART_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_UP, "BUILDING_TRIGGER_MIN_TRACK_CART_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_DOWN, "BUILDING_TRIGGER_MAX_TRACK_CART_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_UP, "BUILDING_TRIGGER_MAX_TRACK_CART_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_UP, "BUILDING_ROLLERS_SPEED_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_DOWN, "BUILDING_ROLLERS_SPEED_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_UP, "BUILDING_TRACK_STOP_FRICTION_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_DOWN, "BUILDING_TRACK_STOP_FRICTION_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_DUMP, "BUILDING_TRACK_STOP_DUMP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_CREATURE, "BUILDING_TRIGGER_ENABLE_CREATURE");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_LOCALS, "BUILDING_TRIGGER_ENABLE_LOCALS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_RESETS, "BUILDING_TRIGGER_RESETS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP, "BUILDING_TRIGGER_MIN_SIZE_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN, "BUILDING_TRIGGER_MIN_SIZE_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP, "BUILDING_TRIGGER_MAX_SIZE_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN, "BUILDING_TRIGGER_MAX_SIZE_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP_PLUS, "BUILDING_TRIGGER_MIN_SIZE_UP_PLUS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS, "BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP_PLUS, "BUILDING_TRIGGER_MAX_SIZE_UP_PLUS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS, "BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN, "UNITVIEW_GEN");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_INV, "UNITVIEW_INV");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF, "UNITVIEW_PRF");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_WND, "UNITVIEW_WND");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_FOLLOW, "UNITVIEW_FOLLOW");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_NEXT, "UNITVIEW_NEXT");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_SLAUGHTER, "UNITVIEW_SLAUGHTER");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GELD, "UNITVIEW_GELD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN_COMBAT, "UNITVIEW_GEN_COMBAT");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN_LABOR, "UNITVIEW_GEN_LABOR");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN_MISC, "UNITVIEW_GEN_MISC");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_PROF, "UNITVIEW_PRF_PROF");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_PET, "UNITVIEW_PRF_PET");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_VIEW, "UNITVIEW_PRF_VIEW");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_NEW_SQUAD, "UNITVIEW_PRF_NEW_SQUAD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_REMOVE_FROM_SQUAD, "UNITVIEW_PRF_REMOVE_FROM_SQUAD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_CURRENT_SQUAD, "UNITVIEW_PRF_NAME_CURRENT_SQUAD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_SELECTED_SQUAD, "UNITVIEW_PRF_NAME_SELECTED_SQUAD");
+
+ bindingNames.insert(INTERFACEKEY_STRING_A000, "STRING_A000");
+ bindingNames.insert(INTERFACEKEY_STRING_A001, "STRING_A001");
+ bindingNames.insert(INTERFACEKEY_STRING_A002, "STRING_A002");
+ bindingNames.insert(INTERFACEKEY_STRING_A003, "STRING_A003");
+ bindingNames.insert(INTERFACEKEY_STRING_A004, "STRING_A004");
+ bindingNames.insert(INTERFACEKEY_STRING_A005, "STRING_A005");
+ bindingNames.insert(INTERFACEKEY_STRING_A006, "STRING_A006");
+ bindingNames.insert(INTERFACEKEY_STRING_A007, "STRING_A007");
+ bindingNames.insert(INTERFACEKEY_STRING_A008, "STRING_A008");
+ bindingNames.insert(INTERFACEKEY_STRING_A009, "STRING_A009");
+ bindingNames.insert(INTERFACEKEY_STRING_A010, "STRING_A010");
+ bindingNames.insert(INTERFACEKEY_STRING_A011, "STRING_A011");
+ bindingNames.insert(INTERFACEKEY_STRING_A012, "STRING_A012");
+ bindingNames.insert(INTERFACEKEY_STRING_A013, "STRING_A013");
+ bindingNames.insert(INTERFACEKEY_STRING_A014, "STRING_A014");
+ bindingNames.insert(INTERFACEKEY_STRING_A015, "STRING_A015");
+ bindingNames.insert(INTERFACEKEY_STRING_A016, "STRING_A016");
+ bindingNames.insert(INTERFACEKEY_STRING_A017, "STRING_A017");
+ bindingNames.insert(INTERFACEKEY_STRING_A018, "STRING_A018");
+ bindingNames.insert(INTERFACEKEY_STRING_A019, "STRING_A019");
+ bindingNames.insert(INTERFACEKEY_STRING_A020, "STRING_A020");
+ bindingNames.insert(INTERFACEKEY_STRING_A021, "STRING_A021");
+ bindingNames.insert(INTERFACEKEY_STRING_A022, "STRING_A022");
+ bindingNames.insert(INTERFACEKEY_STRING_A023, "STRING_A023");
+ bindingNames.insert(INTERFACEKEY_STRING_A024, "STRING_A024");
+ bindingNames.insert(INTERFACEKEY_STRING_A025, "STRING_A025");
+ bindingNames.insert(INTERFACEKEY_STRING_A026, "STRING_A026");
+ bindingNames.insert(INTERFACEKEY_STRING_A027, "STRING_A027");
+ bindingNames.insert(INTERFACEKEY_STRING_A028, "STRING_A028");
+ bindingNames.insert(INTERFACEKEY_STRING_A029, "STRING_A029");
+ bindingNames.insert(INTERFACEKEY_STRING_A030, "STRING_A030");
+ bindingNames.insert(INTERFACEKEY_STRING_A031, "STRING_A031");
+ bindingNames.insert(INTERFACEKEY_STRING_A032, "STRING_A032");
+ bindingNames.insert(INTERFACEKEY_STRING_A033, "STRING_A033");
+ bindingNames.insert(INTERFACEKEY_STRING_A034, "STRING_A034");
+ bindingNames.insert(INTERFACEKEY_STRING_A035, "STRING_A035");
+ bindingNames.insert(INTERFACEKEY_STRING_A036, "STRING_A036");
+ bindingNames.insert(INTERFACEKEY_STRING_A037, "STRING_A037");
+ bindingNames.insert(INTERFACEKEY_STRING_A038, "STRING_A038");
+ bindingNames.insert(INTERFACEKEY_STRING_A039, "STRING_A039");
+ bindingNames.insert(INTERFACEKEY_STRING_A040, "STRING_A040");
+ bindingNames.insert(INTERFACEKEY_STRING_A041, "STRING_A041");
+ bindingNames.insert(INTERFACEKEY_STRING_A042, "STRING_A042");
+ bindingNames.insert(INTERFACEKEY_STRING_A043, "STRING_A043");
+ bindingNames.insert(INTERFACEKEY_STRING_A044, "STRING_A044");
+ bindingNames.insert(INTERFACEKEY_STRING_A045, "STRING_A045");
+ bindingNames.insert(INTERFACEKEY_STRING_A046, "STRING_A046");
+ bindingNames.insert(INTERFACEKEY_STRING_A047, "STRING_A047");
+ bindingNames.insert(INTERFACEKEY_STRING_A048, "STRING_A048");
+ bindingNames.insert(INTERFACEKEY_STRING_A049, "STRING_A049");
+ bindingNames.insert(INTERFACEKEY_STRING_A050, "STRING_A050");
+ bindingNames.insert(INTERFACEKEY_STRING_A051, "STRING_A051");
+ bindingNames.insert(INTERFACEKEY_STRING_A052, "STRING_A052");
+ bindingNames.insert(INTERFACEKEY_STRING_A053, "STRING_A053");
+ bindingNames.insert(INTERFACEKEY_STRING_A054, "STRING_A054");
+ bindingNames.insert(INTERFACEKEY_STRING_A055, "STRING_A055");
+ bindingNames.insert(INTERFACEKEY_STRING_A056, "STRING_A056");
+ bindingNames.insert(INTERFACEKEY_STRING_A057, "STRING_A057");
+ bindingNames.insert(INTERFACEKEY_STRING_A058, "STRING_A058");
+ bindingNames.insert(INTERFACEKEY_STRING_A059, "STRING_A059");
+ bindingNames.insert(INTERFACEKEY_STRING_A060, "STRING_A060");
+ bindingNames.insert(INTERFACEKEY_STRING_A061, "STRING_A061");
+ bindingNames.insert(INTERFACEKEY_STRING_A062, "STRING_A062");
+ bindingNames.insert(INTERFACEKEY_STRING_A063, "STRING_A063");
+ bindingNames.insert(INTERFACEKEY_STRING_A064, "STRING_A064");
+ bindingNames.insert(INTERFACEKEY_STRING_A065, "STRING_A065");
+ bindingNames.insert(INTERFACEKEY_STRING_A066, "STRING_A066");
+ bindingNames.insert(INTERFACEKEY_STRING_A067, "STRING_A067");
+ bindingNames.insert(INTERFACEKEY_STRING_A068, "STRING_A068");
+ bindingNames.insert(INTERFACEKEY_STRING_A069, "STRING_A069");
+ bindingNames.insert(INTERFACEKEY_STRING_A070, "STRING_A070");
+ bindingNames.insert(INTERFACEKEY_STRING_A071, "STRING_A071");
+ bindingNames.insert(INTERFACEKEY_STRING_A072, "STRING_A072");
+ bindingNames.insert(INTERFACEKEY_STRING_A073, "STRING_A073");
+ bindingNames.insert(INTERFACEKEY_STRING_A074, "STRING_A074");
+ bindingNames.insert(INTERFACEKEY_STRING_A075, "STRING_A075");
+ bindingNames.insert(INTERFACEKEY_STRING_A076, "STRING_A076");
+ bindingNames.insert(INTERFACEKEY_STRING_A077, "STRING_A077");
+ bindingNames.insert(INTERFACEKEY_STRING_A078, "STRING_A078");
+ bindingNames.insert(INTERFACEKEY_STRING_A079, "STRING_A079");
+ bindingNames.insert(INTERFACEKEY_STRING_A080, "STRING_A080");
+ bindingNames.insert(INTERFACEKEY_STRING_A081, "STRING_A081");
+ bindingNames.insert(INTERFACEKEY_STRING_A082, "STRING_A082");
+ bindingNames.insert(INTERFACEKEY_STRING_A083, "STRING_A083");
+ bindingNames.insert(INTERFACEKEY_STRING_A084, "STRING_A084");
+ bindingNames.insert(INTERFACEKEY_STRING_A085, "STRING_A085");
+ bindingNames.insert(INTERFACEKEY_STRING_A086, "STRING_A086");
+ bindingNames.insert(INTERFACEKEY_STRING_A087, "STRING_A087");
+ bindingNames.insert(INTERFACEKEY_STRING_A088, "STRING_A088");
+ bindingNames.insert(INTERFACEKEY_STRING_A089, "STRING_A089");
+ bindingNames.insert(INTERFACEKEY_STRING_A090, "STRING_A090");
+ bindingNames.insert(INTERFACEKEY_STRING_A091, "STRING_A091");
+ bindingNames.insert(INTERFACEKEY_STRING_A092, "STRING_A092");
+ bindingNames.insert(INTERFACEKEY_STRING_A093, "STRING_A093");
+ bindingNames.insert(INTERFACEKEY_STRING_A094, "STRING_A094");
+ bindingNames.insert(INTERFACEKEY_STRING_A095, "STRING_A095");
+ bindingNames.insert(INTERFACEKEY_STRING_A096, "STRING_A096");
+ bindingNames.insert(INTERFACEKEY_STRING_A097, "STRING_A097");
+ bindingNames.insert(INTERFACEKEY_STRING_A098, "STRING_A098");
+ bindingNames.insert(INTERFACEKEY_STRING_A099, "STRING_A099");
+ bindingNames.insert(INTERFACEKEY_STRING_A100, "STRING_A100");
+ bindingNames.insert(INTERFACEKEY_STRING_A101, "STRING_A101");
+ bindingNames.insert(INTERFACEKEY_STRING_A102, "STRING_A102");
+ bindingNames.insert(INTERFACEKEY_STRING_A103, "STRING_A103");
+ bindingNames.insert(INTERFACEKEY_STRING_A104, "STRING_A104");
+ bindingNames.insert(INTERFACEKEY_STRING_A105, "STRING_A105");
+ bindingNames.insert(INTERFACEKEY_STRING_A106, "STRING_A106");
+ bindingNames.insert(INTERFACEKEY_STRING_A107, "STRING_A107");
+ bindingNames.insert(INTERFACEKEY_STRING_A108, "STRING_A108");
+ bindingNames.insert(INTERFACEKEY_STRING_A109, "STRING_A109");
+ bindingNames.insert(INTERFACEKEY_STRING_A110, "STRING_A110");
+ bindingNames.insert(INTERFACEKEY_STRING_A111, "STRING_A111");
+ bindingNames.insert(INTERFACEKEY_STRING_A112, "STRING_A112");
+ bindingNames.insert(INTERFACEKEY_STRING_A113, "STRING_A113");
+ bindingNames.insert(INTERFACEKEY_STRING_A114, "STRING_A114");
+ bindingNames.insert(INTERFACEKEY_STRING_A115, "STRING_A115");
+ bindingNames.insert(INTERFACEKEY_STRING_A116, "STRING_A116");
+ bindingNames.insert(INTERFACEKEY_STRING_A117, "STRING_A117");
+ bindingNames.insert(INTERFACEKEY_STRING_A118, "STRING_A118");
+ bindingNames.insert(INTERFACEKEY_STRING_A119, "STRING_A119");
+ bindingNames.insert(INTERFACEKEY_STRING_A120, "STRING_A120");
+ bindingNames.insert(INTERFACEKEY_STRING_A121, "STRING_A121");
+ bindingNames.insert(INTERFACEKEY_STRING_A122, "STRING_A122");
+ bindingNames.insert(INTERFACEKEY_STRING_A123, "STRING_A123");
+ bindingNames.insert(INTERFACEKEY_STRING_A124, "STRING_A124");
+ bindingNames.insert(INTERFACEKEY_STRING_A125, "STRING_A125");
+ bindingNames.insert(INTERFACEKEY_STRING_A126, "STRING_A126");
+ bindingNames.insert(INTERFACEKEY_STRING_A128, "STRING_A128");
+ bindingNames.insert(INTERFACEKEY_STRING_A129, "STRING_A129");
+ bindingNames.insert(INTERFACEKEY_STRING_A130, "STRING_A130");
+ bindingNames.insert(INTERFACEKEY_STRING_A131, "STRING_A131");
+ bindingNames.insert(INTERFACEKEY_STRING_A132, "STRING_A132");
+ bindingNames.insert(INTERFACEKEY_STRING_A133, "STRING_A133");
+ bindingNames.insert(INTERFACEKEY_STRING_A134, "STRING_A134");
+ bindingNames.insert(INTERFACEKEY_STRING_A135, "STRING_A135");
+ bindingNames.insert(INTERFACEKEY_STRING_A136, "STRING_A136");
+ bindingNames.insert(INTERFACEKEY_STRING_A137, "STRING_A137");
+ bindingNames.insert(INTERFACEKEY_STRING_A138, "STRING_A138");
+ bindingNames.insert(INTERFACEKEY_STRING_A139, "STRING_A139");
+ bindingNames.insert(INTERFACEKEY_STRING_A140, "STRING_A140");
+ bindingNames.insert(INTERFACEKEY_STRING_A141, "STRING_A141");
+ bindingNames.insert(INTERFACEKEY_STRING_A142, "STRING_A142");
+ bindingNames.insert(INTERFACEKEY_STRING_A143, "STRING_A143");
+ bindingNames.insert(INTERFACEKEY_STRING_A144, "STRING_A144");
+ bindingNames.insert(INTERFACEKEY_STRING_A145, "STRING_A145");
+ bindingNames.insert(INTERFACEKEY_STRING_A146, "STRING_A146");
+ bindingNames.insert(INTERFACEKEY_STRING_A147, "STRING_A147");
+ bindingNames.insert(INTERFACEKEY_STRING_A148, "STRING_A148");
+ bindingNames.insert(INTERFACEKEY_STRING_A149, "STRING_A149");
+ bindingNames.insert(INTERFACEKEY_STRING_A150, "STRING_A150");
+ bindingNames.insert(INTERFACEKEY_STRING_A151, "STRING_A151");
+ bindingNames.insert(INTERFACEKEY_STRING_A152, "STRING_A152");
+ bindingNames.insert(INTERFACEKEY_STRING_A153, "STRING_A153");
+ bindingNames.insert(INTERFACEKEY_STRING_A154, "STRING_A154");
+ bindingNames.insert(INTERFACEKEY_STRING_A155, "STRING_A155");
+ bindingNames.insert(INTERFACEKEY_STRING_A156, "STRING_A156");
+ bindingNames.insert(INTERFACEKEY_STRING_A157, "STRING_A157");
+ bindingNames.insert(INTERFACEKEY_STRING_A158, "STRING_A158");
+ bindingNames.insert(INTERFACEKEY_STRING_A159, "STRING_A159");
+ bindingNames.insert(INTERFACEKEY_STRING_A160, "STRING_A160");
+ bindingNames.insert(INTERFACEKEY_STRING_A161, "STRING_A161");
+ bindingNames.insert(INTERFACEKEY_STRING_A162, "STRING_A162");
+ bindingNames.insert(INTERFACEKEY_STRING_A163, "STRING_A163");
+ bindingNames.insert(INTERFACEKEY_STRING_A164, "STRING_A164");
+ bindingNames.insert(INTERFACEKEY_STRING_A165, "STRING_A165");
+ bindingNames.insert(INTERFACEKEY_STRING_A166, "STRING_A166");
+ bindingNames.insert(INTERFACEKEY_STRING_A167, "STRING_A167");
+ bindingNames.insert(INTERFACEKEY_STRING_A168, "STRING_A168");
+ bindingNames.insert(INTERFACEKEY_STRING_A169, "STRING_A169");
+ bindingNames.insert(INTERFACEKEY_STRING_A170, "STRING_A170");
+ bindingNames.insert(INTERFACEKEY_STRING_A171, "STRING_A171");
+ bindingNames.insert(INTERFACEKEY_STRING_A172, "STRING_A172");
+ bindingNames.insert(INTERFACEKEY_STRING_A173, "STRING_A173");
+ bindingNames.insert(INTERFACEKEY_STRING_A174, "STRING_A174");
+ bindingNames.insert(INTERFACEKEY_STRING_A175, "STRING_A175");
+ bindingNames.insert(INTERFACEKEY_STRING_A176, "STRING_A176");
+ bindingNames.insert(INTERFACEKEY_STRING_A177, "STRING_A177");
+ bindingNames.insert(INTERFACEKEY_STRING_A178, "STRING_A178");
+ bindingNames.insert(INTERFACEKEY_STRING_A179, "STRING_A179");
+ bindingNames.insert(INTERFACEKEY_STRING_A180, "STRING_A180");
+ bindingNames.insert(INTERFACEKEY_STRING_A181, "STRING_A181");
+ bindingNames.insert(INTERFACEKEY_STRING_A182, "STRING_A182");
+ bindingNames.insert(INTERFACEKEY_STRING_A183, "STRING_A183");
+ bindingNames.insert(INTERFACEKEY_STRING_A184, "STRING_A184");
+ bindingNames.insert(INTERFACEKEY_STRING_A185, "STRING_A185");
+ bindingNames.insert(INTERFACEKEY_STRING_A186, "STRING_A186");
+ bindingNames.insert(INTERFACEKEY_STRING_A187, "STRING_A187");
+ bindingNames.insert(INTERFACEKEY_STRING_A188, "STRING_A188");
+ bindingNames.insert(INTERFACEKEY_STRING_A189, "STRING_A189");
+ bindingNames.insert(INTERFACEKEY_STRING_A190, "STRING_A190");
+ bindingNames.insert(INTERFACEKEY_STRING_A191, "STRING_A191");
+ bindingNames.insert(INTERFACEKEY_STRING_A192, "STRING_A192");
+ bindingNames.insert(INTERFACEKEY_STRING_A193, "STRING_A193");
+ bindingNames.insert(INTERFACEKEY_STRING_A194, "STRING_A194");
+ bindingNames.insert(INTERFACEKEY_STRING_A195, "STRING_A195");
+ bindingNames.insert(INTERFACEKEY_STRING_A196, "STRING_A196");
+ bindingNames.insert(INTERFACEKEY_STRING_A197, "STRING_A197");
+ bindingNames.insert(INTERFACEKEY_STRING_A198, "STRING_A198");
+ bindingNames.insert(INTERFACEKEY_STRING_A199, "STRING_A199");
+ bindingNames.insert(INTERFACEKEY_STRING_A200, "STRING_A200");
+ bindingNames.insert(INTERFACEKEY_STRING_A201, "STRING_A201");
+ bindingNames.insert(INTERFACEKEY_STRING_A202, "STRING_A202");
+ bindingNames.insert(INTERFACEKEY_STRING_A203, "STRING_A203");
+ bindingNames.insert(INTERFACEKEY_STRING_A204, "STRING_A204");
+ bindingNames.insert(INTERFACEKEY_STRING_A205, "STRING_A205");
+ bindingNames.insert(INTERFACEKEY_STRING_A206, "STRING_A206");
+ bindingNames.insert(INTERFACEKEY_STRING_A207, "STRING_A207");
+ bindingNames.insert(INTERFACEKEY_STRING_A208, "STRING_A208");
+ bindingNames.insert(INTERFACEKEY_STRING_A209, "STRING_A209");
+ bindingNames.insert(INTERFACEKEY_STRING_A210, "STRING_A210");
+ bindingNames.insert(INTERFACEKEY_STRING_A211, "STRING_A211");
+ bindingNames.insert(INTERFACEKEY_STRING_A212, "STRING_A212");
+ bindingNames.insert(INTERFACEKEY_STRING_A213, "STRING_A213");
+ bindingNames.insert(INTERFACEKEY_STRING_A214, "STRING_A214");
+ bindingNames.insert(INTERFACEKEY_STRING_A215, "STRING_A215");
+ bindingNames.insert(INTERFACEKEY_STRING_A216, "STRING_A216");
+ bindingNames.insert(INTERFACEKEY_STRING_A217, "STRING_A217");
+ bindingNames.insert(INTERFACEKEY_STRING_A218, "STRING_A218");
+ bindingNames.insert(INTERFACEKEY_STRING_A219, "STRING_A219");
+ bindingNames.insert(INTERFACEKEY_STRING_A220, "STRING_A220");
+ bindingNames.insert(INTERFACEKEY_STRING_A221, "STRING_A221");
+ bindingNames.insert(INTERFACEKEY_STRING_A222, "STRING_A222");
+ bindingNames.insert(INTERFACEKEY_STRING_A223, "STRING_A223");
+ bindingNames.insert(INTERFACEKEY_STRING_A224, "STRING_A224");
+ bindingNames.insert(INTERFACEKEY_STRING_A225, "STRING_A225");
+ bindingNames.insert(INTERFACEKEY_STRING_A226, "STRING_A226");
+ bindingNames.insert(INTERFACEKEY_STRING_A227, "STRING_A227");
+ bindingNames.insert(INTERFACEKEY_STRING_A228, "STRING_A228");
+ bindingNames.insert(INTERFACEKEY_STRING_A229, "STRING_A229");
+ bindingNames.insert(INTERFACEKEY_STRING_A230, "STRING_A230");
+ bindingNames.insert(INTERFACEKEY_STRING_A231, "STRING_A231");
+ bindingNames.insert(INTERFACEKEY_STRING_A232, "STRING_A232");
+ bindingNames.insert(INTERFACEKEY_STRING_A233, "STRING_A233");
+ bindingNames.insert(INTERFACEKEY_STRING_A234, "STRING_A234");
+ bindingNames.insert(INTERFACEKEY_STRING_A235, "STRING_A235");
+ bindingNames.insert(INTERFACEKEY_STRING_A236, "STRING_A236");
+ bindingNames.insert(INTERFACEKEY_STRING_A237, "STRING_A237");
+ bindingNames.insert(INTERFACEKEY_STRING_A238, "STRING_A238");
+ bindingNames.insert(INTERFACEKEY_STRING_A239, "STRING_A239");
+ bindingNames.insert(INTERFACEKEY_STRING_A240, "STRING_A240");
+ bindingNames.insert(INTERFACEKEY_STRING_A241, "STRING_A241");
+ bindingNames.insert(INTERFACEKEY_STRING_A242, "STRING_A242");
+ bindingNames.insert(INTERFACEKEY_STRING_A243, "STRING_A243");
+ bindingNames.insert(INTERFACEKEY_STRING_A244, "STRING_A244");
+ bindingNames.insert(INTERFACEKEY_STRING_A245, "STRING_A245");
+ bindingNames.insert(INTERFACEKEY_STRING_A246, "STRING_A246");
+ bindingNames.insert(INTERFACEKEY_STRING_A247, "STRING_A247");
+ bindingNames.insert(INTERFACEKEY_STRING_A248, "STRING_A248");
+ bindingNames.insert(INTERFACEKEY_STRING_A249, "STRING_A249");
+ bindingNames.insert(INTERFACEKEY_STRING_A250, "STRING_A250");
+ bindingNames.insert(INTERFACEKEY_STRING_A251, "STRING_A251");
+ bindingNames.insert(INTERFACEKEY_STRING_A252, "STRING_A252");
+ bindingNames.insert(INTERFACEKEY_STRING_A253, "STRING_A253");
+ bindingNames.insert(INTERFACEKEY_STRING_A254, "STRING_A254");
+ bindingNames.insert(INTERFACEKEY_STRING_A255, "STRING_A255");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_A, "CUSTOM_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_B, "CUSTOM_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_C, "CUSTOM_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_D, "CUSTOM_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_E, "CUSTOM_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_F, "CUSTOM_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_G, "CUSTOM_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_H, "CUSTOM_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_I, "CUSTOM_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_J, "CUSTOM_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_K, "CUSTOM_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_L, "CUSTOM_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_M, "CUSTOM_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_N, "CUSTOM_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_O, "CUSTOM_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_P, "CUSTOM_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_Q, "CUSTOM_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_R, "CUSTOM_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_S, "CUSTOM_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_T, "CUSTOM_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_U, "CUSTOM_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_V, "CUSTOM_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_W, "CUSTOM_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_X, "CUSTOM_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_Y, "CUSTOM_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_Z, "CUSTOM_Z");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_A, "CUSTOM_SHIFT_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_B, "CUSTOM_SHIFT_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_C, "CUSTOM_SHIFT_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_D, "CUSTOM_SHIFT_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_E, "CUSTOM_SHIFT_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_F, "CUSTOM_SHIFT_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_G, "CUSTOM_SHIFT_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_H, "CUSTOM_SHIFT_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_I, "CUSTOM_SHIFT_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_J, "CUSTOM_SHIFT_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_K, "CUSTOM_SHIFT_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_L, "CUSTOM_SHIFT_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_M, "CUSTOM_SHIFT_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_N, "CUSTOM_SHIFT_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_O, "CUSTOM_SHIFT_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_P, "CUSTOM_SHIFT_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Q, "CUSTOM_SHIFT_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_R, "CUSTOM_SHIFT_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_S, "CUSTOM_SHIFT_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_T, "CUSTOM_SHIFT_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_U, "CUSTOM_SHIFT_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_V, "CUSTOM_SHIFT_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_W, "CUSTOM_SHIFT_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_X, "CUSTOM_SHIFT_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Y, "CUSTOM_SHIFT_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Z, "CUSTOM_SHIFT_Z");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_A, "CUSTOM_CTRL_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_B, "CUSTOM_CTRL_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_C, "CUSTOM_CTRL_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_D, "CUSTOM_CTRL_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_E, "CUSTOM_CTRL_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_F, "CUSTOM_CTRL_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_G, "CUSTOM_CTRL_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_H, "CUSTOM_CTRL_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_I, "CUSTOM_CTRL_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_J, "CUSTOM_CTRL_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_K, "CUSTOM_CTRL_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_L, "CUSTOM_CTRL_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_M, "CUSTOM_CTRL_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_N, "CUSTOM_CTRL_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_O, "CUSTOM_CTRL_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_P, "CUSTOM_CTRL_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_Q, "CUSTOM_CTRL_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_R, "CUSTOM_CTRL_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_S, "CUSTOM_CTRL_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_T, "CUSTOM_CTRL_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_U, "CUSTOM_CTRL_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_V, "CUSTOM_CTRL_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_W, "CUSTOM_CTRL_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_X, "CUSTOM_CTRL_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_Y, "CUSTOM_CTRL_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_Z, "CUSTOM_CTRL_Z");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_A, "CUSTOM_ALT_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_B, "CUSTOM_ALT_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_C, "CUSTOM_ALT_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_D, "CUSTOM_ALT_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_E, "CUSTOM_ALT_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_F, "CUSTOM_ALT_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_G, "CUSTOM_ALT_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_H, "CUSTOM_ALT_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_I, "CUSTOM_ALT_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_J, "CUSTOM_ALT_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_K, "CUSTOM_ALT_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_L, "CUSTOM_ALT_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_M, "CUSTOM_ALT_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_N, "CUSTOM_ALT_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_O, "CUSTOM_ALT_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_P, "CUSTOM_ALT_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_Q, "CUSTOM_ALT_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_R, "CUSTOM_ALT_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_S, "CUSTOM_ALT_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_T, "CUSTOM_ALT_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_U, "CUSTOM_ALT_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_V, "CUSTOM_ALT_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_W, "CUSTOM_ALT_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_X, "CUSTOM_ALT_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_Y, "CUSTOM_ALT_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_Z, "CUSTOM_ALT_Z");
+ bindingNames.insert(INTERFACEKEY_FPS_UP, "FPS_UP");
+ bindingNames.insert(INTERFACEKEY_FPS_DOWN, "FPS_DOWN");
+ bindingNames.insert(INTERFACEKEY_TOGGLE_TTF, "TOGGLE_TTF");
+ bindingNames.insert(INTERFACEKEY_PREFIX, "PREFIX");
+
+
+ displayNames.insert(INTERFACEKEY_NONE, "None");
+ displayNames.insert(INTERFACEKEY_SELECT, "Select");
+ displayNames.insert(INTERFACEKEY_SEC_SELECT, "Secondary Select");
+ displayNames.insert(INTERFACEKEY_DESELECT, "Deselect");
+ displayNames.insert(INTERFACEKEY_SELECT_ALL, "Select all");
+ displayNames.insert(INTERFACEKEY_DESELECT_ALL, "Deselect All");
+ displayNames.insert(INTERFACEKEY_LEAVESCREEN, "Leave screen");
+ displayNames.insert(INTERFACEKEY_LEAVESCREEN_ALL, "Leave all screens");
+ displayNames.insert(INTERFACEKEY_CLOSE_MEGA_ANNOUNCEMENT, "Close mega announcement");
+ displayNames.insert(INTERFACEKEY_TOGGLE_FULLSCREEN, "Toggle Fullscreen");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_ADD, "World Param: Add");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_COPY, "World Param: Copy");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DELETE, "World Param: Delete");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_TITLE, "World Param: Title");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_RANDOM, "World Param: Name, Random");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_ENTER, "World Param: Name, Enter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_RANDOM, "World Param: Seed, Random");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_ENTER, "World Param: Seed, Enter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_LOAD, "World Param: Load");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SAVE, "World Param: Save");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_UP, "World Param: Dim X, Up");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_DOWN, "World Param: Dim X, Down");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_UP, "World Param: Dim Y, Up");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_DOWN, "World Param: Dim Y, Down");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SET, "World Param: Enter Advanced Parameters");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_INCREASE, "World Param: Increase Parameter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DECREASE, "World Param: Decrease Parameter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_ENTER_VALUE, "World Param: Enter Value");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_NULLIFY, "World Param: Nullify Parameter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_PRESET, "World Param: Set Presets");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_CONTINUE, "World Param: Reject, Continue");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ABORT, "World Param: Reject, Abort");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_THIS, "World Param: Reject, Allow This");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_ALL, "World Param: Reject, Allow All");
+ displayNames.insert(INTERFACEKEY_WORLD_GEN_CONTINUE, "World Generation: Continue");
+ displayNames.insert(INTERFACEKEY_WORLD_GEN_USE, "World Generation: Use");
+ displayNames.insert(INTERFACEKEY_WORLD_GEN_ABORT, "World Generation: Abort");
+ displayNames.insert(INTERFACEKEY_SETUP_EMBARK, "Setup game: Embark");
+ displayNames.insert(INTERFACEKEY_SETUP_NAME_FORT, "Setup game: Name Fort");
+ displayNames.insert(INTERFACEKEY_SETUP_NAME_GROUP, "Setup game: Name Group");
+ displayNames.insert(INTERFACEKEY_SETUP_RECLAIM, "Setup game: Reclaim");
+ displayNames.insert(INTERFACEKEY_SETUP_FIND, "Setup game: Find");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES, "Setup game: Notes");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_TAKE_NOTES, "Setup game: Notes, New Note");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_DELETE_NOTE, "Setup game: Notes, Delete Note");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_CHANGE_SYMBOL_SELECTION, "Setup game: Notes, Change Symbol Selection");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_ADOPT_SYMBOL, "Setup game: Notes, Adopt Symbol");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_UP, "Setup game: Resize Local Y Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_DOWN, "Setup game: Resize Local Y Down");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_UP, "Setup game: Resize Local X Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_DOWN, "Setup game: Resize Local X Down");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MUP, "Setup game: Move Local Y Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MDOWN, "Setup game: Move Local Y Down");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MUP, "Setup game: Move Local X Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MDOWN, "Setup game: Move Local X Down");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_1, "Setup game: View Biome 1");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_2, "Setup game: View Biome 2");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_3, "Setup game: View Biome 3");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_4, "Setup game: View Biome 4");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_5, "Setup game: View Biome 5");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_6, "Setup game: View Biome 6");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_7, "Setup game: View Biome 7");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_8, "Setup game: View Biome 8");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_9, "Setup game: View Biome 9");
+ displayNames.insert(INTERFACEKEY_CHOOSE_NAME_RANDOM, "Choose name: Random");
+ displayNames.insert(INTERFACEKEY_CHOOSE_NAME_CLEAR, "Choose name: Clear");
+ displayNames.insert(INTERFACEKEY_CHOOSE_NAME_TYPE, "Choose name: Type");
+ displayNames.insert(INTERFACEKEY_ITEM_DESCRIPTION, "View item: Description");
+ displayNames.insert(INTERFACEKEY_ITEM_FORBID, "View item: Forbid");
+ displayNames.insert(INTERFACEKEY_ITEM_MELT, "View item: Melt");
+ displayNames.insert(INTERFACEKEY_ITEM_DUMP, "View item: Dump");
+ displayNames.insert(INTERFACEKEY_ITEM_HIDE, "View item: Hide");
+ displayNames.insert(INTERFACEKEY_OPTIONS, "Main menu");
+ displayNames.insert(INTERFACEKEY_OPTION_EXPORT, "Options, Export Local Image");
+ displayNames.insert(INTERFACEKEY_HELP, "Help");
+ displayNames.insert(INTERFACEKEY_MOVIES, "Movies");
+ displayNames.insert(INTERFACEKEY_CHANGETAB, "Change tab or highlight selection");
+ displayNames.insert(INTERFACEKEY_SEC_CHANGETAB, "Change tab or highlight selection, secondary");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_UP, "Move selector up");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_DOWN, "Move selector down");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_LEFT, "Move selector left");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_RIGHT, "Move selector right");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEUP, "Page selector up");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN, "Page selector down");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_UP, "Move secondary selector up");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_DOWN, "Move secondary selector down");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEUP, "Page secondary selector up");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEDOWN, "Page secondary selector down");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP, "Move view/cursor up");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN, "Move view/cursor down");
+ displayNames.insert(INTERFACEKEY_CURSOR_LEFT, "Move view/cursor left");
+ displayNames.insert(INTERFACEKEY_CURSOR_RIGHT, "Move view/cursor right");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPLEFT, "Move view/cursor up and left");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPRIGHT, "Move view/cursor up and right");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT, "Move view/cursor down and left");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT, "Move view/cursor down and right");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP_FAST, "Move view/cursor up, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN_FAST, "Move view/cursor down, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_LEFT_FAST, "Move view/cursor left, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_RIGHT_FAST, "Move view/cursor right, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPLEFT_FAST, "Move view/cursor up and left, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPRIGHT_FAST, "Move view/cursor up and right, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT_FAST, "Move view/cursor down and left, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT_FAST, "Move view/cursor down and right, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP_Z, "Move view/cursor up (z)");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN_Z, "Move view/cursor down (z)");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP_Z_AUX, "Move view/cursor up (z), aux");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN_Z_AUX, "Move view/cursor down (z), aux");
+ displayNames.insert(INTERFACEKEY_A_RETURN_TO_ARENA, "Adventure: return to arena");
+ displayNames.insert(INTERFACEKEY_A_MOVE_N, "Adventure: move north");
+ displayNames.insert(INTERFACEKEY_A_MOVE_S, "Adventure: move south");
+ displayNames.insert(INTERFACEKEY_A_MOVE_E, "Adventure: move east");
+ displayNames.insert(INTERFACEKEY_A_MOVE_W, "Adventure: move west");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NW, "Adventure: move northwest");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NE, "Adventure: move northeast");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SW, "Adventure: move southwest");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SE, "Adventure: move southeast");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SAME_SQUARE, "Adventure: move same square");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_N, "Adventure: careful move north up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_S, "Adventure: careful move south up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_E, "Adventure: careful move east up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_W, "Adventure: careful move west up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_NW, "Adventure: careful move northwest up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_NE, "Adventure: careful move northeast up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_SW, "Adventure: careful move southwest up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_SE, "Adventure: careful move southeast up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_UPDOWN, "Adventure: careful move up/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_N_UP, "Adventure: move north/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_S_UP, "Adventure: move south/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_E_UP, "Adventure: move east/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_W_UP, "Adventure: move west/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NW_UP, "Adventure: move northwest/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NE_UP, "Adventure: move northeast/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SW_UP, "Adventure: move southwest/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SE_UP, "Adventure: move southeast/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_UP, "Adventure: move up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_N_DOWN, "Adventure: move north/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_S_DOWN, "Adventure: move south/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_E_DOWN, "Adventure: move east/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_W_DOWN, "Adventure: move west/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NW_DOWN, "Adventure: move northwest/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NE_DOWN, "Adventure: move northeast/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SW_DOWN, "Adventure: move southwest/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SE_DOWN, "Adventure: move southeast/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_DOWN, "Adventure: move down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_UP_AUX, "Adventure: move up, aux");
+ displayNames.insert(INTERFACEKEY_A_MOVE_DOWN_AUX, "Adventure: move down, aux");
+ displayNames.insert(INTERFACEKEY_WORLDGEN_EXPORT_MAP, "World Gen: Export Map");
+ displayNames.insert(INTERFACEKEY_LEGENDS_EXPORT_MAP, "Legends: Export Map");
+ displayNames.insert(INTERFACEKEY_LEGENDS_EXPORT_XML, "Legends: Export XML");
+ displayNames.insert(INTERFACEKEY_LEGENDS_EXPORT_DETAILED_MAP, "Legends: Export Detailed Map");
+ displayNames.insert(INTERFACEKEY_LEGENDS_TOGGLE_CIVSITE, "Legends: Civ/Site");
+ displayNames.insert(INTERFACEKEY_LEGENDS_STRING_FILTER, "Legends: String filter");
+ displayNames.insert(INTERFACEKEY_A_COMBAT_ATTACK, "Adventure: Combat, Attack Mode");
+ displayNames.insert(INTERFACEKEY_A_COMBAT_DODGE, "Adventure: Combat, Dodge Mode");
+ displayNames.insert(INTERFACEKEY_A_COMBAT_CHARGEDEF, "Adventure: Combat, Charge Defend Mode");
+ displayNames.insert(INTERFACEKEY_A_STATUS, "Adventure: Status");
+ displayNames.insert(INTERFACEKEY_A_STATUS_WRESTLE, "Adventure: Status, Close Combat");
+ displayNames.insert(INTERFACEKEY_A_STATUS_CUSTOMIZE, "Adventure: Status, Customize");
+ displayNames.insert(INTERFACEKEY_A_STATUS_KILLS, "Adventure: Status, Kills");
+ displayNames.insert(INTERFACEKEY_A_STATUS_HEALTH, "Adventure: Status, Health");
+ displayNames.insert(INTERFACEKEY_A_STATUS_ATT_SKILL, "Adventure: Status, Att/Skills");
+ displayNames.insert(INTERFACEKEY_A_STATUS_DESC, "Adventure: Status, Desc");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_CUSTOMIZE, "Unit View, Customize");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_HEALTH, "Unit View, Health");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS, "Unit View, Relationships");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_ZOOM, "Unit View, Relationships, Zoom");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_VIEW, "Unit View, Relationships, View");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_KILLS, "Unit View, Kills");
+ displayNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_NICKNAME, "Customize Unit, Nickname");
+ displayNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_PROFNAME, "Customize Unit, Profession");
+ displayNames.insert(INTERFACEKEY_A_CLEAR_ANNOUNCEMENTS, "Adventure: Clear announcements");
+ displayNames.insert(INTERFACEKEY_A_SLEEP, "Adventure: Sleep");
+ displayNames.insert(INTERFACEKEY_A_SLEEP_SLEEP, "Adventure: Sleep, Sleep");
+ displayNames.insert(INTERFACEKEY_A_SLEEP_WAIT, "Adventure: Sleep, Wait");
+ displayNames.insert(INTERFACEKEY_A_SLEEP_DAWN, "Adventure: Sleep, Dawn");
+ displayNames.insert(INTERFACEKEY_A_WAIT, "Adventure: Wait Ten Instants");
+ displayNames.insert(INTERFACEKEY_A_SHORT_WAIT, "Adventure: Wait One Instant");
+ displayNames.insert(INTERFACEKEY_A_ATTACK, "Adventure: Attack");
+ displayNames.insert(INTERFACEKEY_A_ATTACK_CONFIRM, "Adventure: Attack, Confirm");
+ displayNames.insert(INTERFACEKEY_QUICK_ATTACK, "Adventure: Attack, Quick");
+ displayNames.insert(INTERFACEKEY_HEAVY_ATTACK, "Adventure: Attack, Heavy");
+ displayNames.insert(INTERFACEKEY_WILD_ATTACK, "Adventure: Attack, Wild");
+ displayNames.insert(INTERFACEKEY_PRECISE_ATTACK, "Adventure: Attack, Precise");
+ displayNames.insert(INTERFACEKEY_CHARGE_ATTACK, "Adventure: Attack, Charge");
+ displayNames.insert(INTERFACEKEY_MULTI_ATTACK, "Adventure: Attack, Multi");
+ displayNames.insert(INTERFACEKEY_A_LOOK, "Adventure: Look");
+ displayNames.insert(INTERFACEKEY_A_SEARCH, "Adventure: Search");
+ displayNames.insert(INTERFACEKEY_A_ODOR,"Adventure: Describe Odor");
+ displayNames.insert(INTERFACEKEY_A_DISPLAY_ODOR,"Adventure: Display Strongest Odor");
+ displayNames.insert(INTERFACEKEY_A_YIELD,"Adventure: Yield");
+ displayNames.insert(INTERFACEKEY_A_DISPLAY_TRACKS,"Adventure: Display Tracks");
+ displayNames.insert(INTERFACEKEY_A_FRESHEST_TRACK,"Adventure: Freshest Track");
+ displayNames.insert(INTERFACEKEY_A_INV_DRAW_WEAPON,"Adventure: Inv. Draw Weapon");
+ displayNames.insert(INTERFACEKEY_A_JUMP,"Adventure: Jump");
+ displayNames.insert(INTERFACEKEY_A_HOLD,"Adventure: Hold/Hang (Climb)");
+ displayNames.insert(INTERFACEKEY_A_TALK, "Adventure: Talk");
+ displayNames.insert(INTERFACEKEY_A_INTERACT, "Adventure: Inv. Interact");
+ displayNames.insert(INTERFACEKEY_A_ACTION, "Adventure: Misc. Action");
+ displayNames.insert(INTERFACEKEY_A_ACTION_CREATE, "Adventure: Misc. Action, Create");
+ displayNames.insert(INTERFACEKEY_A_ACTION_BUTCHER, "Adventure: Misc. Action, Butcher");
+ displayNames.insert(INTERFACEKEY_A_ACTION_ABILITY, "Adventure: Misc. Action, Ability");
+ displayNames.insert(INTERFACEKEY_A_ACTION_POWER, "Adventure: Misc. Action, Power");
+ displayNames.insert(INTERFACEKEY_A_INV_LOOK, "Adventure: Inv. Look");
+ displayNames.insert(INTERFACEKEY_A_INV_REMOVE, "Adventure: Inv. Remove");
+ displayNames.insert(INTERFACEKEY_A_INV_WEAR, "Adventure: Inv. Wear");
+ displayNames.insert(INTERFACEKEY_A_INV_EATDRINK, "Adventure: Inv. Eat/Drink");
+ displayNames.insert(INTERFACEKEY_A_INV_PUTIN, "Adventure: Inv. Put In");
+ displayNames.insert(INTERFACEKEY_A_INV_DROP, "Adventure: Inv. Drop");
+ displayNames.insert(INTERFACEKEY_A_GROUND, "Adventure: Get/Ground");
+ displayNames.insert(INTERFACEKEY_A_THROW, "Adventure: Throw");
+ displayNames.insert(INTERFACEKEY_A_SHOOT, "Adventure: Fire");
+ displayNames.insert(INTERFACEKEY_A_ANNOUNCEMENTS, "Adventure: Announcements");
+ displayNames.insert(INTERFACEKEY_A_COMBAT, "Adventure: Combat Options");
+ displayNames.insert(INTERFACEKEY_A_MOVEMENT, "Adventure: Movement Options");
+ displayNames.insert(INTERFACEKEY_A_MOVEMENT_SWIM, "Adventure: Movement Options, Swim");
+ displayNames.insert(INTERFACEKEY_A_SNEAK, "Adventure: Sneak");
+ displayNames.insert(INTERFACEKEY_A_SPEED_SNEAK, "Adventure: Speed and Sneaking Options");
+ displayNames.insert(INTERFACEKEY_A_CENTER, "Adventure: Center");
+ displayNames.insert(INTERFACEKEY_A_COMPANIONS, "Adventure: Companions");
+ displayNames.insert(INTERFACEKEY_A_BUILDING, "Adventure: Building Interact");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL, "Adventure: Travel");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_SLEEP, "Adventure: Travel, Sleep");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_MAP, "Adventure: Travel, Map");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_HIDE_INSTRUCTIONS, "Adventure: Travel, Hide Instructions");
+ displayNames.insert(INTERFACEKEY_A_DATE, "Adventure: Get Date");
+ displayNames.insert(INTERFACEKEY_A_WEATHER, "Adventure: Get Weather");
+ displayNames.insert(INTERFACEKEY_A_TEMPERATURE, "Adventure: Get Temperature");
+ displayNames.insert(INTERFACEKEY_A_STANCE, "Adventure: Change Stance");
+ displayNames.insert(INTERFACEKEY_OPTION1, "Option 1");
+ displayNames.insert(INTERFACEKEY_OPTION2, "Option 2");
+ displayNames.insert(INTERFACEKEY_OPTION3, "Option 3");
+ displayNames.insert(INTERFACEKEY_OPTION4, "Option 4");
+ displayNames.insert(INTERFACEKEY_OPTION5, "Option 5");
+ displayNames.insert(INTERFACEKEY_OPTION6, "Option 6");
+ displayNames.insert(INTERFACEKEY_OPTION7, "Option 7");
+ displayNames.insert(INTERFACEKEY_OPTION8, "Option 8");
+ displayNames.insert(INTERFACEKEY_OPTION9, "Option 9");
+ displayNames.insert(INTERFACEKEY_OPTION10, "Option 10");
+ displayNames.insert(INTERFACEKEY_OPTION11, "Option 11");
+ displayNames.insert(INTERFACEKEY_OPTION12, "Option 12");
+ displayNames.insert(INTERFACEKEY_OPTION13, "Option 13");
+ displayNames.insert(INTERFACEKEY_OPTION14, "Option 14");
+ displayNames.insert(INTERFACEKEY_OPTION15, "Option 15");
+ displayNames.insert(INTERFACEKEY_OPTION16, "Option 16");
+ displayNames.insert(INTERFACEKEY_OPTION17, "Option 17");
+ displayNames.insert(INTERFACEKEY_OPTION18, "Option 18");
+ displayNames.insert(INTERFACEKEY_OPTION19, "Option 19");
+ displayNames.insert(INTERFACEKEY_OPTION20, "Option 20");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION1, "Secondary Option 1");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION2, "Secondary Option 2");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION3, "Secondary Option 3");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION4, "Secondary Option 4");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION5, "Secondary Option 5");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION6, "Secondary Option 6");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION7, "Secondary Option 7");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION8, "Secondary Option 8");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION9, "Secondary Option 9");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION10, "Secondary Option 10");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION11, "Secondary Option 11");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION12, "Secondary Option 12");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION13, "Secondary Option 13");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION14, "Secondary Option 14");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION15, "Secondary Option 15");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION16, "Secondary Option 16");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION17, "Secondary Option 17");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION18, "Secondary Option 18");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION19, "Secondary Option 19");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION20, "Secondary Option 20");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MAKE_ASH, "Hotkey: Make Ash");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MAKE_CHARCOAL, "Hotkey: Make Charcoal");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MELT_OBJECT, "Hotkey: Melt Object");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_GREEN, "Hotkey: Green Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CLEAR, "Hotkey: Clear Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CRYSTAL, "Hotkey: Crystal Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_COLLECT_SAND, "Hotkey: Collect Sand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_COLLECT_CLAY, "Hotkey: Collect Clay");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_ROUGH, "Hotkey: Raw Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_ARMORSTAND, "Hotkey: Glass Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_BOX, "Hotkey: Glass Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CABINET, "Hotkey: Glass Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_COFFIN, "Hotkey: Glass Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLOODGATE, "Hotkey: Glass Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_HATCH_COVER, "Hotkey: Glass Hatch Cover");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_GRATE, "Hotkey: Glass Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_GOBLET, "Hotkey: Glass Goblet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_TOY, "Hotkey: Glass Toy");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_INSTRUMENT, "Hotkey: Glass Instrument");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_DOOR, "Hotkey: Glass Portal");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_STATUE, "Hotkey: Glass Statue");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_TABLE, "Hotkey: Glass Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CAGE, "Hotkey: Glass Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CHAIR, "Hotkey: Glass Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_BLOCKS, "Hotkey: Glass Blocks");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLASK, "Hotkey: Glass Vial");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_WEAPONRACK, "Hotkey: Glass Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_WINDOW, "Hotkey: Glass Window");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ASHERY_LYE, "Hotkey: Ashery, Lye");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH, "Hotkey: Ashery, Potash (Lye)");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH_DIRECT, "Hotkey: Ashery, Potash (Ash)");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BARREL, "Hotkey: Carpenter, Barrel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BLOCKS, "Hotkey: Carpenter, Blocks");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BUCKET, "Hotkey: Carpenter, Bucket");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TRAP_ANIMAL, "Hotkey: Carpenter, Animal Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CAGE, "Hotkey: Carpenter, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_ARMORSTAND, "Hotkey: Carpenter, Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BED, "Hotkey: Carpenter, Bed");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CHAIR, "Hotkey: Carpenter, Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_COFFIN, "Hotkey: Carpenter, Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_DOOR, "Hotkey: Carpenter, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_FLOODGATE, "Hotkey: Carpenter, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_HATCH_COVER, "Hotkey: Carpenter, Hatch Cover");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_GRATE, "Hotkey: Carpenter, Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CABINET, "Hotkey: Carpenter, Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BIN, "Hotkey: Carpenter, Bin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BOX, "Hotkey: Carpenter, Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_WEAPONRACK, "Hotkey: Carpenter, Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TABLE, "Hotkey: Carpenter, Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SIEGE_BALLISTA, "Hotkey: Siege Shop, Ballista");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SIEGE_CATAPULT, "Hotkey: Siege Shop, Catapult");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BOX, "Hotkey: Leather, Bag");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_FLASK, "Hotkey: Leather, Flask");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_SHIRT, "Hotkey: Leather, Shirt");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_CLOAK, "Hotkey: Leather, Cloak");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BACKPACK, "Hotkey: Leather, Backpack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_QUIVER, "Hotkey: Leather, Quiver");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_IMAGE, "Hotkey: Leather, Image");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_PLANT, "Hotkey: Clothes, Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_SILK, "Hotkey: Clothes, Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_YARN, "Hotkey: Clothes, Yarn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_SHIRT, "Hotkey: Clothes, Shirt");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CLOAK, "Hotkey: Clothes, Cloak");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_BOX, "Hotkey: Clothes, Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CHAIN, "Hotkey: Clothes, Rope");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_IMAGE, "Hotkey: Clothes, Image");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_STONE, "Hotkey: Crafts, Mat Stone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_WOOD, "Hotkey: Crafts, Mat Wood");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_BONE, "Hotkey: Crafts, Dec Bone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_SHELL, "Hotkey: Crafts, Dec Shell");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_TOOTH, "Hotkey: Crafts, Dec Tooth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_HORN, "Hotkey: Crafts, Dec Horn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_PEARL, "Hotkey: Crafts, Dec Pearl");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOTEM, "Hotkey: Crafts, Totem");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_CLOTH, "Hotkey: Crafts, Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SILK, "Hotkey: Crafts, Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_YARN, "Hotkey: Crafts, Yarn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_WOOD, "Hotkey: Crafts, Wood Material");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_BONE, "Hotkey: Crafts, Bone Material");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_SHELL, "Hotkey: Crafts, Shell Material");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SHELL, "Hotkey: Crafts, Shell");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOOTH, "Hotkey: Crafts, Tooth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_HORN, "Hotkey: Crafts, Horn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_PEARL, "Hotkey: Crafts, Pearl");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_BONE, "Hotkey: Crafts, Bone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_LEATHER, "Hotkey: Crafts, Leather");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SLAB, "Hotkey: Crafts, Slab");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_CRAFTS, "Hotkey: Crafts, Mat Crafts");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_GOBLET, "Hotkey: Crafts, Mat Goblet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_INSTRUMENT, "Hotkey: Crafts, Mat Instrument");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_TOY, "Hotkey: Crafts, Mat Toy");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_WEAPON, "Hotkey: Forge, Weapon");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_ARMOR, "Hotkey: Forge, Armor");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_FURNITURE, "Hotkey: Forge, Furniture");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_SIEGE, "Hotkey: Forge, Siege");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_TRAP, "Hotkey: Forge, Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_OTHER, "Hotkey: Forge, Other");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_METAL, "Hotkey: Forge, Metal Clothing");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARMORSTAND, "Hotkey: Building, Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BED, "Hotkey: Building, Bed");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRACTION_BENCH, "Hotkey: Building, Traction Bench");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SLAB, "Hotkey: Building, Slab");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_NEST_BOX, "Hotkey: Building, Nest Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HIVE, "Hotkey: Building, Hive");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIR, "Hotkey: Building, Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_COFFIN, "Hotkey: Building, Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_DOOR, "Hotkey: Building, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FLOODGATE, "Hotkey: Building, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HATCH, "Hotkey: Building, Hatch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_WALL, "Hotkey: Building, Wall Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_FLOOR, "Hotkey: Building, Floor Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_VERTICAL, "Hotkey: Building, Vertical Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_FLOOR, "Hotkey: Building, Floor Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CABINET, "Hotkey: Building, Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BOX, "Hotkey: Building, Chest");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_KENNEL, "Hotkey: Building, Kennel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FARMPLOT, "Hotkey: Building, Farm Plot");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WEAPONRACK, "Hotkey: Building, Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_STATUE, "Hotkey: Building, Statue");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TABLE, "Hotkey: Building, Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_DIRT, "Hotkey: Building, Dirt Road");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_PAVED, "Hotkey: Building, Paved Road");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BRIDGE, "Hotkey: Building, Bridge");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WELL, "Hotkey: Building, Well");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE, "Hotkey: Building, Siege");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP, "Hotkey: Building, Workshop");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE, "Hotkey: Building, Furnace");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GLASS, "Hotkey: Building, Glass Window");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GEM, "Hotkey: Building, Gem Window");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SHOP, "Hotkey: Building, Shop");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ANIMALTRAP, "Hotkey: Building, Animal Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIN, "Hotkey: Building, Chain");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CAGE, "Hotkey: Building, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRADEDEPOT, "Hotkey: Building, Trade Depot");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP, "Hotkey: Building, Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE, "Hotkey: Building, Machine Component");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SUPPORT, "Hotkey: Building, Support");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARCHERYTARGET, "Hotkey: Building, Archery Target");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_SCREW_PUMP, "Hotkey: Building, Machine Component, Screw Pump");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WATER_WHEEL, "Hotkey: Building, Machine Component, Water Wheel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WINDMILL, "Hotkey: Building, Machine Component, Windmill");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY, "Hotkey: Building, Machine Component, Gear Assembly");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL, "Hotkey: Building, Machine Component, Horizontal Axle");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL, "Hotkey: Building, Machine Component, Vertical Axle");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_ROLLERS, "Hotkey: Building, Machine Component, Rollers");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_BALLISTA, "Hotkey: Building, Siege, Ballista");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_CATAPULT, "Hotkey: Building, Siege, Catapult");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_STONE, "Hotkey: Building, Trap, Stone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_WEAPON, "Hotkey: Building, Trap, Weapon");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_LEVER, "Hotkey: Building, Trap, Lever");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_TRIGGER, "Hotkey: Building, Trap, Trigger");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_CAGE, "Hotkey: Building, Trap, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_SPIKE, "Hotkey: Building, Trap, Upright Spear/Spike");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION, "Hotkey: Building, Wall/Floor/Stairs");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION, "Hotkey: Building, Construction, Fortification");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_WALL, "Hotkey: Building, Construction, Wall");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FLOOR, "Hotkey: Building, Construction, Floor");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_RAMP, "Hotkey: Building, Construction, Ramp");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP, "Hotkey: Building, Construction, Upward Stair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN, "Hotkey: Building, Construction, Downward Stair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN, "Hotkey: Building, Construction, Up/Down Stair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK, "Hotkey: Building, Construction, Track");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP, "Hotkey: Building, Construction, Track Stop");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LEATHER, "Hotkey: Building, Wksp, Leather");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_QUERN, "Hotkey: Building, Wksp, Quern");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MILLSTONE, "Hotkey: Building, Wksp, Millstone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LOOM, "Hotkey: Building, Wksp, Loom");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CLOTHES, "Hotkey: Building, Wksp, Clothes");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BOWYER, "Hotkey: Building, Wksp, Bowyer");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CARPENTER, "Hotkey: Building, Wksp, Carpenter");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_METALSMITH, "Hotkey: Building, Wksp, Metalsmith");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LAVAMILL, "Hotkey: Building, Wksp, Lavamill");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_JEWELER, "Hotkey: Building, Wksp, Jeweler");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MASON, "Hotkey: Building, Wksp, Mason");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BUTCHER, "Hotkey: Building, Wksp, Butcher");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_TANNER, "Hotkey: Building, Wksp, Tanner");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_DYER, "Hotkey: Building, Wksp, Dyer");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN, "Hotkey: Building, Wksp, Craftsman");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_SIEGE, "Hotkey: Building, Wksp, Siege");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MECHANIC, "Hotkey: Building, Wksp, Mechanic");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_STILL, "Hotkey: Building, Wksp, Still");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FARMER, "Hotkey: Building, Wksp, Farmer");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_KITCHEN, "Hotkey: Building, Wksp, Kitchen");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FISHERY, "Hotkey: Building, Wksp, Fishery");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_ASHERY, "Hotkey: Building, Wksp, Ashery");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_WOOD, "Hotkey: Building, Furn, Wood");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER, "Hotkey: Building, Furn, Smelter");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS, "Hotkey: Building, Furn, Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN, "Hotkey: Building, Furn, Kiln");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER_LAVA, "Hotkey: Building, Furn, Smelter");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS_LAVA, "Hotkey: Building, Furn, Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN_LAVA, "Hotkey: Building, Furn, Kiln");
+ displayNames.insert(INTERFACEKEY_HIVE_INSTALL_COLONY, "Hotkey: Building, Hive, Install Colony");
+ displayNames.insert(INTERFACEKEY_HIVE_GATHER_PRODUCTS, "Hotkey: Building, Hive, Gather Products");
+ displayNames.insert(INTERFACEKEY_D_ONESTEP, "Main: One-Step");
+ displayNames.insert(INTERFACEKEY_D_PAUSE, "Main: Pause/Resume");
+ displayNames.insert(INTERFACEKEY_D_DEPOT, "Depot Access");
+ displayNames.insert(INTERFACEKEY_D_HOT_KEYS, "Main: Hot Keys");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY1, "Main: Hot Key 1");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY2, "Main: Hot Key 2");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY3, "Main: Hot Key 3");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY4, "Main: Hot Key 4");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY5, "Main: Hot Key 5");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY6, "Main: Hot Key 6");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY7, "Main: Hot Key 7");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY8, "Main: Hot Key 8");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY9, "Main: Hot Key 9");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY10, "Main: Hot Key 10");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY11, "Main: Hot Key 11");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY12, "Main: Hot Key 12");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY13, "Main: Hot Key 13");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY14, "Main: Hot Key 14");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY15, "Main: Hot Key 15");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY16, "Main: Hot Key 16");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY_CHANGE_NAME, "Hot Keys: Change Name");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY_ZOOM, "Hot Keys: Zoom");
+ displayNames.insert(INTERFACEKEY_D_ANNOUNCE, "Main: Announcements");
+ displayNames.insert(INTERFACEKEY_D_REPORTS, "Main: Reports");
+ displayNames.insert(INTERFACEKEY_D_BUILDING, "Main: Place Building");
+ displayNames.insert(INTERFACEKEY_D_CIVLIST, "Main: Civilizations");
+ displayNames.insert(INTERFACEKEY_D_DESIGNATE, "Main: Designations");
+ displayNames.insert(INTERFACEKEY_D_ARTLIST, "Main: Artifacts");
+ displayNames.insert(INTERFACEKEY_D_NOBLES, "Main: Nobles");
+ displayNames.insert(INTERFACEKEY_D_ORDERS, "Main: Standing Orders");
+ displayNames.insert(INTERFACEKEY_D_MILITARY, "Main: Military");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SQUAD, "Main: Military, Create Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_DISBAND_SQUAD, "Main: Military, Disband Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SUB_SQUAD, "Main: Military, Create Sub-Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_CANCEL_ORDERS, "Main: Military, Cancel Orders");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_POSITIONS, "Main: Military, Positions");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS, "Main: Military, Alerts");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_ADD, "Main: Military, Alerts, Add");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_DELETE, "Main: Military, Alerts, Delete");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET, "Main: Military, Alerts, Set");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_NAME, "Main: Military, Alerts, Name");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET_RETAIN, "Main: Military, Alerts, Set/Retain");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP, "Main: Military, Equip");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_CUSTOMIZE, "Main: Military, Equip, Customize");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_UNIFORM, "Main: Military, Equip, Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_PRIORITY, "Main: Military, Equip, Priority");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_UNIFORMS, "Main: Military, Uniforms");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES, "Main: Military, Supplies");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_DOWN, "Main: Military, Supplies, Water Down");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_UP, "Main: Military, Supplies, Water Up");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_DOWN, "Main: Military, Supplies, Food Down");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_UP, "Main: Military, Supplies, Food Up");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION, "Main: Military, Ammunition");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_ADD_ITEM, "Main: Military, Ammunition, Add Item");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_REMOVE_ITEM, "Main: Military, Ammunition, Remove Item");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT, "Main: Military, Ammunition, Lower Amount");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT, "Main: Military, Ammunition, Raise Amount");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS, "Main: Military, Ammunition, Lower Amount Lots");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS, "Main: Military, Ammunition, Raise Amount Lots");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_MATERIAL, "Main: Military, Ammunition, Material");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_COMBAT, "Main: Military, Ammunition, Combat");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_TRAINING, "Main: Military, Ammunition, Training");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_TRAINING, "Main: Military, Training");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SCHEDULE, "Main: Military, Schedule");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_UNIFORM, "Main: Military, Add Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_DELETE_UNIFORM, "Main: Military, Delete Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_NAME_UNIFORM, "Main: Military, Name Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_NAME_SQUAD, "Main: Military, Name Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_ARMOR, "Main: Military, Add Armor");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_PANTS, "Main: Military, Add Pants");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_HELM, "Main: Military, Add Helm");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_GLOVES, "Main: Military, Add Gloves");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_BOOTS, "Main: Military, Add Boots");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_SHIELD, "Main: Military, Add Shield");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_WEAPON, "Main: Military, Add Weapon");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_MATERIAL, "Main: Military, Add Material");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_COLOR, "Main: Military, Add Color");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_REPLACE_CLOTHING, "Main: Military, Replace Clothing");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EXACT_MATCH, "Main: Military, Exact Match");
+ displayNames.insert(INTERFACEKEY_D_ROOMS, "Main: Rooms");
+ displayNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_T, "Building List: Zoom T");
+ displayNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_Q, "Building List: Zoom Q");
+ displayNames.insert(INTERFACEKEY_RECENTER_ON_LEVER, "Recenter on Lever");
+ displayNames.insert(INTERFACEKEY_D_SQUADS, "Main: Control Squads");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_MOVE, "Main: Control Squads, Move");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_KILL, "Main: Control Squads, Kill");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_KILL_LIST, "Main: Control Squads, Kill List");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_KILL_RECT, "Main: Control Squads, Kill Rect");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_SCHEDULE, "Main: Control Squads, Schedule");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_CANCEL_ORDER, "Main: Control Squads, Cancel Order");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_ALERT, "Main: Control Squads, Alert");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_SELECT_INDIVIDUALS, "Main: Control Squads, Select Individuals");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_CENTER, "Main: Control Squads, Center");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_SLEEP, "Squad Schedule: Sleep");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_CIVILIAN_UNIFORM, "Squad Schedule: Civilian Uniform");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_GIVE_ORDER, "Squad Schedule: Give Order");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_EDIT_ORDER, "Squad Schedule: Edit Order");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_CANCEL_ORDER, "Squad Schedule: Cancel Order");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_COPY_ORDERS, "Squad Schedule: Copy Orders");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_PASTE_ORDERS, "Squad Schedule: Paste Orders");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_MS_NAME, "Squad Schedule: Name Grid Cell");
+ displayNames.insert(INTERFACEKEY_D_STOCKPILES, "Main: Stockpiles");
+ displayNames.insert(INTERFACEKEY_D_CIVZONE, "Main: Activity Zone");
+ displayNames.insert(INTERFACEKEY_D_VIEWUNIT, "Main: View Units");
+ displayNames.insert(INTERFACEKEY_D_JOBLIST, "Main: Job List");
+ displayNames.insert(INTERFACEKEY_D_UNITLIST, "Main: Unit List");
+ displayNames.insert(INTERFACEKEY_D_LOOK, "Main: Look");
+ displayNames.insert(INTERFACEKEY_D_HAULING, "Main: Hauling");
+ displayNames.insert(INTERFACEKEY_D_HAULING_NEW_ROUTE, "Main: Hauling, New Route");
+ displayNames.insert(INTERFACEKEY_D_HAULING_NEW_STOP, "Main: Hauling, New Stop");
+ displayNames.insert(INTERFACEKEY_D_HAULING_REMOVE, "Main: Hauling, Remove");
+ displayNames.insert(INTERFACEKEY_D_HAULING_PROMOTE, "Main: Hauling, Promote");
+ displayNames.insert(INTERFACEKEY_D_HAULING_VEHICLE, "Main: Hauling, Vehicle");
+ displayNames.insert(INTERFACEKEY_D_HAULING_NICKNAME, "Main: Hauling, Name");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_DEPART, "Main: Hauling, Stop, New Leave Condition");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_LINK, "Main: Hauling, Stop, New Stockpile Link");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_REMOVE, "Main: Hauling, Stop, Remove");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_SELECT_PILE, "Main: Hauling, Stop, Stockpile, Select");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_TAKE_GIVE, "Main: Hauling, Stop, Stockpile, Take/Give");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DIR, "Main: Hauling, Stop, Leave Condition, Dir");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MODE, "Main: Hauling, Stop, Leave Condition, Mode");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_UP, "Main: Hauling, Stop, Leave Condition, Timer Up");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_DOWN, "Main: Hauling, Stop, Leave Condition, Timer Down");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_UP, "Main: Hauling, Stop, Leave Condition, Fullness Up");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_DOWN, "Main: Hauling, Stop, Leave Condition, Fullness Down");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MORE_LESS, "Main: Hauling, Stop, Leave Condition, More/Less");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DESIRED_TOTAL, "Main: Hauling, Stop, Leave Condition, Desired/Total");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_CHANGE, "Main: Hauling, Stop, Leave Condition, Change");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_ADVANCED, "Main: Hauling, Stop, Leave Condition, Advanced");
+ displayNames.insert(INTERFACEKEY_D_BURROWS, "Main: Burrows");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_ADD, "Main: Burrows, Add");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_DELETE, "Main: Burrows, Delete");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_DEFINE, "Main: Burrows, Define");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_ADD_UNIT, "Main: Burrows, Add Citizen");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_WORKSHOP_LIMIT, "Main: Burrows, Limit Workshops");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_CENTER, "Main: Burrows, Center");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_NAME, "Main: Burrows, Name");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_CHANGE_SELECTION, "Main: Burrows, Change Selector");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_BRUSH, "Main: Burrows, Brush");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_REMOVE, "Main: Burrows, Paint/Erase");
+ displayNames.insert(INTERFACEKEY_D_NOTE, "Main: Note");
+ displayNames.insert(INTERFACEKEY_D_NOTE_PLACE, "Main: Note, Place");
+ displayNames.insert(INTERFACEKEY_D_NOTE_DELETE, "Main: Note, Delete");
+ displayNames.insert(INTERFACEKEY_D_NOTE_NAME, "Main: Note, Enter Name");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ENTER, "Main: Note, Enter Text");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ADOPT_SYMBOL, "Main: Note, Adopt Symbol");
+ displayNames.insert(INTERFACEKEY_D_NOTE_CHANGE_SELECTION, "Main: Note, Change Selection");
+ displayNames.insert(INTERFACEKEY_D_NOTE_POINTS, "Main: Note, Route, Done");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE, "Main: Note, Routes");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_ADD, "Main: Note, Route, Add");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_EDIT, "Main: Note, Route, Edit");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_DELETE, "Main: Note, Route, Delete");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_CENTER, "Main: Note, Route, Center");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_NAME, "Main: Note, Route, Name");
+ displayNames.insert(INTERFACEKEY_D_BUILDJOB, "Main: Building Jobs");
+ displayNames.insert(INTERFACEKEY_D_STATUS, "Main: Overall Status");
+ displayNames.insert(INTERFACEKEY_D_STATUS_OVERALL_HEALTH_RECENTER, "Main: Status, Overall Health, Recenter");
+ displayNames.insert(INTERFACEKEY_D_BUILDITEM, "Main: Building Items");
+ displayNames.insert(INTERFACEKEY_D_BITEM_FORBID, "Building Items: Forbid");
+ displayNames.insert(INTERFACEKEY_D_BITEM_DUMP, "Building Items: Dump");
+ displayNames.insert(INTERFACEKEY_D_BITEM_MELT, "Building Items: Melt");
+ displayNames.insert(INTERFACEKEY_D_BITEM_HIDE, "Building Items: Hide");
+ displayNames.insert(INTERFACEKEY_D_LOOK_FORBID, "Dwf Look: Forbid");
+ displayNames.insert(INTERFACEKEY_D_LOOK_DUMP, "Dwf Look: Dump");
+ displayNames.insert(INTERFACEKEY_D_LOOK_MELT, "Dwf Look: Melt");
+ displayNames.insert(INTERFACEKEY_D_LOOK_HIDE, "Dwf Look: Hide");
+ displayNames.insert(INTERFACEKEY_D_LOOK_FOLLOW, "Dwf Look: Follow");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_CREATURE, "Dwf Look: Arena Creature");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_ADV_MODE, "Dwf Look: Arena Adv Mode");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_WATER, "Dwf Look: Arena Water");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_MAGMA, "Dwf Look: Arena Magma");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_DOWN, "Arena Creature: Side Down");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_UP, "Arena Creature: Side Up");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_NEW_ITEM, "Arena Creature: New Item");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_BLANK_LIST, "Arena Creature: Blank List");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_REMOVE_ITEM, "Arena Creature: Remove Item");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_UNDEAD, "Arena Creature: Undead");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_STRING, "Arena Creature: String");
+ displayNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_1, "Arena Conflict State 1");
+ displayNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_2, "Arena Conflict State 2");
+ displayNames.insert(INTERFACEKEY_ARENA_MORALE, "Arena Morale");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER, "Arena Weather");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER_SNOW, "Arena Weather: Snow");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER_MUD, "Arena Weather: Mud");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER_CLEAR_SPATTER, "Arena Weather: Clear Spatter");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_TREE, "Dwf Look: Arena Tree");
+ displayNames.insert(INTERFACEKEY_ARENA_TREE_FILTER, "Arena Tree: Filter");
+ displayNames.insert(INTERFACEKEY_ARENA_TREE_AGE, "Arena Tree: Age");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_MOUNT, "Dwf Look: Arena Mount");
+ displayNames.insert(INTERFACEKEY_A_ENTER_NAME, "Adventure: Creation, Name Entry");
+ displayNames.insert(INTERFACEKEY_A_CUST_NAME, "Adventure: Creation, Customize Name");
+ displayNames.insert(INTERFACEKEY_A_RANDOM_NAME, "Adventure: Creation, Random Name");
+ displayNames.insert(INTERFACEKEY_A_CHANGE_GENDER, "Adventure: Creation, Change Gender");
+ displayNames.insert(INTERFACEKEY_A_END_TRAVEL, "Adventure: Travel, Visit Site");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_CLOUDS, "Adventure: Travel, Clouds");
+ displayNames.insert(INTERFACEKEY_A_LOG, "Adventure: Log");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_LOG, "Adventure: Travel, Log");
+ displayNames.insert(INTERFACEKEY_A_LOG_TASKS, "Adventure: Log, Tasks");
+ displayNames.insert(INTERFACEKEY_A_LOG_ENTITIES, "Adventure: Log, Entities");
+ displayNames.insert(INTERFACEKEY_A_LOG_SITES, "Adventure: Log, Sites");
+ displayNames.insert(INTERFACEKEY_A_LOG_SUBREGIONS, "Adventure: Log, Regions");
+ displayNames.insert(INTERFACEKEY_A_LOG_FEATURE_LAYERS, "Adventure: Log, Feature Layers");
+ displayNames.insert(INTERFACEKEY_A_LOG_PEOPLE, "Adventure: Log, People");
+ displayNames.insert(INTERFACEKEY_A_LOG_AGREEMENTS, "Adventure: Log, Agreements");
+ displayNames.insert(INTERFACEKEY_A_LOG_EVENTS, "Adventure: Log, Events");
+ displayNames.insert(INTERFACEKEY_A_LOG_BESTIARY, "Adventure: Log, Bestiary");
+ displayNames.insert(INTERFACEKEY_A_LOG_FILTER, "Adventure: Log, Filter");
+ displayNames.insert(INTERFACEKEY_A_LOG_ZOOM_CURRENT_LOCATION, "Adventure: Log, Zoom to Current Location");
+ displayNames.insert(INTERFACEKEY_A_LOG_ZOOM_SELECTED, "Adventure: Log, Zoom to Selected");
+ displayNames.insert(INTERFACEKEY_A_LOG_LINE, "Adventure: Log, Toggle Line");
+ displayNames.insert(INTERFACEKEY_A_LOG_MAP, "Adventure: Log, Toggle Map/Info");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTOFORBID, "Orders: Forbid");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_PROJECTILE, "Orders: Forbid Projectiles");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_CORPSE, "Orders: Forbid Your Corpse");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_ITEMS, "Orders: Forbid Your Items");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_CORPSE, "Orders: Forbid Other Corpse");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_ITEMS, "Orders: Forbid Other Items");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_GATHER, "Orders: Gather Refuse");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE, "Orders: Gather Outside");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE_VERMIN, "Orders: Gather Outside Vermin");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_CORPSE, "Orders: Dump Corpse");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKULL, "Orders: Dump Skull");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKIN, "Orders: Dump Skin");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_BONE, "Orders: Dump Bone");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SHELL, "Orders: Dump Shell");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_OTHER, "Orders: Dump Other");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_STRAND_TISSUE, "Orders: Dump Strand Tissue");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_FURNITURE, "Orders: Gather Furniture");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_ANIMALS, "Orders: Gather Animals");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_FOOD, "Orders: Gather Food");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_BODIES, "Orders: Gather Bodies");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE, "Orders: Refuse");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_STONE, "Orders: Gather Stone");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_WOOD, "Orders: Gather Wood");
+ displayNames.insert(INTERFACEKEY_ORDERS_ALL_HARVEST, "Orders: All Harvest");
+ displayNames.insert(INTERFACEKEY_ORDERS_SAMEPILE, "Orders: Piles Same");
+ displayNames.insert(INTERFACEKEY_ORDERS_MIXFOODS, "Orders: Mix Foods");
+ displayNames.insert(INTERFACEKEY_ORDERS_EXCEPTIONS, "Orders: Exceptions");
+ displayNames.insert(INTERFACEKEY_ORDERS_LOOM, "Orders: Loom");
+ displayNames.insert(INTERFACEKEY_ORDERS_DYED_CLOTH, "Orders: Dyed Cloth");
+ displayNames.insert(INTERFACEKEY_ORDERS_WORKSHOP, "Orders: Workshop");
+ displayNames.insert(INTERFACEKEY_ORDERS_COLLECT_WEB, "Orders: Auto-Collect Web");
+ displayNames.insert(INTERFACEKEY_ORDERS_SLAUGHTER, "Orders: Auto-Slaughter");
+ displayNames.insert(INTERFACEKEY_ORDERS_BUTCHER, "Orders: Auto-Butcher");
+ displayNames.insert(INTERFACEKEY_ORDERS_TAN, "Orders: Auto-Tan");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_FISHERY, "Orders: Auto-Fishery");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_KITCHEN, "Orders: Auto-Kitchen");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_KILN, "Orders: Auto-Kiln");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_SMELTER, "Orders: Auto-Smelter");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_OTHER, "Orders: Auto-Other");
+ displayNames.insert(INTERFACEKEY_ORDERS_ZONE, "Orders: Zone");
+ displayNames.insert(INTERFACEKEY_ORDERS_ZONE_DRINKING, "Orders: Zone, Drinking");
+ displayNames.insert(INTERFACEKEY_ORDERS_ZONE_FISHING, "Orders: Zone, Fishing");
+ displayNames.insert(INTERFACEKEY_DESTROYBUILDING, "Destroy Building");
+ displayNames.insert(INTERFACEKEY_SUSPENDBUILDING, "Suspend Building");
+ displayNames.insert(INTERFACEKEY_MENU_CONFIRM, "Menu Confirm");
+ displayNames.insert(INTERFACEKEY_SAVE_BINDINGS, "Save Bindings");
+ displayNames.insert(INTERFACEKEY_LOAD_BINDINGS, "Load Bindings");
+ displayNames.insert(INTERFACEKEY_KEYBINDING_COMPLETE, "Complete Binding");
+ displayNames.insert(INTERFACEKEY_ZOOM_IN, "Zoom In");
+ displayNames.insert(INTERFACEKEY_ZOOM_OUT, "Zoom Out");
+ displayNames.insert(INTERFACEKEY_ZOOM_TOGGLE, "Toggle Zoom");
+ displayNames.insert(INTERFACEKEY_ZOOM_RESET, "Reset Zoom");
+ displayNames.insert(INTERFACEKEY_MACRO_BREAK, "Macro, Break");
+ displayNames.insert(INTERFACEKEY_RECORD_MACRO, "Macro, Record");
+ displayNames.insert(INTERFACEKEY_PLAY_MACRO, "Macro, Play");
+ displayNames.insert(INTERFACEKEY_SAVE_MACRO, "Macro, Save");
+ displayNames.insert(INTERFACEKEY_LOAD_MACRO, "Macro, Load");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ALCHEMIST_SOAP, "Hotkey: Alchemist, Soap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_STILL_BREW, "Hotkey: Still, Brew");
+ displayNames.insert(INTERFACEKEY_HOTKEY_STILL_EXTRACT, "Hotkey: Still, Extract");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_COLLECT_SILK, "Hotkey: Loom, Collect Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_CLOTH, "Hotkey: Loom, Weave Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_SILK, "Hotkey: Loom, Weave Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_YARN, "Hotkey: Loom, Weave Yarn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_METAL, "Hotkey: Loom, Metal");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_2, "Hotkey: Kitchen, Meal 1");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_3, "Hotkey: Kitchen, Meal 2");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_4, "Hotkey: Kitchen, Meal 3");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_RENDER_FAT, "Hotkey: Kitchen, Render Fat");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS, "Hotkey: Farmer, Process");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_VIAL, "Hotkey: Farmer, Vial");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BAG, "Hotkey: Farmer, Bag");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BARREL, "Hotkey: Farmer, Barrel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_CHEESE, "Hotkey: Farmer, Cheese");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_MILK, "Hotkey: Farmer, Milk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_SHEAR_CREATURE, "Hotkey: Farmer, Shear");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_SPIN_THREAD, "Hotkey: Farmer, Spin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MILL_MILL, "Hotkey: Mill, Mill");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KENNEL_CATCH_VERMIN, "Hotkey: Kennel, Catch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KENNEL_TAME_VERMIN, "Hotkey: Kennel, Tame Small");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FISHERY_PROCESS, "Hotkey: Fishery, Process");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FISHERY_EXTRACT, "Hotkey: Fishery, Extract");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FISHERY_CATCH, "Hotkey: Fishery, Catch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_BUTCHER, "Hotkey: Butcher, Butcher");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_EXTRACT, "Hotkey: Butcher, Extract");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_CATCH, "Hotkey: Butcher, Catch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TANNER_TAN, "Hotkey: Tanner, Tan");
+ displayNames.insert(INTERFACEKEY_HOTKEY_DYER_THREAD, "Hotkey: Dyer, Thread");
+ displayNames.insert(INTERFACEKEY_HOTKEY_DYER_CLOTH, "Hotkey: Dyer, Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FURNITURE, "Hotkey: Jeweler, Furniture");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FINISHED, "Hotkey: Jeweler, Finished");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_AMMO, "Hotkey: Jeweler, Ammo");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_CUT, "Hotkey: Jeweler, Cut");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_ENCRUST, "Hotkey: Jeweler, Encrust");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_PARTS, "Hotkey: Mechanic, Mechanisms");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_TRACTION_BENCH, "Hotkey: Mechanic, Traction Bench");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_ARMORSTAND, "Hotkey: Mason, Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_BLOCKS, "Hotkey: Mason, Blocks");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_CHAIR, "Hotkey: Mason, Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_COFFIN, "Hotkey: Mason, Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_DOOR, "Hotkey: Mason, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_FLOODGATE, "Hotkey: Mason, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_HATCH_COVER, "Hotkey: Mason, Hatch Cover");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_GRATE, "Hotkey: Mason, Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_CABINET, "Hotkey: Mason, Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_BOX, "Hotkey: Mason, Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_STATUE, "Hotkey: Mason, Statue");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_QUERN, "Hotkey: Mason, Quern");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_MILLSTONE, "Hotkey: Mason, Millstone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_TABLE, "Hotkey: Mason, Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_WEAPONRACK, "Hotkey: Mason, Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_SLAB, "Hotkey: Mason, Slab");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_BRIDGE, "Hotkey: Trap, Bridge");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_GEAR_ASSEMBLY, "Hotkey: Trap, Gear Assembly");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_DOOR, "Hotkey: Trap, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_FLOODGATE, "Hotkey: Trap, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_SPIKE, "Hotkey: Trap, Spike");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_HATCH, "Hotkey: Trap, Hatch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_WALL, "Hotkey: Trap, Wall Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_FLOOR, "Hotkey: Trap, Floor Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_VERTICAL, "Hotkey: Trap, Vertical Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_FLOOR, "Hotkey: Trap, Floor Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_SUPPORT, "Hotkey: Trap, Support");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_CHAIN, "Hotkey: Trap, Chain");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_CAGE, "Hotkey: Trap, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_PULL_LEVER, "Hotkey: Trap, Lever");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_TRACK_STOP, "Hotkey: Trap, Track Stop");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ADD, "Buildjob: Add");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CANCEL, "Buildjob: Cancel");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_PROMOTE, "Buildjob: Promote");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_NOW, "Buildjob: Now");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_REPEAT, "Buildjob: Repeat");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_SUSPEND, "Buildjob: Suspend");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_WORKSHOP_PROFILE, "Buildjob: Workshop Profile");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_WELL_FREE, "Buildjob: Well, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_WELL_SIZE, "Buildjob: Well, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_FREE, "Buildjob: Target, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_SIZE, "Buildjob: Target, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_DOWN, "Buildjob: Target, Down");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_UP, "Buildjob: Target, Up");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_RIGHT, "Buildjob: Target, Right");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_LEFT, "Buildjob: Target, Left");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STATUE_ASSIGN, "Buildjob: Statue, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STATUE_FREE, "Buildjob: Statue, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STATUE_SIZE, "Buildjob: Statue, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_JUSTICE, "Buildjob: Cage, Justice");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_FREE, "Buildjob: Cage, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_SIZE, "Buildjob: Cage, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN_OCC, "Buildjob: Cage, Assign Occ");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_WATER, "Buildjob: Cage, Water");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN, "Buildjob: Cage, Assign Owner");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN_OCC, "Buildjob: Chain, Assign Occ");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_JUSTICE, "Buildjob: Chain, Justice");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN, "Buildjob: Chain, Assign Owner");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_FREE, "Buildjob: Chain, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_SIZE, "Buildjob: Chain, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_FIRING, "Buildjob: Siege, Fire");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_ORIENT, "Buildjob: Siege, Orient");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DOOR_INTERNAL, "Buildjob: Door, Internal");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DOOR_LOCK, "Buildjob: Door, Forbid");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DOOR_AJAR, "Buildjob: Door, Pet-passable");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_ASSIGN, "Buildjob: Coffin, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_FREE, "Buildjob: Coffin, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_SIZE, "Buildjob: Coffin, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_BURIAL, "Buildjob: Coffin, Gen. Burial");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_CIV, "Buildjob: Coffin, Allow Citizens");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_PET, "Buildjob: Coffin, Allow Pets");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_ASSIGN, "Buildjob: Chair, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_FREE, "Buildjob: Chair, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_SIZE, "Buildjob: Chair, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_ASSIGN, "Buildjob: Table, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_HALL, "Buildjob: Table, Hall");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_FREE, "Buildjob: Table, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_SIZE, "Buildjob: Table, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_ASSIGN, "Buildjob: Bed, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_FREE, "Buildjob: Bed, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_BARRACKS, "Buildjob: Bed, Barracks");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_DORMITORY, "Buildjob: Bed, Dormitory");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_RENT, "Buildjob: Bed, Rent");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_SIZE, "Buildjob: Bed, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_NAME, "Buildjob: Bed, Name");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_SLEEP, "Buildjob: Bed, Sleep");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_TRAIN, "Buildjob: Bed, Train");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_INDIV_EQ, "Buildjob: Bed, Indiv Eq");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_SQUAD_EQ, "Buildjob: Bed, Squad Eq");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_POSITION, "Buildjob: Bed, Position");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BRING, "Buildjob: Depot, Bring");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_TRADE, "Buildjob: Depot, Trade");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_REQUEST_TRADER, "Buildjob: Depot, Request Trader");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BROKER_ONLY, "Buildjob: Depot, Broker Only");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_NONE, "Buildjob: Animal Trap, No Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_MEAT, "Buildjob: Animal Trap, Meat Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_FISH, "Buildjob: Animal Trap, Fish Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_GEM, "Buildjob: Animal Trap, Gem Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_FALLOW, "Buildjob: Farm, Fallow");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_FERTILIZE, "Buildjob: Farm, Fertilize");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_SEASFERT, "Buildjob: Farm, Seas Fert");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_SPRING, "Buildjob: Farm, Spring");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_SUMMER, "Buildjob: Farm, Summer");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_AUTUMN, "Buildjob: Farm, Autumn");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_WINTER, "Buildjob: Farm, Winter");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_MASTER, "Buildjob: Stockpile, Master");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_LINK_ANYWHERE, "Buildjob: Stockpile, Link/Anywhere");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_GIVE_TO, "Buildjob: Stockpile, Give To");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_WHEELBARROW, "Buildjob: Stockpile, Wheelbarrow");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_DELETE_CHILD, "Buildjob: Stockpile, Delete Child");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_SETTINGS, "Buildjob: Stockpile, Settings");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_UP, "Buildjob: Stockpile, Barrel Up");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_DOWN, "Buildjob: Stockpile, Barrel Down");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_ZERO, "Buildjob: Stockpile, Barrel Zero");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_MAX, "Buildjob: Stockpile, Barrel Max");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_UP, "Buildjob: Stockpile, Bin Up");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_DOWN, "Buildjob: Stockpile, Bin Down");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_ZERO, "Buildjob: Stockpile, Bin Zero");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_MAX, "Buildjob: Stockpile, Bin Max");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BONE, "Buildjob: Rack, Mat, Bone");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BRONZE, "Buildjob: Rack, Mat, Bronze");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_COPPER, "Buildjob: Rack, Mat, Copper");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_IRON, "Buildjob: Rack, Mat, Iron");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_STEEL, "Buildjob: Rack, Mat, Steel");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_WOOD, "Buildjob: Rack, Mat, Wood");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_METAL, "Buildjob: Rack, Mat, Special Metal");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BONE, "Buildjob: Stand, Mat, Bone");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_LEATHER, "Buildjob: Stand, Mat, Leather");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_COPPER, "Buildjob: Stand, Mat, Copper");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BRONZE, "Buildjob: Stand, Mat, Bronze");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_STEEL, "Buildjob: Stand, Mat, Steel");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_IRON, "Buildjob: Stand, Mat, Iron");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_WOOD, "Buildjob: Stand, Mat, Wood");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_METAL, "Buildjob: Stand, Mat, Special Metal");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ASSIGN, "Buildjob: Rackstand, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_FREE, "Buildjob: Rackstand, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_SIZE, "Buildjob: Rackstand, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ITEM, "Buildjob: Rackstand, Item");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_MAT, "Buildjob: Rackstand, Mat");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS1, "Buildjob: Rackstand, All Items");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL1, "Buildjob: Rackstand, No Items");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS2, "Buildjob: Rackstand, All Mats");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL2, "Buildjob: Rackstand, No Mats");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_ENABLE, "Stockpile Settings: Enable");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_DISABLE, "Stockpile Settings: Disable");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_ALL, "Stockpile Settings: Permit All");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_ALL, "Stockpile Settings: Forbid All");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_SUB, "Stockpile Settings: Permit Sub");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_SUB, "Stockpile Settings: Forbit Sub");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC1, "Stockpile Settings: Specific 1");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC2, "Stockpile Settings: Specific 2");
+ displayNames.insert(INTERFACEKEY_MOVIE_RECORD, "Movie: Record");
+ displayNames.insert(INTERFACEKEY_MOVIE_PLAY, "Movie: Play");
+ displayNames.insert(INTERFACEKEY_MOVIE_SAVE, "Movie: Save");
+ displayNames.insert(INTERFACEKEY_MOVIE_LOAD, "Movie: Load");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_VIEW, "Assign Trade: View");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_STRING, "Assign Trade: String");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_EXCLUDE_PROHIBITED, "Assign Trade: Exclude Prohibited");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_PENDING, "Assign Trade: Pending");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_SORT, "Assign Trade: Sort");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_REPLACE, "Noble List: Replace");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_SETTINGS, "Noble List: Settings");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_CAPITAL, "Noble List: Capital");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_VIEW_CANDIDATE, "Noble List: View Candidate");
+ displayNames.insert(INTERFACEKEY_A_BARTER_VIEW, "Adventure: Barter, View");
+ displayNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_1, "Adventure: Barter, Currency 1");
+ displayNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_2, "Adventure: Barter, Currency 2");
+ displayNames.insert(INTERFACEKEY_A_BARTER_TRADE, "Adventure: Barter, Trade");
+ displayNames.insert(INTERFACEKEY_TRADE_VIEW, "Trade, View");
+ displayNames.insert(INTERFACEKEY_TRADE_TRADE, "Trade, Trade");
+ displayNames.insert(INTERFACEKEY_TRADE_OFFER, "Trade, Offer");
+ displayNames.insert(INTERFACEKEY_TRADE_SEIZE, "Trade, Seize");
+ displayNames.insert(INTERFACEKEY_STORES_VIEW, "Stores, View");
+ displayNames.insert(INTERFACEKEY_STORES_FORBID, "Stores, Forbid");
+ displayNames.insert(INTERFACEKEY_STORES_MELT, "Stores, Melt");
+ displayNames.insert(INTERFACEKEY_STORES_DUMP, "Stores, Dump");
+ displayNames.insert(INTERFACEKEY_STORES_ZOOM, "Stores, Zoom");
+ displayNames.insert(INTERFACEKEY_STORES_HIDE, "Stores, Hide");
+ displayNames.insert(INTERFACEKEY_MILITARY_ACTIVATE, "Military, Activate");
+ displayNames.insert(INTERFACEKEY_MILITARY_VIEW, "Military, View");
+ displayNames.insert(INTERFACEKEY_MILITARY_WEAPON, "Military, Weapon");
+ displayNames.insert(INTERFACEKEY_MILITARY_ZOOM, "Military, Zoom");
+ displayNames.insert(INTERFACEKEY_ANNOUNCE_ZOOM, "Announcements, Zoom");
+ displayNames.insert(INTERFACEKEY_UNITJOB_REMOVE_CRE, "Unitjob, Remove Unit");
+ displayNames.insert(INTERFACEKEY_UNITJOB_ZOOM_CRE, "Unitjob, Zoom Unit");
+ displayNames.insert(INTERFACEKEY_UNITJOB_ZOOM_BUILD, "Unitjob, Zoom Building");
+ displayNames.insert(INTERFACEKEY_UNITJOB_VIEW, "Unitjob, View");
+ displayNames.insert(INTERFACEKEY_UNITJOB_MANAGER, "Unitjob, Manager");
+ displayNames.insert(INTERFACEKEY_MANAGER_NEW_ORDER, "Manager, New Order");
+ displayNames.insert(INTERFACEKEY_MANAGER_REMOVE, "Manager, Remove");
+ displayNames.insert(INTERFACEKEY_MANAGER_PROMOTE, "Manager, Promote");
+ displayNames.insert(INTERFACEKEY_MANAGER_MAX, "Manager, Max");
+ displayNames.insert(INTERFACEKEY_MANAGER_WAGES, "Manager, Wages");
+ displayNames.insert(INTERFACEKEY_PET_BUTCHER, "Animals, Slaughter");
+ displayNames.insert(INTERFACEKEY_PET_GELD, "Animals, Geld");
+ displayNames.insert(INTERFACEKEY_ANIMAL_SELECT_TRAINER, "Animals, Trainer");
+ displayNames.insert(INTERFACEKEY_ANIMAL_WAR_TRAINING, "Animals, War Training");
+ displayNames.insert(INTERFACEKEY_ANIMAL_HUNTING_TRAINING, "Animals, Hunting Training");
+ displayNames.insert(INTERFACEKEY_KITCHEN_COOK, "Kitchen, Cook");
+ displayNames.insert(INTERFACEKEY_KITCHEN_BREW, "Kitchen, Brew");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_NEW, "Setup, New");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_VIEW, "Setup, View");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_CUSTOMIZE_UNIT, "Setup, Customize Unit");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE, "Setup, Save Profile");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_ABORT, "Setup, Save Profile, Abort");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_GO, "Setup, Save Profile, Go");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_VIEW_PROFILE_PROBLEMS, "Setup, View Profile Problems");
+ displayNames.insert(INTERFACEKEY_CIVZONE_REMOVE, "Main: Activity Zone, Remove");
+ displayNames.insert(INTERFACEKEY_CIVZONE_REMOVE_ZONE, "Main: Activity Zone, Remove Zone");
+ displayNames.insert(INTERFACEKEY_CIVZONE_SHAPE, "Main: Activity Zone, Shape");
+ displayNames.insert(INTERFACEKEY_CIVZONE_NEXT, "Main: Activity Zone, Next");
+ displayNames.insert(INTERFACEKEY_CIVZONE_WATER_SOURCE, "Main: Activity Zone, Water Source");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER, "Main: Activity Zone, Gather");
+ displayNames.insert(INTERFACEKEY_CIVZONE_DUMP, "Main: Activity Zone, Garbage Dump");
+ displayNames.insert(INTERFACEKEY_CIVZONE_POND, "Main: Activity Zone, Pond");
+ displayNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL, "Main: Activity Zone, Hospital");
+ displayNames.insert(INTERFACEKEY_CIVZONE_SAND_COLLECT, "Main: Activity Zone, Sand Collect");
+ displayNames.insert(INTERFACEKEY_CIVZONE_CLAY_COLLECT, "Main: Activity Zone, Clay Collect");
+ displayNames.insert(INTERFACEKEY_CIVZONE_ACTIVE, "Main: Activity Zone, Active");
+ displayNames.insert(INTERFACEKEY_CIVZONE_FISH, "Main: Activity Zone, Fish");
+ displayNames.insert(INTERFACEKEY_CIVZONE_MEETING, "Main: Activity Zone, Meeting");
+ displayNames.insert(INTERFACEKEY_CIVZONE_ANIMAL_TRAINING, "Main: Activity Zone, Animal Training");
+ displayNames.insert(INTERFACEKEY_CIVZONE_POND_OPTIONS, "Main: Activity Zone, Pond Options");
+ displayNames.insert(INTERFACEKEY_CIVZONE_POND_WATER, "Main: Activity Zone: Pond, Water");
+ displayNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL_OPTIONS, "Main: Activity Zone, Hospital Options");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS, "Main: Activity Zone, Gather Options");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_TREES, "Main: Activity Zone, Gather Options, Pick Trees");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_SHRUBS, "Main: Activity Zone, Gather Options, Pick Shrubs");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_GATHER_FALLEN, "Main: Activity Zone, Gather Options, Gather Fallen");
+ displayNames.insert(INTERFACEKEY_CIVZONE_PEN, "Main: Activity Zone, Pen");
+ displayNames.insert(INTERFACEKEY_CIVZONE_PEN_OPTIONS, "Main: Activity Zone, Pen Options");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_ANIMAL, "Stockpile, Animal");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_FOOD, "Stockpile, Food");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_WEAPON, "Stockpile, Weapon");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_ARMOR, "Stockpile, Armor");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM, "Stockpile, Custom");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM_SETTINGS, "Stockpile, Custom Settings");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_FURNITURE, "Stockpile, Furniture");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_GRAVEYARD, "Stockpile, Corpse");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_REFUSE, "Stockpile, Refuse");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_WOOD, "Stockpile, Wood");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_STONE, "Stockpile, Stone");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_GEM, "Stockpile, Gem");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_BARBLOCK, "Stockpile, Bar/Block");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_CLOTH, "Stockpile, Cloth");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_LEATHER, "Stockpile, Leather");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_AMMO, "Stockpile, Ammo");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_COINS, "Stockpile, Coins");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_FINISHED, "Stockpile, Finished");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_NONE, "Stockpile, None");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_BITEM, "Designate, Building/Item");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_CLAIM, "Designate, Reclaim");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_UNCLAIM, "Designate, Forbid");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_MELT, "Designate, Melt");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_NO_MELT, "Designate, No Melt");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_DUMP, "Designate, Dump");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_NO_DUMP, "Designate, No Dump");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_HIDE, "Designate, Hide");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_NO_HIDE, "Designate, No Hide");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC, "Designate, Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_HIGH, "Designate, High Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_NORMAL, "Designate, Normal Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_LOW, "Designate, Low Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_RESTRICTED, "Designate, Restricted Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT, "Designate, Increase Weight");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT, "Designate, Decrease Weight");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE, "Designate, Increase Weight More");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE, "Designate, Decrease Weight More");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_DIG, "Designate, Dig");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_DIG_REMOVE_STAIRS_RAMPS, "Designate, Dig Remove Stairs Ramps");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UP, "Designate, U Stair");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STAIR_DOWN, "Designate, D Stair");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UPDOWN, "Designate, UD Stair");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_RAMP, "Designate, Ramp");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_CHANNEL, "Designate, Channel");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_CHOP, "Designate, Chop");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_PLANTS, "Designate, Plants");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_SMOOTH, "Designate, Smooth");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_ENGRAVE, "Designate, Engrave");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_FORTIFY, "Designate, Fortify");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRACK, "Designate, Carve Track");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_ENGRAVING, "Designate, Toggle Engraving");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STANDARD_MARKER, "Designate, Standard/Marker");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_MINE_MODE, "Designate, Mine Mode");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_MARKER, "Designate, Toggle Marker");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_UNDO, "Designate, Undo");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_REMOVE_CONSTRUCTION, "Designate, Remove Construction");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_Y_UP, "Building, Change Height +");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_Y_DOWN, "Building, Change Height -");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_X_UP, "Building, Change Width +");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_X_DOWN, "Building, Change Width -");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_UP, "Building, Orient Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_LEFT, "Building, Orient Left");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_RIGHT, "Building, Orient Right");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_DOWN, "Building, Orient Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_NONE, "Building, Orient None");
+ displayNames.insert(INTERFACEKEY_BUILDING_VIEW_ITEM, "Building, View Item");
+ displayNames.insert(INTERFACEKEY_BUILDING_ADVANCE_STAGE, "Building, Done Selecting");
+ displayNames.insert(INTERFACEKEY_BUILDING_EXPAND_CONTRACT, "Building, Expand/Contract");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_WATER, "Building, Trigger, Enable Water");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_UP, "Building, Trigger, Min Water Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_DOWN, "Building, Trigger, Min Water Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_UP, "Building, Trigger, Max Water Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_DOWN, "Building, Trigger, Max Water Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_MAGMA, "Building, Trigger, Enabler Magma");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_UP, "Building, Trigger, Min Magma Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_DOWN, "Building, Trigger, Min Magma Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_UP, "Building, Trigger, Max Magma Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_DOWN, "Building, Trigger, Max Magma Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_TRACK_CART, "Building, Trigger, Enable Cart");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_DOWN, "Building, Trigger, Min Cart Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_UP, "Building, Trigger, Min Cart Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_DOWN, "Building, Trigger, Max Cart Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_UP, "Building, Trigger, Max Cart Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_UP, "Building, Rollers, Speed Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_DOWN, "Building, Rollers, Speed Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_UP, "Building, Track Stop, Friction Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_DOWN, "Building, Track Stop, Friction Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_DUMP, "Building, Track Stop, Dump");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_CREATURE, "Building, Trigger, Enable Creature");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_LOCALS, "Building, Trigger, Enable Locals");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_RESETS, "Building, Trigger, Resets");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP, "Building, Trigger, Min Size Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN, "Building, Trigger, Min Size Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP, "Building, Trigger, Max Size Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN, "Building, Trigger, Max Size Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP_PLUS, "Building, Trigger, Min Size Up+");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS, "Building, Trigger, Min Size Down+");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP_PLUS, "Building, Trigger, Max Size Up+");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS, "Building, Trigger, Max Size Down+");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN, "Unitview, General");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_INV, "Unitview, Inventory");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF, "Unitview, Prefs");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_WND, "Unitview, Wounds");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_NEXT, "Unitview, Next Unit");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_FOLLOW, "Unitview, Follow");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_SLAUGHTER, "Unitview, Slaughter");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GELD, "Unitview, Geld");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN_COMBAT, "Unitview, General, Combat");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN_LABOR, "Unitview, General, Labor");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN_MISC, "Unitview, General, Misc");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_PROF, "Unitview, Prefs, Labor");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_PET, "Unitview, Prefs, Pets");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_VIEW, "Unitview, Prefs, Profile");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_NEW_SQUAD, "Unitview, Prefs, New Squad");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_REMOVE_FROM_SQUAD, "Unitview, Prefs, Remove From Squad");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_CURRENT_SQUAD, "Unitview, Prefs, Name Current Squad");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_SELECTED_SQUAD, "Unitview, Prefs, Name Selected Squad");
+
+ displayNames.insert(INTERFACEKEY_STRING_A000, "String: Backspace");
+ displayNames.insert(INTERFACEKEY_STRING_A001, "String: Character 001");
+ displayNames.insert(INTERFACEKEY_STRING_A002, "String: Character 002");
+ displayNames.insert(INTERFACEKEY_STRING_A003, "String: Character 003");
+ displayNames.insert(INTERFACEKEY_STRING_A004, "String: Character 004");
+ displayNames.insert(INTERFACEKEY_STRING_A005, "String: Character 005");
+ displayNames.insert(INTERFACEKEY_STRING_A006, "String: Character 006");
+ displayNames.insert(INTERFACEKEY_STRING_A007, "String: Character 007");
+ displayNames.insert(INTERFACEKEY_STRING_A008, "String: Character 008");
+ displayNames.insert(INTERFACEKEY_STRING_A009, "String: Character 009");
+ displayNames.insert(INTERFACEKEY_STRING_A010, "String: Character 010");
+ displayNames.insert(INTERFACEKEY_STRING_A011, "String: Character 011");
+ displayNames.insert(INTERFACEKEY_STRING_A012, "String: Character 012");
+ displayNames.insert(INTERFACEKEY_STRING_A013, "String: Character 013");
+ displayNames.insert(INTERFACEKEY_STRING_A014, "String: Character 014");
+ displayNames.insert(INTERFACEKEY_STRING_A015, "String: Character 015");
+ displayNames.insert(INTERFACEKEY_STRING_A016, "String: Character 016");
+ displayNames.insert(INTERFACEKEY_STRING_A017, "String: Character 017");
+ displayNames.insert(INTERFACEKEY_STRING_A018, "String: Character 018");
+ displayNames.insert(INTERFACEKEY_STRING_A019, "String: Character 019");
+ displayNames.insert(INTERFACEKEY_STRING_A020, "String: Character 020");
+ displayNames.insert(INTERFACEKEY_STRING_A021, "String: Character 021");
+ displayNames.insert(INTERFACEKEY_STRING_A022, "String: Character 022");
+ displayNames.insert(INTERFACEKEY_STRING_A023, "String: Character 023");
+ displayNames.insert(INTERFACEKEY_STRING_A024, "String: Character 024");
+ displayNames.insert(INTERFACEKEY_STRING_A025, "String: Character 025");
+ displayNames.insert(INTERFACEKEY_STRING_A026, "String: Character 026");
+ displayNames.insert(INTERFACEKEY_STRING_A027, "String: Character 027");
+ displayNames.insert(INTERFACEKEY_STRING_A028, "String: Character 028");
+ displayNames.insert(INTERFACEKEY_STRING_A029, "String: Character 029");
+ displayNames.insert(INTERFACEKEY_STRING_A030, "String: Character 030");
+ displayNames.insert(INTERFACEKEY_STRING_A031, "String: Character 031");
+ displayNames.insert(INTERFACEKEY_STRING_A032, "String: Character 032");
+ displayNames.insert(INTERFACEKEY_STRING_A033, "String: Character 033");
+ displayNames.insert(INTERFACEKEY_STRING_A034, "String: Character 034");
+ displayNames.insert(INTERFACEKEY_STRING_A035, "String: Character 035");
+ displayNames.insert(INTERFACEKEY_STRING_A036, "String: Character 036");
+ displayNames.insert(INTERFACEKEY_STRING_A037, "String: Character 037");
+ displayNames.insert(INTERFACEKEY_STRING_A038, "String: Character 038");
+ displayNames.insert(INTERFACEKEY_STRING_A039, "String: Character 039");
+ displayNames.insert(INTERFACEKEY_STRING_A040, "String: Character 040");
+ displayNames.insert(INTERFACEKEY_STRING_A041, "String: Character 041");
+ displayNames.insert(INTERFACEKEY_STRING_A042, "String: Character 042");
+ displayNames.insert(INTERFACEKEY_STRING_A043, "String: Character 043");
+ displayNames.insert(INTERFACEKEY_STRING_A044, "String: Character 044");
+ displayNames.insert(INTERFACEKEY_STRING_A045, "String: Character 045");
+ displayNames.insert(INTERFACEKEY_STRING_A046, "String: Character 046");
+ displayNames.insert(INTERFACEKEY_STRING_A047, "String: Character 047");
+ displayNames.insert(INTERFACEKEY_STRING_A048, "String: Character 048");
+ displayNames.insert(INTERFACEKEY_STRING_A049, "String: Character 049");
+ displayNames.insert(INTERFACEKEY_STRING_A050, "String: Character 050");
+ displayNames.insert(INTERFACEKEY_STRING_A051, "String: Character 051");
+ displayNames.insert(INTERFACEKEY_STRING_A052, "String: Character 052");
+ displayNames.insert(INTERFACEKEY_STRING_A053, "String: Character 053");
+ displayNames.insert(INTERFACEKEY_STRING_A054, "String: Character 054");
+ displayNames.insert(INTERFACEKEY_STRING_A055, "String: Character 055");
+ displayNames.insert(INTERFACEKEY_STRING_A056, "String: Character 056");
+ displayNames.insert(INTERFACEKEY_STRING_A057, "String: Character 057");
+ displayNames.insert(INTERFACEKEY_STRING_A058, "String: Character 058");
+ displayNames.insert(INTERFACEKEY_STRING_A059, "String: Character 059");
+ displayNames.insert(INTERFACEKEY_STRING_A060, "String: Character 060");
+ displayNames.insert(INTERFACEKEY_STRING_A061, "String: Character 061");
+ displayNames.insert(INTERFACEKEY_STRING_A062, "String: Character 062");
+ displayNames.insert(INTERFACEKEY_STRING_A063, "String: Character 063");
+ displayNames.insert(INTERFACEKEY_STRING_A064, "String: Character 064");
+ displayNames.insert(INTERFACEKEY_STRING_A065, "String: Character 065");
+ displayNames.insert(INTERFACEKEY_STRING_A066, "String: Character 066");
+ displayNames.insert(INTERFACEKEY_STRING_A067, "String: Character 067");
+ displayNames.insert(INTERFACEKEY_STRING_A068, "String: Character 068");
+ displayNames.insert(INTERFACEKEY_STRING_A069, "String: Character 069");
+ displayNames.insert(INTERFACEKEY_STRING_A070, "String: Character 070");
+ displayNames.insert(INTERFACEKEY_STRING_A071, "String: Character 071");
+ displayNames.insert(INTERFACEKEY_STRING_A072, "String: Character 072");
+ displayNames.insert(INTERFACEKEY_STRING_A073, "String: Character 073");
+ displayNames.insert(INTERFACEKEY_STRING_A074, "String: Character 074");
+ displayNames.insert(INTERFACEKEY_STRING_A075, "String: Character 075");
+ displayNames.insert(INTERFACEKEY_STRING_A076, "String: Character 076");
+ displayNames.insert(INTERFACEKEY_STRING_A077, "String: Character 077");
+ displayNames.insert(INTERFACEKEY_STRING_A078, "String: Character 078");
+ displayNames.insert(INTERFACEKEY_STRING_A079, "String: Character 079");
+ displayNames.insert(INTERFACEKEY_STRING_A080, "String: Character 080");
+ displayNames.insert(INTERFACEKEY_STRING_A081, "String: Character 081");
+ displayNames.insert(INTERFACEKEY_STRING_A082, "String: Character 082");
+ displayNames.insert(INTERFACEKEY_STRING_A083, "String: Character 083");
+ displayNames.insert(INTERFACEKEY_STRING_A084, "String: Character 084");
+ displayNames.insert(INTERFACEKEY_STRING_A085, "String: Character 085");
+ displayNames.insert(INTERFACEKEY_STRING_A086, "String: Character 086");
+ displayNames.insert(INTERFACEKEY_STRING_A087, "String: Character 087");
+ displayNames.insert(INTERFACEKEY_STRING_A088, "String: Character 088");
+ displayNames.insert(INTERFACEKEY_STRING_A089, "String: Character 089");
+ displayNames.insert(INTERFACEKEY_STRING_A090, "String: Character 090");
+ displayNames.insert(INTERFACEKEY_STRING_A091, "String: Character 091");
+ displayNames.insert(INTERFACEKEY_STRING_A092, "String: Character 092");
+ displayNames.insert(INTERFACEKEY_STRING_A093, "String: Character 093");
+ displayNames.insert(INTERFACEKEY_STRING_A094, "String: Character 094");
+ displayNames.insert(INTERFACEKEY_STRING_A095, "String: Character 095");
+ displayNames.insert(INTERFACEKEY_STRING_A096, "String: Character 096");
+ displayNames.insert(INTERFACEKEY_STRING_A097, "String: Character 097");
+ displayNames.insert(INTERFACEKEY_STRING_A098, "String: Character 098");
+ displayNames.insert(INTERFACEKEY_STRING_A099, "String: Character 099");
+ displayNames.insert(INTERFACEKEY_STRING_A100, "String: Character 100");
+ displayNames.insert(INTERFACEKEY_STRING_A101, "String: Character 101");
+ displayNames.insert(INTERFACEKEY_STRING_A102, "String: Character 102");
+ displayNames.insert(INTERFACEKEY_STRING_A103, "String: Character 103");
+ displayNames.insert(INTERFACEKEY_STRING_A104, "String: Character 104");
+ displayNames.insert(INTERFACEKEY_STRING_A105, "String: Character 105");
+ displayNames.insert(INTERFACEKEY_STRING_A106, "String: Character 106");
+ displayNames.insert(INTERFACEKEY_STRING_A107, "String: Character 107");
+ displayNames.insert(INTERFACEKEY_STRING_A108, "String: Character 108");
+ displayNames.insert(INTERFACEKEY_STRING_A109, "String: Character 109");
+ displayNames.insert(INTERFACEKEY_STRING_A110, "String: Character 110");
+ displayNames.insert(INTERFACEKEY_STRING_A111, "String: Character 111");
+ displayNames.insert(INTERFACEKEY_STRING_A112, "String: Character 112");
+ displayNames.insert(INTERFACEKEY_STRING_A113, "String: Character 113");
+ displayNames.insert(INTERFACEKEY_STRING_A114, "String: Character 114");
+ displayNames.insert(INTERFACEKEY_STRING_A115, "String: Character 115");
+ displayNames.insert(INTERFACEKEY_STRING_A116, "String: Character 116");
+ displayNames.insert(INTERFACEKEY_STRING_A117, "String: Character 117");
+ displayNames.insert(INTERFACEKEY_STRING_A118, "String: Character 118");
+ displayNames.insert(INTERFACEKEY_STRING_A119, "String: Character 119");
+ displayNames.insert(INTERFACEKEY_STRING_A120, "String: Character 120");
+ displayNames.insert(INTERFACEKEY_STRING_A121, "String: Character 121");
+ displayNames.insert(INTERFACEKEY_STRING_A122, "String: Character 122");
+ displayNames.insert(INTERFACEKEY_STRING_A123, "String: Character 123");
+ displayNames.insert(INTERFACEKEY_STRING_A124, "String: Character 124");
+ displayNames.insert(INTERFACEKEY_STRING_A125, "String: Character 125");
+ displayNames.insert(INTERFACEKEY_STRING_A126, "String: Character 126");
+ displayNames.insert(INTERFACEKEY_STRING_A128, "String: Character 128");
+ displayNames.insert(INTERFACEKEY_STRING_A129, "String: Character 129");
+ displayNames.insert(INTERFACEKEY_STRING_A130, "String: Character 130");
+ displayNames.insert(INTERFACEKEY_STRING_A131, "String: Character 131");
+ displayNames.insert(INTERFACEKEY_STRING_A132, "String: Character 132");
+ displayNames.insert(INTERFACEKEY_STRING_A133, "String: Character 133");
+ displayNames.insert(INTERFACEKEY_STRING_A134, "String: Character 134");
+ displayNames.insert(INTERFACEKEY_STRING_A135, "String: Character 135");
+ displayNames.insert(INTERFACEKEY_STRING_A136, "String: Character 136");
+ displayNames.insert(INTERFACEKEY_STRING_A137, "String: Character 137");
+ displayNames.insert(INTERFACEKEY_STRING_A138, "String: Character 138");
+ displayNames.insert(INTERFACEKEY_STRING_A139, "String: Character 139");
+ displayNames.insert(INTERFACEKEY_STRING_A140, "String: Character 140");
+ displayNames.insert(INTERFACEKEY_STRING_A141, "String: Character 141");
+ displayNames.insert(INTERFACEKEY_STRING_A142, "String: Character 142");
+ displayNames.insert(INTERFACEKEY_STRING_A143, "String: Character 143");
+ displayNames.insert(INTERFACEKEY_STRING_A144, "String: Character 144");
+ displayNames.insert(INTERFACEKEY_STRING_A145, "String: Character 145");
+ displayNames.insert(INTERFACEKEY_STRING_A146, "String: Character 146");
+ displayNames.insert(INTERFACEKEY_STRING_A147, "String: Character 147");
+ displayNames.insert(INTERFACEKEY_STRING_A148, "String: Character 148");
+ displayNames.insert(INTERFACEKEY_STRING_A149, "String: Character 149");
+ displayNames.insert(INTERFACEKEY_STRING_A150, "String: Character 150");
+ displayNames.insert(INTERFACEKEY_STRING_A151, "String: Character 151");
+ displayNames.insert(INTERFACEKEY_STRING_A152, "String: Character 152");
+ displayNames.insert(INTERFACEKEY_STRING_A153, "String: Character 153");
+ displayNames.insert(INTERFACEKEY_STRING_A154, "String: Character 154");
+ displayNames.insert(INTERFACEKEY_STRING_A155, "String: Character 155");
+ displayNames.insert(INTERFACEKEY_STRING_A156, "String: Character 156");
+ displayNames.insert(INTERFACEKEY_STRING_A157, "String: Character 157");
+ displayNames.insert(INTERFACEKEY_STRING_A158, "String: Character 158");
+ displayNames.insert(INTERFACEKEY_STRING_A159, "String: Character 159");
+ displayNames.insert(INTERFACEKEY_STRING_A160, "String: Character 160");
+ displayNames.insert(INTERFACEKEY_STRING_A161, "String: Character 161");
+ displayNames.insert(INTERFACEKEY_STRING_A162, "String: Character 162");
+ displayNames.insert(INTERFACEKEY_STRING_A163, "String: Character 163");
+ displayNames.insert(INTERFACEKEY_STRING_A164, "String: Character 164");
+ displayNames.insert(INTERFACEKEY_STRING_A165, "String: Character 165");
+ displayNames.insert(INTERFACEKEY_STRING_A166, "String: Character 166");
+ displayNames.insert(INTERFACEKEY_STRING_A167, "String: Character 167");
+ displayNames.insert(INTERFACEKEY_STRING_A168, "String: Character 168");
+ displayNames.insert(INTERFACEKEY_STRING_A169, "String: Character 169");
+ displayNames.insert(INTERFACEKEY_STRING_A170, "String: Character 170");
+ displayNames.insert(INTERFACEKEY_STRING_A171, "String: Character 171");
+ displayNames.insert(INTERFACEKEY_STRING_A172, "String: Character 172");
+ displayNames.insert(INTERFACEKEY_STRING_A173, "String: Character 173");
+ displayNames.insert(INTERFACEKEY_STRING_A174, "String: Character 174");
+ displayNames.insert(INTERFACEKEY_STRING_A175, "String: Character 175");
+ displayNames.insert(INTERFACEKEY_STRING_A176, "String: Character 176");
+ displayNames.insert(INTERFACEKEY_STRING_A177, "String: Character 177");
+ displayNames.insert(INTERFACEKEY_STRING_A178, "String: Character 178");
+ displayNames.insert(INTERFACEKEY_STRING_A179, "String: Character 179");
+ displayNames.insert(INTERFACEKEY_STRING_A180, "String: Character 180");
+ displayNames.insert(INTERFACEKEY_STRING_A181, "String: Character 181");
+ displayNames.insert(INTERFACEKEY_STRING_A182, "String: Character 182");
+ displayNames.insert(INTERFACEKEY_STRING_A183, "String: Character 183");
+ displayNames.insert(INTERFACEKEY_STRING_A184, "String: Character 184");
+ displayNames.insert(INTERFACEKEY_STRING_A185, "String: Character 185");
+ displayNames.insert(INTERFACEKEY_STRING_A186, "String: Character 186");
+ displayNames.insert(INTERFACEKEY_STRING_A187, "String: Character 187");
+ displayNames.insert(INTERFACEKEY_STRING_A188, "String: Character 188");
+ displayNames.insert(INTERFACEKEY_STRING_A189, "String: Character 189");
+ displayNames.insert(INTERFACEKEY_STRING_A190, "String: Character 190");
+ displayNames.insert(INTERFACEKEY_STRING_A191, "String: Character 191");
+ displayNames.insert(INTERFACEKEY_STRING_A192, "String: Character 192");
+ displayNames.insert(INTERFACEKEY_STRING_A193, "String: Character 193");
+ displayNames.insert(INTERFACEKEY_STRING_A194, "String: Character 194");
+ displayNames.insert(INTERFACEKEY_STRING_A195, "String: Character 195");
+ displayNames.insert(INTERFACEKEY_STRING_A196, "String: Character 196");
+ displayNames.insert(INTERFACEKEY_STRING_A197, "String: Character 197");
+ displayNames.insert(INTERFACEKEY_STRING_A198, "String: Character 198");
+ displayNames.insert(INTERFACEKEY_STRING_A199, "String: Character 199");
+ displayNames.insert(INTERFACEKEY_STRING_A200, "String: Character 200");
+ displayNames.insert(INTERFACEKEY_STRING_A201, "String: Character 201");
+ displayNames.insert(INTERFACEKEY_STRING_A202, "String: Character 202");
+ displayNames.insert(INTERFACEKEY_STRING_A203, "String: Character 203");
+ displayNames.insert(INTERFACEKEY_STRING_A204, "String: Character 204");
+ displayNames.insert(INTERFACEKEY_STRING_A205, "String: Character 205");
+ displayNames.insert(INTERFACEKEY_STRING_A206, "String: Character 206");
+ displayNames.insert(INTERFACEKEY_STRING_A207, "String: Character 207");
+ displayNames.insert(INTERFACEKEY_STRING_A208, "String: Character 208");
+ displayNames.insert(INTERFACEKEY_STRING_A209, "String: Character 209");
+ displayNames.insert(INTERFACEKEY_STRING_A210, "String: Character 210");
+ displayNames.insert(INTERFACEKEY_STRING_A211, "String: Character 211");
+ displayNames.insert(INTERFACEKEY_STRING_A212, "String: Character 212");
+ displayNames.insert(INTERFACEKEY_STRING_A213, "String: Character 213");
+ displayNames.insert(INTERFACEKEY_STRING_A214, "String: Character 214");
+ displayNames.insert(INTERFACEKEY_STRING_A215, "String: Character 215");
+ displayNames.insert(INTERFACEKEY_STRING_A216, "String: Character 216");
+ displayNames.insert(INTERFACEKEY_STRING_A217, "String: Character 217");
+ displayNames.insert(INTERFACEKEY_STRING_A218, "String: Character 218");
+ displayNames.insert(INTERFACEKEY_STRING_A219, "String: Character 219");
+ displayNames.insert(INTERFACEKEY_STRING_A220, "String: Character 220");
+ displayNames.insert(INTERFACEKEY_STRING_A221, "String: Character 221");
+ displayNames.insert(INTERFACEKEY_STRING_A222, "String: Character 222");
+ displayNames.insert(INTERFACEKEY_STRING_A223, "String: Character 223");
+ displayNames.insert(INTERFACEKEY_STRING_A224, "String: Character 224");
+ displayNames.insert(INTERFACEKEY_STRING_A225, "String: Character 225");
+ displayNames.insert(INTERFACEKEY_STRING_A226, "String: Character 226");
+ displayNames.insert(INTERFACEKEY_STRING_A227, "String: Character 227");
+ displayNames.insert(INTERFACEKEY_STRING_A228, "String: Character 228");
+ displayNames.insert(INTERFACEKEY_STRING_A229, "String: Character 229");
+ displayNames.insert(INTERFACEKEY_STRING_A230, "String: Character 230");
+ displayNames.insert(INTERFACEKEY_STRING_A231, "String: Character 231");
+ displayNames.insert(INTERFACEKEY_STRING_A232, "String: Character 232");
+ displayNames.insert(INTERFACEKEY_STRING_A233, "String: Character 233");
+ displayNames.insert(INTERFACEKEY_STRING_A234, "String: Character 234");
+ displayNames.insert(INTERFACEKEY_STRING_A235, "String: Character 235");
+ displayNames.insert(INTERFACEKEY_STRING_A236, "String: Character 236");
+ displayNames.insert(INTERFACEKEY_STRING_A237, "String: Character 237");
+ displayNames.insert(INTERFACEKEY_STRING_A238, "String: Character 238");
+ displayNames.insert(INTERFACEKEY_STRING_A239, "String: Character 239");
+ displayNames.insert(INTERFACEKEY_STRING_A240, "String: Character 240");
+ displayNames.insert(INTERFACEKEY_STRING_A241, "String: Character 241");
+ displayNames.insert(INTERFACEKEY_STRING_A242, "String: Character 242");
+ displayNames.insert(INTERFACEKEY_STRING_A243, "String: Character 243");
+ displayNames.insert(INTERFACEKEY_STRING_A244, "String: Character 244");
+ displayNames.insert(INTERFACEKEY_STRING_A245, "String: Character 245");
+ displayNames.insert(INTERFACEKEY_STRING_A246, "String: Character 246");
+ displayNames.insert(INTERFACEKEY_STRING_A247, "String: Character 247");
+ displayNames.insert(INTERFACEKEY_STRING_A248, "String: Character 248");
+ displayNames.insert(INTERFACEKEY_STRING_A249, "String: Character 249");
+ displayNames.insert(INTERFACEKEY_STRING_A250, "String: Character 250");
+ displayNames.insert(INTERFACEKEY_STRING_A251, "String: Character 251");
+ displayNames.insert(INTERFACEKEY_STRING_A252, "String: Character 252");
+ displayNames.insert(INTERFACEKEY_STRING_A253, "String: Character 253");
+ displayNames.insert(INTERFACEKEY_STRING_A254, "String: Character 254");
+ displayNames.insert(INTERFACEKEY_STRING_A255, "String: Character 255");
+ displayNames.insert(INTERFACEKEY_CUSTOM_A, "Custom: A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_B, "Custom: B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_C, "Custom: C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_D, "Custom: D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_E, "Custom: E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_F, "Custom: F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_G, "Custom: G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_H, "Custom: H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_I, "Custom: I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_J, "Custom: J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_K, "Custom: K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_L, "Custom: L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_M, "Custom: M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_N, "Custom: N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_O, "Custom: O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_P, "Custom: P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_Q, "Custom: Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_R, "Custom: R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_S, "Custom: S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_T, "Custom: T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_U, "Custom: U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_V, "Custom: V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_W, "Custom: W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_X, "Custom: X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_Y, "Custom: Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_Z, "Custom: Z");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_A, "Custom: Shift + A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_B, "Custom: Shift + B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_C, "Custom: Shift + C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_D, "Custom: Shift + D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_E, "Custom: Shift + E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_F, "Custom: Shift + F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_G, "Custom: Shift + G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_H, "Custom: Shift + H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_I, "Custom: Shift + I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_J, "Custom: Shift + J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_K, "Custom: Shift + K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_L, "Custom: Shift + L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_M, "Custom: Shift + M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_N, "Custom: Shift + N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_O, "Custom: Shift + O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_P, "Custom: Shift + P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Q, "Custom: Shift + Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_R, "Custom: Shift + R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_S, "Custom: Shift + S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_T, "Custom: Shift + T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_U, "Custom: Shift + U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_V, "Custom: Shift + V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_W, "Custom: Shift + W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_X, "Custom: Shift + X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Y, "Custom: Shift + Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Z, "Custom: Shift + Z");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_A, "Custom: Ctrl + A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_B, "Custom: Ctrl + B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_C, "Custom: Ctrl + C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_D, "Custom: Ctrl + D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_E, "Custom: Ctrl + E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_F, "Custom: Ctrl + F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_G, "Custom: Ctrl + G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_H, "Custom: Ctrl + H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_I, "Custom: Ctrl + I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_J, "Custom: Ctrl + J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_K, "Custom: Ctrl + K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_L, "Custom: Ctrl + L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_M, "Custom: Ctrl + M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_N, "Custom: Ctrl + N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_O, "Custom: Ctrl + O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_P, "Custom: Ctrl + P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_Q, "Custom: Ctrl + Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_R, "Custom: Ctrl + R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_S, "Custom: Ctrl + S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_T, "Custom: Ctrl + T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_U, "Custom: Ctrl + U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_V, "Custom: Ctrl + V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_W, "Custom: Ctrl + W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_X, "Custom: Ctrl + X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_Y, "Custom: Ctrl + Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_Z, "Custom: Ctrl + Z");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_A, "Custom: Alt + A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_B, "Custom: Alt + B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_C, "Custom: Alt + C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_D, "Custom: Alt + D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_E, "Custom: Alt + E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_F, "Custom: Alt + F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_G, "Custom: Alt + G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_H, "Custom: Alt + H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_I, "Custom: Alt + I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_J, "Custom: Alt + J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_K, "Custom: Alt + K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_L, "Custom: Alt + L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_M, "Custom: Alt + M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_N, "Custom: Alt + N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_O, "Custom: Alt + O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_P, "Custom: Alt + P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_Q, "Custom: Alt + Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_R, "Custom: Alt + R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_S, "Custom: Alt + S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_T, "Custom: Alt + T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_U, "Custom: Alt + U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_V, "Custom: Alt + V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_W, "Custom: Alt + W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_X, "Custom: Alt + X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_Y, "Custom: Alt + Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_Z, "Custom: Alt + Z");
+ displayNames.insert(INTERFACEKEY_FPS_UP, "Increase FPS limit");
+ displayNames.insert(INTERFACEKEY_FPS_DOWN, "Decrease FPS limit");
+ displayNames.insert(INTERFACEKEY_TOGGLE_TTF, "Toggle Truetype rendering");
+ displayNames.insert(INTERFACEKEY_PREFIX, "Command repeat prefix-key");
+
+
+ sdlNames.insert(SDLK_BACKSPACE, "Backspace");
+ sdlNames.insert(SDLK_TAB, "Tab");
+ sdlNames.insert(SDLK_CLEAR, "Clear");
+ sdlNames.insert(SDLK_RETURN, "Enter");
+ sdlNames.insert(SDLK_PAUSE, "Pause");
+ sdlNames.insert(SDLK_ESCAPE, "ESC");
+ sdlNames.insert(SDLK_SPACE, "Space");
+ sdlNames.insert(SDLK_EXCLAIM, "Exclaim");
+ sdlNames.insert(SDLK_QUOTEDBL, "Quotedbl");
+ sdlNames.insert(SDLK_HASH, "Hash");
+ sdlNames.insert(SDLK_DOLLAR, "Dollar");
+ sdlNames.insert(SDLK_AMPERSAND, "Ampersand");
+ sdlNames.insert(SDLK_QUOTE, "Quote");
+ sdlNames.insert(SDLK_LEFTPAREN, "Leftparen");
+ sdlNames.insert(SDLK_RIGHTPAREN, "Rightparen");
+ sdlNames.insert(SDLK_ASTERISK, "Asterisk");
+ sdlNames.insert(SDLK_PLUS, "Plus");
+ sdlNames.insert(SDLK_COMMA, "Comma");
+ sdlNames.insert(SDLK_MINUS, "Minus");
+ sdlNames.insert(SDLK_PERIOD, "Period");
+ sdlNames.insert(SDLK_SLASH, "Slash");
+ sdlNames.insert(SDLK_0, "0");
+ sdlNames.insert(SDLK_1, "1");
+ sdlNames.insert(SDLK_2, "2");
+ sdlNames.insert(SDLK_3, "3");
+ sdlNames.insert(SDLK_4, "4");
+ sdlNames.insert(SDLK_5, "5");
+ sdlNames.insert(SDLK_6, "6");
+ sdlNames.insert(SDLK_7, "7");
+ sdlNames.insert(SDLK_8, "8");
+ sdlNames.insert(SDLK_9, "9");
+ sdlNames.insert(SDLK_COLON, "Colon");
+ sdlNames.insert(SDLK_SEMICOLON, "Semicolon");
+ sdlNames.insert(SDLK_LESS, "Less");
+ sdlNames.insert(SDLK_EQUALS, "Equals");
+ sdlNames.insert(SDLK_GREATER, "Greater");
+ sdlNames.insert(SDLK_QUESTION, "Question");
+ sdlNames.insert(SDLK_AT, "At");
+ sdlNames.insert(SDLK_LEFTBRACKET, "Leftbracket");
+ sdlNames.insert(SDLK_BACKSLASH, "Backslash");
+ sdlNames.insert(SDLK_RIGHTBRACKET, "Rightbracket");
+ sdlNames.insert(SDLK_CARET, "Caret");
+ sdlNames.insert(SDLK_UNDERSCORE, "Underscore");
+ sdlNames.insert(SDLK_BACKQUOTE, "Backquote");
+ sdlNames.insert(SDLK_a, "a");
+ sdlNames.insert(SDLK_b, "b");
+ sdlNames.insert(SDLK_c, "c");
+ sdlNames.insert(SDLK_d, "d");
+ sdlNames.insert(SDLK_e, "e");
+ sdlNames.insert(SDLK_f, "f");
+ sdlNames.insert(SDLK_g, "g");
+ sdlNames.insert(SDLK_h, "h");
+ sdlNames.insert(SDLK_i, "i");
+ sdlNames.insert(SDLK_j, "j");
+ sdlNames.insert(SDLK_k, "k");
+ sdlNames.insert(SDLK_l, "l");
+ sdlNames.insert(SDLK_m, "m");
+ sdlNames.insert(SDLK_n, "n");
+ sdlNames.insert(SDLK_o, "o");
+ sdlNames.insert(SDLK_p, "p");
+ sdlNames.insert(SDLK_q, "q");
+ sdlNames.insert(SDLK_r, "r");
+ sdlNames.insert(SDLK_s, "s");
+ sdlNames.insert(SDLK_t, "t");
+ sdlNames.insert(SDLK_u, "u");
+ sdlNames.insert(SDLK_v, "v");
+ sdlNames.insert(SDLK_w, "w");
+ sdlNames.insert(SDLK_x, "x");
+ sdlNames.insert(SDLK_y, "y");
+ sdlNames.insert(SDLK_z, "z");
+ sdlNames.insert(SDLK_DELETE, "Delete");
+ sdlNames.insert(SDLK_KP0, "Numpad 0");
+ sdlNames.insert(SDLK_KP1, "Numpad 1");
+ sdlNames.insert(SDLK_KP2, "Numpad 2");
+ sdlNames.insert(SDLK_KP3, "Numpad 3");
+ sdlNames.insert(SDLK_KP4, "Numpad 4");
+ sdlNames.insert(SDLK_KP5, "Numpad 5");
+ sdlNames.insert(SDLK_KP6, "Numpad 6");
+ sdlNames.insert(SDLK_KP7, "Numpad 7");
+ sdlNames.insert(SDLK_KP8, "Numpad 8");
+ sdlNames.insert(SDLK_KP9, "Numpad 9");
+ sdlNames.insert(SDLK_KP_PERIOD, "Numpad Period");
+ sdlNames.insert(SDLK_KP_DIVIDE, "Numpad Divide");
+ sdlNames.insert(SDLK_KP_MULTIPLY, "Numpad Multiply");
+ sdlNames.insert(SDLK_KP_PLUS, "Numpad Plus");
+ sdlNames.insert(SDLK_KP_MINUS, "Numpad Minus");
+ sdlNames.insert(SDLK_KP_ENTER, "Numpad Enter");
+ sdlNames.insert(SDLK_KP_EQUALS, "Numpad Equals");
+ sdlNames.insert(SDLK_UP, "Up");
+ sdlNames.insert(SDLK_DOWN, "Down");
+ sdlNames.insert(SDLK_RIGHT, "Right");
+ sdlNames.insert(SDLK_LEFT, "Left");
+ sdlNames.insert(SDLK_INSERT, "Insert");
+ sdlNames.insert(SDLK_HOME, "Home");
+ sdlNames.insert(SDLK_END, "End");
+ sdlNames.insert(SDLK_PAGEUP, "Page Up");
+ sdlNames.insert(SDLK_PAGEDOWN, "Page Down");
+ sdlNames.insert(SDLK_F1, "F1");
+ sdlNames.insert(SDLK_F2, "F2");
+ sdlNames.insert(SDLK_F3, "F3");
+ sdlNames.insert(SDLK_F4, "F4");
+ sdlNames.insert(SDLK_F5, "F5");
+ sdlNames.insert(SDLK_F6, "F6");
+ sdlNames.insert(SDLK_F7, "F7");
+ sdlNames.insert(SDLK_F8, "F8");
+ sdlNames.insert(SDLK_F9, "F9");
+ sdlNames.insert(SDLK_F10, "F10");
+ sdlNames.insert(SDLK_F11, "F11");
+ sdlNames.insert(SDLK_F12, "F12");
+ sdlNames.insert(SDLK_F13, "F13");
+ sdlNames.insert(SDLK_F14, "F14");
+ sdlNames.insert(SDLK_F15, "F15");
+ sdlNames.insert(SDLK_NUMLOCK, "Numlock");
+ sdlNames.insert(SDLK_CAPSLOCK, "Capslock");
+ sdlNames.insert(SDLK_SCROLLOCK, "Scrollock");
+ sdlNames.insert(SDLK_RSHIFT, "Rshift");
+ sdlNames.insert(SDLK_LSHIFT, "Lshift");
+ sdlNames.insert(SDLK_RCTRL, "Rctrl");
+ sdlNames.insert(SDLK_LCTRL, "Lctrl");
+ sdlNames.insert(SDLK_RALT, "Ralt");
+ sdlNames.insert(SDLK_LALT, "Lalt");
+ sdlNames.insert(SDLK_RMETA, "Rmeta");
+ sdlNames.insert(SDLK_LMETA, "Lmeta");
+ sdlNames.insert(SDLK_LSUPER, "Lsuper");
+ sdlNames.insert(SDLK_RSUPER, "Rsuper");
+ sdlNames.insert(SDLK_MODE, "Mode");
+ sdlNames.insert(SDLK_COMPOSE, "Compose");
+ sdlNames.insert(SDLK_HELP, "Help");
+ sdlNames.insert(SDLK_PRINT, "Print");
+ sdlNames.insert(SDLK_SYSREQ, "Sysreq");
+ sdlNames.insert(SDLK_BREAK, "Break");
+ sdlNames.insert(SDLK_MENU, "Menu");
+ sdlNames.insert(SDLK_POWER, "Power");
+ sdlNames.insert(SDLK_EURO, "Euro");
+ sdlNames.insert(SDLK_UNDO, "Undo");
+}
diff --git a/g_src/keybindings.h b/g_src/keybindings.h new file mode 100755 index 0000000..f1c9a95 --- /dev/null +++ b/g_src/keybindings.h @@ -0,0 +1,1524 @@ +#ifndef KEYBINDINGS_H
+#define KEYBINDINGS_H
+
+#include <SDL/SDL.h>
+#include <map>
+#include <string>
+
+#include "bimap.h"
+
+typedef long InterfaceKey;
+
+enum InterfaceKeyType
+{
+ INTERFACEKEY_NONE=0,
+ INTERFACEKEY_SELECT,
+ INTERFACEKEY_SEC_SELECT,
+ INTERFACEKEY_DESELECT,
+ INTERFACEKEY_SELECT_ALL,
+ INTERFACEKEY_DESELECT_ALL,
+ INTERFACEKEY_LEAVESCREEN,
+ INTERFACEKEY_LEAVESCREEN_ALL,
+ INTERFACEKEY_CLOSE_MEGA_ANNOUNCEMENT,
+ INTERFACEKEY_OPTIONS,
+ INTERFACEKEY_OPTION_EXPORT,
+ INTERFACEKEY_HELP,
+ INTERFACEKEY_TOGGLE_FULLSCREEN,
+ INTERFACEKEY_MOVIES,
+ INTERFACEKEY_ZOOM_IN,
+ INTERFACEKEY_ZOOM_OUT,
+ INTERFACEKEY_ZOOM_TOGGLE,
+ INTERFACEKEY_ZOOM_RESET,
+ INTERFACEKEY_MOVIE_RECORD,
+ INTERFACEKEY_MOVIE_PLAY,
+ INTERFACEKEY_MOVIE_SAVE,
+ INTERFACEKEY_MOVIE_LOAD,
+ INTERFACEKEY_TOGGLE_TTF,
+ INTERFACEKEY_FPS_UP,
+ INTERFACEKEY_FPS_DOWN,
+ INTERFACEKEY_CHANGETAB,
+ INTERFACEKEY_SEC_CHANGETAB,
+ INTERFACEKEY_STANDARDSCROLL_UP,
+ INTERFACEKEY_STANDARDSCROLL_DOWN,
+ INTERFACEKEY_STANDARDSCROLL_LEFT,
+ INTERFACEKEY_STANDARDSCROLL_RIGHT,
+ INTERFACEKEY_STANDARDSCROLL_PAGEUP,
+ INTERFACEKEY_STANDARDSCROLL_PAGEDOWN,
+ INTERFACEKEY_SECONDSCROLL_UP,
+ INTERFACEKEY_SECONDSCROLL_DOWN,
+ INTERFACEKEY_SECONDSCROLL_PAGEUP,
+ INTERFACEKEY_SECONDSCROLL_PAGEDOWN,
+ INTERFACEKEY_CURSOR_UP,
+ INTERFACEKEY_CURSOR_DOWN,
+ INTERFACEKEY_CURSOR_LEFT,
+ INTERFACEKEY_CURSOR_RIGHT,
+ INTERFACEKEY_CURSOR_UPLEFT,
+ INTERFACEKEY_CURSOR_UPRIGHT,
+ INTERFACEKEY_CURSOR_DOWNLEFT,
+ INTERFACEKEY_CURSOR_DOWNRIGHT,
+ INTERFACEKEY_CURSOR_UP_FAST,
+ INTERFACEKEY_CURSOR_DOWN_FAST,
+ INTERFACEKEY_CURSOR_LEFT_FAST,
+ INTERFACEKEY_CURSOR_RIGHT_FAST,
+ INTERFACEKEY_CURSOR_UPLEFT_FAST,
+ INTERFACEKEY_CURSOR_UPRIGHT_FAST,
+ INTERFACEKEY_CURSOR_DOWNLEFT_FAST,
+ INTERFACEKEY_CURSOR_DOWNRIGHT_FAST,
+ INTERFACEKEY_CURSOR_UP_Z,
+ INTERFACEKEY_CURSOR_DOWN_Z,
+ INTERFACEKEY_CURSOR_UP_Z_AUX,
+ INTERFACEKEY_CURSOR_DOWN_Z_AUX,
+ INTERFACEKEY_MENU_CONFIRM,
+ INTERFACEKEY_SAVE_BINDINGS,
+ INTERFACEKEY_LOAD_BINDINGS,
+ INTERFACEKEY_MACRO_BREAK,
+ INTERFACEKEY_RECORD_MACRO,
+ INTERFACEKEY_PLAY_MACRO,
+ INTERFACEKEY_SAVE_MACRO,
+ INTERFACEKEY_LOAD_MACRO,
+ INTERFACEKEY_PREFIX,
+ INTERFACEKEY_OPTION1,
+ INTERFACEKEY_OPTION2,
+ INTERFACEKEY_OPTION3,
+ INTERFACEKEY_OPTION4,
+ INTERFACEKEY_OPTION5,
+ INTERFACEKEY_OPTION6,
+ INTERFACEKEY_OPTION7,
+ INTERFACEKEY_OPTION8,
+ INTERFACEKEY_OPTION9,
+ INTERFACEKEY_OPTION10,
+ INTERFACEKEY_OPTION11,
+ INTERFACEKEY_OPTION12,
+ INTERFACEKEY_OPTION13,
+ INTERFACEKEY_OPTION14,
+ INTERFACEKEY_OPTION15,
+ INTERFACEKEY_OPTION16,
+ INTERFACEKEY_OPTION17,
+ INTERFACEKEY_OPTION18,
+ INTERFACEKEY_OPTION19,
+ INTERFACEKEY_OPTION20,
+ INTERFACEKEY_SEC_OPTION1,
+ INTERFACEKEY_SEC_OPTION2,
+ INTERFACEKEY_SEC_OPTION3,
+ INTERFACEKEY_SEC_OPTION4,
+ INTERFACEKEY_SEC_OPTION5,
+ INTERFACEKEY_SEC_OPTION6,
+ INTERFACEKEY_SEC_OPTION7,
+ INTERFACEKEY_SEC_OPTION8,
+ INTERFACEKEY_SEC_OPTION9,
+ INTERFACEKEY_SEC_OPTION10,
+ INTERFACEKEY_SEC_OPTION11,
+ INTERFACEKEY_SEC_OPTION12,
+ INTERFACEKEY_SEC_OPTION13,
+ INTERFACEKEY_SEC_OPTION14,
+ INTERFACEKEY_SEC_OPTION15,
+ INTERFACEKEY_SEC_OPTION16,
+ INTERFACEKEY_SEC_OPTION17,
+ INTERFACEKEY_SEC_OPTION18,
+ INTERFACEKEY_SEC_OPTION19,
+ INTERFACEKEY_SEC_OPTION20,
+ INTERFACEKEY_CUSTOM_A,
+ INTERFACEKEY_CUSTOM_B,
+ INTERFACEKEY_CUSTOM_C,
+ INTERFACEKEY_CUSTOM_D,
+ INTERFACEKEY_CUSTOM_E,
+ INTERFACEKEY_CUSTOM_F,
+ INTERFACEKEY_CUSTOM_G,
+ INTERFACEKEY_CUSTOM_H,
+ INTERFACEKEY_CUSTOM_I,
+ INTERFACEKEY_CUSTOM_J,
+ INTERFACEKEY_CUSTOM_K,
+ INTERFACEKEY_CUSTOM_L,
+ INTERFACEKEY_CUSTOM_M,
+ INTERFACEKEY_CUSTOM_N,
+ INTERFACEKEY_CUSTOM_O,
+ INTERFACEKEY_CUSTOM_P,
+ INTERFACEKEY_CUSTOM_Q,
+ INTERFACEKEY_CUSTOM_R,
+ INTERFACEKEY_CUSTOM_S,
+ INTERFACEKEY_CUSTOM_T,
+ INTERFACEKEY_CUSTOM_U,
+ INTERFACEKEY_CUSTOM_V,
+ INTERFACEKEY_CUSTOM_W,
+ INTERFACEKEY_CUSTOM_X,
+ INTERFACEKEY_CUSTOM_Y,
+ INTERFACEKEY_CUSTOM_Z,
+ INTERFACEKEY_CUSTOM_SHIFT_A,
+ INTERFACEKEY_CUSTOM_SHIFT_B,
+ INTERFACEKEY_CUSTOM_SHIFT_C,
+ INTERFACEKEY_CUSTOM_SHIFT_D,
+ INTERFACEKEY_CUSTOM_SHIFT_E,
+ INTERFACEKEY_CUSTOM_SHIFT_F,
+ INTERFACEKEY_CUSTOM_SHIFT_G,
+ INTERFACEKEY_CUSTOM_SHIFT_H,
+ INTERFACEKEY_CUSTOM_SHIFT_I,
+ INTERFACEKEY_CUSTOM_SHIFT_J,
+ INTERFACEKEY_CUSTOM_SHIFT_K,
+ INTERFACEKEY_CUSTOM_SHIFT_L,
+ INTERFACEKEY_CUSTOM_SHIFT_M,
+ INTERFACEKEY_CUSTOM_SHIFT_N,
+ INTERFACEKEY_CUSTOM_SHIFT_O,
+ INTERFACEKEY_CUSTOM_SHIFT_P,
+ INTERFACEKEY_CUSTOM_SHIFT_Q,
+ INTERFACEKEY_CUSTOM_SHIFT_R,
+ INTERFACEKEY_CUSTOM_SHIFT_S,
+ INTERFACEKEY_CUSTOM_SHIFT_T,
+ INTERFACEKEY_CUSTOM_SHIFT_U,
+ INTERFACEKEY_CUSTOM_SHIFT_V,
+ INTERFACEKEY_CUSTOM_SHIFT_W,
+ INTERFACEKEY_CUSTOM_SHIFT_X,
+ INTERFACEKEY_CUSTOM_SHIFT_Y,
+ INTERFACEKEY_CUSTOM_SHIFT_Z,
+ INTERFACEKEY_CUSTOM_CTRL_A,
+ INTERFACEKEY_CUSTOM_CTRL_B,
+ INTERFACEKEY_CUSTOM_CTRL_C,
+ INTERFACEKEY_CUSTOM_CTRL_D,
+ INTERFACEKEY_CUSTOM_CTRL_E,
+ INTERFACEKEY_CUSTOM_CTRL_F,
+ INTERFACEKEY_CUSTOM_CTRL_G,
+ INTERFACEKEY_CUSTOM_CTRL_H,
+ INTERFACEKEY_CUSTOM_CTRL_I,
+ INTERFACEKEY_CUSTOM_CTRL_J,
+ INTERFACEKEY_CUSTOM_CTRL_K,
+ INTERFACEKEY_CUSTOM_CTRL_L,
+ INTERFACEKEY_CUSTOM_CTRL_M,
+ INTERFACEKEY_CUSTOM_CTRL_N,
+ INTERFACEKEY_CUSTOM_CTRL_O,
+ INTERFACEKEY_CUSTOM_CTRL_P,
+ INTERFACEKEY_CUSTOM_CTRL_Q,
+ INTERFACEKEY_CUSTOM_CTRL_R,
+ INTERFACEKEY_CUSTOM_CTRL_S,
+ INTERFACEKEY_CUSTOM_CTRL_T,
+ INTERFACEKEY_CUSTOM_CTRL_U,
+ INTERFACEKEY_CUSTOM_CTRL_V,
+ INTERFACEKEY_CUSTOM_CTRL_W,
+ INTERFACEKEY_CUSTOM_CTRL_X,
+ INTERFACEKEY_CUSTOM_CTRL_Y,
+ INTERFACEKEY_CUSTOM_CTRL_Z,
+ INTERFACEKEY_CUSTOM_ALT_A,
+ INTERFACEKEY_CUSTOM_ALT_B,
+ INTERFACEKEY_CUSTOM_ALT_C,
+ INTERFACEKEY_CUSTOM_ALT_D,
+ INTERFACEKEY_CUSTOM_ALT_E,
+ INTERFACEKEY_CUSTOM_ALT_F,
+ INTERFACEKEY_CUSTOM_ALT_G,
+ INTERFACEKEY_CUSTOM_ALT_H,
+ INTERFACEKEY_CUSTOM_ALT_I,
+ INTERFACEKEY_CUSTOM_ALT_J,
+ INTERFACEKEY_CUSTOM_ALT_K,
+ INTERFACEKEY_CUSTOM_ALT_L,
+ INTERFACEKEY_CUSTOM_ALT_M,
+ INTERFACEKEY_CUSTOM_ALT_N,
+ INTERFACEKEY_CUSTOM_ALT_O,
+ INTERFACEKEY_CUSTOM_ALT_P,
+ INTERFACEKEY_CUSTOM_ALT_Q,
+ INTERFACEKEY_CUSTOM_ALT_R,
+ INTERFACEKEY_CUSTOM_ALT_S,
+ INTERFACEKEY_CUSTOM_ALT_T,
+ INTERFACEKEY_CUSTOM_ALT_U,
+ INTERFACEKEY_CUSTOM_ALT_V,
+ INTERFACEKEY_CUSTOM_ALT_W,
+ INTERFACEKEY_CUSTOM_ALT_X,
+ INTERFACEKEY_CUSTOM_ALT_Y,
+ INTERFACEKEY_CUSTOM_ALT_Z,
+
+ WORLDKEY_START,
+ INTERFACEKEY_WORLD_PARAM_TITLE=WORLDKEY_START,
+ INTERFACEKEY_WORLD_PARAM_ADD,
+ INTERFACEKEY_WORLD_PARAM_COPY,
+ INTERFACEKEY_WORLD_PARAM_DELETE,
+ INTERFACEKEY_WORLD_PARAM_NAME_RANDOM,
+ INTERFACEKEY_WORLD_PARAM_NAME_ENTER,
+ INTERFACEKEY_WORLD_PARAM_SEED_RANDOM,
+ INTERFACEKEY_WORLD_PARAM_SEED_ENTER,
+ INTERFACEKEY_WORLD_PARAM_LOAD,
+ INTERFACEKEY_WORLD_PARAM_SAVE,
+ INTERFACEKEY_WORLD_PARAM_DIM_X_UP,
+ INTERFACEKEY_WORLD_PARAM_DIM_X_DOWN,
+ INTERFACEKEY_WORLD_PARAM_DIM_Y_UP,
+ INTERFACEKEY_WORLD_PARAM_DIM_Y_DOWN,
+ INTERFACEKEY_WORLD_PARAM_SET,
+ INTERFACEKEY_WORLD_PARAM_INCREASE,
+ INTERFACEKEY_WORLD_PARAM_DECREASE,
+ INTERFACEKEY_WORLD_PARAM_ENTER_VALUE,
+ INTERFACEKEY_WORLD_PARAM_NULLIFY,
+ INTERFACEKEY_WORLD_PARAM_PRESET,
+ INTERFACEKEY_WORLD_PARAM_REJECT_CONTINUE,
+ INTERFACEKEY_WORLD_PARAM_REJECT_ABORT,
+ INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_THIS,
+ INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_ALL,
+ INTERFACEKEY_WORLD_GEN_CONTINUE,
+ INTERFACEKEY_WORLD_GEN_USE,
+ INTERFACEKEY_WORLD_GEN_ABORT,
+ INTERFACEKEY_WORLDGEN_EXPORT_MAP,
+ INTERFACEKEY_LEGENDS_EXPORT_MAP,
+ INTERFACEKEY_LEGENDS_EXPORT_XML,
+ INTERFACEKEY_LEGENDS_EXPORT_DETAILED_MAP,
+ INTERFACEKEY_LEGENDS_TOGGLE_CIVSITE,
+ INTERFACEKEY_LEGENDS_STRING_FILTER,
+
+ ADVENTURERKEY_START,
+ INTERFACEKEY_A_RETURN_TO_ARENA=ADVENTURERKEY_START,
+ INTERFACEKEY_A_MOVE_N,
+ INTERFACEKEY_A_MOVE_S,
+ INTERFACEKEY_A_MOVE_E,
+ INTERFACEKEY_A_MOVE_W,
+ INTERFACEKEY_A_MOVE_NW,
+ INTERFACEKEY_A_MOVE_NE,
+ INTERFACEKEY_A_MOVE_SW,
+ INTERFACEKEY_A_MOVE_SE,
+ INTERFACEKEY_A_MOVE_SAME_SQUARE,
+ INTERFACEKEY_A_CARE_MOVE_N,
+ INTERFACEKEY_A_CARE_MOVE_S,
+ INTERFACEKEY_A_CARE_MOVE_E,
+ INTERFACEKEY_A_CARE_MOVE_W,
+ INTERFACEKEY_A_CARE_MOVE_NW,
+ INTERFACEKEY_A_CARE_MOVE_NE,
+ INTERFACEKEY_A_CARE_MOVE_SW,
+ INTERFACEKEY_A_CARE_MOVE_SE,
+ INTERFACEKEY_A_CARE_MOVE_UPDOWN,
+ INTERFACEKEY_A_MOVE_N_UP,
+ INTERFACEKEY_A_MOVE_S_UP,
+ INTERFACEKEY_A_MOVE_E_UP,
+ INTERFACEKEY_A_MOVE_W_UP,
+ INTERFACEKEY_A_MOVE_NW_UP,
+ INTERFACEKEY_A_MOVE_NE_UP,
+ INTERFACEKEY_A_MOVE_SW_UP,
+ INTERFACEKEY_A_MOVE_SE_UP,
+ INTERFACEKEY_A_MOVE_UP,
+ INTERFACEKEY_A_MOVE_N_DOWN,
+ INTERFACEKEY_A_MOVE_S_DOWN,
+ INTERFACEKEY_A_MOVE_E_DOWN,
+ INTERFACEKEY_A_MOVE_W_DOWN,
+ INTERFACEKEY_A_MOVE_NW_DOWN,
+ INTERFACEKEY_A_MOVE_NE_DOWN,
+ INTERFACEKEY_A_MOVE_SW_DOWN,
+ INTERFACEKEY_A_MOVE_SE_DOWN,
+ INTERFACEKEY_A_MOVE_DOWN,
+ INTERFACEKEY_A_MOVE_UP_AUX,
+ INTERFACEKEY_A_MOVE_DOWN_AUX,
+ INTERFACEKEY_A_COMBAT_ATTACK,
+ INTERFACEKEY_A_COMBAT_DODGE,
+ INTERFACEKEY_A_COMBAT_CHARGEDEF,
+ INTERFACEKEY_A_STATUS,
+ INTERFACEKEY_A_STATUS_WRESTLE,
+ INTERFACEKEY_A_STATUS_CUSTOMIZE,
+ INTERFACEKEY_A_STATUS_KILLS,
+ INTERFACEKEY_A_STATUS_HEALTH,
+ INTERFACEKEY_A_STATUS_ATT_SKILL,
+ INTERFACEKEY_A_STATUS_DESC,
+ INTERFACEKEY_A_CLEAR_ANNOUNCEMENTS,
+ INTERFACEKEY_A_SLEEP,
+ INTERFACEKEY_A_SLEEP_SLEEP,
+ INTERFACEKEY_A_SLEEP_WAIT,
+ INTERFACEKEY_A_SLEEP_DAWN,
+ INTERFACEKEY_A_WAIT,
+ INTERFACEKEY_A_SHORT_WAIT,
+ INTERFACEKEY_A_ATTACK,
+ INTERFACEKEY_A_ATTACK_CONFIRM,
+ INTERFACEKEY_QUICK_ATTACK,
+ INTERFACEKEY_HEAVY_ATTACK,
+ INTERFACEKEY_WILD_ATTACK,
+ INTERFACEKEY_PRECISE_ATTACK,
+ INTERFACEKEY_CHARGE_ATTACK,
+ INTERFACEKEY_MULTI_ATTACK,
+ INTERFACEKEY_A_LOOK,
+ INTERFACEKEY_A_SEARCH,
+ INTERFACEKEY_A_ODOR,
+ INTERFACEKEY_A_DISPLAY_ODOR,
+ INTERFACEKEY_A_YIELD,
+ INTERFACEKEY_A_DISPLAY_TRACKS,
+ INTERFACEKEY_A_FRESHEST_TRACK,
+ INTERFACEKEY_A_INV_DRAW_WEAPON,
+ INTERFACEKEY_A_JUMP,
+ INTERFACEKEY_A_HOLD,
+ INTERFACEKEY_A_TALK,
+ INTERFACEKEY_A_INTERACT,
+ INTERFACEKEY_A_ACTION,
+ INTERFACEKEY_A_ACTION_CREATE,
+ INTERFACEKEY_A_ACTION_BUTCHER,
+ INTERFACEKEY_A_ACTION_ABILITY,
+ INTERFACEKEY_A_ACTION_POWER,
+ INTERFACEKEY_A_INV_LOOK,
+ INTERFACEKEY_A_INV_REMOVE,
+ INTERFACEKEY_A_INV_WEAR,
+ INTERFACEKEY_A_INV_EATDRINK,
+ INTERFACEKEY_A_INV_PUTIN,
+ INTERFACEKEY_A_INV_DROP,
+ INTERFACEKEY_A_GROUND,
+ INTERFACEKEY_A_THROW,
+ INTERFACEKEY_A_SHOOT,
+ INTERFACEKEY_A_ANNOUNCEMENTS,
+ INTERFACEKEY_A_COMBAT,
+ INTERFACEKEY_A_MOVEMENT,
+ INTERFACEKEY_A_MOVEMENT_SWIM,
+ INTERFACEKEY_A_SNEAK,
+ INTERFACEKEY_A_SPEED_SNEAK,
+ INTERFACEKEY_A_CENTER,
+ INTERFACEKEY_A_COMPANIONS,
+ INTERFACEKEY_A_BUILDING,
+ INTERFACEKEY_A_TRAVEL,
+ INTERFACEKEY_A_TRAVEL_SLEEP,
+ INTERFACEKEY_A_TRAVEL_MAP,
+ INTERFACEKEY_A_TRAVEL_HIDE_INSTRUCTIONS,
+ INTERFACEKEY_A_DATE,
+ INTERFACEKEY_A_WEATHER,
+ INTERFACEKEY_A_TEMPERATURE,
+ INTERFACEKEY_A_STANCE,
+ INTERFACEKEY_A_ENTER_NAME,
+ INTERFACEKEY_A_CUST_NAME,
+ INTERFACEKEY_A_RANDOM_NAME,
+ INTERFACEKEY_A_CHANGE_GENDER,
+ INTERFACEKEY_A_END_TRAVEL,
+ INTERFACEKEY_A_TRAVEL_CLOUDS,
+ INTERFACEKEY_A_LOG,
+ INTERFACEKEY_A_TRAVEL_LOG,
+ INTERFACEKEY_A_LOG_TASKS,
+ INTERFACEKEY_A_LOG_ENTITIES,
+ INTERFACEKEY_A_LOG_SITES,
+ INTERFACEKEY_A_LOG_SUBREGIONS,
+ INTERFACEKEY_A_LOG_FEATURE_LAYERS,
+ INTERFACEKEY_A_LOG_PEOPLE,
+ INTERFACEKEY_A_LOG_AGREEMENTS,
+ INTERFACEKEY_A_LOG_EVENTS,
+ INTERFACEKEY_A_LOG_BESTIARY,
+ INTERFACEKEY_A_LOG_FILTER,
+ INTERFACEKEY_A_LOG_ZOOM_CURRENT_LOCATION,
+ INTERFACEKEY_A_LOG_ZOOM_SELECTED,
+ INTERFACEKEY_A_LOG_LINE,
+ INTERFACEKEY_A_LOG_MAP,
+ INTERFACEKEY_A_BARTER_VIEW,
+ INTERFACEKEY_A_BARTER_CURRENCY_1,
+ INTERFACEKEY_A_BARTER_CURRENCY_2,
+ INTERFACEKEY_A_BARTER_TRADE,
+
+ EMBARKKEY_START,
+ INTERFACEKEY_SETUP_EMBARK=EMBARKKEY_START,
+ INTERFACEKEY_SETUP_NAME_FORT,
+ INTERFACEKEY_SETUP_NAME_GROUP,
+ INTERFACEKEY_SETUP_RECLAIM,
+ INTERFACEKEY_SETUP_FIND,
+ INTERFACEKEY_SETUP_NOTES,
+ INTERFACEKEY_SETUP_NOTES_TAKE_NOTES,
+ INTERFACEKEY_SETUP_NOTES_DELETE_NOTE,
+ INTERFACEKEY_SETUP_NOTES_CHANGE_SYMBOL_SELECTION,
+ INTERFACEKEY_SETUP_NOTES_ADOPT_SYMBOL,
+ INTERFACEKEY_SETUP_LOCAL_Y_UP,
+ INTERFACEKEY_SETUP_LOCAL_Y_DOWN,
+ INTERFACEKEY_SETUP_LOCAL_X_UP,
+ INTERFACEKEY_SETUP_LOCAL_X_DOWN,
+ INTERFACEKEY_SETUP_LOCAL_Y_MUP,
+ INTERFACEKEY_SETUP_LOCAL_Y_MDOWN,
+ INTERFACEKEY_SETUP_LOCAL_X_MUP,
+ INTERFACEKEY_SETUP_LOCAL_X_MDOWN,
+ INTERFACEKEY_SETUP_BIOME_1,
+ INTERFACEKEY_SETUP_BIOME_2,
+ INTERFACEKEY_SETUP_BIOME_3,
+ INTERFACEKEY_SETUP_BIOME_4,
+ INTERFACEKEY_SETUP_BIOME_5,
+ INTERFACEKEY_SETUP_BIOME_6,
+ INTERFACEKEY_SETUP_BIOME_7,
+ INTERFACEKEY_SETUP_BIOME_8,
+ INTERFACEKEY_SETUP_BIOME_9,
+ INTERFACEKEY_CHOOSE_NAME_RANDOM,
+ INTERFACEKEY_CHOOSE_NAME_CLEAR,
+ INTERFACEKEY_CHOOSE_NAME_TYPE,
+ INTERFACEKEY_SETUPGAME_NEW,
+ INTERFACEKEY_SETUPGAME_VIEW,
+ INTERFACEKEY_SETUPGAME_CUSTOMIZE_UNIT,
+ INTERFACEKEY_SETUPGAME_SAVE_PROFILE,
+ INTERFACEKEY_SETUPGAME_SAVE_PROFILE_ABORT,
+ INTERFACEKEY_SETUPGAME_SAVE_PROFILE_GO,
+ INTERFACEKEY_SETUPGAME_VIEW_PROFILE_PROBLEMS,
+
+ BUILDINGKEY_START,
+ INTERFACEKEY_BUILDJOB_ADD=BUILDINGKEY_START,
+ INTERFACEKEY_BUILDJOB_CANCEL,
+ INTERFACEKEY_BUILDJOB_PROMOTE,
+ INTERFACEKEY_BUILDJOB_NOW,
+ INTERFACEKEY_BUILDJOB_REPEAT,
+ INTERFACEKEY_BUILDJOB_SUSPEND,
+ INTERFACEKEY_BUILDJOB_WORKSHOP_PROFILE,
+ INTERFACEKEY_BUILDJOB_WELL_FREE,
+ INTERFACEKEY_BUILDJOB_WELL_SIZE,
+ INTERFACEKEY_BUILDJOB_TARGET_FREE,
+ INTERFACEKEY_BUILDJOB_TARGET_SIZE,
+ INTERFACEKEY_BUILDJOB_TARGET_DOWN,
+ INTERFACEKEY_BUILDJOB_TARGET_UP,
+ INTERFACEKEY_BUILDJOB_TARGET_RIGHT,
+ INTERFACEKEY_BUILDJOB_TARGET_LEFT,
+ INTERFACEKEY_BUILDJOB_STATUE_ASSIGN,
+ INTERFACEKEY_BUILDJOB_STATUE_FREE,
+ INTERFACEKEY_BUILDJOB_STATUE_SIZE,
+ INTERFACEKEY_BUILDJOB_CAGE_JUSTICE,
+ INTERFACEKEY_BUILDJOB_CAGE_FREE,
+ INTERFACEKEY_BUILDJOB_CAGE_SIZE,
+ INTERFACEKEY_BUILDJOB_CAGE_ASSIGN_OCC,
+ INTERFACEKEY_BUILDJOB_CAGE_WATER,
+ INTERFACEKEY_BUILDJOB_CAGE_ASSIGN,
+ INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN_OCC,
+ INTERFACEKEY_BUILDJOB_CHAIN_JUSTICE,
+ INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN,
+ INTERFACEKEY_BUILDJOB_CHAIN_FREE,
+ INTERFACEKEY_BUILDJOB_CHAIN_SIZE,
+ INTERFACEKEY_BUILDJOB_SIEGE_FIRING,
+ INTERFACEKEY_BUILDJOB_SIEGE_ORIENT,
+ INTERFACEKEY_BUILDJOB_DOOR_INTERNAL,
+ INTERFACEKEY_BUILDJOB_DOOR_LOCK,
+ INTERFACEKEY_BUILDJOB_DOOR_AJAR,
+ INTERFACEKEY_BUILDJOB_COFFIN_ASSIGN,
+ INTERFACEKEY_BUILDJOB_COFFIN_FREE,
+ INTERFACEKEY_BUILDJOB_COFFIN_SIZE,
+ INTERFACEKEY_BUILDJOB_COFFIN_BURIAL,
+ INTERFACEKEY_BUILDJOB_COFFIN_CIV,
+ INTERFACEKEY_BUILDJOB_COFFIN_PET,
+ INTERFACEKEY_BUILDJOB_CHAIR_ASSIGN,
+ INTERFACEKEY_BUILDJOB_CHAIR_FREE,
+ INTERFACEKEY_BUILDJOB_CHAIR_SIZE,
+ INTERFACEKEY_BUILDJOB_TABLE_ASSIGN,
+ INTERFACEKEY_BUILDJOB_TABLE_HALL,
+ INTERFACEKEY_BUILDJOB_TABLE_FREE,
+ INTERFACEKEY_BUILDJOB_TABLE_SIZE,
+ INTERFACEKEY_BUILDJOB_BED_ASSIGN,
+ INTERFACEKEY_BUILDJOB_BED_FREE,
+ INTERFACEKEY_BUILDJOB_BED_BARRACKS,
+ INTERFACEKEY_BUILDJOB_BED_DORMITORY,
+ INTERFACEKEY_BUILDJOB_BED_RENT,
+ INTERFACEKEY_BUILDJOB_BED_SIZE,
+ INTERFACEKEY_BUILDJOB_BED_NAME,
+ INTERFACEKEY_BUILDJOB_BED_SLEEP,
+ INTERFACEKEY_BUILDJOB_BED_TRAIN,
+ INTERFACEKEY_BUILDJOB_BED_INDIV_EQ,
+ INTERFACEKEY_BUILDJOB_BED_SQUAD_EQ,
+ INTERFACEKEY_BUILDJOB_BED_POSITION,
+ INTERFACEKEY_BUILDJOB_DEPOT_BRING,
+ INTERFACEKEY_BUILDJOB_DEPOT_TRADE,
+ INTERFACEKEY_BUILDJOB_DEPOT_REQUEST_TRADER,
+ INTERFACEKEY_BUILDJOB_DEPOT_BROKER_ONLY,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_NONE,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_MEAT,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_FISH,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_GEM,
+ INTERFACEKEY_BUILDJOB_FARM_FALLOW,
+ INTERFACEKEY_BUILDJOB_FARM_FERTILIZE,
+ INTERFACEKEY_BUILDJOB_FARM_SEASFERT,
+ INTERFACEKEY_BUILDJOB_FARM_SPRING,
+ INTERFACEKEY_BUILDJOB_FARM_SUMMER,
+ INTERFACEKEY_BUILDJOB_FARM_AUTUMN,
+ INTERFACEKEY_BUILDJOB_FARM_WINTER,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_BONE,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_BRONZE,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_COPPER,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_IRON,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_STEEL,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_WOOD,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_METAL,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_BONE,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_LEATHER,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_COPPER,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_BRONZE,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_STEEL,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_IRON,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_WOOD,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_METAL,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_ASSIGN,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_FREE,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_SIZE,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_ITEM,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_MAT,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS1,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_KILL1,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS2,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_KILL2,
+ INTERFACEKEY_HOTKEY_BUILDING_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_BUILDING_BED,
+ INTERFACEKEY_HOTKEY_BUILDING_CHAIR,
+ INTERFACEKEY_HOTKEY_BUILDING_COFFIN,
+ INTERFACEKEY_HOTKEY_BUILDING_DOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_FLOODGATE,
+ INTERFACEKEY_HOTKEY_BUILDING_HATCH,
+ INTERFACEKEY_HOTKEY_BUILDING_GRATE_WALL,
+ INTERFACEKEY_HOTKEY_BUILDING_GRATE_FLOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_BARS_VERTICAL,
+ INTERFACEKEY_HOTKEY_BUILDING_BARS_FLOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_CABINET,
+ INTERFACEKEY_HOTKEY_BUILDING_BOX,
+ INTERFACEKEY_HOTKEY_BUILDING_KENNEL,
+ INTERFACEKEY_HOTKEY_BUILDING_FARMPLOT,
+ INTERFACEKEY_HOTKEY_BUILDING_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_BUILDING_STATUE,
+ INTERFACEKEY_HOTKEY_BUILDING_TABLE,
+ INTERFACEKEY_HOTKEY_BUILDING_ROAD_DIRT,
+ INTERFACEKEY_HOTKEY_BUILDING_ROAD_PAVED,
+ INTERFACEKEY_HOTKEY_BUILDING_BRIDGE,
+ INTERFACEKEY_HOTKEY_BUILDING_WELL,
+ INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE,
+ INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GLASS,
+ INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GEM,
+ INTERFACEKEY_HOTKEY_BUILDING_SHOP,
+ INTERFACEKEY_HOTKEY_BUILDING_ANIMALTRAP,
+ INTERFACEKEY_HOTKEY_BUILDING_CHAIN,
+ INTERFACEKEY_HOTKEY_BUILDING_CAGE,
+ INTERFACEKEY_HOTKEY_BUILDING_TRADEDEPOT,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE,
+ INTERFACEKEY_HOTKEY_BUILDING_SUPPORT,
+ INTERFACEKEY_HOTKEY_BUILDING_ARCHERYTARGET,
+ INTERFACEKEY_HOTKEY_BUILDING_TRACTION_BENCH,
+ INTERFACEKEY_HOTKEY_BUILDING_SLAB,
+ INTERFACEKEY_HOTKEY_BUILDING_NEST_BOX,
+ INTERFACEKEY_HOTKEY_BUILDING_HIVE,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_SCREW_PUMP,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WATER_WHEEL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WINDMILL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_ROLLERS,
+ INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_BALLISTA,
+ INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_CATAPULT,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_STONE,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_WEAPON,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_LEVER,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_TRIGGER,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_CAGE,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_SPIKE,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_WALL,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FLOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_RAMP,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LEATHER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_QUERN,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MILLSTONE,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LOOM,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CLOTHES,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BOWYER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CARPENTER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_METALSMITH,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LAVAMILL,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_JEWELER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MASON,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BUTCHER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_TANNER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_DYER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_SIEGE,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MECHANIC,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_STILL,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FARMER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_KITCHEN,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FISHERY,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_ASHERY,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_WOOD,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER_LAVA,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS_LAVA,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN_LAVA,
+ INTERFACEKEY_HIVE_INSTALL_COLONY,
+ INTERFACEKEY_HIVE_GATHER_PRODUCTS,
+ INTERFACEKEY_BUILDING_DIM_Y_UP,
+ INTERFACEKEY_BUILDING_DIM_Y_DOWN,
+ INTERFACEKEY_BUILDING_DIM_X_UP,
+ INTERFACEKEY_BUILDING_DIM_X_DOWN,
+ INTERFACEKEY_BUILDING_ORIENT_UP,
+ INTERFACEKEY_BUILDING_ORIENT_LEFT,
+ INTERFACEKEY_BUILDING_ORIENT_RIGHT,
+ INTERFACEKEY_BUILDING_ORIENT_DOWN,
+ INTERFACEKEY_BUILDING_ORIENT_NONE,
+ INTERFACEKEY_BUILDING_VIEW_ITEM,
+ INTERFACEKEY_BUILDING_ADVANCE_STAGE,
+ INTERFACEKEY_BUILDING_EXPAND_CONTRACT,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_WATER,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_MAGMA,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_TRACK_CART,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_CREATURE,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_LOCALS,
+ INTERFACEKEY_BUILDING_TRIGGER_RESETS,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP_PLUS,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP_PLUS,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS,
+ INTERFACEKEY_BUILDING_ROLLERS_SPEED_UP,
+ INTERFACEKEY_BUILDING_ROLLERS_SPEED_DOWN,
+ INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_UP,
+ INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_DOWN,
+ INTERFACEKEY_BUILDING_TRACK_STOP_DUMP,
+ INTERFACEKEY_DESTROYBUILDING,
+ INTERFACEKEY_SUSPENDBUILDING,
+ INTERFACEKEY_BUILDINGLIST_ZOOM_T,
+ INTERFACEKEY_BUILDINGLIST_ZOOM_Q,
+ INTERFACEKEY_RECENTER_ON_LEVER,
+
+ WORKSHOPKEY_START,
+ INTERFACEKEY_HOTKEY_MAKE_ASH=WORKSHOPKEY_START,
+ INTERFACEKEY_HOTKEY_MAKE_CHARCOAL,
+ INTERFACEKEY_HOTKEY_MELT_OBJECT,
+ INTERFACEKEY_HOTKEY_GLASS_GREEN,
+ INTERFACEKEY_HOTKEY_GLASS_CLEAR,
+ INTERFACEKEY_HOTKEY_GLASS_CRYSTAL,
+ INTERFACEKEY_HOTKEY_COLLECT_SAND,
+ INTERFACEKEY_HOTKEY_COLLECT_CLAY,
+ INTERFACEKEY_HOTKEY_GLASS_ROUGH,
+ INTERFACEKEY_HOTKEY_GLASS_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_GLASS_BOX,
+ INTERFACEKEY_HOTKEY_GLASS_CABINET,
+ INTERFACEKEY_HOTKEY_GLASS_COFFIN,
+ INTERFACEKEY_HOTKEY_GLASS_FLOODGATE,
+ INTERFACEKEY_HOTKEY_GLASS_HATCH_COVER,
+ INTERFACEKEY_HOTKEY_GLASS_GRATE,
+ INTERFACEKEY_HOTKEY_GLASS_GOBLET,
+ INTERFACEKEY_HOTKEY_GLASS_TOY,
+ INTERFACEKEY_HOTKEY_GLASS_INSTRUMENT,
+ INTERFACEKEY_HOTKEY_GLASS_DOOR,
+ INTERFACEKEY_HOTKEY_GLASS_STATUE,
+ INTERFACEKEY_HOTKEY_GLASS_TABLE,
+ INTERFACEKEY_HOTKEY_GLASS_CAGE,
+ INTERFACEKEY_HOTKEY_GLASS_CHAIR,
+ INTERFACEKEY_HOTKEY_GLASS_BLOCKS,
+ INTERFACEKEY_HOTKEY_GLASS_FLASK,
+ INTERFACEKEY_HOTKEY_GLASS_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_GLASS_WINDOW,
+ INTERFACEKEY_HOTKEY_ASHERY_LYE,
+ INTERFACEKEY_HOTKEY_ASHERY_POTASH,
+ INTERFACEKEY_HOTKEY_ASHERY_POTASH_DIRECT,
+ INTERFACEKEY_HOTKEY_CARPENTER_BARREL,
+ INTERFACEKEY_HOTKEY_CARPENTER_BLOCKS,
+ INTERFACEKEY_HOTKEY_CARPENTER_BUCKET,
+ INTERFACEKEY_HOTKEY_CARPENTER_TRAP_ANIMAL,
+ INTERFACEKEY_HOTKEY_CARPENTER_CAGE,
+ INTERFACEKEY_HOTKEY_CARPENTER_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_CARPENTER_BED,
+ INTERFACEKEY_HOTKEY_CARPENTER_CHAIR,
+ INTERFACEKEY_HOTKEY_CARPENTER_COFFIN,
+ INTERFACEKEY_HOTKEY_CARPENTER_DOOR,
+ INTERFACEKEY_HOTKEY_CARPENTER_FLOODGATE,
+ INTERFACEKEY_HOTKEY_CARPENTER_HATCH_COVER,
+ INTERFACEKEY_HOTKEY_CARPENTER_GRATE,
+ INTERFACEKEY_HOTKEY_CARPENTER_CABINET,
+ INTERFACEKEY_HOTKEY_CARPENTER_BIN,
+ INTERFACEKEY_HOTKEY_CARPENTER_BOX,
+ INTERFACEKEY_HOTKEY_CARPENTER_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_CARPENTER_TABLE,
+ INTERFACEKEY_HOTKEY_SIEGE_BALLISTA,
+ INTERFACEKEY_HOTKEY_SIEGE_CATAPULT,
+ INTERFACEKEY_HOTKEY_LEATHER_BOX,
+ INTERFACEKEY_HOTKEY_LEATHER_FLASK,
+ INTERFACEKEY_HOTKEY_LEATHER_SHIRT,
+ INTERFACEKEY_HOTKEY_LEATHER_CLOAK,
+ INTERFACEKEY_HOTKEY_LEATHER_BACKPACK,
+ INTERFACEKEY_HOTKEY_LEATHER_QUIVER,
+ INTERFACEKEY_HOTKEY_LEATHER_IMAGE,
+ INTERFACEKEY_HOTKEY_CLOTHES_MAT_PLANT,
+ INTERFACEKEY_HOTKEY_CLOTHES_MAT_SILK,
+ INTERFACEKEY_HOTKEY_CLOTHES_MAT_YARN,
+ INTERFACEKEY_HOTKEY_CLOTHES_SHIRT,
+ INTERFACEKEY_HOTKEY_CLOTHES_CLOAK,
+ INTERFACEKEY_HOTKEY_CLOTHES_BOX,
+ INTERFACEKEY_HOTKEY_CLOTHES_CHAIN,
+ INTERFACEKEY_HOTKEY_CLOTHES_IMAGE,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_STONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_WOOD,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_BONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_SHELL,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_TOOTH,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_HORN,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_PEARL,
+ INTERFACEKEY_HOTKEY_CRAFTS_TOTEM,
+ INTERFACEKEY_HOTKEY_CRAFTS_CLOTH,
+ INTERFACEKEY_HOTKEY_CRAFTS_SILK,
+ INTERFACEKEY_HOTKEY_CRAFTS_YARN,
+ INTERFACEKEY_HOTKEY_CRAFTS_SEL_WOOD,
+ INTERFACEKEY_HOTKEY_CRAFTS_SEL_BONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_SEL_SHELL,
+ INTERFACEKEY_HOTKEY_CRAFTS_SHELL,
+ INTERFACEKEY_HOTKEY_CRAFTS_TOOTH,
+ INTERFACEKEY_HOTKEY_CRAFTS_HORN,
+ INTERFACEKEY_HOTKEY_CRAFTS_PEARL,
+ INTERFACEKEY_HOTKEY_CRAFTS_BONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_LEATHER,
+ INTERFACEKEY_HOTKEY_CRAFTS_SLAB,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_CRAFTS,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_GOBLET,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_INSTRUMENT,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_TOY,
+ INTERFACEKEY_HOTKEY_SMITH_WEAPON,
+ INTERFACEKEY_HOTKEY_SMITH_ARMOR,
+ INTERFACEKEY_HOTKEY_SMITH_FURNITURE,
+ INTERFACEKEY_HOTKEY_SMITH_SIEGE,
+ INTERFACEKEY_HOTKEY_SMITH_TRAP,
+ INTERFACEKEY_HOTKEY_SMITH_OTHER,
+ INTERFACEKEY_HOTKEY_SMITH_METAL,
+ INTERFACEKEY_HOTKEY_ALCHEMIST_SOAP,
+ INTERFACEKEY_HOTKEY_STILL_BREW,
+ INTERFACEKEY_HOTKEY_STILL_EXTRACT,
+ INTERFACEKEY_HOTKEY_LOOM_COLLECT_SILK,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_CLOTH,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_SILK,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_YARN,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_METAL,
+ INTERFACEKEY_HOTKEY_KITCHEN_COOK_2,
+ INTERFACEKEY_HOTKEY_KITCHEN_COOK_3,
+ INTERFACEKEY_HOTKEY_KITCHEN_COOK_4,
+ INTERFACEKEY_HOTKEY_KITCHEN_RENDER_FAT,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS_VIAL,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS_BAG,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS_BARREL,
+ INTERFACEKEY_HOTKEY_FARMER_CHEESE,
+ INTERFACEKEY_HOTKEY_FARMER_MILK,
+ INTERFACEKEY_HOTKEY_FARMER_SHEAR_CREATURE,
+ INTERFACEKEY_HOTKEY_FARMER_SPIN_THREAD,
+ INTERFACEKEY_HOTKEY_MILL_MILL,
+ INTERFACEKEY_HOTKEY_KENNEL_CATCH_VERMIN,
+ INTERFACEKEY_HOTKEY_KENNEL_TAME_VERMIN,
+ INTERFACEKEY_HOTKEY_FISHERY_PROCESS,
+ INTERFACEKEY_HOTKEY_FISHERY_EXTRACT,
+ INTERFACEKEY_HOTKEY_FISHERY_CATCH,
+ INTERFACEKEY_HOTKEY_BUTCHER_BUTCHER,
+ INTERFACEKEY_HOTKEY_BUTCHER_EXTRACT,
+ INTERFACEKEY_HOTKEY_BUTCHER_CATCH,
+ INTERFACEKEY_HOTKEY_TANNER_TAN,
+ INTERFACEKEY_HOTKEY_DYER_THREAD,
+ INTERFACEKEY_HOTKEY_DYER_CLOTH,
+ INTERFACEKEY_HOTKEY_JEWELER_FURNITURE,
+ INTERFACEKEY_HOTKEY_JEWELER_FINISHED,
+ INTERFACEKEY_HOTKEY_JEWELER_AMMO,
+ INTERFACEKEY_HOTKEY_JEWELER_CUT,
+ INTERFACEKEY_HOTKEY_JEWELER_ENCRUST,
+ INTERFACEKEY_HOTKEY_MECHANIC_PARTS,
+ INTERFACEKEY_HOTKEY_MECHANIC_TRACTION_BENCH,
+ INTERFACEKEY_HOTKEY_MASON_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_MASON_BLOCKS,
+ INTERFACEKEY_HOTKEY_MASON_CHAIR,
+ INTERFACEKEY_HOTKEY_MASON_COFFIN,
+ INTERFACEKEY_HOTKEY_MASON_DOOR,
+ INTERFACEKEY_HOTKEY_MASON_FLOODGATE,
+ INTERFACEKEY_HOTKEY_MASON_HATCH_COVER,
+ INTERFACEKEY_HOTKEY_MASON_GRATE,
+ INTERFACEKEY_HOTKEY_MASON_CABINET,
+ INTERFACEKEY_HOTKEY_MASON_BOX,
+ INTERFACEKEY_HOTKEY_MASON_STATUE,
+ INTERFACEKEY_HOTKEY_MASON_TABLE,
+ INTERFACEKEY_HOTKEY_MASON_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_MASON_QUERN,
+ INTERFACEKEY_HOTKEY_MASON_MILLSTONE,
+ INTERFACEKEY_HOTKEY_MASON_SLAB,
+ INTERFACEKEY_HOTKEY_TRAP_BRIDGE,
+ INTERFACEKEY_HOTKEY_TRAP_DOOR,
+ INTERFACEKEY_HOTKEY_TRAP_FLOODGATE,
+ INTERFACEKEY_HOTKEY_TRAP_SPIKE,
+ INTERFACEKEY_HOTKEY_TRAP_HATCH,
+ INTERFACEKEY_HOTKEY_TRAP_GRATE_WALL,
+ INTERFACEKEY_HOTKEY_TRAP_GRATE_FLOOR,
+ INTERFACEKEY_HOTKEY_TRAP_BARS_VERTICAL,
+ INTERFACEKEY_HOTKEY_TRAP_BARS_FLOOR,
+ INTERFACEKEY_HOTKEY_TRAP_SUPPORT,
+ INTERFACEKEY_HOTKEY_TRAP_CHAIN,
+ INTERFACEKEY_HOTKEY_TRAP_CAGE,
+ INTERFACEKEY_HOTKEY_TRAP_GEAR_ASSEMBLY,
+ INTERFACEKEY_HOTKEY_TRAP_TRACK_STOP,
+ INTERFACEKEY_HOTKEY_TRAP_PULL_LEVER,
+
+ PILEZONEKEY_START,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_MASTER=PILEZONEKEY_START,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_LINK_ANYWHERE,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_GIVE_TO,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_DELETE_CHILD,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_SETTINGS,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_UP,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_DOWN,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_ZERO,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_MAX,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_UP,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_DOWN,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_ZERO,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_MAX,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_WHEELBARROW,
+ INTERFACEKEY_STOCKPILE_ANIMAL,
+ INTERFACEKEY_STOCKPILE_FOOD,
+ INTERFACEKEY_STOCKPILE_WEAPON,
+ INTERFACEKEY_STOCKPILE_ARMOR,
+ INTERFACEKEY_STOCKPILE_CUSTOM,
+ INTERFACEKEY_STOCKPILE_CUSTOM_SETTINGS,
+ INTERFACEKEY_STOCKPILE_FURNITURE,
+ INTERFACEKEY_STOCKPILE_GRAVEYARD,
+ INTERFACEKEY_STOCKPILE_REFUSE,
+ INTERFACEKEY_STOCKPILE_WOOD,
+ INTERFACEKEY_STOCKPILE_STONE,
+ INTERFACEKEY_STOCKPILE_GEM,
+ INTERFACEKEY_STOCKPILE_BARBLOCK,
+ INTERFACEKEY_STOCKPILE_CLOTH,
+ INTERFACEKEY_STOCKPILE_LEATHER,
+ INTERFACEKEY_STOCKPILE_AMMO,
+ INTERFACEKEY_STOCKPILE_COINS,
+ INTERFACEKEY_STOCKPILE_FINISHED,
+ INTERFACEKEY_STOCKPILE_NONE,
+ INTERFACEKEY_STOCKPILE_SETTINGS_ENABLE,
+ INTERFACEKEY_STOCKPILE_SETTINGS_DISABLE,
+ INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_ALL,
+ INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_ALL,
+ INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_SUB,
+ INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_SUB,
+ INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC1,
+ INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC2,
+ INTERFACEKEY_CIVZONE_REMOVE,
+ INTERFACEKEY_CIVZONE_REMOVE_ZONE,
+ INTERFACEKEY_CIVZONE_SHAPE,
+ INTERFACEKEY_CIVZONE_NEXT,
+ INTERFACEKEY_CIVZONE_WATER_SOURCE,
+ INTERFACEKEY_CIVZONE_FISH,
+ INTERFACEKEY_CIVZONE_GATHER,
+ INTERFACEKEY_CIVZONE_DUMP,
+ INTERFACEKEY_CIVZONE_POND,
+ INTERFACEKEY_CIVZONE_HOSPITAL,
+ INTERFACEKEY_CIVZONE_SAND_COLLECT,
+ INTERFACEKEY_CIVZONE_CLAY_COLLECT,
+ INTERFACEKEY_CIVZONE_ACTIVE,
+ INTERFACEKEY_CIVZONE_MEETING,
+ INTERFACEKEY_CIVZONE_ANIMAL_TRAINING,
+ INTERFACEKEY_CIVZONE_PEN,
+ INTERFACEKEY_CIVZONE_PEN_OPTIONS,
+ INTERFACEKEY_CIVZONE_POND_OPTIONS,
+ INTERFACEKEY_CIVZONE_POND_WATER,
+ INTERFACEKEY_CIVZONE_HOSPITAL_OPTIONS,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_TREES,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_SHRUBS,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS_GATHER_FALLEN,
+
+ STOCKORDERKEY_START,
+ INTERFACEKEY_STORES_VIEW=STOCKORDERKEY_START,
+ INTERFACEKEY_STORES_ZOOM,
+ INTERFACEKEY_STORES_FORBID,
+ INTERFACEKEY_STORES_MELT,
+ INTERFACEKEY_STORES_DUMP,
+ INTERFACEKEY_STORES_HIDE,
+ INTERFACEKEY_PET_BUTCHER,
+ INTERFACEKEY_PET_GELD,
+ INTERFACEKEY_ANIMAL_SELECT_TRAINER,
+ INTERFACEKEY_ANIMAL_WAR_TRAINING,
+ INTERFACEKEY_ANIMAL_HUNTING_TRAINING,
+ INTERFACEKEY_KITCHEN_COOK,
+ INTERFACEKEY_KITCHEN_BREW,
+ INTERFACEKEY_ORDERS_AUTOFORBID,
+ INTERFACEKEY_ORDERS_FORBID_PROJECTILE,
+ INTERFACEKEY_ORDERS_FORBID_YOUR_CORPSE,
+ INTERFACEKEY_ORDERS_FORBID_YOUR_ITEMS,
+ INTERFACEKEY_ORDERS_FORBID_OTHER_CORPSE,
+ INTERFACEKEY_ORDERS_FORBID_OTHER_ITEMS,
+ INTERFACEKEY_ORDERS_REFUSE_GATHER,
+ INTERFACEKEY_ORDERS_REFUSE_OUTSIDE,
+ INTERFACEKEY_ORDERS_REFUSE_OUTSIDE_VERMIN,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_CORPSE,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_SKULL,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_BONE,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_SHELL,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_SKIN,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_OTHER,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_STRAND_TISSUE,
+ INTERFACEKEY_ORDERS_GATHER_FURNITURE,
+ INTERFACEKEY_ORDERS_GATHER_ANIMALS,
+ INTERFACEKEY_ORDERS_GATHER_FOOD,
+ INTERFACEKEY_ORDERS_GATHER_BODIES,
+ INTERFACEKEY_ORDERS_REFUSE,
+ INTERFACEKEY_ORDERS_GATHER_STONE,
+ INTERFACEKEY_ORDERS_GATHER_WOOD,
+ INTERFACEKEY_ORDERS_ALL_HARVEST,
+ INTERFACEKEY_ORDERS_SAMEPILE,
+ INTERFACEKEY_ORDERS_MIXFOODS,
+ INTERFACEKEY_ORDERS_LOOM,
+ INTERFACEKEY_ORDERS_DYED_CLOTH,
+ INTERFACEKEY_ORDERS_EXCEPTIONS,
+ INTERFACEKEY_ORDERS_WORKSHOP,
+ INTERFACEKEY_ORDERS_COLLECT_WEB,
+ INTERFACEKEY_ORDERS_SLAUGHTER,
+ INTERFACEKEY_ORDERS_BUTCHER,
+ INTERFACEKEY_ORDERS_TAN,
+ INTERFACEKEY_ORDERS_AUTO_FISHERY,
+ INTERFACEKEY_ORDERS_AUTO_KITCHEN,
+ INTERFACEKEY_ORDERS_AUTO_KILN,
+ INTERFACEKEY_ORDERS_AUTO_SMELTER,
+ INTERFACEKEY_ORDERS_AUTO_OTHER,
+ INTERFACEKEY_ORDERS_ZONE,
+ INTERFACEKEY_ORDERS_ZONE_DRINKING,
+ INTERFACEKEY_ORDERS_ZONE_FISHING,
+
+ DWARFMAINKEY_START,
+ INTERFACEKEY_D_ONESTEP=DWARFMAINKEY_START,
+ INTERFACEKEY_D_PAUSE,
+ INTERFACEKEY_D_DEPOT,
+ INTERFACEKEY_D_HOT_KEYS,
+ INTERFACEKEY_D_HOTKEY1,
+ INTERFACEKEY_D_HOTKEY2,
+ INTERFACEKEY_D_HOTKEY3,
+ INTERFACEKEY_D_HOTKEY4,
+ INTERFACEKEY_D_HOTKEY5,
+ INTERFACEKEY_D_HOTKEY6,
+ INTERFACEKEY_D_HOTKEY7,
+ INTERFACEKEY_D_HOTKEY8,
+ INTERFACEKEY_D_HOTKEY9,
+ INTERFACEKEY_D_HOTKEY10,
+ INTERFACEKEY_D_HOTKEY11,
+ INTERFACEKEY_D_HOTKEY12,
+ INTERFACEKEY_D_HOTKEY13,
+ INTERFACEKEY_D_HOTKEY14,
+ INTERFACEKEY_D_HOTKEY15,
+ INTERFACEKEY_D_HOTKEY16,
+ INTERFACEKEY_D_HOTKEY_CHANGE_NAME,
+ INTERFACEKEY_D_HOTKEY_ZOOM,
+ INTERFACEKEY_D_ANNOUNCE,
+ INTERFACEKEY_D_REPORTS,
+ INTERFACEKEY_D_BUILDING,
+ INTERFACEKEY_D_CIVLIST,
+ INTERFACEKEY_D_DESIGNATE,
+ INTERFACEKEY_D_ARTLIST,
+ INTERFACEKEY_D_NOBLES,
+ INTERFACEKEY_D_ORDERS,
+ INTERFACEKEY_D_MILITARY,
+ INTERFACEKEY_D_ROOMS,
+ INTERFACEKEY_D_SQUADS,
+ INTERFACEKEY_D_STOCKPILES,
+ INTERFACEKEY_D_CIVZONE,
+ INTERFACEKEY_D_VIEWUNIT,
+ INTERFACEKEY_D_JOBLIST,
+ INTERFACEKEY_D_UNITLIST,
+ INTERFACEKEY_D_LOOK,
+ INTERFACEKEY_D_HAULING,
+ INTERFACEKEY_D_HAULING_NEW_ROUTE,
+ INTERFACEKEY_D_HAULING_NEW_STOP,
+ INTERFACEKEY_D_HAULING_REMOVE,
+ INTERFACEKEY_D_HAULING_PROMOTE,
+ INTERFACEKEY_D_HAULING_VEHICLE,
+ INTERFACEKEY_D_HAULING_NICKNAME,
+ INTERFACEKEY_D_HAULING_STOP_NEW_DEPART,
+ INTERFACEKEY_D_HAULING_STOP_NEW_LINK,
+ INTERFACEKEY_D_HAULING_STOP_REMOVE,
+ INTERFACEKEY_D_HAULING_STOP_SL_SELECT_PILE,
+ INTERFACEKEY_D_HAULING_STOP_SL_TAKE_GIVE,
+ INTERFACEKEY_D_HAULING_STOP_LC_DIR,
+ INTERFACEKEY_D_HAULING_STOP_LC_MODE,
+ INTERFACEKEY_D_HAULING_STOP_LC_TIMER_UP,
+ INTERFACEKEY_D_HAULING_STOP_LC_TIMER_DOWN,
+ INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_UP,
+ INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_DOWN,
+ INTERFACEKEY_D_HAULING_STOP_LC_MORE_LESS,
+ INTERFACEKEY_D_HAULING_STOP_LC_DESIRED_TOTAL,
+ INTERFACEKEY_D_HAULING_STOP_LC_CHANGE,
+ INTERFACEKEY_D_HAULING_STOP_LC_ADVANCED,
+ INTERFACEKEY_D_BURROWS,
+ INTERFACEKEY_D_BURROWS_ADD,
+ INTERFACEKEY_D_BURROWS_DELETE,
+ INTERFACEKEY_D_BURROWS_DEFINE,
+ INTERFACEKEY_D_BURROWS_ADD_UNIT,
+ INTERFACEKEY_D_BURROWS_WORKSHOP_LIMIT,
+ INTERFACEKEY_D_BURROWS_CENTER,
+ INTERFACEKEY_D_BURROWS_NAME,
+ INTERFACEKEY_D_BURROWS_CHANGE_SELECTION,
+ INTERFACEKEY_D_BURROWS_BRUSH,
+ INTERFACEKEY_D_BURROWS_REMOVE,
+ INTERFACEKEY_D_NOTE,
+ INTERFACEKEY_D_NOTE_PLACE,
+ INTERFACEKEY_D_NOTE_DELETE,
+ INTERFACEKEY_D_NOTE_NAME,
+ INTERFACEKEY_D_NOTE_ENTER,
+ INTERFACEKEY_D_NOTE_ADOPT_SYMBOL,
+ INTERFACEKEY_D_NOTE_CHANGE_SELECTION,
+ INTERFACEKEY_D_NOTE_POINTS,
+ INTERFACEKEY_D_NOTE_ROUTE,
+ INTERFACEKEY_D_NOTE_ROUTE_ADD,
+ INTERFACEKEY_D_NOTE_ROUTE_EDIT,
+ INTERFACEKEY_D_NOTE_ROUTE_DELETE,
+ INTERFACEKEY_D_NOTE_ROUTE_CENTER,
+ INTERFACEKEY_D_NOTE_ROUTE_NAME,
+ INTERFACEKEY_D_BUILDJOB,
+ INTERFACEKEY_D_STATUS,
+ INTERFACEKEY_D_STATUS_OVERALL_HEALTH_RECENTER,
+ INTERFACEKEY_D_BUILDITEM,
+ INTERFACEKEY_D_BITEM_FORBID,
+ INTERFACEKEY_D_BITEM_DUMP,
+ INTERFACEKEY_D_BITEM_MELT,
+ INTERFACEKEY_D_BITEM_HIDE,
+ INTERFACEKEY_D_LOOK_FORBID,
+ INTERFACEKEY_D_LOOK_DUMP,
+ INTERFACEKEY_D_LOOK_MELT,
+ INTERFACEKEY_D_LOOK_HIDE,
+ INTERFACEKEY_D_LOOK_FOLLOW,
+ INTERFACEKEY_D_LOOK_ARENA_CREATURE,
+ INTERFACEKEY_D_LOOK_ARENA_ADV_MODE,
+ INTERFACEKEY_D_LOOK_ARENA_WATER,
+ INTERFACEKEY_D_LOOK_ARENA_MAGMA,
+ INTERFACEKEY_ARENA_CREATURE_SIDE_DOWN,
+ INTERFACEKEY_ARENA_CREATURE_SIDE_UP,
+ INTERFACEKEY_ARENA_CREATURE_NEW_ITEM,
+ INTERFACEKEY_ARENA_CREATURE_BLANK_LIST,
+ INTERFACEKEY_ARENA_CREATURE_REMOVE_ITEM,
+ INTERFACEKEY_ARENA_CREATURE_UNDEAD,
+ INTERFACEKEY_ARENA_CREATURE_STRING,
+ INTERFACEKEY_ARENA_CONFLICT_STATE_1,
+ INTERFACEKEY_ARENA_CONFLICT_STATE_2,
+ INTERFACEKEY_ARENA_MORALE,
+ INTERFACEKEY_ARENA_WEATHER,
+ INTERFACEKEY_ARENA_WEATHER_SNOW,
+ INTERFACEKEY_ARENA_WEATHER_MUD,
+ INTERFACEKEY_ARENA_WEATHER_CLEAR_SPATTER,
+ INTERFACEKEY_D_LOOK_ARENA_TREE,
+ INTERFACEKEY_ARENA_TREE_FILTER,
+ INTERFACEKEY_ARENA_TREE_AGE,
+ INTERFACEKEY_D_LOOK_ARENA_MOUNT,
+ INTERFACEKEY_ASSIGNTRADE_VIEW,
+ INTERFACEKEY_ASSIGNTRADE_STRING,
+ INTERFACEKEY_ASSIGNTRADE_EXCLUDE_PROHIBITED,
+ INTERFACEKEY_ASSIGNTRADE_PENDING,
+ INTERFACEKEY_ASSIGNTRADE_SORT,
+ INTERFACEKEY_NOBLELIST_REPLACE,
+ INTERFACEKEY_NOBLELIST_SETTINGS,
+ INTERFACEKEY_NOBLELIST_CAPITAL,
+ INTERFACEKEY_NOBLELIST_VIEW_CANDIDATE,
+ INTERFACEKEY_TRADE_VIEW,
+ INTERFACEKEY_TRADE_TRADE,
+ INTERFACEKEY_TRADE_OFFER,
+ INTERFACEKEY_TRADE_SEIZE,
+ INTERFACEKEY_MILITARY_ACTIVATE,
+ INTERFACEKEY_MILITARY_VIEW,
+ INTERFACEKEY_MILITARY_WEAPON,
+ INTERFACEKEY_MILITARY_ZOOM,
+ INTERFACEKEY_ANNOUNCE_ZOOM,
+ INTERFACEKEY_UNITJOB_REMOVE_CRE,
+ INTERFACEKEY_UNITJOB_ZOOM_CRE,
+ INTERFACEKEY_UNITJOB_ZOOM_BUILD,
+ INTERFACEKEY_UNITJOB_VIEW,
+ INTERFACEKEY_UNITJOB_MANAGER,
+ INTERFACEKEY_MANAGER_NEW_ORDER,
+ INTERFACEKEY_MANAGER_REMOVE,
+ INTERFACEKEY_MANAGER_PROMOTE,
+ INTERFACEKEY_MANAGER_MAX,
+ INTERFACEKEY_MANAGER_WAGES,
+ INTERFACEKEY_DESIGNATE_BITEM,
+ INTERFACEKEY_DESIGNATE_CLAIM,
+ INTERFACEKEY_DESIGNATE_UNCLAIM,
+ INTERFACEKEY_DESIGNATE_MELT,
+ INTERFACEKEY_DESIGNATE_NO_MELT,
+ INTERFACEKEY_DESIGNATE_DUMP,
+ INTERFACEKEY_DESIGNATE_NO_DUMP,
+ INTERFACEKEY_DESIGNATE_HIDE,
+ INTERFACEKEY_DESIGNATE_NO_HIDE,
+ INTERFACEKEY_DESIGNATE_DIG,
+ INTERFACEKEY_DESIGNATE_DIG_REMOVE_STAIRS_RAMPS,
+ INTERFACEKEY_DESIGNATE_TRAFFIC,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_HIGH,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_NORMAL,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_LOW,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_RESTRICTED,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE,
+ INTERFACEKEY_DESIGNATE_STAIR_UP,
+ INTERFACEKEY_DESIGNATE_STAIR_DOWN,
+ INTERFACEKEY_DESIGNATE_STAIR_UPDOWN,
+ INTERFACEKEY_DESIGNATE_RAMP,
+ INTERFACEKEY_DESIGNATE_CHANNEL,
+ INTERFACEKEY_DESIGNATE_CHOP,
+ INTERFACEKEY_DESIGNATE_PLANTS,
+ INTERFACEKEY_DESIGNATE_SMOOTH,
+ INTERFACEKEY_DESIGNATE_ENGRAVE,
+ INTERFACEKEY_DESIGNATE_FORTIFY,
+ INTERFACEKEY_DESIGNATE_TRACK,
+ INTERFACEKEY_DESIGNATE_TOGGLE_ENGRAVING,
+ INTERFACEKEY_DESIGNATE_STANDARD_MARKER,
+ INTERFACEKEY_DESIGNATE_MINE_MODE,
+ INTERFACEKEY_DESIGNATE_TOGGLE_MARKER,
+ INTERFACEKEY_DESIGNATE_UNDO,
+ INTERFACEKEY_DESIGNATE_REMOVE_CONSTRUCTION,
+ INTERFACEKEY_ITEM_DESCRIPTION,
+ INTERFACEKEY_ITEM_FORBID,
+ INTERFACEKEY_ITEM_MELT,
+ INTERFACEKEY_ITEM_DUMP,
+ INTERFACEKEY_ITEM_HIDE,
+ INTERFACEKEY_UNITVIEW_CUSTOMIZE,
+ INTERFACEKEY_UNITVIEW_HEALTH,
+ INTERFACEKEY_UNITVIEW_RELATIONSHIPS,
+ INTERFACEKEY_UNITVIEW_RELATIONSHIPS_ZOOM,
+ INTERFACEKEY_UNITVIEW_RELATIONSHIPS_VIEW,
+ INTERFACEKEY_UNITVIEW_KILLS,
+ INTERFACEKEY_UNITVIEW_GEN,
+ INTERFACEKEY_UNITVIEW_INV,
+ INTERFACEKEY_UNITVIEW_PRF,
+ INTERFACEKEY_UNITVIEW_WND,
+ INTERFACEKEY_UNITVIEW_FOLLOW,
+ INTERFACEKEY_UNITVIEW_NEXT,
+ INTERFACEKEY_UNITVIEW_SLAUGHTER,
+ INTERFACEKEY_UNITVIEW_GELD,
+ INTERFACEKEY_UNITVIEW_GEN_COMBAT,
+ INTERFACEKEY_UNITVIEW_GEN_LABOR,
+ INTERFACEKEY_UNITVIEW_GEN_MISC,
+ INTERFACEKEY_UNITVIEW_PRF_PROF,
+ INTERFACEKEY_UNITVIEW_PRF_PET,
+ INTERFACEKEY_UNITVIEW_PRF_VIEW,
+ INTERFACEKEY_UNITVIEW_PRF_NEW_SQUAD,
+ INTERFACEKEY_UNITVIEW_PRF_REMOVE_FROM_SQUAD,
+ INTERFACEKEY_UNITVIEW_PRF_NAME_CURRENT_SQUAD,
+ INTERFACEKEY_UNITVIEW_PRF_NAME_SELECTED_SQUAD,
+ INTERFACEKEY_CUSTOMIZE_UNIT_NICKNAME,
+ INTERFACEKEY_CUSTOMIZE_UNIT_PROFNAME,
+
+ MILITIAKEY_START,
+ INTERFACEKEY_D_MILITARY_CREATE_SQUAD=MILITIAKEY_START,
+ INTERFACEKEY_D_MILITARY_DISBAND_SQUAD,
+ INTERFACEKEY_D_MILITARY_CREATE_SUB_SQUAD,
+ INTERFACEKEY_D_MILITARY_CANCEL_ORDERS,
+ INTERFACEKEY_D_MILITARY_POSITIONS,
+ INTERFACEKEY_D_MILITARY_ALERTS,
+ INTERFACEKEY_D_MILITARY_ALERTS_ADD,
+ INTERFACEKEY_D_MILITARY_ALERTS_DELETE,
+ INTERFACEKEY_D_MILITARY_ALERTS_SET,
+ INTERFACEKEY_D_MILITARY_ALERTS_NAME,
+ INTERFACEKEY_D_MILITARY_ALERTS_SET_RETAIN,
+ INTERFACEKEY_D_MILITARY_EQUIP,
+ INTERFACEKEY_D_MILITARY_EQUIP_CUSTOMIZE,
+ INTERFACEKEY_D_MILITARY_EQUIP_UNIFORM,
+ INTERFACEKEY_D_MILITARY_EQUIP_PRIORITY,
+ INTERFACEKEY_D_MILITARY_UNIFORMS,
+ INTERFACEKEY_D_MILITARY_SUPPLIES,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_DOWN,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_UP,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_DOWN,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_UP,
+ INTERFACEKEY_D_MILITARY_AMMUNITION,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_ADD_ITEM,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_REMOVE_ITEM,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_MATERIAL,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_COMBAT,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_TRAINING,
+ INTERFACEKEY_D_MILITARY_TRAINING,
+ INTERFACEKEY_D_MILITARY_SCHEDULE,
+ INTERFACEKEY_D_MILITARY_ADD_UNIFORM,
+ INTERFACEKEY_D_MILITARY_DELETE_UNIFORM,
+ INTERFACEKEY_D_MILITARY_NAME_UNIFORM,
+ INTERFACEKEY_D_MILITARY_NAME_SQUAD,
+ INTERFACEKEY_D_MILITARY_ADD_ARMOR,
+ INTERFACEKEY_D_MILITARY_ADD_PANTS,
+ INTERFACEKEY_D_MILITARY_ADD_HELM,
+ INTERFACEKEY_D_MILITARY_ADD_GLOVES,
+ INTERFACEKEY_D_MILITARY_ADD_BOOTS,
+ INTERFACEKEY_D_MILITARY_ADD_SHIELD,
+ INTERFACEKEY_D_MILITARY_ADD_WEAPON,
+ INTERFACEKEY_D_MILITARY_ADD_MATERIAL,
+ INTERFACEKEY_D_MILITARY_ADD_COLOR,
+ INTERFACEKEY_D_MILITARY_REPLACE_CLOTHING,
+ INTERFACEKEY_D_MILITARY_EXACT_MATCH,
+ INTERFACEKEY_D_SQUADS_MOVE,
+ INTERFACEKEY_D_SQUADS_KILL,
+ INTERFACEKEY_D_SQUADS_KILL_LIST,
+ INTERFACEKEY_D_SQUADS_KILL_RECT,
+ INTERFACEKEY_D_SQUADS_SCHEDULE,
+ INTERFACEKEY_D_SQUADS_CANCEL_ORDER,
+ INTERFACEKEY_D_SQUADS_ALERT,
+ INTERFACEKEY_D_SQUADS_SELECT_INDIVIDUALS,
+ INTERFACEKEY_D_SQUADS_CENTER,
+ INTERFACEKEY_D_SQUAD_SCH_SLEEP,
+ INTERFACEKEY_D_SQUAD_SCH_CIVILIAN_UNIFORM,
+ INTERFACEKEY_D_SQUAD_SCH_GIVE_ORDER,
+ INTERFACEKEY_D_SQUAD_SCH_EDIT_ORDER,
+ INTERFACEKEY_D_SQUAD_SCH_CANCEL_ORDER,
+ INTERFACEKEY_D_SQUAD_SCH_COPY_ORDERS,
+ INTERFACEKEY_D_SQUAD_SCH_PASTE_ORDERS,
+ INTERFACEKEY_D_SQUAD_SCH_MS_NAME,
+
+ //TEXTENTRY
+ INTERFACEKEY_STRING_A000,
+ INTERFACEKEY_STRING_A001,
+ INTERFACEKEY_STRING_A002,
+ INTERFACEKEY_STRING_A003,
+ INTERFACEKEY_STRING_A004,
+ INTERFACEKEY_STRING_A005,
+ INTERFACEKEY_STRING_A006,
+ INTERFACEKEY_STRING_A007,
+ INTERFACEKEY_STRING_A008,
+ INTERFACEKEY_STRING_A009,
+ INTERFACEKEY_STRING_A010,
+ INTERFACEKEY_STRING_A011,
+ INTERFACEKEY_STRING_A012,
+ INTERFACEKEY_STRING_A013,
+ INTERFACEKEY_STRING_A014,
+ INTERFACEKEY_STRING_A015,
+ INTERFACEKEY_STRING_A016,
+ INTERFACEKEY_STRING_A017,
+ INTERFACEKEY_STRING_A018,
+ INTERFACEKEY_STRING_A019,
+ INTERFACEKEY_STRING_A020,
+ INTERFACEKEY_STRING_A021,
+ INTERFACEKEY_STRING_A022,
+ INTERFACEKEY_STRING_A023,
+ INTERFACEKEY_STRING_A024,
+ INTERFACEKEY_STRING_A025,
+ INTERFACEKEY_STRING_A026,
+ INTERFACEKEY_STRING_A027,
+ INTERFACEKEY_STRING_A028,
+ INTERFACEKEY_STRING_A029,
+ INTERFACEKEY_STRING_A030,
+ INTERFACEKEY_STRING_A031,
+ INTERFACEKEY_STRING_A032,
+ INTERFACEKEY_STRING_A033,
+ INTERFACEKEY_STRING_A034,
+ INTERFACEKEY_STRING_A035,
+ INTERFACEKEY_STRING_A036,
+ INTERFACEKEY_STRING_A037,
+ INTERFACEKEY_STRING_A038,
+ INTERFACEKEY_STRING_A039,
+ INTERFACEKEY_STRING_A040,
+ INTERFACEKEY_STRING_A041,
+ INTERFACEKEY_STRING_A042,
+ INTERFACEKEY_STRING_A043,
+ INTERFACEKEY_STRING_A044,
+ INTERFACEKEY_STRING_A045,
+ INTERFACEKEY_STRING_A046,
+ INTERFACEKEY_STRING_A047,
+ INTERFACEKEY_STRING_A048,
+ INTERFACEKEY_STRING_A049,
+ INTERFACEKEY_STRING_A050,
+ INTERFACEKEY_STRING_A051,
+ INTERFACEKEY_STRING_A052,
+ INTERFACEKEY_STRING_A053,
+ INTERFACEKEY_STRING_A054,
+ INTERFACEKEY_STRING_A055,
+ INTERFACEKEY_STRING_A056,
+ INTERFACEKEY_STRING_A057,
+ INTERFACEKEY_STRING_A058,
+ INTERFACEKEY_STRING_A059,
+ INTERFACEKEY_STRING_A060,
+ INTERFACEKEY_STRING_A061,
+ INTERFACEKEY_STRING_A062,
+ INTERFACEKEY_STRING_A063,
+ INTERFACEKEY_STRING_A064,
+ INTERFACEKEY_STRING_A065,
+ INTERFACEKEY_STRING_A066,
+ INTERFACEKEY_STRING_A067,
+ INTERFACEKEY_STRING_A068,
+ INTERFACEKEY_STRING_A069,
+ INTERFACEKEY_STRING_A070,
+ INTERFACEKEY_STRING_A071,
+ INTERFACEKEY_STRING_A072,
+ INTERFACEKEY_STRING_A073,
+ INTERFACEKEY_STRING_A074,
+ INTERFACEKEY_STRING_A075,
+ INTERFACEKEY_STRING_A076,
+ INTERFACEKEY_STRING_A077,
+ INTERFACEKEY_STRING_A078,
+ INTERFACEKEY_STRING_A079,
+ INTERFACEKEY_STRING_A080,
+ INTERFACEKEY_STRING_A081,
+ INTERFACEKEY_STRING_A082,
+ INTERFACEKEY_STRING_A083,
+ INTERFACEKEY_STRING_A084,
+ INTERFACEKEY_STRING_A085,
+ INTERFACEKEY_STRING_A086,
+ INTERFACEKEY_STRING_A087,
+ INTERFACEKEY_STRING_A088,
+ INTERFACEKEY_STRING_A089,
+ INTERFACEKEY_STRING_A090,
+ INTERFACEKEY_STRING_A091,
+ INTERFACEKEY_STRING_A092,
+ INTERFACEKEY_STRING_A093,
+ INTERFACEKEY_STRING_A094,
+ INTERFACEKEY_STRING_A095,
+ INTERFACEKEY_STRING_A096,
+ INTERFACEKEY_STRING_A097,
+ INTERFACEKEY_STRING_A098,
+ INTERFACEKEY_STRING_A099,
+ INTERFACEKEY_STRING_A100,
+ INTERFACEKEY_STRING_A101,
+ INTERFACEKEY_STRING_A102,
+ INTERFACEKEY_STRING_A103,
+ INTERFACEKEY_STRING_A104,
+ INTERFACEKEY_STRING_A105,
+ INTERFACEKEY_STRING_A106,
+ INTERFACEKEY_STRING_A107,
+ INTERFACEKEY_STRING_A108,
+ INTERFACEKEY_STRING_A109,
+ INTERFACEKEY_STRING_A110,
+ INTERFACEKEY_STRING_A111,
+ INTERFACEKEY_STRING_A112,
+ INTERFACEKEY_STRING_A113,
+ INTERFACEKEY_STRING_A114,
+ INTERFACEKEY_STRING_A115,
+ INTERFACEKEY_STRING_A116,
+ INTERFACEKEY_STRING_A117,
+ INTERFACEKEY_STRING_A118,
+ INTERFACEKEY_STRING_A119,
+ INTERFACEKEY_STRING_A120,
+ INTERFACEKEY_STRING_A121,
+ INTERFACEKEY_STRING_A122,
+ INTERFACEKEY_STRING_A123,
+ INTERFACEKEY_STRING_A124,
+ INTERFACEKEY_STRING_A125,
+ INTERFACEKEY_STRING_A126,
+ INTERFACEKEY_STRING_A128,
+ INTERFACEKEY_STRING_A129,
+ INTERFACEKEY_STRING_A130,
+ INTERFACEKEY_STRING_A131,
+ INTERFACEKEY_STRING_A132,
+ INTERFACEKEY_STRING_A133,
+ INTERFACEKEY_STRING_A134,
+ INTERFACEKEY_STRING_A135,
+ INTERFACEKEY_STRING_A136,
+ INTERFACEKEY_STRING_A137,
+ INTERFACEKEY_STRING_A138,
+ INTERFACEKEY_STRING_A139,
+ INTERFACEKEY_STRING_A140,
+ INTERFACEKEY_STRING_A141,
+ INTERFACEKEY_STRING_A142,
+ INTERFACEKEY_STRING_A143,
+ INTERFACEKEY_STRING_A144,
+ INTERFACEKEY_STRING_A145,
+ INTERFACEKEY_STRING_A146,
+ INTERFACEKEY_STRING_A147,
+ INTERFACEKEY_STRING_A148,
+ INTERFACEKEY_STRING_A149,
+ INTERFACEKEY_STRING_A150,
+ INTERFACEKEY_STRING_A151,
+ INTERFACEKEY_STRING_A152,
+ INTERFACEKEY_STRING_A153,
+ INTERFACEKEY_STRING_A154,
+ INTERFACEKEY_STRING_A155,
+ INTERFACEKEY_STRING_A156,
+ INTERFACEKEY_STRING_A157,
+ INTERFACEKEY_STRING_A158,
+ INTERFACEKEY_STRING_A159,
+ INTERFACEKEY_STRING_A160,
+ INTERFACEKEY_STRING_A161,
+ INTERFACEKEY_STRING_A162,
+ INTERFACEKEY_STRING_A163,
+ INTERFACEKEY_STRING_A164,
+ INTERFACEKEY_STRING_A165,
+ INTERFACEKEY_STRING_A166,
+ INTERFACEKEY_STRING_A167,
+ INTERFACEKEY_STRING_A168,
+ INTERFACEKEY_STRING_A169,
+ INTERFACEKEY_STRING_A170,
+ INTERFACEKEY_STRING_A171,
+ INTERFACEKEY_STRING_A172,
+ INTERFACEKEY_STRING_A173,
+ INTERFACEKEY_STRING_A174,
+ INTERFACEKEY_STRING_A175,
+ INTERFACEKEY_STRING_A176,
+ INTERFACEKEY_STRING_A177,
+ INTERFACEKEY_STRING_A178,
+ INTERFACEKEY_STRING_A179,
+ INTERFACEKEY_STRING_A180,
+ INTERFACEKEY_STRING_A181,
+ INTERFACEKEY_STRING_A182,
+ INTERFACEKEY_STRING_A183,
+ INTERFACEKEY_STRING_A184,
+ INTERFACEKEY_STRING_A185,
+ INTERFACEKEY_STRING_A186,
+ INTERFACEKEY_STRING_A187,
+ INTERFACEKEY_STRING_A188,
+ INTERFACEKEY_STRING_A189,
+ INTERFACEKEY_STRING_A190,
+ INTERFACEKEY_STRING_A191,
+ INTERFACEKEY_STRING_A192,
+ INTERFACEKEY_STRING_A193,
+ INTERFACEKEY_STRING_A194,
+ INTERFACEKEY_STRING_A195,
+ INTERFACEKEY_STRING_A196,
+ INTERFACEKEY_STRING_A197,
+ INTERFACEKEY_STRING_A198,
+ INTERFACEKEY_STRING_A199,
+ INTERFACEKEY_STRING_A200,
+ INTERFACEKEY_STRING_A201,
+ INTERFACEKEY_STRING_A202,
+ INTERFACEKEY_STRING_A203,
+ INTERFACEKEY_STRING_A204,
+ INTERFACEKEY_STRING_A205,
+ INTERFACEKEY_STRING_A206,
+ INTERFACEKEY_STRING_A207,
+ INTERFACEKEY_STRING_A208,
+ INTERFACEKEY_STRING_A209,
+ INTERFACEKEY_STRING_A210,
+ INTERFACEKEY_STRING_A211,
+ INTERFACEKEY_STRING_A212,
+ INTERFACEKEY_STRING_A213,
+ INTERFACEKEY_STRING_A214,
+ INTERFACEKEY_STRING_A215,
+ INTERFACEKEY_STRING_A216,
+ INTERFACEKEY_STRING_A217,
+ INTERFACEKEY_STRING_A218,
+ INTERFACEKEY_STRING_A219,
+ INTERFACEKEY_STRING_A220,
+ INTERFACEKEY_STRING_A221,
+ INTERFACEKEY_STRING_A222,
+ INTERFACEKEY_STRING_A223,
+ INTERFACEKEY_STRING_A224,
+ INTERFACEKEY_STRING_A225,
+ INTERFACEKEY_STRING_A226,
+ INTERFACEKEY_STRING_A227,
+ INTERFACEKEY_STRING_A228,
+ INTERFACEKEY_STRING_A229,
+ INTERFACEKEY_STRING_A230,
+ INTERFACEKEY_STRING_A231,
+ INTERFACEKEY_STRING_A232,
+ INTERFACEKEY_STRING_A233,
+ INTERFACEKEY_STRING_A234,
+ INTERFACEKEY_STRING_A235,
+ INTERFACEKEY_STRING_A236,
+ INTERFACEKEY_STRING_A237,
+ INTERFACEKEY_STRING_A238,
+ INTERFACEKEY_STRING_A239,
+ INTERFACEKEY_STRING_A240,
+ INTERFACEKEY_STRING_A241,
+ INTERFACEKEY_STRING_A242,
+ INTERFACEKEY_STRING_A243,
+ INTERFACEKEY_STRING_A244,
+ INTERFACEKEY_STRING_A245,
+ INTERFACEKEY_STRING_A246,
+ INTERFACEKEY_STRING_A247,
+ INTERFACEKEY_STRING_A248,
+ INTERFACEKEY_STRING_A249,
+ INTERFACEKEY_STRING_A250,
+ INTERFACEKEY_STRING_A251,
+ INTERFACEKEY_STRING_A252,
+ INTERFACEKEY_STRING_A253,
+ INTERFACEKEY_STRING_A254,
+ INTERFACEKEY_STRING_A255,
+ INTERFACEKEY_KEYBINDING_COMPLETE,
+ INTERFACEKEYNUM,
+};
+
+extern bimap<InterfaceKey,std::string> bindingNames;
+extern bimap<InterfaceKey,std::string> displayNames;
+extern bimap<SDLKey,std::string> sdlNames;
+
+void keybinding_init();
+
+#endif
diff --git a/g_src/mail.hpp b/g_src/mail.hpp new file mode 100755 index 0000000..b158e31 --- /dev/null +++ b/g_src/mail.hpp @@ -0,0 +1,155 @@ +#ifndef MAIL_H +#define MAIL_H + +#include <SDL/SDL.h> +#include <SDL/SDL_thread.h> +#include <queue> + +template <typename T> +class MBox { + T val; + SDL_sem *fill, *empty; +public: + bool try_read(T &r) { // Attempt to read the mbox. Returns true if read succeeded. + if (SDL_SemTryWait(fill) == 0) { + r = val; + SDL_SemPost(empty); + return true; + } else + return false; + } + void read(T &r) { + SDL_SemWait(fill); + r = val; + SDL_SemPost(empty); + } + void write(const T &v) { + SDL_SemWait(empty); + val = v; + SDL_SemPost(fill); + } + bool try_write(const T &v) { // Returns true if the write succeeded + if (SDL_SemTryWait(empty) == 0) { + val = v; + SDL_SemPost(fill); + return true; + } else + return false; + } + MBox(T &v) { + MBox(); + write(v); + } + MBox() { + fill = SDL_CreateSemaphore(0); + empty = SDL_CreateSemaphore(1); + } + ~MBox() { + SDL_DestroySemaphore(fill); + SDL_DestroySemaphore(empty); + } +}; + +template <typename T> +class MVar { + SDL_sem *s; +public: + T val; + void lock() { SDL_SemWait(s); } + void unlock() { SDL_SemPost(s); } + MVar() { s = SDL_CreateSemaphore(1); } + ~MVar() { SDL_DestroySemaphore(s); } + void write(const T &w) { lock(); val = w; unlock(); } + void read(T &r) { lock(); r = val; unlock(); } + T read() { T r; read(r); return r; } +}; + + +template<bool start_locked = false> +class Lock { + SDL_sem *s; +public: + void lock() { SDL_SemWait(s); } + void unlock() { SDL_SemPost(s); } + Lock() { s = SDL_CreateSemaphore(start_locked ? 0 : 1); } + ~Lock() { SDL_DestroySemaphore(s); } +}; + + +template<typename T> +class Chan { + MVar<std::queue<T> > vals; + SDL_sem *fill; +public: + bool try_read(T &r) { + if (SDL_SemTryWait(fill) == 0) { + vals.lock(); + r = vals.val.front(); + vals.val.pop(); + vals.unlock(); + return true; + } else + return false; + } + void read(T &r) { + SDL_SemWait(fill); + vals.lock(); + r = vals.val.front(); + vals.val.pop(); + vals.unlock(); + } + void write(const T &w) { + vals.lock(); + vals.val.push(w); + vals.unlock(); + SDL_SemPost(fill); + } + Chan() { + fill = SDL_CreateSemaphore(0); + } + ~Chan() { + SDL_DestroySemaphore(fill); + } +}; + +template<> +class Chan<void> { + SDL_sem *fill; +public: + bool try_read() { + if (SDL_SemTryWait(fill) == 0) + return true; + return false; + } + void read() { + SDL_SemWait(fill); + } + void write() { + SDL_SemPost(fill); + } + Chan() { + fill = SDL_CreateSemaphore(0); + } + ~Chan() { + SDL_DestroySemaphore(fill); + } +}; + +template<typename L, typename R> +struct Either { + bool isL; + union { + L left; + R right; + }; + Either(const L &l) { + isL = true; + left = l; + } + Either(const R &r) { + isL = false; + right = r; + } +}; + +#endif diff --git a/g_src/music_and_sound_fmodex.cpp b/g_src/music_and_sound_fmodex.cpp new file mode 100755 index 0000000..7262c94 --- /dev/null +++ b/g_src/music_and_sound_fmodex.cpp @@ -0,0 +1,308 @@ +#ifndef NO_FMOD + +#include "platform.h" +#include <string.h> +#include <math.h> +#include <iosfwd> +#include <iostream> +#include <ios> +#include <streambuf> +#include <istream> +#include <ostream> +#include <iomanip> +#include <sstream> +#include <cstdlib> +#include <fstream> +#include <map> + +#include "svector.h" + +#ifdef WIN32 + +#ifndef INTEGER_TYPES + #define INTEGER_TYPES + typedef short int16_t; + typedef int int32_t; + typedef long long int64_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; +#endif + +typedef int32_t VIndex; +typedef int32_t Ordinal; + +#endif + +#include "random.h" + +using std::string; +using std::map; +using std::pair; + +#include "basics.h" +#include "endian.h" +#include "files.h" +#include "enabler.h" +#include "init.h" + +#include "music_and_sound_fmodex.h" +#include "music_and_sound_v.h" + +void musicsoundst::startbackgroundmusic(int new_song) +{ + if (!on || new_song < 0 || new_song > MAXSONGNUM || mod[new_song].sound == NULL) { + return; + } + + if (song != new_song) { + + stopbackgroundmusic(); /* This is safe to call, even if song isn't valid. */ + + song = new_song; + FMOD_CHANNELINDEX cid = static_cast<FMOD_CHANNELINDEX>(0); + system->playSound(cid, mod[song].sound, false, &mod[song].channel); + } +} + +void musicsoundst::stopbackgroundmusic() +{ + if (!on || song == -1) { + return; + } + + if (mod[song].channel != NULL) { + mod[song].channel->stop(); + mod[song].channel = NULL; + } + + song = -1; +} + +/* Set channel to less than 0 to have FMOD decide the channel for you. */ +void musicsoundst::playsound(int s,int channel) +{ + if (!on || s < 0 || s > MAXSOUNDNUM || samp[s].sound == NULL) { + return; + } + + if (channel >= 0) { + FMOD_CHANNELINDEX cid = static_cast<FMOD_CHANNELINDEX>(channel); + system->playSound(cid, samp[s].sound, false, &samp[s].channel); + } else { + system->playSound(FMOD_CHANNEL_FREE, samp[s].sound, false, &samp[s].channel); + } +} + +// Toady: +/* Yeah, I started porting all that other crap, but it wasn't all applicable to ex + * and besides which, you never call it anyway. + */ +void musicsoundst::playsound(int s, int min_channel, int max_channel, int force_channel) +{ + if (!on || s < 0 || s > MAXSOUNDNUM || samp[s].sound == NULL) { + return; + } + + playsound(s, force_channel); +} + +// Prints a relevent error message to stderr. +inline void err(FMOD_RESULT r) +{ + std::cerr << "sound: failure: " << FMOD_ErrorString(r) << std::endl; +} + +void musicsoundst::initsound() +{ + FMOD_RESULT result = FMOD::System_Create(&system); + if (result != FMOD_OK) { + err(result); + on = 0; + return; + } + +#if defined(linux) + /* Set up the sound system. Default to ALSA. */ + switch (this->sound_system) { + default: + case ALSA: + result = system->setOutput(FMOD_OUTPUTTYPE_ALSA); + break; + case OSS: + result = system->setOutput(FMOD_OUTPUTTYPE_OSS); + break; + case ESD: + result = system->setOutput(FMOD_OUTPUTTYPE_ESD); + break; + } + if (result != FMOD_OK) { + err(result); + on = 0; + return; + } +#endif + + SoftChannelNumber = SOUND_CHANNELNUM; + result = system->init(SoftChannelNumber, FMOD_INIT_NORMAL, NULL); + if (result != FMOD_OK) { + err(result); + on = 0; + return; + } + + result = system->getMasterChannelGroup(&masterchannelgroup); + if (result != FMOD_OK) { + err(result); + on = 0; + return; + } + + set_master_volume(init.media.volume); + + on = 1; +} + +void musicsoundst::deinitsound() +{ + if (!on) { + return; + } + + int s; + for (s = 0; s < MAXSONGNUM; s++) { + if (mod[s].sound != NULL) { + mod[s].sound->release(); + mod[s].sound = NULL; + mod[s].channel = NULL; + } + } + + for (s = 0; s < MAXSOUNDNUM; s++) { + if (samp[s].sound != NULL) { + samp[s].sound->release(); + samp[s].sound = NULL; + samp[s].channel = NULL; + } + } + + system->release(); + on = 0; +} + + + +void musicsoundst::set_song(string &filename, int slot) +{ + if (!on || slot < 0 || slot > MAXSONGNUM) { + return; + } + + if (mod[slot].sound != NULL) { + mod[slot].sound->release(); + mod[slot].sound = NULL; + mod[slot].channel = NULL; + } + + FMOD_RESULT result = system->createSound(filename.c_str(), FMOD_DEFAULT, 0, &mod[slot].sound); + if (result != FMOD_OK) { + mod[slot].sound = NULL; + mod[slot].channel = NULL; + return; + } + + mod[slot].sound->setMode(FMOD_LOOP_NORMAL); +} + +void musicsoundst::set_sound(string &filename, int slot, int pan, int priority) +{ + if (!on || slot < 0 || slot > MAXSOUNDNUM) { + return; + } + + if (samp[slot].sound != NULL) { + samp[slot].sound->release(); + samp[slot].sound = NULL; + samp[slot].channel = NULL; + } + + FMOD_RESULT result = system->createSound(filename.c_str(), FMOD_DEFAULT, 0, &samp[slot].sound); + if (result != FMOD_OK) { + samp[slot].sound = NULL; + samp[slot].channel = NULL; + return; + } +} + +void musicsoundst::set_sound_params(int slot, int p1, int vol, int pan, int priority) +{ + if (slot < 0 || slot > MAXSOUNDNUM) { + return; + } if (samp[slot].channel == NULL || on == 0) { + return; + } + + samp[slot].channel->setPan(oldval_to_panfloat(pan)); + samp[slot].channel->setVolume(oldval_to_volumefloat(vol)); + samp[slot].channel->setPriority(oldval_to_priority(priority)); + samp[slot].channel->setFrequency(static_cast<float>(p1)); +} + +void musicsoundst::stop_sound(int channel) +{ + FMOD::Channel* c; + + FMOD_RESULT result = system->getChannel((int)channel, &c); + if (result != FMOD_OK) { + return; + } + + c->stop(); +} + + +void musicsoundst::set_master_volume(long newvol) +{ + masterchannelgroup->setVolume(oldval_to_volumefloat(newvol)); +} + +// Converts old FMOD 3 0 - 255 volume values to FMOD Ex 0.0 <-> 1.0 float values. +float musicsoundst::oldval_to_volumefloat(int val) +{ + if (val < 0) { + return 0.0; + } else if (val > 255) { + return 1.0; + } + + return static_cast<float>(val) / 255; +} + +// Converts old FMOD 3 0 - 255 pan values to FMOD Ex -1.0 <-> 1.0 float values. +float musicsoundst::oldval_to_panfloat(int val) +{ + if (val < 0) { + return -1.0; + } else if (val > 255) { + return 1.0; + } + + float n = static_cast<float>(val) / 255; + return (n * 2) - 1.0; +} + +// Converts old FMOD 3 0(lowest) - 255(highest) priority values to +// FmodEx 0(highest) - 256(lowest) priority values. +int musicsoundst::oldval_to_priority(int val) +{ + if (val < 0) { + return 256; + } else if (val > 255) { + return 0; + } + + return 255 - val; +} + +#endif // NO_FMOD + diff --git a/g_src/music_and_sound_fmodex.h b/g_src/music_and_sound_fmodex.h new file mode 100755 index 0000000..444d555 --- /dev/null +++ b/g_src/music_and_sound_fmodex.h @@ -0,0 +1,102 @@ +//copyright (c) 2006 by tarn adams + +#define SOUND_CHANNELNUM 16 + +#include <string> +#include <map> + +#ifndef NO_FMOD + +#include <fmod.hpp> +#include <fmod_errors.h> + +/* The maximums can be no larger than the largest value + * of a signed integer. + */ +#define MAXSONGNUM 1000 +#define MAXSOUNDNUM 1000 +#define FSOUND_STEREOPAN 0 + +struct fmodSound { + FMOD::Sound *sound; + FMOD::Channel *channel; +}; + + + +class musicsoundst +{ + public: + enum linux_sound_system { + ALSA, + OSS, + ESD, + }; + + int SoftChannelNumber; + + musicsoundst() : song(-1), system(NULL), masterchannelgroup(NULL), sound_system(ALSA) + { + int s; + for (s = 0; s < MAXSONGNUM; s++) { + mod[s].sound = NULL; + mod[s].channel = NULL; + } + + for (s = 0; s < MAXSOUNDNUM; s++) { + samp[s].sound = NULL; + samp[s].channel = NULL; + } + } + ~musicsoundst() + { + deinitsound(); + } + + void startbackgroundmusic(int new_song); + void stopbackgroundmusic(); + void playsound(int s,int channel=-1); + void playsound(int s,int min_channel,int max_channel,int force_channel); + void initsound(); + void deinitsound(); + void set_song(string &filename,int slot); + void set_sound(string &filename,int slot,int pan=-1,int priority=0); + void set_sound_params(int slot,int p1,int vol,int pan,int priority); + void stop_sound(int channel); + void stop_sound() { + masterchannelgroup->stop(); + } + void set_master_volume(long newvol); + void update() { + if (!on) { + return; + } + + system->update(); + } + + void set_sound_system(musicsoundst::linux_sound_system system) { + sound_system = system; + } + + private: + float oldval_to_volumefloat(int val); + float oldval_to_panfloat(int val); + int oldval_to_priority(int val); + + int song; + char musicactive; + char soundpriority; + int soundplaying; + + char on; + + FMOD::System *system; + FMOD::ChannelGroup *masterchannelgroup; + fmodSound mod[MAXSONGNUM]; + fmodSound samp[MAXSOUNDNUM]; + + musicsoundst::linux_sound_system sound_system; +}; +#endif + diff --git a/g_src/music_and_sound_g.h b/g_src/music_and_sound_g.h new file mode 100755 index 0000000..dc9acb0 --- /dev/null +++ b/g_src/music_and_sound_g.h @@ -0,0 +1,13 @@ +#ifndef MUSIC_AND_SOUND_G +#define MUSIC_AND_SOUND_G + +// Fmodex works well enough on windows/os x, but on some linux distributions it fails badly +#if defined(linux) +#include "music_and_sound_openal.h" +#else +#include "music_and_sound_fmodex.h" +#endif // unix + +extern musicsoundst musicsound; + +#endif diff --git a/g_src/music_and_sound_openal.cpp b/g_src/music_and_sound_openal.cpp new file mode 100755 index 0000000..1ee0941 --- /dev/null +++ b/g_src/music_and_sound_openal.cpp @@ -0,0 +1,688 @@ +#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "music_and_sound_openal.h"
+#include "music_and_sound_v.h"
+
+#define ABORT(str) do { printf("%s: line %d: %s\n", __FILE__, __LINE__, str); abort(); } while(0);
+static bool init_openal();
+static bool init_sndfile();
+
+using namespace std;
+
+#define alPrintErrors() do { alPrintErrors_(__FILE__,__LINE__); } while(0);
+
+static void alPrintErrors_(const char* file, int line) {
+ ALenum err;
+ while ((err = alGetError()) != AL_NO_ERROR) {
+ printf("At %s: %d: ", file, line);
+ switch (err) {
+ case AL_INVALID_NAME: puts("AL_INVALID_NAME detected"); break;
+ case AL_INVALID_ENUM: puts("AL_INVALID_ENUM detected"); break;
+ case AL_INVALID_VALUE: puts("AL_INVALID_VALUE detected"); break;
+ case AL_INVALID_OPERATION: puts("AL_INVALID_OPERATION detected"); break;
+ case AL_OUT_OF_MEMORY: puts("AL_OUT_OF_MEMORY detected"); break;
+ }
+ }
+}
+
+bool musicsoundst::initsound() {
+ if (functional) return true;
+
+ // Load the libraries
+ if (!init_openal()) {
+ puts("Dynamically loading the OpenAL library failed, disabling sound");
+ MessageBox(NULL, "Dynamically loading the OpenAL library failed, disabling sound", 0, 0);
+ return false;
+ }
+ if (!init_sndfile()) {
+ puts("Dynamically loading the sndfile library failed, disabling sound");
+ MessageBox(NULL, "Dynamically loading the sndfile library failed, disabling sound", 0, 0);
+ return false;
+ }
+
+ // Find out what devices we have available
+ const char *devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+ if (!devices) {
+ puts("No sound devices available. Sound disabled. OpenAL broken?");
+ return false;
+ }
+
+ const char *firstdevice = devices;
+ puts("Sound devices available:");
+ while (*devices) {
+ puts(devices);
+ devices += strlen(devices) + 1;
+ }
+ printf("Picking %s. If your desired device was missing, make sure you have the appropriate 32-bit libraries installed. If you wanted a different device, configure ~/.openalrc appropriately.\n",
+ firstdevice);
+
+ // Create the context
+ device = alcOpenDevice(firstdevice);
+ if (!device)
+ return false;
+
+ const ALCint attrlist[] = { ALC_FREQUENCY, SOUND_FREQUENCY,
+ ALC_MONO_SOURCES, 0,
+ ALC_STEREO_SOURCES, SOUND_CHANNELNUM };
+ context = alcCreateContext(device, attrlist);
+ if (context) {
+ puts("Perfect OpenAL context attributes GET");
+ goto done;
+ }
+ context = alcCreateContext(device, NULL);
+ if (context) {
+ puts("Using OpenAL in compatibility mode");
+ goto done;
+ }
+ alcCloseDevice(device);
+ return false;
+
+ done:
+ if (ALC_FALSE == alcMakeContextCurrent(context)) {
+ puts("alcMakeContextCurrent failed");
+ return false;
+ }
+ functional = true;
+ return true;
+}
+
+// int main() {
+// musicsound.initsound();
+// string str = "data/sound/song_title.ogg";
+// musicsound.set_song(str, 14);
+// musicsound.startbackgroundmusic(14);
+// sleep(9999);
+// exit(1);
+// }
+
+void musicsoundst::set_song(string &filename, slot slot) {
+ if (!functional) return;
+
+ // printf("%s requested in %d-%d\n", filename.c_str(), (int)slot.first, slot.second);
+ if (!buffers.count(filename)) {
+ // Song not already loaded. Load it.
+ SF_INFO sfinfo;
+ sfinfo.format = 0;
+ SNDFILE *sf = sf_open(filename.c_str(), SFM_READ, &sfinfo);
+ if (!sf) {
+ printf("%s not found, sound not loaded\n", filename.c_str());
+ goto end;
+ }
+ short *buffer = new short[sfinfo.channels * sfinfo.frames];
+ sf_count_t frames_read = sf_readf_short(sf, buffer, sfinfo.frames);
+ if (frames_read != sfinfo.frames)
+ printf("%s: %d frames requested, %d frames read. Corrupted file?\n",
+ filename.c_str(), (int)sfinfo.frames, (int)frames_read);
+ sf_close(sf);
+ // Construct openal buffer and load this
+ ALuint albuf;
+ alGenBuffers(1, &albuf);
+ if (!alIsBuffer(albuf)) {
+ puts("Constructing OpenAL buffer mysteriously failed!");
+ goto end;
+ }
+ ALenum format;
+ switch (sfinfo.channels) {
+ case 1: format = AL_FORMAT_MONO16;
+ break;
+ case 2: format = AL_FORMAT_STEREO16;
+ break;
+ default:
+ printf("%s: Unexpected number of channels: %d\n",
+ filename.c_str(), (int)sfinfo.channels);
+ goto end;
+ }
+ alBufferData(albuf, format, (ALvoid*)buffer,
+ sfinfo.channels * sfinfo.frames * 2, sfinfo.samplerate);
+ alPrintErrors();
+ delete[] buffer;
+
+ // Create a source for this song
+ ALuint source;
+ alGenSources(1, &source);
+ if (!alIsSource(source)) {
+ puts("Constructing OpenAL source mysteriously failed!");
+ goto end;
+ }
+ alSourceQueueBuffers(source, 1, &albuf);
+
+ buffers[filename] = albuf;
+ sources[filename] = source;
+ }
+
+ // Store the requested song in the requested slot.
+ // Say, should this alter the playing song if that slot is already playing?
+ slot_buffer[slot] = buffers[filename];
+ slot_source[slot] = sources[filename];
+
+ end:
+ alPrintErrors();
+}
+
+void musicsoundst::set_song(string &filename, int slot) {
+ set_song(filename, make_pair(true, slot));
+}
+
+void musicsoundst::set_master_volume(long newvol) {
+ if (!functional) return;
+ alListenerf(AL_GAIN, newvol / 255.0f);
+}
+
+void musicsoundst::playsound(slot slot) {
+ if (!functional) return;
+ // printf("%d requested\n", slot);
+ if (!slot_source.count(slot)) {
+ // printf("Slot %d-%d requested, but no song loaded\n", (int)slot.first, slot.second);
+ return;
+ }
+ if (background_slot == slot) {
+ puts("playsound called on background song, background song cancelled!?");
+ background_slot = make_pair(false,-1);
+ }
+ alSourcei(slot_source[slot], AL_LOOPING, AL_FALSE);
+ alSourcePlay(slot_source[slot]);
+ alPrintErrors();
+}
+
+void musicsoundst::playsound(int slot) {
+ playsound(make_pair(false,slot));
+}
+
+void musicsoundst::startbackgroundmusic(slot slot) {
+ if (!functional) return;
+
+ if (!slot_source.count(slot)) {
+ // printf("Slot %d-%d requested, but no song loaded\n", (int)slot.first, slot.second);
+ return;
+ }
+
+ if (background_slot == slot)
+ return; // Verily, it is already playing
+ stop_sound(background_slot);
+ background_slot = slot;
+ // printf("%d backgrounded\n", slot);
+
+ alSourcei(slot_source[slot], AL_LOOPING, AL_TRUE);
+ alSourcePlay(slot_source[slot]);
+ alPrintErrors();
+}
+
+void musicsoundst::startbackgroundmusic(int slot) {
+ startbackgroundmusic(make_pair(true,slot));
+}
+
+void musicsoundst::stopbackgroundmusic() {
+ if (!functional) return;
+ if (background_slot == make_pair(false,-1)) return;
+
+ alSourceStop(slot_source[background_slot]);
+}
+
+void musicsoundst::stop_sound() {
+ if (!functional) return;
+ // Stop all playing sounds. Does this include background music?
+ std::map<std::string,ALuint>::iterator it;
+ for (it = sources.begin(); it != sources.end(); ++it)
+ alSourceStop(it->second);
+}
+
+void musicsoundst::stop_sound(slot slot) {
+ if (!functional) return;
+ if (slot_source.count(slot) == 0) return;
+ ALuint source = slot_source[slot];
+ alSourceStop(source);
+}
+
+void musicsoundst::deinitsound() {
+ if (!functional) return;
+
+ std::map<std::string,ALuint>::iterator it;
+ // Free all sources
+ for (it = sources.begin(); it != sources.end(); ++it) {
+ ALuint source = it->second;
+ alDeleteSources(1, &source);
+ }
+ // Free all sample memory
+ for (it = buffers.begin(); it != buffers.end(); ++it) {
+ ALuint buffer = it->second;
+ alDeleteBuffers(1, &buffer);
+ }
+ // Deinit OpenAL
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(context);
+ alcCloseDevice(device);
+
+ functional=false;
+}
+
+void musicsoundst::set_sound(string &filename, int slot, int pan, int priority) {
+ if (!functional) return;
+ set_song(filename, make_pair(false,slot));
+}
+
+// Deprecated stuff below
+
+void musicsoundst::playsound(int s, int channel) {
+ if (!functional) return;
+ playsound(s);
+}
+
+
+//// OpenAL, ALC and sndfile stub ////
+
+static void (*_alEnable)( ALenum capability );
+static void (*_alDisable)( ALenum capability );
+static ALboolean (*_alIsEnabled)( ALenum capability );
+static const ALchar* (*_alGetString)( ALenum param );
+static void (*_alGetBooleanv)( ALenum param, ALboolean* data );
+static void (*_alGetIntegerv)( ALenum param, ALint* data );
+static void (*_alGetFloatv)( ALenum param, ALfloat* data );
+static void (*_alGetDoublev)( ALenum param, ALdouble* data );
+static ALboolean (*_alGetBoolean)( ALenum param );
+static ALint (*_alGetInteger)( ALenum param );
+static ALfloat (*_alGetFloat)( ALenum param );
+static ALdouble (*_alGetDouble)( ALenum param );
+static ALenum (*_alGetError)( void );
+static ALboolean (*_alIsExtensionPresent)( const ALchar* extname );
+static void* (*_alGetProcAddress)( const ALchar* fname );
+static ALenum (*_alGetEnumValue)( const ALchar* ename );
+static void (*_alListenerf)( ALenum param, ALfloat value );
+static void (*_alListener3f)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
+static void (*_alListenerfv)( ALenum param, const ALfloat* values );
+static void (*_alListeneri)( ALenum param, ALint value );
+static void (*_alListener3i)( ALenum param, ALint value1, ALint value2, ALint value3 );
+static void (*_alListeneriv)( ALenum param, const ALint* values );
+static void (*_alGetListenerf)( ALenum param, ALfloat* value );
+static void (*_alGetListener3f)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
+static void (*_alGetListenerfv)( ALenum param, ALfloat* values );
+static void (*_alGetListeneri)( ALenum param, ALint* value );
+static void (*_alGetListener3i)( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
+static void (*_alGetListeneriv)( ALenum param, ALint* values );
+static void (*_alGenSources)( ALsizei n, ALuint* sources );
+static void (*_alDeleteSources)( ALsizei n, const ALuint* sources );
+static ALboolean (*_alIsSource)( ALuint sid );
+static void (*_alSourcef)( ALuint sid, ALenum param, ALfloat value );
+static void (*_alSource3f)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
+static void (*_alSourcefv)( ALuint sid, ALenum param, const ALfloat* values );
+static void (*_alSourcei)( ALuint sid, ALenum param, ALint value );
+static void (*_alSource3i)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
+static void (*_alSourceiv)( ALuint sid, ALenum param, const ALint* values );
+static void (*_alGetSourcef)( ALuint sid, ALenum param, ALfloat* value );
+static void (*_alGetSource3f)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
+static void (*_alGetSourcefv)( ALuint sid, ALenum param, ALfloat* values );
+static void (*_alGetSourcei)( ALuint sid, ALenum param, ALint* value );
+static void (*_alGetSource3i)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
+static void (*_alGetSourceiv)( ALuint sid, ALenum param, ALint* values );
+static void (*_alSourcePlayv)( ALsizei ns, const ALuint *sids );
+static void (*_alSourceStopv)( ALsizei ns, const ALuint *sids );
+static void (*_alSourceRewindv)( ALsizei ns, const ALuint *sids );
+static void (*_alSourcePausev)( ALsizei ns, const ALuint *sids );
+static void (*_alSourcePlay)( ALuint sid );
+static void (*_alSourceStop)( ALuint sid );
+static void (*_alSourceRewind)( ALuint sid );
+static void (*_alSourcePause)( ALuint sid );
+static void (*_alSourceQueueBuffers)( ALuint sid, ALsizei numEntries, const ALuint *bids );
+static void (*_alSourceUnqueueBuffers)( ALuint sid, ALsizei numEntries, ALuint *bids );
+static void (*_alGenBuffers)( ALsizei n, ALuint* buffers );
+static void (*_alDeleteBuffers)( ALsizei n, const ALuint* buffers );
+static ALboolean (*_alIsBuffer)( ALuint bid );
+static void (*_alBufferData)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
+static void (*_alBufferf)( ALuint bid, ALenum param, ALfloat value );
+static void (*_alBuffer3f)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
+static void (*_alBufferfv)( ALuint bid, ALenum param, const ALfloat* values );
+static void (*_alBufferi)( ALuint bid, ALenum param, ALint value );
+static void (*_alBuffer3i)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
+static void (*_alBufferiv)( ALuint bid, ALenum param, const ALint* values );
+static void (*_alGetBufferf)( ALuint bid, ALenum param, ALfloat* value );
+static void (*_alGetBuffer3f)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
+static void (*_alGetBufferfv)( ALuint bid, ALenum param, ALfloat* values );
+static void (*_alGetBufferi)( ALuint bid, ALenum param, ALint* value );
+static void (*_alGetBuffer3i)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
+static void (*_alGetBufferiv)( ALuint bid, ALenum param, ALint* values );
+static void (*_alDopplerFactor)( ALfloat value );
+static void (*_alDopplerVelocity)( ALfloat value );
+static void (*_alSpeedOfSound)( ALfloat value );
+static void (*_alDistanceModel)( ALenum distanceModel );
+static ALCcontext * (*_alcCreateContext)( ALCdevice *device, const ALCint* attrlist );
+static ALCboolean (*_alcMakeContextCurrent)( ALCcontext *context );
+static void (*_alcProcessContext)( ALCcontext *context );
+static void (*_alcSuspendContext)( ALCcontext *context );
+static void (*_alcDestroyContext)( ALCcontext *context );
+static ALCcontext * (*_alcGetCurrentContext)( void );
+static ALCdevice* (*_alcGetContextsDevice)( ALCcontext *context );
+static ALCdevice * (*_alcOpenDevice)( const ALCchar *devicename );
+static ALCboolean (*_alcCloseDevice)( ALCdevice *device );
+static ALCenum (*_alcGetError)( ALCdevice *device );
+static ALCboolean (*_alcIsExtensionPresent)( ALCdevice *device, const ALCchar *extname );
+static void * (*_alcGetProcAddress)( ALCdevice *device, const ALCchar *funcname );
+static ALCenum (*_alcGetEnumValue)( ALCdevice *device, const ALCchar *enumname );
+static const ALCchar * (*_alcGetString)( ALCdevice *device, ALCenum param );
+static void (*_alcGetIntegerv)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data );
+static ALCdevice* (*_alcCaptureOpenDevice)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
+static ALCboolean (*_alcCaptureCloseDevice)( ALCdevice *device );
+static void (*_alcCaptureStart)( ALCdevice *device );
+static void (*_alcCaptureStop)( ALCdevice *device );
+static void (*_alcCaptureSamples)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
+
+static bool linkit(void **target, const char *symbol, void *handle) {
+ *target = dlsym(handle, symbol);
+ if (!*target) {
+ printf("Failed to link %s\n", symbol);
+ return false;
+ }
+ return true;
+}
+
+static bool init_openal() {
+ void *handle = dlopen("libopenal.so", RTLD_LAZY);
+ if (!handle) handle = dlopen("libopenal.so.1", RTLD_LAZY);
+ if (!handle) return false;
+
+ if (!linkit((void**)&_alEnable, "alEnable", handle)) return false;
+ if (!linkit((void**)&_alDisable, "alDisable", handle)) return false;
+ if (!linkit((void**)&_alIsEnabled, "alIsEnabled", handle)) return false;
+ if (!linkit((void**)&_alGetString, "alGetString", handle)) return false;
+ if (!linkit((void**)&_alGetBooleanv, "alGetBooleanv", handle)) return false;
+ if (!linkit((void**)&_alGetIntegerv, "alGetIntegerv", handle)) return false;
+ if (!linkit((void**)&_alGetFloatv, "alGetFloatv", handle)) return false;
+ if (!linkit((void**)&_alGetDoublev, "alGetDoublev", handle)) return false;
+ if (!linkit((void**)&_alGetBoolean, "alGetBoolean", handle)) return false;
+ if (!linkit((void**)&_alGetInteger, "alGetInteger", handle)) return false;
+ if (!linkit((void**)&_alGetFloat, "alGetFloat", handle)) return false;
+ if (!linkit((void**)&_alGetDouble, "alGetDouble", handle)) return false;
+ if (!linkit((void**)&_alGetError, "alGetError", handle)) return false;
+ if (!linkit((void**)&_alIsExtensionPresent, "alIsExtensionPresent", handle)) return false;
+ if (!linkit((void**)&_alGetProcAddress, "alGetProcAddress", handle)) return false;
+ if (!linkit((void**)&_alGetEnumValue, "alGetEnumValue", handle)) return false;
+ if (!linkit((void**)&_alListenerf, "alListenerf", handle)) return false;
+ if (!linkit((void**)&_alListener3f, "alListener3f", handle)) return false;
+ if (!linkit((void**)&_alListenerfv, "alListenerfv", handle)) return false;
+ if (!linkit((void**)&_alListeneri, "alListeneri", handle)) return false;
+ if (!linkit((void**)&_alListener3i, "alListener3i", handle)) return false;
+ if (!linkit((void**)&_alListeneriv, "alListeneriv", handle)) return false;
+ if (!linkit((void**)&_alGetListenerf, "alGetListenerf", handle)) return false;
+ if (!linkit((void**)&_alGetListener3f, "alGetListener3f", handle)) return false;
+ if (!linkit((void**)&_alGetListenerfv, "alGetListenerfv", handle)) return false;
+ if (!linkit((void**)&_alGetListeneri, "alGetListeneri", handle)) return false;
+ if (!linkit((void**)&_alGetListener3i, "alGetListener3i", handle)) return false;
+ if (!linkit((void**)&_alGetListeneriv, "alGetListeneriv", handle)) return false;
+ if (!linkit((void**)&_alGenSources, "alGenSources", handle)) return false;
+ if (!linkit((void**)&_alDeleteSources, "alDeleteSources", handle)) return false;
+ if (!linkit((void**)&_alIsSource, "alIsSource", handle)) return false;
+ if (!linkit((void**)&_alSourcef, "alSourcef", handle)) return false;
+ if (!linkit((void**)&_alSource3f, "alSource3f", handle)) return false;
+ if (!linkit((void**)&_alSourcefv, "alSourcefv", handle)) return false;
+ if (!linkit((void**)&_alSourcei, "alSourcei", handle)) return false;
+ if (!linkit((void**)&_alSource3i, "alSource3i", handle)) return false;
+ if (!linkit((void**)&_alSourceiv, "alSourceiv", handle)) return false;
+ if (!linkit((void**)&_alGetSourcef, "alGetSourcef", handle)) return false;
+ if (!linkit((void**)&_alGetSource3f, "alGetSource3f", handle)) return false;
+ if (!linkit((void**)&_alGetSourcefv, "alGetSourcefv", handle)) return false;
+ if (!linkit((void**)&_alGetSourcei, "alGetSourcei", handle)) return false;
+ if (!linkit((void**)&_alGetSource3i, "alGetSource3i", handle)) return false;
+ if (!linkit((void**)&_alGetSourceiv, "alGetSourceiv", handle)) return false;
+ if (!linkit((void**)&_alSourcePlayv, "alSourcePlayv", handle)) return false;
+ if (!linkit((void**)&_alSourceStopv, "alSourceStopv", handle)) return false;
+ if (!linkit((void**)&_alSourceRewindv, "alSourceRewindv", handle)) return false;
+ if (!linkit((void**)&_alSourcePausev, "alSourcePausev", handle)) return false;
+ if (!linkit((void**)&_alSourcePlay, "alSourcePlay", handle)) return false;
+ if (!linkit((void**)&_alSourceStop, "alSourceStop", handle)) return false;
+ if (!linkit((void**)&_alSourceRewind, "alSourceRewind", handle)) return false;
+ if (!linkit((void**)&_alSourcePause, "alSourcePause", handle)) return false;
+ if (!linkit((void**)&_alSourceQueueBuffers, "alSourceQueueBuffers", handle)) return false;
+ if (!linkit((void**)&_alSourceUnqueueBuffers, "alSourceUnqueueBuffers", handle)) return false;
+ if (!linkit((void**)&_alGenBuffers, "alGenBuffers", handle)) return false;
+ if (!linkit((void**)&_alDeleteBuffers, "alDeleteBuffers", handle)) return false;
+ if (!linkit((void**)&_alIsBuffer, "alIsBuffer", handle)) return false;
+ if (!linkit((void**)&_alBufferData, "alBufferData", handle)) return false;
+ if (!linkit((void**)&_alBufferf, "alBufferf", handle)) return false;
+ if (!linkit((void**)&_alBuffer3f, "alBuffer3f", handle)) return false;
+ if (!linkit((void**)&_alBufferfv, "alBufferfv", handle)) return false;
+ if (!linkit((void**)&_alBufferi, "alBufferi", handle)) return false;
+ if (!linkit((void**)&_alBuffer3i, "alBuffer3i", handle)) return false;
+ if (!linkit((void**)&_alBufferiv, "alBufferiv", handle)) return false;
+ if (!linkit((void**)&_alGetBufferf, "alGetBufferf", handle)) return false;
+ if (!linkit((void**)&_alGetBuffer3f, "alGetBuffer3f", handle)) return false;
+ if (!linkit((void**)&_alGetBufferfv, "alGetBufferfv", handle)) return false;
+ if (!linkit((void**)&_alGetBufferi, "alGetBufferi", handle)) return false;
+ if (!linkit((void**)&_alGetBuffer3i, "alGetBuffer3i", handle)) return false;
+ if (!linkit((void**)&_alGetBufferiv, "alGetBufferiv", handle)) return false;
+ if (!linkit((void**)&_alDopplerFactor, "alDopplerFactor", handle)) return false;
+ if (!linkit((void**)&_alDopplerVelocity, "alDopplerVelocity", handle)) return false;
+ if (!linkit((void**)&_alSpeedOfSound, "alSpeedOfSound", handle)) return false;
+ if (!linkit((void**)&_alDistanceModel, "alDistanceModel", handle)) return false;
+ if (!linkit((void**)&_alcCreateContext, "alcCreateContext", handle)) return false;
+ if (!linkit((void**)&_alcMakeContextCurrent, "alcMakeContextCurrent", handle)) return false;
+ if (!linkit((void**)&_alcProcessContext, "alcProcessContext", handle)) return false;
+ if (!linkit((void**)&_alcSuspendContext, "alcSuspendContext", handle)) return false;
+ if (!linkit((void**)&_alcDestroyContext, "alcDestroyContext", handle)) return false;
+ if (!linkit((void**)&_alcGetCurrentContext, "alcGetCurrentContext", handle)) return false;
+ if (!linkit((void**)&_alcGetContextsDevice, "alcGetContextsDevice", handle)) return false;
+ if (!linkit((void**)&_alcOpenDevice, "alcOpenDevice", handle)) return false;
+ if (!linkit((void**)&_alcCloseDevice, "alcCloseDevice", handle)) return false;
+ if (!linkit((void**)&_alcGetError, "alcGetError", handle)) return false;
+ if (!linkit((void**)&_alcIsExtensionPresent, "alcIsExtensionPresent", handle)) return false;
+ if (!linkit((void**)&_alcGetProcAddress, "alcGetProcAddress", handle)) return false;
+ if (!linkit((void**)&_alcGetEnumValue, "alcGetEnumValue", handle)) return false;
+ if (!linkit((void**)&_alcGetString, "alcGetString", handle)) return false;
+ if (!linkit((void**)&_alcGetIntegerv, "alcGetIntegerv", handle)) return false;
+ if (!linkit((void**)&_alcCaptureOpenDevice, "alcCaptureOpenDevice", handle)) return false;
+ if (!linkit((void**)&_alcCaptureCloseDevice, "alcCaptureCloseDevice", handle)) return false;
+ if (!linkit((void**)&_alcCaptureStart, "alcCaptureStart", handle)) return false;
+ if (!linkit((void**)&_alcCaptureStop, "alcCaptureStop", handle)) return false;
+ if (!linkit((void**)&_alcCaptureSamples, "alcCaptureSamples", handle)) return false;
+
+ return true;
+}
+
+
+void alEnable( ALenum capability ) { _alEnable(capability); }
+void alDisable( ALenum capability ) { _alDisable(capability); }
+ALboolean alIsEnabled( ALenum capability ) { _alIsEnabled(capability); }
+const ALchar* alGetString( ALenum param ) { return _alGetString(param); }
+void alGetBooleanv( ALenum param, ALboolean* data ) { _alGetBooleanv(param, data); }
+void alGetIntegerv( ALenum param, ALint* data ) { _alGetIntegerv(param, data); }
+void alGetFloatv( ALenum param, ALfloat* data ) { _alGetFloatv(param, data); }
+void alGetDoublev( ALenum param, ALdouble* data ) { _alGetDoublev(param, data); }
+ALboolean alGetBoolean( ALenum param ) { return _alGetBoolean(param); }
+ALint alGetInteger( ALenum param ) { return _alGetInteger(param); }
+ALfloat alGetFloat( ALenum param ) { return _alGetFloat(param); }
+ALdouble alGetDouble( ALenum param ) { return _alGetDouble(param); }
+ALenum alGetError( void ) { _alGetError(); }
+ALboolean alIsExtensionPresent( const ALchar* extname ) { return _alIsExtensionPresent(extname); }
+void* alGetProcAddress( const ALchar* fname ) { return _alGetProcAddress(fname); }
+ALenum alGetEnumValue( const ALchar* ename ) { return _alGetEnumValue(ename); }
+void alListenerf( ALenum param, ALfloat value ) { return _alListenerf(param, value); }
+void alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { return _alListener3f(param, value1, value2, value3); }
+void alListenerfv( ALenum param, const ALfloat* values ) { return _alListenerfv(param, values); }
+void alListeneri( ALenum param, ALint value ) { return _alListeneri(param, value); }
+void alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 ) { return _alListener3i(param, value1, value2, value3); }
+void alListeneriv( ALenum param, const ALint* values ) { return _alListeneriv(param, values); }
+void alGetListenerf( ALenum param, ALfloat* value ) { return _alGetListenerf(param, value); }
+void alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ) { return _alGetListener3f(param, value1, value2, value3); }
+void alGetListenerfv( ALenum param, ALfloat* values ) { return _alGetListenerfv(param, values); }
+void alGetListeneri( ALenum param, ALint* value ) { return _alGetListeneri(param, value); }
+void alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 ) { return _alGetListener3i(param, value1, value2, value3); }
+void alGetListeneriv( ALenum param, ALint* values ) { return _alGetListeneriv(param, values); }
+void alGenSources( ALsizei n, ALuint* sources ) { return _alGenSources(n, sources); }
+void alDeleteSources( ALsizei n, const ALuint* sources ) { return _alDeleteSources(n, sources); }
+ALboolean alIsSource( ALuint sid ) { return _alIsSource(sid); }
+void alSourcef( ALuint sid, ALenum param, ALfloat value ) { return _alSourcef(sid, param, value); }
+void alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { return _alSource3f(sid, param, value1, value2, value3); }
+void alSourcefv( ALuint sid, ALenum param, const ALfloat* values ) { return _alSourcefv(sid, param, values); }
+void alSourcei( ALuint sid, ALenum param, ALint value ) { return _alSourcei(sid, param, value); }
+void alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ) { return _alSource3i(sid, param, value1, value2, value3); }
+void alSourceiv( ALuint sid, ALenum param, const ALint* values ) { return _alSourceiv(sid, param, values); }
+void alGetSourcef( ALuint sid, ALenum param, ALfloat* value ) { return _alGetSourcef(sid, param, value); }
+void alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) { return _alGetSource3f(sid, param, value1, value2, value3); }
+void alGetSourcefv( ALuint sid, ALenum param, ALfloat* values ) { return _alGetSourcefv(sid, param, values); }
+void alGetSourcei( ALuint sid, ALenum param, ALint* value ) { return _alGetSourcei(sid, param, value); }
+void alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3) { return _alGetSource3i(sid, param, value1, value2, value3); }
+void alGetSourceiv( ALuint sid, ALenum param, ALint* values ) { return _alGetSourceiv(sid, param, values); }
+void alSourcePlayv( ALsizei ns, const ALuint *sids ) { return _alSourcePlayv(ns, sids); }
+void alSourceStopv( ALsizei ns, const ALuint *sids ) { return _alSourceStopv(ns, sids); }
+void alSourceRewindv( ALsizei ns, const ALuint *sids ) { return _alSourceRewindv(ns, sids); }
+void alSourcePausev( ALsizei ns, const ALuint *sids ) { return _alSourcePausev(ns, sids); }
+void alSourcePlay( ALuint sid ) { return _alSourcePlay(sid); }
+void alSourceStop( ALuint sid ) { return _alSourceStop(sid); }
+void alSourceRewind( ALuint sid ) { return _alSourceRewind(sid); }
+void alSourcePause( ALuint sid ) { return _alSourcePause(sid); }
+void alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids ) { return _alSourceQueueBuffers(sid, numEntries, bids); }
+void alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids ) { return _alSourceUnqueueBuffers(sid, numEntries, bids); }
+void alGenBuffers( ALsizei n, ALuint* buffers ) { return _alGenBuffers(n, buffers); }
+void alDeleteBuffers( ALsizei n, const ALuint* buffers ) { return _alDeleteBuffers(n, buffers); }
+ALboolean alIsBuffer( ALuint bid ) { return _alIsBuffer(bid); }
+void alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ) { return _alBufferData(bid, format, data, size, freq); }
+void alBufferf( ALuint bid, ALenum param, ALfloat value ) { return _alBufferf(bid, param, value); }
+void alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { return _alBuffer3f(bid, param, value1, value2, value3); }
+void alBufferfv( ALuint bid, ALenum param, const ALfloat* values ) { return _alBufferfv(bid, param, values); }
+void alBufferi( ALuint bid, ALenum param, ALint value ) { return _alBufferi(bid, param, value); }
+void alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ) { return _alBuffer3i(bid, param, value1, value2, value3); }
+void alBufferiv( ALuint bid, ALenum param, const ALint* values ) { return _alBufferiv(bid, param, values); }
+void alGetBufferf( ALuint bid, ALenum param, ALfloat* value ) { return _alGetBufferf(bid, param, value); }
+void alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) { return _alGetBuffer3f(bid, param, value1, value2, value3); }
+void alGetBufferfv( ALuint bid, ALenum param, ALfloat* values ) { return _alGetBufferfv(bid, param, values); }
+void alGetBufferi( ALuint bid, ALenum param, ALint* value ) { return _alGetBufferi(bid, param, value); }
+void alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3) { return _alGetBuffer3i(bid, param, value1, value2, value3); }
+void alGetBufferiv( ALuint bid, ALenum param, ALint* values ) { return _alGetBufferiv(bid, param, values); }
+void alDopplerFactor( ALfloat value ) { return _alDopplerFactor(value); }
+void alDopplerVelocity( ALfloat value ) { return _alDopplerVelocity(value); }
+void alSpeedOfSound( ALfloat value ) { return _alSpeedOfSound(value); }
+void alDistanceModel( ALenum distanceModel ) { return _alDistanceModel(distanceModel); }
+ALCcontext * alcCreateContext( ALCdevice *device, const ALCint* attrlist ) { return _alcCreateContext(device, attrlist); }
+ALCboolean alcMakeContextCurrent( ALCcontext *context ) { return _alcMakeContextCurrent(context); }
+void alcProcessContext( ALCcontext *context ) { return _alcProcessContext(context); }
+void alcSuspendContext( ALCcontext *context ) { return _alcSuspendContext(context); }
+void alcDestroyContext( ALCcontext *context ) { return _alcDestroyContext(context); }
+ALCcontext * alcGetCurrentContext( void ) { return _alcGetCurrentContext(); }
+ALCdevice* alcGetContextsDevice( ALCcontext *context ) { return _alcGetContextsDevice(context); }
+ALCdevice * alcOpenDevice( const ALCchar *devicename ) { return _alcOpenDevice(devicename); }
+ALCboolean alcCloseDevice( ALCdevice *device ) { return _alcCloseDevice(device); }
+ALCenum alcGetError( ALCdevice *device ) { return _alcGetError(device); }
+ALCboolean alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname ) { return _alcIsExtensionPresent(device, extname); }
+void * alcGetProcAddress( ALCdevice *device, const ALCchar *funcname ) { return _alcGetProcAddress(device, funcname); }
+ALCenum alcGetEnumValue( ALCdevice *device, const ALCchar *enumname ) { return _alcGetEnumValue(device, enumname); }
+const ALCchar * alcGetString( ALCdevice *device, ALCenum param ) { return _alcGetString(device, param); }
+void alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ) { return _alcGetIntegerv(device, param, size, data); }
+ALCdevice* alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ) { return _alcCaptureOpenDevice(devicename, frequency, format, buffersize); }
+ALCboolean alcCaptureCloseDevice( ALCdevice *device ) { return _alcCaptureCloseDevice(device); }
+void alcCaptureStart( ALCdevice *device ) { return _alcCaptureStart(device); }
+void alcCaptureStop( ALCdevice *device ) { return _alcCaptureStop(device); }
+void alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ) { return _alcCaptureSamples(device, buffer, samples); }
+
+
+static SNDFILE* (*_sf_open) (const char *path, int mode, SF_INFO *sfinfo);
+static SNDFILE* (*_sf_open_fd) (int fd, int mode, SF_INFO *sfinfo, int close_desc);
+static SNDFILE* (*_sf_open_virtual) (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data);
+static int (*_sf_error) (SNDFILE *sndfile);
+static const char* (*_sf_strerror) (SNDFILE *sndfile);
+static const char* (*_sf_error_number) (int errnum);
+static int (*_sf_perror) (SNDFILE *sndfile);
+static int (*_sf_error_str) (SNDFILE *sndfile, char* str, size_t len);
+static int (*_sf_command) (SNDFILE *sndfile, int command, void *data, int datasize);
+static int (*_sf_format_check) (const SF_INFO *info);
+static sf_count_t (*_sf_seek) (SNDFILE *sndfile, sf_count_t frames, int whence);
+static int (*_sf_set_string) (SNDFILE *sndfile, int str_type, const char* str);
+static const char* (*_sf_get_string) (SNDFILE *sndfile, int str_type);
+static const char * (*_sf_version_string) (void);
+static sf_count_t (*_sf_read_raw) (SNDFILE *sndfile, void *ptr, sf_count_t bytes);
+static sf_count_t (*_sf_write_raw) (SNDFILE *sndfile, const void *ptr, sf_count_t bytes);
+static sf_count_t (*_sf_readf_short) (SNDFILE *sndfile, short *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_short) (SNDFILE *sndfile, const short *ptr, sf_count_t frames);
+static sf_count_t (*_sf_readf_int) (SNDFILE *sndfile, int *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_int) (SNDFILE *sndfile, const int *ptr, sf_count_t frames);
+static sf_count_t (*_sf_readf_float) (SNDFILE *sndfile, float *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_float) (SNDFILE *sndfile, const float *ptr, sf_count_t frames);
+static sf_count_t (*_sf_readf_double) (SNDFILE *sndfile, double *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_double) (SNDFILE *sndfile, const double *ptr, sf_count_t frames);
+static sf_count_t (*_sf_read_short) (SNDFILE *sndfile, short *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_short) (SNDFILE *sndfile, const short *ptr, sf_count_t items);
+static sf_count_t (*_sf_read_int) (SNDFILE *sndfile, int *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_int) (SNDFILE *sndfile, const int *ptr, sf_count_t items);
+static sf_count_t (*_sf_read_float) (SNDFILE *sndfile, float *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_float) (SNDFILE *sndfile, const float *ptr, sf_count_t items);
+static sf_count_t (*_sf_read_double) (SNDFILE *sndfile, double *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_double) (SNDFILE *sndfile, const double *ptr, sf_count_t items);
+static int (*_sf_close) (SNDFILE *sndfile);
+static void (*_sf_write_sync) (SNDFILE *sndfile);
+
+static bool init_sndfile() {
+ void *handle = dlopen("libsndfile.so", RTLD_LAZY);
+ if (!handle) handle = dlopen("libsndfile.so.1", RTLD_LAZY);
+ if (!handle) return false;
+
+ if (!linkit((void**)&_sf_open, "sf_open", handle)) return false;
+ if (!linkit((void**)&_sf_open_fd, "sf_open_fd", handle)) return false;
+ if (!linkit((void**)&_sf_open_virtual, "sf_open_virtual", handle)) return false;
+ if (!linkit((void**)&_sf_error, "sf_error", handle)) return false;
+ if (!linkit((void**)&_sf_strerror, "sf_strerror", handle)) return false;
+ if (!linkit((void**)&_sf_error_number, "sf_error_number", handle)) return false;
+ if (!linkit((void**)&_sf_perror, "sf_perror", handle)) return false;
+ if (!linkit((void**)&_sf_error_str, "sf_error_str", handle)) return false;
+ if (!linkit((void**)&_sf_command, "sf_command", handle)) return false;
+ if (!linkit((void**)&_sf_format_check, "sf_format_check", handle)) return false;
+ if (!linkit((void**)&_sf_seek, "sf_seek", handle)) return false;
+ if (!linkit((void**)&_sf_set_string, "sf_set_string", handle)) return false;
+ if (!linkit((void**)&_sf_get_string, "sf_get_string", handle)) return false;
+ if (!linkit((void**)&_sf_version_string, "sf_version_string", handle)) return false;
+ if (!linkit((void**)&_sf_read_raw, "sf_read_raw", handle)) return false;
+ if (!linkit((void**)&_sf_write_raw, "sf_write_raw", handle)) return false;
+ if (!linkit((void**)&_sf_readf_short, "sf_readf_short", handle)) return false;
+ if (!linkit((void**)&_sf_writef_short, "sf_writef_short", handle)) return false;
+ if (!linkit((void**)&_sf_readf_int, "sf_readf_int", handle)) return false;
+ if (!linkit((void**)&_sf_writef_int, "sf_writef_int", handle)) return false;
+ if (!linkit((void**)&_sf_readf_float, "sf_readf_float", handle)) return false;
+ if (!linkit((void**)&_sf_writef_float, "sf_writef_float", handle)) return false;
+ if (!linkit((void**)&_sf_readf_double, "sf_readf_double", handle)) return false;
+ if (!linkit((void**)&_sf_writef_double, "sf_writef_double", handle)) return false;
+ if (!linkit((void**)&_sf_read_short, "sf_read_short", handle)) return false;
+ if (!linkit((void**)&_sf_write_short, "sf_write_short", handle)) return false;
+ if (!linkit((void**)&_sf_read_int, "sf_read_int", handle)) return false;
+ if (!linkit((void**)&_sf_write_int, "sf_write_int", handle)) return false;
+ if (!linkit((void**)&_sf_read_float, "sf_read_float", handle)) return false;
+ if (!linkit((void**)&_sf_write_float, "sf_write_float", handle)) return false;
+ if (!linkit((void**)&_sf_read_double, "sf_read_double", handle)) return false;
+ if (!linkit((void**)&_sf_write_double, "sf_write_double", handle)) return false;
+ if (!linkit((void**)&_sf_close, "sf_close", handle)) return false;
+ if (!linkit((void**)&_sf_write_sync, "sf_write_sync", handle)) return false;
+
+ return true;
+}
+
+
+SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) { return _sf_open(path, mode, sfinfo); }
+SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) { return _sf_open_fd(fd, mode, sfinfo, close_desc); }
+SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) { return _sf_open_virtual(sfvirtual, mode, sfinfo, user_data); }
+int sf_error (SNDFILE *sndfile) { return _sf_error(sndfile); }
+const char* sf_strerror (SNDFILE *sndfile) { return _sf_strerror(sndfile); }
+const char* sf_error_number (int errnum) { return _sf_error_number(errnum); }
+int sf_perror (SNDFILE *sndfile) { return _sf_perror(sndfile); }
+int sf_error_str (SNDFILE *sndfile, char* str, size_t len) { return _sf_error_str(sndfile, str, len); }
+int sf_command (SNDFILE *sndfile, int command, void *data, int datasize) { return _sf_command(sndfile, command, data, datasize); }
+int sf_format_check (const SF_INFO *info) { return _sf_format_check(info); }
+sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) { return _sf_seek(sndfile, frames, whence); }
+int sf_set_string (SNDFILE *sndfile, int str_type, const char* str) { return _sf_set_string(sndfile, str_type, str); }
+const char* sf_get_string (SNDFILE *sndfile, int str_type) { return _sf_get_string(sndfile, str_type); }
+const char * sf_version_string (void) { return _sf_version_string(); }
+sf_count_t sf_read_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) { return _sf_read_raw(sndfile, ptr, bytes); }
+sf_count_t sf_write_raw (SNDFILE *sndfile, const void *ptr, sf_count_t bytes) { return _sf_write_raw(sndfile, ptr, bytes); }
+sf_count_t sf_readf_short (SNDFILE *sndfile, short *ptr, sf_count_t frames) { return _sf_readf_short(sndfile, ptr, frames); }
+sf_count_t sf_writef_short (SNDFILE *sndfile, const short *ptr, sf_count_t frames) { return _sf_writef_short(sndfile, ptr, frames); }
+sf_count_t sf_readf_int (SNDFILE *sndfile, int *ptr, sf_count_t frames) { return _sf_readf_int(sndfile, ptr, frames); }
+sf_count_t sf_writef_int (SNDFILE *sndfile, const int *ptr, sf_count_t frames) { return _sf_writef_int(sndfile, ptr, frames); }
+sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames) { return _sf_readf_float(sndfile, ptr, frames); }
+sf_count_t sf_writef_float (SNDFILE *sndfile, const float *ptr, sf_count_t frames) { return _sf_writef_float(sndfile, ptr, frames); }
+sf_count_t sf_readf_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) { return _sf_readf_double(sndfile, ptr, frames); }
+sf_count_t sf_writef_double (SNDFILE *sndfile, const double *ptr, sf_count_t frames) { return _sf_writef_double(sndfile, ptr, frames); }
+sf_count_t sf_read_short (SNDFILE *sndfile, short *ptr, sf_count_t items) { return _sf_read_short(sndfile, ptr, items); }
+sf_count_t sf_write_short (SNDFILE *sndfile, const short *ptr, sf_count_t items) { return _sf_write_short(sndfile, ptr, items); }
+sf_count_t sf_read_int (SNDFILE *sndfile, int *ptr, sf_count_t items) { return _sf_read_int(sndfile, ptr, items); }
+sf_count_t sf_write_int (SNDFILE *sndfile, const int *ptr, sf_count_t items) { return _sf_write_int(sndfile, ptr, items); }
+sf_count_t sf_read_float (SNDFILE *sndfile, float *ptr, sf_count_t items) { return _sf_read_float(sndfile, ptr, items); }
+sf_count_t sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t items) { return _sf_write_float(sndfile, ptr, items); }
+sf_count_t sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t items) { return _sf_read_double(sndfile, ptr, items); }
+sf_count_t sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t items) { return _sf_write_double(sndfile, ptr, items); }
+int sf_close (SNDFILE *sndfile) { return _sf_close(sndfile); }
+void sf_write_sync (SNDFILE *sndfile) { return _sf_write_sync(sndfile); }
diff --git a/g_src/music_and_sound_openal.h b/g_src/music_and_sound_openal.h new file mode 100755 index 0000000..b4f3de9 --- /dev/null +++ b/g_src/music_and_sound_openal.h @@ -0,0 +1,82 @@ +#ifndef MUSIC_AND_SOUND_OPENAL_H +#define MUSIC_AND_SOUND_OPENAL_H + +#include <AL/al.h> +#include <AL/alc.h> + +// HACKY HACKY HACK +// Fixes sndfile.h, until the bug is properly fixed +#include <stdio.h> +#include <sys/types.h> +#define _MSCVER +typedef int64_t __int64; +#include <sndfile.h> +#undef _MSCVER +// END HACKY HACKY HACK + +#include <string> +#include <vector> +#include <list> +#include <map> +#include <algorithm> +#include <utility> + +#define SOUND_CHANNELNUM 16 + +// Preferred mixer frequency. Should be the same as what the ogg files +// use, to avoid resampling. +#define SOUND_FREQUENCY 44100 + +// If the bool is false, a sound; otherwise a song +typedef std::pair<bool,int> slot; + +class musicsoundst +{ + public: + bool initsound(); // Returns false if it failed + void update() {} + void set_master_volume(long newvol); + + void set_song(std::string &filename, slot slot); + void set_song(std::string &filename, int slot); + void playsound(slot slot); + void playsound(int slot); // Assumes sound + + void startbackgroundmusic(slot slot); + void startbackgroundmusic(int slot); // Assumes song + void stopbackgroundmusic(); + void stop_sound(); + void stop_sound(slot slot); + void playsound(int s,int channel); + void set_sound(std::string &filename,int slot,int pan=-1,int priority=0); + void deinitsound(); + + // Deprecated: + void forcebackgroundmusic(int slot, unsigned long time); + void playsound(int s,int min_channel,int max_channel,int force_channel); + void set_sound_params(int slot,int p1,int vol,int pan,int priority); + + musicsoundst() { + functional = false; + background_slot = slot(false,-1); + } + + ~musicsoundst() { + deinitsound(); + } + + private: + bool functional; + ALCdevice *device; + ALCcontext *context; + + std::map<std::string,ALuint> buffers; // OpenAL buffers + std::map<std::string,ALuint> sources; // And sources + std::map<slot, ALuint> slot_buffer; // Mappings from DF slots to openal + std::map<slot, ALuint> slot_source; + + slot background_slot; // Currently playing background music, or -1 +}; + + +#endif diff --git a/g_src/music_and_sound_v.h b/g_src/music_and_sound_v.h new file mode 100755 index 0000000..7c76874 --- /dev/null +++ b/g_src/music_and_sound_v.h @@ -0,0 +1,11 @@ +//copyright (c) 2006 by tarn adams + +#ifndef NO_FMOD +#include "enabler.h" +#include "init.h" + +extern enablerst enabler; +extern initst init; +musicsoundst musicsound; + +#endif
\ No newline at end of file diff --git a/g_src/platform.h b/g_src/platform.h new file mode 100755 index 0000000..64e5c74 --- /dev/null +++ b/g_src/platform.h @@ -0,0 +1,102 @@ +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +#ifdef WIN32 +#undef WINDOWS_LEAN_AND_MEAN +#define WINDOWS_LEAN_AND_MEAN +# include <windows.h> +#else + +#define stricmp strcasecmp +#define strnicmp strncasecmp + +enum { + // NOTE: These probably don't match Windows values. + MB_OK = 0x01, + MB_YESNO = 0x02, + MB_ICONQUESTION = 0x10, + MB_ICONEXCLAMATION = 0x20, + + IDOK = 1, + IDNO, + IDYES, +}; + + +typedef int HANDLE; +typedef HANDLE HINSTANCE; +typedef HANDLE HWND; +typedef HANDLE HDC; +typedef HANDLE HGLRC; + +#ifndef HWND_DESKTOP +#define HWND_DESKTOP ((HWND)-1) +#endif + + +typedef int BOOL; + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +typedef unsigned short WORD; +typedef unsigned long DWORD; + +typedef unsigned int UINT; +typedef short SHORT; +typedef long LONG; +typedef long long LONGLONG; + +typedef WORD WPARAM; +typedef DWORD LPARAM; + + +typedef struct { + LONG x; + LONG y; +} POINT; + +typedef union { + struct { + DWORD LowPart; + LONG HighPart; + }; + struct { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; +} LARGE_INTEGER; + +typedef struct { + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; +} MSG; + + +DWORD GetTickCount(); // returns ms since system startup +BOOL CreateDirectory(const char* pathname, void*); +BOOL DeleteFile(const char* filename); +void ZeroMemory(void* dest, int len); +BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount); +BOOL QueryPerformanceFrequency(LARGE_INTEGER* performanceCount); +int MessageBox(HWND *dummy, const char* text, const char* caption, UINT type); +char* itoa(int value, char* result, int base); + +#endif // WIN32 + +/* +SHORT Enabler_GetKeyState(int virtKey); +int Enabler_ShowCursor(BOOL show); +*/ + +#endif // _PLATFORM_H_ + diff --git a/g_src/random.cpp b/g_src/random.cpp new file mode 100755 index 0000000..1059cb9 --- /dev/null +++ b/g_src/random.cpp @@ -0,0 +1,206 @@ +#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "basics.h"
+
+#include "random.h"
+
+extern int32_t basic_seed;
+extern int mt_index[MT_BUFFER_NUM];
+extern short mt_cur_buffer;
+extern short mt_virtual_buffer;
+extern uint32_t mt_buffer[MT_BUFFER_NUM][MT_LEN];
+
+//public domain RNG stuff by Michael Brundage
+ //with some modifications by me to handle more buffers
+
+void mt_init()
+{
+ mt_cur_buffer=0;
+ mt_virtual_buffer=0;
+
+ mt_buffer[0][0]=GetTickCount();
+ int i;
+ for(i=1;i<MT_LEN;i++)
+ {
+ //2010: better init line from wikipedia, ultimate source unknown
+ mt_buffer[0][i]=1812433253UL * (mt_buffer[0][i-1] ^ (mt_buffer[0][i-1]>>30)) + i;
+ }
+ mt_index[0]=MT_LEN*sizeof(uint32_t);
+
+ int32_t j;
+ for(j=0;j<20;j++)trandom_twist();
+}
+
+#define MT_IA 397
+#define MT_IB (MT_LEN - MT_IA)
+#define UPPER_MASK 0x80000000
+#define LOWER_MASK 0x7FFFFFFF
+#define MATRIX_A 0x9908B0DF
+#define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK)
+#define MAGIC(s) (((s)&1)*MATRIX_A)
+
+uint32_t mt_trandom()
+{
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+ int idx = mt_index[mt_cur_buffer];
+ uint32_t s;
+ int i;
+
+ if (idx == MT_LEN*sizeof(uint32_t))
+ {
+ idx = 0;
+ i = 0;
+ for (; i < MT_IB; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s);
+ }
+ for (; i < MT_LEN-1; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s);
+ }
+
+ s = TWIST(b, MT_LEN-1, 0);
+ b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s);
+ }
+ mt_index[mt_cur_buffer] = idx + sizeof(uint32_t);
+ return *(uint32_t *)((unsigned char *)b + idx);
+}
+
+void trandom_twist()
+{
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+ uint32_t s;
+ int i;
+
+ i = 0;
+ for (; i < MT_IB; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s);
+ }
+ for (; i < MT_LEN-1; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s);
+ }
+
+ s = TWIST(b, MT_LEN-1, 0);
+ b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s);
+}
+
+//back to my crap - tarn
+void pop_trandom_uniform_seed()
+{
+ if(mt_virtual_buffer>0)mt_virtual_buffer--;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)mt_cur_buffer=MT_BUFFER_NUM-1;
+}
+
+void push_trandom_uniform_seed(uint32_t newseed)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed;
+ for(i=1;i<MT_LEN;i++)
+ {
+ //2010: better init line from wikipedia, ultimate source unknown
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+void push_trandom_double_seed(uint32_t newseed1,uint32_t newseed2)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed1/2+newseed2/2;
+ for(i=1;i<MT_LEN;i++)
+ {
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+void push_trandom_triple_seed(uint32_t newseed1,uint32_t newseed2,uint32_t newseed3)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed1/3+newseed2/3+newseed3/3;
+ for(i=1;i<MT_LEN;i++)
+ {
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+//picks a random number from 0 to max-1
+int32_t basic_random(int32_t max)
+{
+ r_num();
+
+ return (int32_t)((uint32_t)basic_seed/((1073741824UL/(uint32_t)max)+1UL));
+}
+
+//sets seed to a random number from 0 to 1 billion
+void r_num()
+{
+ basic_seed=(int32_t)(((uint32_t)basic_seed*907725UL+99979777UL)%1073741824UL);
+}
\ No newline at end of file diff --git a/g_src/random.h b/g_src/random.h new file mode 100755 index 0000000..a160db9 --- /dev/null +++ b/g_src/random.h @@ -0,0 +1,40 @@ +#ifndef RANDOM_H +#define RANDOM_H + +#ifndef WIN32 +#include <stdint.h> +#endif //WIN32 + +#define MT_BUFFER_NUM 10 +#define MT_LEN 624 + + +void mt_init(); +uint32_t mt_trandom(); +static int32_t trandom(uint32_t max=2147483647LU) + { + if(max<=1)return 0; + uint32_t seed=mt_trandom(); + seed=seed%2147483647LU; + seed=seed/((2147483647LU/max)+1); + + return((int32_t)seed); + } +static int32_t loadtrandom(uint32_t max=2147483647LU) + { + uint32_t seed=mt_trandom(); + seed=seed%max; + + return((int32_t)seed); + } +void push_trandom_uniform_seed(uint32_t newseed); +void push_trandom_double_seed(uint32_t newseed1,uint32_t newseed2); +void push_trandom_triple_seed(uint32_t newseed1,uint32_t newseed2,uint32_t newseed3); +void pop_trandom_uniform_seed(); +void trandom_twist(); + +void r_num(); +int32_t basic_random(int32_t max=2147483647); + + +#endif diff --git a/g_src/renderer_2d.hpp b/g_src/renderer_2d.hpp new file mode 100755 index 0000000..d088162 --- /dev/null +++ b/g_src/renderer_2d.hpp @@ -0,0 +1,352 @@ +#include "enabler.h" +#include "init.h" +#include "resize++.h" +#include "ttf_manager.hpp" + +#include <iostream> +using namespace std; + +void report_error(const char*, const char*); + +class renderer_2d_base : public renderer { +protected: + SDL_Surface *screen; + map<texture_fullid, SDL_Surface*> tile_cache; + int dispx, dispy, dimx, dimy; + // We may shrink or enlarge dispx/dispy in response to zoom requests. dispx/y_z are the + // size we actually display tiles at. + int dispx_z, dispy_z; + // Viewport origin + int origin_x, origin_y; + + SDL_Surface *tile_cache_lookup(texture_fullid &id, bool convert=true) { + map<texture_fullid, SDL_Surface*>::iterator it = tile_cache.find(id); + if (it != tile_cache.end()) { + return it->second; + } else { + // Create the colorized texture + SDL_Surface *tex = enabler.textures.get_texture_data(id.texpos); + SDL_Surface *color; + color = SDL_CreateRGBSurface(SDL_SWSURFACE, + tex->w, tex->h, + tex->format->BitsPerPixel, + tex->format->Rmask, + tex->format->Gmask, + tex->format->Bmask, + 0); + if (!color) { + MessageBox (NULL, "Unable to create texture!", "Fatal error", MB_OK | MB_ICONEXCLAMATION); + abort(); + } + + // Fill it + Uint32 color_fgi = SDL_MapRGB(color->format, id.r*255, id.g*255, id.b*255); + Uint8 *color_fg = (Uint8*) &color_fgi; + Uint32 color_bgi = SDL_MapRGB(color->format, id.br*255, id.bg*255, id.bb*255); + Uint8 *color_bg = (Uint8*) &color_bgi; + SDL_LockSurface(tex); + SDL_LockSurface(color); + + Uint8 *pixel_src, *pixel_dst; + for (int y = 0; y < tex->h; y++) { + pixel_src = ((Uint8*)tex->pixels) + (y * tex->pitch); + pixel_dst = ((Uint8*)color->pixels) + (y * color->pitch); + for (int x = 0; x < tex->w; x++, pixel_src+=4, pixel_dst+=4) { + float alpha = pixel_src[3] / 255.0; + for (int c = 0; c < 3; c++) { + float fg = color_fg[c] / 255.0, bg = color_bg[c] / 255.0, tex = pixel_src[c] / 255.0; + pixel_dst[c] = ((alpha * (tex * fg)) + ((1 - alpha) * bg)) * 255; + } + } + } + + SDL_UnlockSurface(color); + SDL_UnlockSurface(tex); + + SDL_Surface *disp = convert ? + SDL_Resize(color, dispx_z, dispy_z) : // Convert to display format; deletes color + color; // color is not deleted, but we don't want it to be. + // Insert and return + tile_cache[id] = disp; + return disp; + } + } + + virtual bool init_video(int w, int h) { + // Get ourselves a 2D SDL window + Uint32 flags = init.display.flag.has_flag(INIT_DISPLAY_FLAG_2DHW) ? SDL_HWSURFACE : SDL_SWSURFACE; + flags |= init.display.flag.has_flag(INIT_DISPLAY_FLAG_2DASYNC) ? SDL_ASYNCBLIT : 0; + + // Set it up for windowed or fullscreen, depending. + if (enabler.is_fullscreen()) { + flags |= SDL_FULLSCREEN; + } else { + if (!init.display.flag.has_flag(INIT_DISPLAY_FLAG_NOT_RESIZABLE)) + flags |= SDL_RESIZABLE; + } + + // (Re)create the window + screen = SDL_SetVideoMode(w, h, 32, flags); + if (screen == NULL) cout << "INIT FAILED!" << endl; + + return screen != NULL; + } + +public: + list<pair<SDL_Surface*,SDL_Rect> > ttfs_to_render; + + void update_tile(int x, int y) { + // Figure out where to blit + SDL_Rect dst; + dst.x = dispx_z * x + origin_x; + dst.y = dispy_z * y + origin_y; + // Read tiles from gps, create cached texture + Either<texture_fullid,texture_ttfid> id = screen_to_texid(x, y); + SDL_Surface *tex; + if (id.isL) { // Ordinary tile, cached here + tex = tile_cache_lookup(id.left); + // And blit. + SDL_BlitSurface(tex, NULL, screen, &dst); + } else { // TTF, cached in ttf_manager so no point in also caching here + tex = ttf_manager.get_texture(id.right); + // Blit later + ttfs_to_render.push_back(make_pair(tex, dst)); + } + } + + void update_all() { + SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); + for (int x = 0; x < gps.dimx; x++) + for (int y = 0; y < gps.dimy; y++) + update_tile(x, y); + } + + virtual void render() { + // Render the TTFs, which we left for last + for (auto it = ttfs_to_render.begin(); it != ttfs_to_render.end(); ++it) { + SDL_BlitSurface(it->first, NULL, screen, &it->second); + } + ttfs_to_render.clear(); + // And flip out. + SDL_Flip(screen); + } + + virtual ~renderer_2d_base() { + for (auto it = tile_cache.cbegin(); it != tile_cache.cend(); ++it) + SDL_FreeSurface(it->second); + for (auto it = ttfs_to_render.cbegin(); it != ttfs_to_render.cend(); ++it) + SDL_FreeSurface(it->first); + } + + void grid_resize(int w, int h) { + dimx = w; dimy = h; + // Only reallocate the grid if it actually changes + if (init.display.grid_x != dimx || init.display.grid_y != dimy) + gps_allocate(dimx, dimy); + // But always force a full display cycle + gps.force_full_display_count = 1; + enabler.flag |= ENABLERFLAG_RENDER; + } + + renderer_2d_base() { + zoom_steps = forced_steps = 0; + } + + int zoom_steps, forced_steps; + int natural_w, natural_h; + + void compute_forced_zoom() { + forced_steps = 0; + pair<int,int> zoomed = compute_zoom(); + while (zoomed.first < MIN_GRID_X || zoomed.second < MIN_GRID_Y) { + forced_steps++; + zoomed = compute_zoom(); + } + while (zoomed.first > MAX_GRID_X || zoomed.second > MAX_GRID_Y) { + forced_steps--; + zoomed = compute_zoom(); + } + } + + pair<int,int> compute_zoom(bool clamp = false) { + const int dispx = enabler.is_fullscreen() ? + init.font.large_font_dispx : + init.font.small_font_dispx; + const int dispy = enabler.is_fullscreen() ? + init.font.large_font_dispy : + init.font.small_font_dispy; + int w, h; + if (dispx < dispy) { + w = natural_w + zoom_steps + forced_steps; + h = double(natural_h) * (double(w) / double(natural_w)); + } else { + h = natural_h + zoom_steps + forced_steps; + w = double(natural_w) * (double(h) / double(natural_h)); + } + if (clamp) { + w = MIN(MAX(w, MIN_GRID_X), MAX_GRID_X); + h = MIN(MAX(h, MIN_GRID_Y), MAX_GRID_Y); + } + return make_pair(w,h); + } + + + void resize(int w, int h) { + // We've gotten resized.. first step is to reinitialize video + cout << "New window size: " << w << "x" << h << endl; + init_video(w, h); + dispx = enabler.is_fullscreen() ? + init.font.large_font_dispx : + init.font.small_font_dispx; + dispy = enabler.is_fullscreen() ? + init.font.large_font_dispy : + init.font.small_font_dispy; + cout << "Font size: " << dispx << "x" << dispy << endl; + // If grid size is currently overridden, we don't change it + if (enabler.overridden_grid_sizes.size() == 0) { + // (Re)calculate grid-size + dimx = MIN(MAX(w / dispx, MIN_GRID_X), MAX_GRID_X); + dimy = MIN(MAX(h / dispy, MIN_GRID_Y), MAX_GRID_Y); + cout << "Resizing grid to " << dimx << "x" << dimy << endl; + grid_resize(dimx, dimy); + } + // Calculate zoomed tile size + natural_w = MAX(w / dispx,1); + natural_h = MAX(h / dispy,1); + compute_forced_zoom(); + reshape(compute_zoom(true)); + cout << endl; + } + + void reshape(pair<int,int> max_grid) { + int w = max_grid.first, + h = max_grid.second; + // Compute the largest tile size that will fit this grid into the window, roughly maintaining aspect ratio + double try_x = dispx, try_y = dispy; + try_x = screen->w / w; + try_y = MIN(try_x / dispx * dispy, screen->h / h); + try_x = MIN(try_x, try_y / dispy * dispx); + dispx_z = MAX(1,try_x); dispy_z = MAX(try_y,1); + cout << "Resizing font to " << dispx_z << "x" << dispy_z << endl; + // Remove now-obsolete tile catalog + for (map<texture_fullid, SDL_Surface*>::iterator it = tile_cache.begin(); + it != tile_cache.end(); + ++it) + SDL_FreeSurface(it->second); + tile_cache.clear(); + // Recompute grid based on the new tile size + w = CLAMP(screen->w / dispx_z, MIN_GRID_X, MAX_GRID_X); + h = CLAMP(screen->h / dispy_z, MIN_GRID_Y, MAX_GRID_Y); + // Reset grid size +#ifdef DEBUG + cout << "Resizing grid to " << w << "x" << h << endl; +#endif + gps_allocate(w,h); + // Force redisplay + gps.force_full_display_count = 1; + // Calculate viewport origin, for centering + origin_x = (screen->w - dispx_z * w) / 2; + origin_y = (screen->h - dispy_z * h) / 2; + // Reset TTF rendering + ttf_manager.init(dispy_z, dispx_z); + } + +private: + + void set_fullscreen() { + if (enabler.is_fullscreen()) { + init.display.desired_windowed_width = screen->w; + init.display.desired_windowed_height = screen->h; + resize(init.display.desired_fullscreen_width, + init.display.desired_fullscreen_height); + } else { + resize(init.display.desired_windowed_width, init.display.desired_windowed_height); + } + } + + bool get_mouse_coords(int &x, int &y) { + int mouse_x, mouse_y; + SDL_GetMouseState(&mouse_x, &mouse_y); + mouse_x -= origin_x; mouse_y -= origin_y; + if (mouse_x < 0 || mouse_x >= dispx_z*dimx || + mouse_y < 0 || mouse_y >= dispy_z*dimy) + return false; + x = mouse_x / dispx_z; + y = mouse_y / dispy_z; + return true; + } + + void zoom(zoom_commands cmd) { + pair<int,int> before = compute_zoom(true); + int before_steps = zoom_steps; + switch (cmd) { + case zoom_in: zoom_steps -= init.input.zoom_speed; break; + case zoom_out: zoom_steps += init.input.zoom_speed; break; + case zoom_reset: + zoom_steps = 0; + case zoom_resetgrid: + compute_forced_zoom(); + break; + } + pair<int,int> after = compute_zoom(true); + if (after == before && (cmd == zoom_in || cmd == zoom_out)) + zoom_steps = before_steps; + else + reshape(after); + } + +}; + +class renderer_2d : public renderer_2d_base { +public: + renderer_2d() { + // Disable key repeat + SDL_EnableKeyRepeat(0, 0); + // Set window title/icon. + SDL_WM_SetCaption(GAME_TITLE_STRING, NULL); + SDL_Surface *icon = IMG_Load("data/art/icon.png"); + if (icon != NULL) { + SDL_WM_SetIcon(icon, NULL); + // The icon's surface doesn't get used past this point. + SDL_FreeSurface(icon); + } + + // Find the current desktop resolution if fullscreen resolution is auto + if (init.display.desired_fullscreen_width == 0 || + init.display.desired_fullscreen_height == 0) { + const struct SDL_VideoInfo *info = SDL_GetVideoInfo(); + init.display.desired_fullscreen_width = info->current_w; + init.display.desired_fullscreen_height = info->current_h; + } + + // Initialize our window + bool worked = init_video(enabler.is_fullscreen() ? + init.display.desired_fullscreen_width : + init.display.desired_windowed_width, + enabler.is_fullscreen() ? + init.display.desired_fullscreen_height : + init.display.desired_windowed_height); + + // Fallback to windowed mode if fullscreen fails + if (!worked && enabler.is_fullscreen()) { + enabler.fullscreen = false; + report_error("SDL initialization failure, trying windowed mode", SDL_GetError()); + worked = init_video(init.display.desired_windowed_width, + init.display.desired_windowed_height); + } + // Quit if windowed fails + if (!worked) { + report_error("SDL initialization failure", SDL_GetError()); + exit(EXIT_FAILURE); + } + } +}; + +class renderer_offscreen : public renderer_2d_base { + virtual bool init_video(int, int); +public: + virtual ~renderer_offscreen(); + renderer_offscreen(int, int); + void update_all(int, int); + void save_to_file(const string &file); +}; diff --git a/g_src/renderer_curses.cpp b/g_src/renderer_curses.cpp new file mode 100755 index 0000000..2d90d9c --- /dev/null +++ b/g_src/renderer_curses.cpp @@ -0,0 +1,369 @@ +static bool curses_initialized = false;
+
+static void endwin_void() {
+ if (curses_initialized) {
+ endwin();
+ curses_initialized = false;
+ }
+}
+
+class renderer_curses : public renderer {
+ std::map<std::pair<int,int>,int> color_pairs;
+
+ // Map from DF color to ncurses color
+ static int ncurses_map_color(int color) {
+ if (color < 0) abort();
+ switch (color) {
+ case 0: return 0;
+ case 1: return 4;
+ case 2: return 2;
+ case 3: return 6;
+ case 4: return 1;
+ case 5: return 5;
+ case 6: return 3;
+ case 7: return 7;
+ default: return ncurses_map_color(color - 7);
+ }
+ }
+
+ // Look up, or create, a curses color pair
+ int lookup_pair(pair<int,int> color) {
+ map<pair<int,int>,int>::iterator it = color_pairs.find(color);
+ if (it != color_pairs.end()) return it->second;
+ // We don't already have it. Make sure it's in range.
+ if (color.first < 0 || color.first > 7 || color.second < 0 || color.second > 7) return 0;
+ // We don't already have it. Generate a new pair if possible.
+ if (color_pairs.size() < COLOR_PAIRS - 1) {
+ const short pair = color_pairs.size() + 1;
+ init_pair(pair, ncurses_map_color(color.first), ncurses_map_color(color.second));
+ color_pairs[color] = pair;
+ return pair;
+ }
+ // We don't have it, and there's no space for more. Find the closest equivalent.
+ int score = 999, pair = 0;
+ int rfg = color.first % 16, rbg = color.second % 16;
+ for (auto it = color_pairs.cbegin(); it != color_pairs.cend(); ++it) {
+ int fg = it->first.first;
+ int bg = it->first.second;
+ int candidate = it->second;
+ int candidate_score = 0; // Lower is better.
+ if (rbg != bg) {
+ if (rbg == 0 || rbg == 15)
+ candidate_score += 3; // We would like to keep the background black/white.
+ if ((rbg == 7 || rbg == 8)) {
+ if (bg == 7 || bg == 8)
+ candidate_score += 1; // Well, it's still grey.
+ else
+ candidate_score += 2;
+ }
+ }
+ if (rfg != fg) {
+ if (rfg == 0 || rfg == 15)
+ candidate_score += 5; // Keep the foreground black/white if at all possible.
+ if (rfg == 7 || rfg == 8) {
+ if (fg == 7 || fg == 8)
+ candidate_score += 1; // Still grey. Meh.
+ else
+ candidate_score += 3;
+ }
+ }
+ if (candidate_score < score) {
+ score = candidate_score;
+ pair = candidate;
+ }
+ }
+ color_pairs[color] = pair;
+ return pair;
+ }
+
+public:
+
+ void update_tile(int x, int y) {
+ const int ch = gps.screen[x*gps.dimy*4 + y*4 + 0];
+ const int fg = gps.screen[x*gps.dimy*4 + y*4 + 1];
+ const int bg = gps.screen[x*gps.dimy*4 + y*4 + 2];
+ const int bold = gps.screen[x*gps.dimy*4 + y*4 + 3];
+
+ const int pair = lookup_pair(make_pair(fg,bg));
+
+ if (ch == 219 && !bold) {
+ // It's â–ˆ, which is used for borders and digging designations.
+ // A_REVERSE space looks better if it isn't completely tall.
+ // Which is most of the time, for me at least.
+ // â–ˆ <-- Do you see gaps?
+ // â–ˆ
+ // The color can't be bold.
+ wattrset(*stdscr_p, COLOR_PAIR(pair) | A_REVERSE);
+ mvwaddstr(*stdscr_p, y, x, " ");
+ } else {
+ wattrset(*stdscr_p, COLOR_PAIR(pair) | (bold ? A_BOLD : 0));
+ wchar_t chs[2] = {charmap[ch],0};
+ mvwaddwstr(*stdscr_p, y, x, chs);
+ }
+ }
+
+ void update_all() {
+ for (int x = 0; x < init.display.grid_x; x++)
+ for (int y = 0; y < init.display.grid_y; y++)
+ update_tile(x, y);
+ }
+
+ void render() {
+ refresh();
+ }
+
+ void resize(int w, int h) {
+ if (enabler.overridden_grid_sizes.size() == 0)
+ gps_allocate(w, h);
+ erase();
+ // Force a full display cycle
+ gps.force_full_display_count = 1;
+ enabler.flag |= ENABLERFLAG_RENDER;
+ }
+
+ void grid_resize(int w, int h) {
+ gps_allocate(w, h);
+ }
+
+ renderer_curses() {
+ init_curses();
+ }
+
+ bool get_mouse_coords(int &x, int &y) {
+ return false;
+ }
+};
+
+// Reads from getch, collapsing utf-8 encoding to the actual unicode
+// character. Ncurses symbols (left arrow, etc.) are returned as
+// positive values, unicode as negative. Error returns 0.
+static int getch_utf8() {
+ int byte = wgetch(*stdscr_p);
+ if (byte == ERR) return 0;
+ if (byte > 0xff) return byte;
+ int len = decode_utf8_predict_length(byte);
+ if (!len) return 0;
+ string input(len,0); input[0] = byte;
+ for (int i = 1; i < len; i++) input[i] = wgetch(*stdscr_p);
+ return -decode_utf8(input);
+}
+
+void enablerst::eventLoop_ncurses() {
+ int x, y, oldx = 0, oldy = 0;
+ renderer_curses *renderer = static_cast<renderer_curses*>(this->renderer);
+
+ while (loopvar) {
+ // Check for terminal resize
+ getmaxyx(*stdscr_p, y, x);
+ if (y != oldy || x != oldx) {
+ pause_async_loop();
+ renderer->resize(x, y);
+ unpause_async_loop();
+ oldx = x; oldy = y;
+ }
+
+ // Deal with input
+ Uint32 now = SDL_GetTicks();
+ // Read keyboard input, if any, and transform to artificial SDL
+ // events for enabler_input.
+ int key;
+ bool paused_loop = false;
+ while ((key = getch_utf8())) {
+ if (!paused_loop) {
+ pause_async_loop();
+ paused_loop = true;
+ }
+ bool esc = false;
+ if (key == KEY_MOUSE) {
+ MEVENT ev;
+ if (getmouse(&ev) == OK) {
+ // TODO: Deal with curses mouse input. And turn it on above.
+ }
+ } else if (key == -27) { // esc
+ int second = getch_utf8();
+ if (second) { // That was an escape sequence
+ esc = true;
+ key = second;
+ }
+ }
+ add_input_ncurses(key, now, esc);
+ }
+
+ if (paused_loop)
+ unpause_async_loop();
+
+ // Run the common logic
+ do_frame();
+ }
+}
+
+
+//// libncursesw stub ////
+
+extern "C" {
+ static void *handle;
+ WINDOW **stdscr_p;
+
+ int COLOR_PAIRS;
+ static int (*_erase)(void);
+ static int (*_wmove)(WINDOW *w, int y, int x);
+ static int (*_waddnstr)(WINDOW *w, const char *s, int n);
+ static int (*_nodelay)(WINDOW *w, bool b);
+ static int (*_refresh)(void);
+ static int (*_wgetch)(WINDOW *w);
+ static int (*_endwin)(void);
+ static WINDOW *(*_initscr)(void);
+ static int (*_raw)(void);
+ static int (*_keypad)(WINDOW *w, bool b);
+ static int (*_noecho)(void);
+ static int (*_set_escdelay)(int delay);
+ static int (*_curs_set)(int s);
+ static int (*_start_color)(void);
+ static int (*_init_pair)(short p, short fg, short bg);
+ static int (*_getmouse)(MEVENT *m);
+ static int (*_waddnwstr)(WINDOW *w, const wchar_t *s, int i);
+
+ static void *dlsym_orexit(const char *symbol, bool actually_exit = true) {
+ void *sym = dlsym(handle, symbol);
+ if (!sym) {
+ printf("Symbol not found: %s\n", symbol);
+ if (actually_exit)
+ exit(EXIT_FAILURE);
+ }
+ return sym;
+ }
+
+ int erase(void) {
+ return _erase();
+ }
+ int wmove(WINDOW *w, int y, int x) {
+ return _wmove(w, y, x);
+ }
+ int waddnstr(WINDOW *w, const char *s, int n) {
+ return _waddnstr(w, s, n);
+ }
+ int nodelay(WINDOW *w, bool b) {
+ return _nodelay(w, b);
+ }
+ int refresh(void) {
+ return _refresh();
+ }
+ int wgetch(WINDOW *w) {
+ return _wgetch(w);
+ }
+ int endwin(void) {
+ return _endwin();
+ }
+ WINDOW *initscr(void) {
+ return _initscr();
+ }
+ int raw(void) {
+ return _raw();
+ }
+ int keypad(WINDOW *w, bool b) {
+ return _keypad(w, b);
+ }
+ int noecho(void) {
+ return _noecho();
+ }
+ int set_escdelay(int delay) {
+ if (_set_escdelay)
+ return _set_escdelay(delay);
+ else
+ return 0;
+ }
+ int curs_set(int s) {
+ return _curs_set(s);
+ }
+ int start_color(void) {
+ return _start_color();
+ }
+ int init_pair(short p, short fg, short bg) {
+ return _init_pair(p, fg, bg);
+ }
+ int getmouse(MEVENT *m) {
+ return _getmouse(m);
+ }
+ int waddnwstr(WINDOW *w, const wchar_t *s, int n) {
+ return _waddnwstr(w, s, n);
+ }
+
+ void init_curses() {
+ static bool stub_initialized = false;
+ // Initialize the stub
+ if (!stub_initialized) {
+ stub_initialized = true;
+ // We prefer libncursesw, but we'll accept libncurses if we have to
+ handle = dlopen("libncursesw.so.5", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncursesw.so", RTLD_LAZY);
+ if (handle) goto opened;
+ puts("Didn't find any flavor of libncursesw, attempting libncurses");
+ sleep(5);
+ handle = dlopen("libncurses.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncurses.so.5", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncurses.so", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncurses.5.4.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("/usr/lib/libncurses.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("/usr/lib/libncurses.5.4.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+
+ opened:
+ if (!handle) {
+ puts("Unable to open any flavor of libncurses!");
+ exit(EXIT_FAILURE);
+ }
+ // Okay, look up our symbols
+ int *pairs = (int*)dlsym_orexit("COLOR_PAIRS");
+ COLOR_PAIRS = *pairs;
+ stdscr_p = (WINDOW**)dlsym_orexit("stdscr");
+ _erase = (int (*)(void))dlsym_orexit("erase");
+ _wmove = (int (*)(WINDOW *w, int y, int x))dlsym_orexit("wmove");
+ _waddnstr = (int (*)(WINDOW *w, const char *s, int n))dlsym_orexit("waddnstr");
+ _nodelay = (int (*)(WINDOW *w, bool b))dlsym_orexit("nodelay");
+ _refresh = (int (*)(void))dlsym_orexit("refresh");
+ _wgetch = (int (*)(WINDOW *w))dlsym_orexit("wgetch");
+ _endwin = (int (*)(void))dlsym_orexit("endwin");
+ _initscr = (WINDOW *(*)(void))dlsym_orexit("initscr");
+ _raw = (int (*)(void))dlsym_orexit("raw");
+ _keypad = (int (*)(WINDOW *w, bool b))dlsym_orexit("keypad");
+ _noecho = (int (*)(void))dlsym_orexit("noecho");
+ _set_escdelay = (int (*)(int delay))dlsym_orexit("set_escdelay", false);
+ _curs_set = (int (*)(int s))dlsym_orexit("curs_set");
+ _start_color = (int (*)(void))dlsym_orexit("start_color");
+ _init_pair = (int (*)(short p, short fg, short bg))dlsym_orexit("init_pair");
+ _getmouse = (int (*)(MEVENT *m))dlsym_orexit("getmouse");
+ _waddnwstr = (int (*)(WINDOW *w, const wchar_t *s, int i))dlsym_orexit("waddnwstr");
+ }
+
+ // Initialize curses
+ if (!curses_initialized) {
+ curses_initialized = true;
+ WINDOW *new_window = initscr();
+ if (!new_window) {
+ puts("unable to create ncurses window - initscr failed!");
+ exit(EXIT_FAILURE);
+ }
+ // in some versions of curses, initscr does not update stdscr!
+ if (!*stdscr_p) *stdscr_p = new_window;
+ raw();
+ noecho();
+ keypad(*stdscr_p, true);
+ nodelay(*stdscr_p, true);
+ set_escdelay(25); // Possible bug
+ curs_set(0);
+ mmask_t dummy;
+ // mousemask(ALL_MOUSE_EVENTS, &dummy);
+ start_color();
+ init_pair(1, COLOR_WHITE, COLOR_BLACK);
+
+ atexit(endwin_void);
+ }
+ }
+};
+
diff --git a/g_src/renderer_offscreen.cpp b/g_src/renderer_offscreen.cpp new file mode 100755 index 0000000..a3a7f16 --- /dev/null +++ b/g_src/renderer_offscreen.cpp @@ -0,0 +1,86 @@ +#include "renderer_2d.hpp" + + +bool renderer_offscreen::init_video(int w, int h) { + if (screen) SDL_FreeSurface(screen); + // Create an offscreen buffer + screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0, 0, 0, 0); + assert(screen); + return true; +} + +renderer_offscreen::~renderer_offscreen() { + //ASSUMES renderer_offscreen IS NEVER gps_allocate()'d THROUGH reshape()/grid_resize() + //to-do: flag for those calls on the renderer to control this behavior? + renderer::screen = NULL; + renderer::screentexpos = NULL; + renderer::screentexpos_addcolor = NULL; + renderer::screentexpos_grayscale = NULL; + renderer::screentexpos_cf = NULL; + renderer::screentexpos_cbr = NULL; + renderer::screen_old = NULL; + renderer::screentexpos_old = NULL; + renderer::screentexpos_addcolor_old = NULL; + renderer::screentexpos_grayscale_old = NULL; + renderer::screentexpos_cf_old = NULL; + renderer::screentexpos_cbr_old = NULL; + + SDL_FreeSurface(screen); +} + +// Create an offscreen renderer of a given grid-size +renderer_offscreen::renderer_offscreen(int grid_x, int grid_y) { + screen = NULL; + dispx = enabler.is_fullscreen() ? + init.font.large_font_dispx : + init.font.small_font_dispx; + dispy = enabler.is_fullscreen() ? + init.font.large_font_dispy : + init.font.small_font_dispy; + dispx_z = dispx; + dispy_z = dispy; + origin_x = origin_y = 0; + zoom_steps = forced_steps = 0; + natural_w = dispx * grid_x; + natural_h = dispy * grid_y; + dimx = grid_x; + dimy = grid_y; + init_video(natural_w, natural_h); + // Copy the GPS pointers here + renderer::screen = gps.screen; + renderer::screentexpos = gps.screentexpos; + renderer::screentexpos_addcolor = gps.screentexpos_addcolor; + renderer::screentexpos_grayscale = gps.screentexpos_grayscale; + renderer::screentexpos_cf = gps.screentexpos_cf; + renderer::screentexpos_cbr = gps.screentexpos_cbr; +} + +// Slurp the entire gps content into the renderer at some given offset +void renderer_offscreen::update_all(int offset_x, int offset_y) { + for (int x = 0; x < gps.dimx; x++) { + for (int y = 0; y < gps.dimy; y++) { + // Read tiles from gps, create cached texture + Either<texture_fullid,texture_ttfid> id = screen_to_texid(x, y); + SDL_Surface *tex = id.isL ? + tile_cache_lookup(id.left, false) : + ttf_manager.get_texture(id.right); + if (id.isL) { + tex = tile_cache_lookup(id.left); + } else { + tex = enabler.textures.get_texture_data(id.right); + } + // Figure out where to blit + SDL_Rect dst; + dst.x = dispx * (x+offset_x); + dst.y = dispy * (y+offset_y); + // And blit. + SDL_BlitSurface(tex, NULL, screen, &dst); + } + } +} + +// Save the image to some file +void renderer_offscreen::save_to_file(const string &file) { + // TODO: Support png, etc. + SDL_SaveBMP(screen, file.c_str()); +} diff --git a/g_src/renderer_opengl.hpp b/g_src/renderer_opengl.hpp new file mode 100755 index 0000000..0ea3c6c --- /dev/null +++ b/g_src/renderer_opengl.hpp @@ -0,0 +1,609 @@ +// STANDARD +class renderer_opengl : public renderer { +public: + virtual bool uses_opengl() { return true; } + +protected: + SDL_Surface *screen; + + int dispx, dispy; // Cache of the current font size + + bool init_video(int w, int h) { + // Get ourselves an opengl-enabled SDL window + Uint32 flags = SDL_HWSURFACE | SDL_OPENGL; + + // Set it up for windowed or fullscreen, depending. + if (enabler.is_fullscreen()) { + flags |= SDL_FULLSCREEN; + } else { + if (!init.display.flag.has_flag(INIT_DISPLAY_FLAG_NOT_RESIZABLE)) + flags |= SDL_RESIZABLE; + } + + // Setup OpenGL attributes + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, init.window.flag.has_flag(INIT_WINDOW_FLAG_VSYNC_ON)); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, + init.display.flag.has_flag(INIT_DISPLAY_FLAG_SINGLE_BUFFER) ? 0 : 1); + + // (Re)create the window + screen = SDL_SetVideoMode(w, h, 32, flags); + + if (!screen) return false; + + // Test double-buffering status + int test; + SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &test); + if (test != ((init.display.flag.has_flag(INIT_DISPLAY_FLAG_SINGLE_BUFFER)) ? 0 : 1)) { + if (enabler.is_fullscreen()); + //errorlog << "Requested single-buffering not available\n" << flush; + else + report_error("OpenGL", "Requested single-buffering not available"); + } + + // (Re)initialize GLEW. Technically only needs to be done once on + // linux, but on windows forgetting will cause crashes. + glewInit(); + + // Set the viewport and clear + glViewport(0, 0, screen->w, screen->h); + glClear(GL_COLOR_BUFFER_BIT); + + return true; + } + + // Vertexes, foreground color, background color, texture coordinates + GLfloat *vertexes, *fg, *bg, *tex; + + void write_tile_vertexes(GLfloat x, GLfloat y, GLfloat *vertex) { + vertex[0] = x; // Upper left + vertex[1] = y; + vertex[2] = x+1; // Upper right + vertex[3] = y; + vertex[4] = x; // Lower left + vertex[5] = y+1; + vertex[6] = x; // Lower left again (triangle 2) + vertex[7] = y+1; + vertex[8] = x+1; // Upper right + vertex[9] = y; + vertex[10] = x+1; // Lower right + vertex[11] = y+1; + } + + virtual void allocate(int tiles) { + vertexes = static_cast<GLfloat*>(realloc(vertexes, sizeof(GLfloat) * tiles * 2 * 6)); + assert(vertexes); + fg = static_cast<GLfloat*>(realloc(fg, sizeof(GLfloat) * tiles * 4 * 6)); + assert(fg); + bg = static_cast<GLfloat*>(realloc(bg, sizeof(GLfloat) * tiles * 4 * 6)); + assert(bg); + tex = static_cast<GLfloat*>(realloc(tex, sizeof(GLfloat) * tiles * 2 * 6)); + assert(tex); + + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, vertexes); + } + + virtual void init_opengl() { + enabler.textures.upload_textures(); + } + + virtual void uninit_opengl() { + enabler.textures.remove_uploaded_textures(); + } + + virtual void draw(int vertex_count) { + // Render the background colors + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glColorPointer(4, GL_FLOAT, 0, bg); + glDrawArrays(GL_TRIANGLES, 0, vertex_count); + // Render the foreground, colors and textures both + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_NOTEQUAL, 0); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glTexCoordPointer(2, GL_FLOAT, 0, tex); + glColorPointer(4, GL_FLOAT, 0, fg); + glDrawArrays(GL_TRIANGLES, 0, vertex_count); + + printGLError(); + } + + void write_tile_arrays(int x, int y, GLfloat *fg, GLfloat *bg, GLfloat *tex) { + Either<texture_fullid,texture_ttfid> id = screen_to_texid(x, y); + if (id.isL) { // An ordinary tile + const gl_texpos *txt = enabler.textures.gl_texpos; + // TODO: Only bother to set the one that's actually read in flat-shading mode + // And set flat-shading mode. + for (int i = 0; i < 6; i++) { + *(fg++) = id.left.r; + *(fg++) = id.left.g; + *(fg++) = id.left.b; + *(fg++) = 1; + + *(bg++) = id.left.br; + *(bg++) = id.left.bg; + *(bg++) = id.left.bb; + *(bg++) = 1; + } + // Set texture coordinates + *(tex++) = txt[id.left.texpos].left; // Upper left + *(tex++) = txt[id.left.texpos].bottom; + *(tex++) = txt[id.left.texpos].right; // Upper right + *(tex++) = txt[id.left.texpos].bottom; + *(tex++) = txt[id.left.texpos].left; // Lower left + *(tex++) = txt[id.left.texpos].top; + + *(tex++) = txt[id.left.texpos].left; // Lower left + *(tex++) = txt[id.left.texpos].top; + *(tex++) = txt[id.left.texpos].right; // Upper right + *(tex++) = txt[id.left.texpos].bottom; + *(tex++) = txt[id.left.texpos].right; // Lower right + *(tex++) = txt[id.left.texpos].top; + } else { + // TODO + } + } + +public: + void update_tile(int x, int y) { + const int tile = x*gps.dimy + y; + // Update the arrays + GLfloat *fg = this->fg + tile * 4 * 6; + GLfloat *bg = this->bg + tile * 4 * 6; + GLfloat *tex = this->tex + tile * 2 * 6; + write_tile_arrays(x, y, fg, bg, tex); + } + + void update_all() { + glClear(GL_COLOR_BUFFER_BIT); + for (int x = 0; x < gps.dimx; x++) + for (int y = 0; y < gps.dimy; y++) + update_tile(x, y); + } + + void render() { + draw(gps.dimx*gps.dimy*6); + if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_ARB_SYNC) && GL_ARB_sync) { + assert(enabler.sync == NULL); + enabler.sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + } + SDL_GL_SwapBuffers(); + } + + renderer_opengl() { + // Init member variables so realloc'll work + screen = NULL; + vertexes = NULL; + fg = NULL; + bg = NULL; + tex = NULL; + zoom_steps = forced_steps = 0; + + // Disable key repeat + SDL_EnableKeyRepeat(0, 0); + // Set window title/icon. + SDL_WM_SetCaption(GAME_TITLE_STRING, NULL); + SDL_Surface *icon = IMG_Load("data/art/icon.png"); + if (icon != NULL) { + SDL_WM_SetIcon(icon, NULL); + // The icon's surface doesn't get used past this point. + SDL_FreeSurface(icon); + } + + // Find the current desktop resolution if fullscreen resolution is auto + if (init.display.desired_fullscreen_width == 0 || + init.display.desired_fullscreen_height == 0) { + const struct SDL_VideoInfo *info = SDL_GetVideoInfo(); + init.display.desired_fullscreen_width = info->current_w; + init.display.desired_fullscreen_height = info->current_h; + } + + // Initialize our window + bool worked = init_video(enabler.is_fullscreen() ? + init.display.desired_fullscreen_width : + init.display.desired_windowed_width, + enabler.is_fullscreen() ? + init.display.desired_fullscreen_height : + init.display.desired_windowed_height); + + // Fallback to windowed mode if fullscreen fails + if (!worked && enabler.is_fullscreen()) { + enabler.fullscreen = false; + report_error("SDL initialization failure, trying windowed mode", SDL_GetError()); + worked = init_video(init.display.desired_windowed_width, + init.display.desired_windowed_height); + } + // Quit if windowed fails + if (!worked) { + report_error("SDL initialization failure", SDL_GetError()); + exit(EXIT_FAILURE); + } + + // Initialize opengl + init_opengl(); + } + + virtual ~renderer_opengl() { + free(vertexes); + free(fg); + free(bg); + free(tex); + } + + int zoom_steps, forced_steps; + int natural_w, natural_h; // How large our view would be if it wasn't zoomed + + void zoom(zoom_commands cmd) { + pair<int,int> before = compute_zoom(true); + int before_steps = zoom_steps; + switch (cmd) { + case zoom_in: zoom_steps -= init.input.zoom_speed; break; + case zoom_out: zoom_steps += init.input.zoom_speed; break; + case zoom_reset: + zoom_steps = 0; + case zoom_resetgrid: + compute_forced_zoom(); + break; + } + pair<int,int> after = compute_zoom(true); + if (after == before && (cmd == zoom_in || cmd == zoom_out)) + zoom_steps = before_steps; + else + reshape(after); + } + + void compute_forced_zoom() { + forced_steps = 0; + pair<int,int> zoomed = compute_zoom(); + while (zoomed.first < MIN_GRID_X || zoomed.second < MIN_GRID_Y) { + forced_steps++; + zoomed = compute_zoom(); + } + while (zoomed.first > MAX_GRID_X || zoomed.second > MAX_GRID_Y) { + forced_steps--; + zoomed = compute_zoom(); + } + } + + pair<int,int> compute_zoom(bool clamp = false) { + const int dispx = enabler.is_fullscreen() ? + init.font.large_font_dispx : + init.font.small_font_dispx; + const int dispy = enabler.is_fullscreen() ? + init.font.large_font_dispy : + init.font.small_font_dispy; + int w, h; + if (dispx < dispy) { + w = natural_w + zoom_steps + forced_steps; + h = double(natural_h) * (double(w) / double(natural_w)); + } else { + h = natural_h + zoom_steps + forced_steps; + w = double(natural_w) * (double(h) / double(natural_h)); + } + if (clamp) { + w = MIN(MAX(w, MIN_GRID_X), MAX_GRID_X); + h = MIN(MAX(h, MIN_GRID_Y), MAX_GRID_Y); + } + return make_pair(w,h); + } + + // Parameters: grid units + void reshape(pair<int,int> size) { + int w = MIN(MAX(size.first, MIN_GRID_X), MAX_GRID_X); + int h = MIN(MAX(size.second, MIN_GRID_Y), MAX_GRID_Y); +#ifdef DEBUG + cout << "Resizing grid to " << w << "x" << h << endl; +#endif + gps_allocate(w, h); + reshape_gl(); + } + + int off_x, off_y, size_x, size_y; + + bool get_mouse_coords(int &x, int &y) { + int mouse_x, mouse_y; + SDL_GetMouseState(&mouse_x, &mouse_y); + mouse_x -= off_x; mouse_y -= off_y; + if (mouse_x < 0 || mouse_y < 0 || + mouse_x >= size_x || mouse_y >= size_y) + return false; // Out of bounds + x = double(mouse_x) / double(size_x) * double(gps.dimx); + y = double(mouse_y) / double(size_y) * double(gps.dimy); + return true; + } + + virtual void reshape_gl() { + // Allocate array memory + allocate(gps.dimx * gps.dimy); + // Initialize the vertex array + int tile = 0; + for (GLfloat x = 0; x < gps.dimx; x++) + for (GLfloat y = 0; y < gps.dimy; y++, tile++) + write_tile_vertexes(x, y, vertexes + 6*2*tile); + // Setup invariant state + glEnableClientState(GL_COLOR_ARRAY); + /// Set up our coordinate system + if (forced_steps + zoom_steps == 0 && + init.display.flag.has_flag(INIT_DISPLAY_FLAG_BLACK_SPACE)) { + size_x = gps.dimx * dispx; + size_y = gps.dimy * dispy; + off_x = (screen->w - size_x) / 2; + off_y = (screen->h - size_y) / 2; + } else { + // If we're zooming (or just not using black space), we use the + // entire window. + size_x = screen->w; + size_y = screen->h; + off_x = off_y = 0; + } + glViewport(off_x, off_y, size_x, size_y); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, gps.dimx, gps.dimy, 0); + } + + // Parameters: window size + void resize(int w, int h) { + // (Re)calculate grid-size + dispx = enabler.is_fullscreen() ? + init.font.large_font_dispx : + init.font.small_font_dispx; + dispy = enabler.is_fullscreen() ? + init.font.large_font_dispy : + init.font.small_font_dispy; + natural_w = MAX(w / dispx,1); + natural_h = MAX(h / dispy,1); + // Compute forced_steps so we satisfy our grid-size limits + compute_forced_zoom(); + // Force a full display cycle + gps.force_full_display_count = 1; + enabler.flag |= ENABLERFLAG_RENDER; + // Reinitialize the video + uninit_opengl(); + init_video(w, h); + init_opengl(); + // Only reshape if we're free to pick grid size + if (enabler.overridden_grid_sizes.size() == 0) + reshape(compute_zoom()); + } + + // Parameters: grid size + void grid_resize(int w, int h) { + reshape(make_pair(w, h)); + } + +public: + void set_fullscreen() { + if (enabler.is_fullscreen()) { + init.display.desired_windowed_width = screen->w; + init.display.desired_windowed_height = screen->h; + resize(init.display.desired_fullscreen_width, + init.display.desired_fullscreen_height); + } else { + resize(init.display.desired_windowed_width, init.display.desired_windowed_height); + } + } +}; + +// Specialization for PARTIAL:0 +class renderer_once : public renderer_opengl { + int tile_count; + +protected: + void update_tile(int x, int y) { + write_tile_vertexes(x, y, vertexes + tile_count * 6 * 2); + write_tile_arrays(x, y, + fg + tile_count * 6 * 4, + bg + tile_count * 6 * 4, + tex + tile_count * 6 * 2); + tile_count++; + } + + void draw(int dummy) { + renderer_opengl::draw(tile_count*6); + tile_count = 0; + } + +public: + renderer_once() { + tile_count = 0; + } +}; + +// PARTIAL:N +class renderer_partial : public renderer_opengl { + int buffersz; + list<int> erasz; // Previous eras + int current_erasz; // And the current one + int sum_erasz; + int head, tail; // First unused tile, first used tile respectively + int redraw_count; // Number of eras to max out at + + void update_tile(int x, int y) { + write_tile_vertexes(x, y, vertexes + head * 6 * 2); + write_tile_arrays(x, y, + fg + head * 6 * 4, + bg + head * 6 * 4, + tex + head * 6 * 2); + head = (head + 1) % buffersz; + current_erasz++; sum_erasz++; + if (head == tail) { + //gamelog << "Expanding partial-printing buffer" << endl; + // Buffer is full, expand it. + renderer_opengl::allocate(buffersz * 2); + // Move the tail to the end of the newly allocated space + tail += buffersz; + memmove(vertexes + tail * 6 * 2, vertexes + head * 6 * 2, sizeof(GLfloat) * 6 * 2 * (buffersz - head)); + memmove(fg + tail * 6 * 4, fg + head * 6 * 4, sizeof(GLfloat) * 6 * 4 * (buffersz - head)); + memmove(bg + tail * 6 * 4, fg + head * 6 * 4, sizeof(GLfloat) * 6 * 4 * (buffersz - head)); + memmove(tex + tail * 6 * 2, fg + head * 6 * 2, sizeof(GLfloat) * 6 * 2 * (buffersz - head)); + // And finish. + buffersz *= 2; + } + } + + void allocate(int tile_count) { + assert(false); + } + + virtual void reshape_gl() { + // TODO: This function is duplicate code w/base class reshape_gl + // Setup invariant state + glEnableClientState(GL_COLOR_ARRAY); + /// Set up our coordinate system + if (forced_steps + zoom_steps == 0 && + init.display.flag.has_flag(INIT_DISPLAY_FLAG_BLACK_SPACE)) { + size_x = gps.dimx * dispx; + size_y = gps.dimy * dispy; + off_x = (screen->w - size_x) / 2; + off_y = (screen->h - size_y) / 2; + } else { + // If we're zooming (or just not using black space), we use the + // entire window. + size_x = screen->w; + size_y = screen->h; + off_x = off_y = 0; + } + glViewport(off_x, off_y, size_x, size_y); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0, gps.dimx, gps.dimy, 0); + } + + void draw_arrays(GLfloat *vertexes, GLfloat *fg, GLfloat *bg, GLfloat *tex, int tile_count) { + // Set vertex pointer + glVertexPointer(2, GL_FLOAT, 0, vertexes); + // Render the background colors + glDisable(GL_TEXTURE_2D); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glDisable(GL_BLEND); + glDisable(GL_ALPHA_TEST); + glColorPointer(4, GL_FLOAT, 0, bg); + glDrawArrays(GL_TRIANGLES, 0, tile_count * 6); + // Render the foreground, colors and textures both + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_NOTEQUAL, 0); + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColorPointer(4, GL_FLOAT, 0, fg); + glTexCoordPointer(2, GL_FLOAT, 0, tex); + glDrawArrays(GL_TRIANGLES, 0, tile_count * 6); + } + + void draw(int dummy) { + if (tail > head) { + // We're straddling the end of the array, so have to do this in two steps + draw_arrays(vertexes + tail * 6 * 2, + fg + tail * 6 * 4, + bg + tail * 6 * 4, + tex + tail * 6 * 2, + buffersz - tail); + draw_arrays(vertexes, fg, bg, tex, head-1); + } else { + draw_arrays(vertexes + tail * 6 * 2, + fg + tail * 6 * 4, + bg + tail * 6 * 4, + tex + tail * 6 * 2, + sum_erasz); + } + + printGLError(); + erasz.push_back(current_erasz); current_erasz = 0; + if (erasz.size() == redraw_count) { + // Right, time to retire the oldest era. + tail = (tail + erasz.front()) % buffersz; + sum_erasz -= erasz.front(); + erasz.pop_front(); + } + } + +public: + renderer_partial() { + redraw_count = init.display.partial_print_count; + buffersz = 2048; + renderer_opengl::allocate(buffersz); + current_erasz = head = tail = sum_erasz = 0; + } +}; + +class renderer_accum_buffer : public renderer_once { + void draw(int vertex_count) { + // Copy the previous frame's buffer back in + glAccum(GL_RETURN, 1); + renderer_once::draw(vertex_count); + // Store the screen contents back to the buffer + glAccum(GL_LOAD, 1); + } +}; + +class renderer_framebuffer : public renderer_once { + GLuint framebuffer, fb_texture; + + void init_opengl() { + glGenFramebuffersEXT(1, &framebuffer); + // Allocate FBO texture memory + glGenTextures(1, &fb_texture); + glBindTexture(GL_TEXTURE_2D, fb_texture); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + screen->w, screen->h, + 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + + // Bind texture to FBO + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer); + glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, fb_texture, 0); + renderer_once::init_opengl(); + } + + void uninit_opengl() { + renderer_once::uninit_opengl(); + glDeleteTextures(1, &fb_texture); + glDeleteFramebuffersEXT(1, &framebuffer); + } + + void draw(int vertex_count) { + // Bind the framebuffer + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0); + // Draw + renderer_once::draw(vertex_count); + // Draw the framebuffer to screen + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0); + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer); + glBlitFramebufferEXT(0,0, screen->w, screen->h, + 0,0, screen->w, screen->h, + GL_COLOR_BUFFER_BIT, GL_NEAREST); + printGLError(); + } +}; + +class renderer_vbo : public renderer_opengl { + GLuint vbo; // Vertexes only + + void init_opengl() { + renderer_opengl::init_opengl(); + glGenBuffersARB(1, &vbo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, gps.dimx*gps.dimy*6*2*sizeof(GLfloat), vertexes, GL_STATIC_DRAW_ARB); + glVertexPointer(2, GL_FLOAT, 0, 0); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); + } + + void uninit_opengl() { + glDeleteBuffersARB(1, &vbo); + renderer_opengl::uninit_opengl(); + } +}; diff --git a/g_src/resize++.cpp b/g_src/resize++.cpp new file mode 100755 index 0000000..fd1b77c --- /dev/null +++ b/g_src/resize++.cpp @@ -0,0 +1,269 @@ +#include <cmath> +#include <vector> + +#include <SDL/SDL.h> + +#include "resize++.h" + +//code adapted by David Olsen from Lanczos filtering article on wikipedia.org + +#ifndef M_PI +#define M_PI 3.14159265359 +#endif + +static inline double Lanczos(double x, int Radius) +{ + if (x == 0.0) return 1.0; + if (x <= -Radius || x >= Radius) return 0.0; + double tmp = x * M_PI; + return Radius * std::sin(tmp) * std::sin(tmp / Radius) / (tmp * tmp); +} + +static inline void Resample(SDL_Surface * src, SDL_Surface * dst, int filter) +{ + const double blur = 1.0; + double factor = dst->w / (double)src->w; + double scale = std::min(factor, 1.0) / blur; + int FilterRadius = filter; + if (filter < 1 ) + FilterRadius = 1; + if (filter > 3) //automatically determine fastest filter setting + { + FilterRadius = 3; + if (scale < 0.67) FilterRadius = 2; + if (scale <= 0.5) FilterRadius = 1; + } + double support = FilterRadius / scale; + + std::vector<double> contribution_x(std::min((size_t)src->w, 5+(size_t)(2*support))); + /* 5 = room for rounding up in calculations of start, stop and support */ + + Uint32 ** temp = new Uint32 * [src->h]; //array of source->height * dest->width + for (int i = 0 ; i < src->h; i++) + temp[i] = new Uint32 [dst->w]; + + if (support <= 0.5) { support = 0.5 + 1E-12; scale = 1.0; } + + for (int x = 0; x < dst->w; ++x) + { + double center = (x + 0.5) / factor; + size_t start = (size_t)std::max(center - support + 0.5, (double)0); + size_t stop = (size_t)std::min(center + support + 0.5, (double)src->w); + double density = 0.0; + size_t nmax = stop - start; + double s = start - center + 0.5; + double point[4] = {0,0,0,0}; + Uint8 v; + double diff; + + for (int y = 0; y < src->h; y++) + { + for (size_t n = 0; n < nmax; ++n) + { + if (y == 0) + { //only come up with the contribution list once per column. + contribution_x[n] = Lanczos (s * scale, FilterRadius); + density += contribution_x[n]; + s++; + } + //it MUST be a 32-bit surface for following code to work correctly + Uint8 * p = (Uint8 *)src->pixels + y * src->pitch + (start+n) * 4; + for (int c = 0; c < 4; c++) + point[c] += p[c] * contribution_x[n]; + } + /* Normalize. Truncate to Uint8 values. Place in temp array*/ + Uint8 * p = (Uint8 *)&temp[y][x]; + for (size_t c = 0; c < 4; c++) + { + if (density != 0.0 && density != 1.0) + point[c] /= density; + if (point[c] < 0) + point[c] = 0; + if (point[c] > 255) + point[c] = 255; + v = (Uint8) point[c]; + diff = point[c] - (double)v; + if (diff < 0) + diff = -diff; + if (diff >= 0.5) + v++; + p[c] = v; + point[c] = 0; //reset value for next loop + } + } + } + + factor = dst->h / (double)src->h; + scale = std::min(factor, 1.0) / blur; + if (filter > 3) //automatically determine fastest filter setting + { + FilterRadius = 3; + if (scale < 0.67) FilterRadius = 2; + if (scale <= 0.5) FilterRadius = 1; + } + support = FilterRadius / scale; + + std::vector<double> contribution_y(std::min((size_t)src->h, 5+(size_t)(2*support))); + + if (support <= 0.5) { support = 0.5 + 1E-12; scale = 1.0; } + + for (int y = 0; y<dst->h; ++y) + { + double center = (y + 0.5) / factor; + size_t start = (size_t)std::max(center - support + 0.5, (double)0); + size_t stop = (size_t)std::min(center + support + 0.5, (double)src->h); + double density = 0.0; + size_t nmax = stop-start; + double s = start - center+0.5; + double point[4] = {0,0,0,0}; + Uint8 v; + double diff; + + for (int x=0; x<dst->w; x++) + { + for (size_t n=0; n<nmax; ++n) + { + if (x == 0) + { + contribution_y[n] = Lanczos(s * scale, FilterRadius); + density += contribution_y[n]; + s++; + } + Uint8 * p = (Uint8 *)&temp[start+n][x]; + for (int c = 0; c < 4; c++) + point[c] += p[c] * contribution_y[n]; + } + //destination must also be a 32 bit surface for this to work! + Uint8 * p = (Uint8 *)dst->pixels + y * dst->pitch + x * 4; + for (size_t c = 0; c < 4; c++) + { + if (density != 0.0 && density != 1.0) + point[c] /= density; + if (point[c] < 0) + point[c] = 0; + if (point[c] > 255) + point[c] = 255; + v = (Uint8) point[c]; + diff = point[c] - (double)v; + if (diff < 0) + diff = -diff; + if (diff >= 0.5) + v++; + p[c] = v; + point[c] = 0; + } + } + } + + //free the temp array, so we don't leak any memory + for (int i = 0 ; i < src->h; i++) + delete [] temp[i]; + delete [] temp; +} + +static inline Uint32 get_pixel(SDL_Surface *surface, int x, int y) +{ + int bpp = surface->format->BytesPerPixel; + /* Here p is the address to the pixel we want to retrieve */ + Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; + + switch(bpp) + { + case 1: return *p; + case 2: return *(Uint16 *)p; + case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + return p[0] << 16 | p[1] << 8 | p[2]; + else + return p[0] | p[1] << 8 | p[2] << 16; + case 4: return *(Uint32 *)p; + default: return 0; /* shouldn't happen, but avoids warnings */ + } +} + +static inline bool has_alpha(SDL_Surface * src) +{ + Uint8 r, g, b, a; + bool is_alpha = false; + + if SDL_MUSTLOCK(src) SDL_LockSurface(src); + + for (int x = 0; x < src->w; x++) + for (int y = 0; y < src->h; y++) + { + SDL_GetRGBA(get_pixel(src, x, y), src->format, &r, &g, &b, &a); + if (a != SDL_ALPHA_OPAQUE) + { + is_alpha = true; + x = src->w; + break; + } + } + + if SDL_MUSTLOCK(src) SDL_UnlockSurface(src); + + return is_alpha; +} + +SDL_Surface* SDL_Resize(SDL_Surface *src, float factor, bool free, int filter) +{ + if (factor > 100.0f) factor = 100.0f; //let's be reasonable... + int new_w = (int)(src->w * factor), + new_h = (int)(src->h * factor); + if (new_w < 1) new_w = 1; + if (new_h < 1) new_h = 1; + + return SDL_Resize(src, new_w, new_h, free, filter); +} + +SDL_Surface* SDL_Resize(SDL_Surface *src, int new_w, int new_h, bool free, int filter) +{ + SDL_Surface * dst; + bool is_alpha = has_alpha(src); + + if (src->w == new_w && src->h == new_h) + { + //No change in size. Return an optimized image. + if (is_alpha) + { + dst = SDL_DisplayFormatAlpha(src); + SDL_SetAlpha(src, SDL_SRCALPHA, 0); + } + else + dst = SDL_DisplayFormat(src); + + if (free) + SDL_FreeSurface(src); + return dst; + } + + Uint32 rmask = 0x000000ff, + gmask = 0x0000ff00, + bmask = 0x00ff0000, + amask = 0xff000000; + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; + #endif + + dst = SDL_CreateRGBSurface(0, new_w, new_h, 32, rmask, gmask, bmask, amask); + SDL_Surface * temp = SDL_ConvertSurface(src,dst->format,0); + if (free) + SDL_FreeSurface(src); + src = temp; + + Resample(src,dst,filter); + + SDL_FreeSurface(temp); + if (is_alpha) + { + temp = SDL_DisplayFormatAlpha(dst); + SDL_SetAlpha(temp, SDL_SRCALPHA, 0); + } + else + temp = SDL_DisplayFormat(dst); + + SDL_FreeSurface(dst); + return temp; +} diff --git a/g_src/resize++.h b/g_src/resize++.h new file mode 100755 index 0000000..8f9b097 --- /dev/null +++ b/g_src/resize++.h @@ -0,0 +1,68 @@ +/*resize++.cpp : + High quality image scaling with Lanczos interpolation method adapted + from the Lanczos filtering code available on wikipedia.org. + -by David Olsen. + + There are two methods to use the library, the only difference is in + whether the image should be scaled to a specific size in pixels, + or be scaled proportionally by a certain percentage(1.0 = 100%). + + If scale_factor > 1.0 image will be enlarged, < 1.0 will shrink the image + + All scaling operations will return an image that has been optimized(using + SDL_DisplayFormat or SDL_DisplayFormatAlpha, as appropriate) for the + current screen mode (Even images that were not resized will return an + optimized surface pointer, i.e. scale_factor = 1.0). The SDL_SRCALPHA flag + is also set for the returned image, if appropriate. + + The option to free or not free the source image is given, so that if you + desire to make multiple copies of a source image at various sizes, + you do not need to reload the image for each operation. + + The filter variable determines the radius of the Lanczos filter. + The following settings can be used: + 1 = Quickest filtering mode, but when used for enlarging, produces + blocky results, similar to the nearest neighbor approach. + When used for reductions, it outputs very nice results. + 2 = Medium filtering mode - slightly faster than 3, but slower than 1. + When enlarging, this mode produces high quality results similar + to (but a bit better than) bilinear interpolation. + 3 = The highest quality mode, also the slowest, but only about 30% + slower than mode 1. This mode will produce the best enlargements. + There is no need for a filter radius greater than 3. + The default filtering value passed to the function is 4. Any number + greater than 3 will tell the library to automatically choose the quickest + filtering mode that still maintains highest quality output. Basically, + if you are shrinking an image greatly, it will choose radius of 1. + If you shrink an image a little bit, it will choose radius of 2. + For all other operations, it will choose a radius of 3. + You may therefore specify which filter mode to use manually, if speed + is a particular issue, or let it be automatically handled, + for highest quality results. + + The typical usage pattern can be demonstrated as follows: + SDL_Surface *image = SDL_LoadBMP("myimage.bmp"); + image = SDL_Resize(image,320,240); //scale image to 320x240 + //the original image is freed, and image points to the new scaled surface. + + or + + SDL_Surface *image = SDL_LoadBMP("myimage.bmp"); + SDL_Surface *small_image = SDL_Resize(image,0.5f,false); //shrink to 50% size + SDL_Surface *big_image = SDL_Resize(image,2.0f,false); //enlarge to 200% size + //image still points to the original loaded surface. + + If you have any questions or comments, feel free to contact me(David Olsen) at: + jolynsbass@gmail.com + +*/ + +#ifndef __RESIZEpp__ +#define __RESIZEpp__ + +#include <SDL/SDL.h> + +SDL_Surface * SDL_Resize(SDL_Surface *src, float scale_factor, bool free_src = true, int filter = 4); +SDL_Surface * SDL_Resize(SDL_Surface *src, int new_w, int new_h, bool free_src = true, int filter = 4); + +#endif diff --git a/g_src/svector.h b/g_src/svector.h new file mode 100755 index 0000000..3d9e81a --- /dev/null +++ b/g_src/svector.h @@ -0,0 +1,28 @@ +//pelican aka sam dennis wrote this +#ifndef SVECTOR_H +#define SVECTOR_H + +#include <vector> +#include <memory> + +template <class T, class A = std::allocator<T> > +class svector : public std::vector<T, A> { +#ifndef WIN32 + public: + using std::vector<T, A>::begin; +#endif + +#ifdef WIN32 + public: +#endif + void erase(typename std::vector<T, A>::size_type i) { + std::vector<T, A> &vec = *this; + vec.erase(begin() + i); + } + void insert(typename std::vector<T, A>::size_type i, const T &v) { + + std::vector<T, A> &vec = *this; + vec.insert(begin() + i, v); + } +}; +#endif diff --git a/g_src/template.h b/g_src/template.h new file mode 100755 index 0000000..0272675 --- /dev/null +++ b/g_src/template.h @@ -0,0 +1,1235 @@ +template <class T> int32_t get_vector_sum(svector<T> &vec) +{ + T total=0; + auto ii_s=vec.begin(),ii_e=vec.end(); + for(;ii_s<ii_e;++ii_s) + { + total+=(*ii_s); + } + return total; +} + +template <class T> int32_t get_random_biased_index(svector<T> &chance) +{ + if(chance.size()==0) + { + errorlog_string("Empty biased index vector"); + return -1; + } + + T roll=trandom(get_vector_sum(chance)); + + auto ii_s=chance.begin(),ii_e=chance.end(); + auto ii_b=ii_s; + for(;ii_s<ii_e;++ii_s) + { + if(roll<(*ii_s))return (int32_t)(ii_s-ii_b); + roll-=(*ii_s); + } + + errorlog_string("Biased index vector computation error"); + return 0;//MORE FUNCTIONS WILL BE HAPPIER WITH 0 THAN -1 HERE +} + +template <class T> void zero_vector(svector<T> &vc) +{ + //NOTE: vector MEMORY IS GUARANTEED TO BE CONTIGUOUS, AND THIS IS FASTER THAN GOING THROUGH ONE BY ONE + //apparently this gives linux a headache though, so back to the slower way + //int32_t sz=vc.size(); + //if(sz==0)return; + //memset(&(vc[0]),0,sizeof(T)*sz); + auto ii_s=vc.begin(),ii_e=vc.end(); + for(;ii_s<ii_e;++ii_s)(*ii_s)=0; +} + +template <class T> bool positive_vector(svector<T> &vc) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + for(;ii_s<ii_e;++ii_s) + { + if((*ii_s)>0)return true; + } + return false; +} + +template <class T> void add_unique_to_vector(T nl,svector<T> &vc) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + for(;ii_s<ii_e;++ii_s) + { + if((*ii_s)==nl)return; + } + vc.push_back(nl); +} + +template <class T,class T2> void add_dual_unique_to_vectors(T nl,T2 nl2,svector<T> &vc,svector<T2> &vc2) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + auto ii_s2=vc2.begin(),ii_e2=vc2.end(); + for(;ii_s<ii_e;++ii_s,++ii_s2) + { + if((*ii_s)==nl&& + (*ii_s2)==nl2)return; + } + vc.push_back(nl); + vc2.push_back(nl2); +} + +template <class T,class T2,class T3,class T4> void add_quad_unique_to_vectors(T nl,T2 nl2,T3 nl3,T4 nl4, + svector<T> &vc,svector<T2> &vc2,svector<T3> &vc3,svector<T4> &vc4) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + auto ii_s2=vc2.begin(),ii_e2=vc2.end(); + auto ii_s3=vc3.begin(),ii_e3=vc3.end(); + auto ii_s4=vc4.begin(),ii_e4=vc4.end(); + for(;ii_s<ii_e;++ii_s,++ii_s2,++ii_s3,++ii_s4) + { + if((*ii_s)==nl&& + (*ii_s2)==nl2&& + (*ii_s3)==nl3&& + (*ii_s4)==nl4)return; + } + vc.push_back(nl); + vc2.push_back(nl2); + vc3.push_back(nl3); + vc4.push_back(nl4); +} + +template <class T> void remove_all_from_vector(T nl,svector<T> &vc) +{ + int32_t i; + for(i=(int32_t)vc.size()-1;i>=0;i--) + { + if(vc[i]==nl)vc.erase(i); + } +} + +template <class T,class T2> void remove_all_from_dual_vectors(T nl,T2 nl2,svector<T> &vc,svector<T2> &vc2) +{ + int32_t i; + for(i=(int32_t)vc.size()-1;i>=0;i--) + { + if(vc[i]==nl&& + vc2[i]==nl2) + { + vc.erase(i); + vc2.erase(i); + } + } +} + +template <class T> int32_t get_vector_index(T a,svector<T> &v) +{ + auto ii_s=v.begin(),ii_e=v.end(); + auto ii_b=ii_s; + for(;ii_s<ii_e;++ii_s) + { + if((*ii_s)==a)return (int32_t)(ii_s-ii_b); + } + return -1; +} + +template <class T,class T2> int32_t get_dual_vector_index(T a1,T2 a2,svector<T> &vc,svector<T2> &vc2) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + auto ii_s2=vc2.begin(),ii_e2=vc2.end(); + auto ii_b=ii_s; + for(;ii_s<ii_e;++ii_s,++ii_s2) + { + if((*ii_s)==a1&& + (*ii_s2)==a2)return (int32_t)(ii_s-ii_b); + } + return -1; +} + +template <class T,class T2,class T3,class T4> int32_t get_quad_vector_index(T a1,T2 a2,T3 a3,T4 a4, + svector<T> &vc,svector<T2> &vc2, + svector<T3> &vc3,svector<T4> &vc4) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + auto ii_s2=vc2.begin(),ii_e2=vc2.end(); + auto ii_s3=vc3.begin(),ii_e3=vc3.end(); + auto ii_s4=vc4.begin(),ii_e4=vc4.end(); + auto ii_b=ii_s; + for(;ii_s<ii_e;++ii_s,++ii_s2,++ii_s3,++ii_s4) + { + if((*ii_s)==a1&& + (*ii_s2)==a2&& + (*ii_s3)==a3&& + (*ii_s4)==a4)return (int32_t)(ii_s-ii_b); + } + return -1; +} + +template <class T> void merge_vectors(T &master, T &merger) +{ + auto ii_s=merger.begin(),ii_e=merger.end(); + for(;ii_s<ii_e;++ii_s) + { + auto ii_s2=master.begin(),ii_e2=master.end(); + for(;ii_s2<ii_e2;++ii_s2) + { + if((*ii_s)==(*ii_s2))break; + } + if(ii_s2>=ii_e2) + { + master.push_back((*ii_s)); + } + } +} + +template <class T> int32_t get_common_element_vector_index(T &master, T &merger) +{ + auto ii_s=merger.begin(),ii_e=merger.end(); + auto ii_s2=master.begin(),ii_e2=master.end(); + auto ii_b2=ii_s2; + + for(;ii_s<ii_e;++ii_s) + { + for(;ii_s2<ii_e2;++ii_s2) + { + if((*ii_s)==(*ii_s2))return (int32_t)(ii_s2-ii_b2); + } + ii_s2=ii_b2; + } + + return -1; +} + +template <class T,class T2> void merge_dual_vectors(T &master, T2 &master2, T &merger, T2 &merger2) +{ + auto ii_s=merger.begin(),ii_e=merger.end(); + auto ii_s2=merger2.begin(),ii_e2=merger2.end(); + for(;ii_s<ii_e;++ii_s,++ii_s2) + { + auto ii_s3=master.begin(),ii_e3=master.end(); + auto ii_s4=master2.begin(),ii_e4=master2.end(); + for(;ii_s3<ii_e3;++ii_s3,++ii_s4) + { + if((*ii_s)==(*ii_s3)&& + (*ii_s2)==(*ii_s4))break; + } + if(ii_s3>=ii_e3) + { + master.push_back((*ii_s)); + master2.push_back((*ii_s2)); + } + } +} + +template <class T,class T2,class T3,class T4> void merge_quad_vectors(T &master, T2 &master2, T3 &master3, T4 &master4, + T &merger, T2 &merger2, T3 &merger3, T4 &merger4) +{ + auto ii_s=merger.begin(),ii_e=merger.end(); + auto ii_s2=merger2.begin(),ii_e2=merger2.end(); + auto ii_s3=merger3.begin(),ii_e3=merger3.end(); + auto ii_s4=merger4.begin(),ii_e4=merger4.end(); + for(;ii_s<ii_e;++ii_s,++ii_s2,++ii_s3,++ii_s4) + { + auto ii_s5=master.begin(),ii_e5=master.end(); + auto ii_s6=master2.begin(),ii_e6=master2.end(); + auto ii_s7=master3.begin(),ii_e7=master3.end(); + auto ii_s8=master4.begin(),ii_e8=master4.end(); + for(;ii_s5<ii_e5;++ii_s5,++ii_s6,++ii_s7,++ii_s8) + { + if((*ii_s)==(*ii_s5)&& + (*ii_s2)==(*ii_s6)&& + (*ii_s3)==(*ii_s7)&& + (*ii_s4)==(*ii_s8))break; + } + if(ii_s5>=ii_e5) + { + master.push_back((*ii_s)); + master2.push_back((*ii_s2)); + master3.push_back((*ii_s3)); + master4.push_back((*ii_s4)); + } + } +} + +template <class T> void cull_vectors(T &master,T &cull) +{ + int32_t i,i2; + for(i=(int32_t)cull.size()-1;i>=0;i--) + { + for(i2=(int32_t)master.size()-1;i2>=0;i2--) + { + if(cull[i]==master[i2]) + { + master.erase(i2); + break; + } + } + } +} + +template <class T> void push_on_vector(T &master,T &new_stuff) +{ + auto ii_s=new_stuff.begin(),ii_e=new_stuff.end(); + for(;ii_s<ii_e;++ii_s) + { + master.push_back(*ii_s); + } +} + +template<class T> VIndex add_to_global_id_vector(T ptr,svector<T> &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return 1; + } + if(vect[size-1]->global_id<ptr->global_id) + { + vect.push_back(ptr); + return size; + } + + int32_t start=0; + int32_t end=size-1; + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->global_id==ptr->global_id)return -1; + if(start==end) + { + if(cptr->global_id<ptr->global_id) + { + if(start+1>=size)return -1;//push_back() FOR UNIQUE ALREADY HANDLED + else + { + vect.insert(start+1,ptr); + return start+1; + } + } + else if(cptr->global_id>ptr->global_id) + { + vect.insert(start,ptr); + return start; + } + return -1; + } + + if(cptr->global_id>ptr->global_id)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr->global_id<ptr->global_id) + { + if(start+1>=size)return -1;//push_back() FOR UNIQUE ALREADY HANDLED + else + { + vect.insert(start+1,ptr); + return start+1; + } + } + else if(cptr->global_id>ptr->global_id) + { + vect.insert(start,ptr); + return start; + } + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr->global_id<ptr->global_id) + { + if(end+1>=size)return -1;//push_back() FOR UNIQUE ALREADY HANDLED + else + { + vect.insert(end+1,ptr); + return end+1; + } + } + else if(cptr->global_id>ptr->global_id) + { + vect.insert(end,ptr); + return end; + } + } + return -1;//push_back() FOR UNIQUE ALREADY HANDLED SO NO else +} + +template<class T> void remove_from_global_id_vector(T ptr,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + cptr=vect[mid]; + if(cptr==ptr) + { + vect.erase(mid); + return; + } + + if(cptr->global_id>ptr->global_id)end=mid-1; + else start=mid+1; + } +} + +template<class T> void remove_from_global_id_vector_by_id(int32_t id,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + cptr=vect[mid]; + if(cptr->global_id==id) + { + vect.erase(mid); + return; + } + + if(cptr->global_id>id)end=mid-1; + else start=mid+1; + } +} + +template<class T> T get_from_global_id_vector(int32_t id,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->global_id==id)return cptr; + else if(cptr->global_id>id)end=mid-1; + else start=mid+1; + } + + return NULL; +} + +template<class T> int32_t get_index_from_global_id_vector(int32_t id,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->global_id==id)return mid; + else if(cptr->global_id>id)end=mid-1; + else start=mid+1; + } + + return -1; +} + +template<class T> VIndex add_to_binary_vector(T ptr,svector<T> &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return 0; + } + if(vect[size-1]<ptr) + { + vect.push_back(ptr); + return size; + } + + int32_t start=0; + int32_t end=size-1; + int32_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr) + { + vect.insert(mid,ptr);//INSERT A COPY HERE SINCE THIS IS A NON-UNIQUE VECTOR + return mid; + } + if(start==end) + { + if(cptr<ptr) + { + if(start+1>=size)vect.push_back(ptr); + else vect.insert(start+1,ptr); + return start+1; + } + else + { + vect.insert(start,ptr); + return start; + } + } + + if(cptr>ptr)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr<ptr) + { + if(start+1>=size)vect.push_back(ptr); + else vect.insert(start+1,ptr); + return start+1; + } + else + { + vect.insert(start,ptr); + return start; + } + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr<ptr) + { + if(end+1>=size)vect.push_back(ptr); + else vect.insert(end+1,ptr); + return end+1; + } + else + { + vect.insert(end,ptr); + return end; + } + } + else vect.push_back(ptr); + return end; +} + +//NOTE: RETURNS -1 IF ALREADY PRESENT, NOT THE INDEX +template<class T> VIndex add_unique_to_binary_vector(T ptr,svector<T> &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return 0; + } + if(vect[size-1]<ptr) + { + vect.push_back(ptr); + return size; + } + + int32_t start=0; + int32_t end=size-1; + int32_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr)return -1;//ALREADY IN VECTOR + if(start==end) + { + if(cptr<ptr) + { + if(start+1>=(int32_t)vect.size())return -1;//push_back() CASE ALREADY HANDLED + + vect.insert(start+1,ptr); + return start+1; + } + else if(cptr>ptr) + { + vect.insert(start,ptr); + return start; + } + return -1; + } + + if(cptr>ptr)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr<ptr) + { + if(start+1>=size)return -1;//push_back() CASE ALREADY HANDLED + + vect.insert(start+1,ptr); + return start+1; + } + else if(cptr>ptr) + { + vect.insert(start,ptr); + return start; + } + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr<ptr) + { + if(end+1>=size)return -1;//push_back() CASE ALREADY HANDLED + + vect.insert(end+1,ptr); + return end+1; + } + else if(cptr>ptr) + { + vect.insert(end,ptr); + return end; + } + } + return -1;//push_back() CASE ALREADY HANDLED SO NO else +} + +//NOTE: RETURNS INDEX IF ALREADY PRESENT +template<class T> VIndex add_unique_to_binary_vector_always_index(T ptr,svector<T> &vect,bool &was_present) +{ + was_present=false; + + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return 0; + } + if(vect[size-1]<ptr) + { + vect.push_back(ptr); + return size; + } + + int32_t start=0; + int32_t end=size-1; + int32_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr){was_present=true;return mid;}//ALREADY IN VECTOR + if(start==end) + { + if(cptr<ptr) + { + if(start+1>=(int32_t)vect.size())return -1;//push_back() CASE ALREADY HANDLED + + vect.insert(start+1,ptr); + return start+1; + } + else if(cptr>ptr) + { + vect.insert(start,ptr); + return start; + } + return -1; + } + + if(cptr>ptr)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr<ptr) + { + if(start+1>=size)return -1;//push_back() CASE ALREADY HANDLED + + vect.insert(start+1,ptr); + return start+1; + } + else if(cptr>ptr) + { + vect.insert(start,ptr); + return start; + } + if(cptr==ptr){was_present=true;return start;}//ALREADY IN VECTOR + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr<ptr) + { + if(end+1>=size)return -1;//push_back() CASE ALREADY HANDLED + + vect.insert(end+1,ptr); + return end+1; + } + else if(cptr>ptr) + { + vect.insert(end,ptr); + return end; + } + if(cptr==ptr){was_present=true;return end;}//ALREADY IN VECTOR + } + return -1;//push_back() CASE ALREADY HANDLED SO NO else +} + +template<class T> void remove_from_binary_vector(T ptr,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + int32_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr) + { + vect.erase(mid); + return; + } + + if(cptr>ptr)end=mid-1; + else start=mid+1; + } +} + +template<class T> int32_t get_index_from_binary_vector(T id,svector<T> &vect) +{ + int32_t size=vect.size(); + if(size==0||id==-1)return -1; + + int32_t start=0; + int32_t end=size-1; + int32_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==id) + { + return mid; + } + + if(cptr>id)end=mid-1; + else start=mid+1; + } + + return -1; +} + +template<class T> int32_t get_floor_index_from_binary_vector(T ptr,svector<T> &vect) +{ + int32_t size=vect.size(); + if(size==0)return -1; + if(vect[size-1]<ptr)return size-1; + + int32_t start=0; + int32_t end=size-1; + int32_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr) + { + while(mid>0) + { + if(vect[mid-1]<ptr)return mid; + mid--; + } + return mid; + } + if(start==end) + { + if(cptr<ptr) + { + if(start+1>=size)return start; + else return start; + } + //NOTE: cptr>ptr as == is already handled above + else + { + if(start<=0)return 0; + else return start-1; + } + } + + if(cptr>ptr)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr<ptr) + { + if(start+1>=size)return start; + else return start; + } + else if(cptr>ptr) + { + if(start<=0)return 0; + else return start-1; + } + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr<ptr) + { + if(end+1>=size)return end; + else return end; + } + else if(cptr>ptr) + { + if(end<=0)return 0; + else return end-1; + } + } + return start; +} + +template<class T> void fixed_array_push_back(T ptr,T *vect,int32_t &size,int32_t max) +{ + if(size>=max)return; + vect[size]=ptr; + size++; +} + +template<class T> void fixed_array_insert(int32_t index,T ptr,T *vect,int32_t &size,int32_t max) +{ + if(size>=max)return; + if(size>0) + { + T *ptr1=vect+size; + T *ptr2=vect+(size-1); + T *stop=vect+index; + while(ptr2>=stop) + { + (*ptr1)=(*ptr2); + --ptr1; + --ptr2; + } + (*ptr1)=ptr; + return; + } + else + { + vect[index]=ptr; + ++size; + } +} + +template<class T> void add_to_fixed_binary_array(T ptr,T *vect,int32_t &size,int32_t max) +{ + if(size==0) + { + fixed_array_push_back(ptr,vect,size,max); + return; + } + if(vect[size-1]<ptr) + { + fixed_array_push_back(ptr,vect,size,max); + return; + } + + int32_t start=0; + int32_t end=size-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr) + { + fixed_array_insert(mid,ptr,vect,size,max);//INSERT A COPY SINCE THIS IS NON-UNIQUE CASE + return; + } + if(start==end) + { + if(cptr<ptr) + { + if(start+1>=size)fixed_array_push_back(ptr,vect,size,max); + else fixed_array_insert(start+1,ptr,vect,size,max); + } + else fixed_array_insert(start,ptr,vect,size,max); + return; + } + + if(cptr>ptr)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr<ptr) + { + if(start+1>=size)fixed_array_push_back(ptr,vect,size,max); + else fixed_array_insert(start+1,ptr,vect,size,max); + } + else fixed_array_insert(start,ptr,vect,size,max); + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr<ptr) + { + if(end+1>=size)fixed_array_push_back(ptr,vect,size,max); + else fixed_array_insert(end+1,ptr,vect,size,max); + } + else fixed_array_insert(end,ptr,vect,size,max); + } + else fixed_array_push_back(ptr,vect,size,max); +} + +template<class T> void add_unique_to_fixed_binary_array(T ptr,T *vect,int32_t &size,int32_t max) +{ + if(size==0) + { + fixed_array_push_back(ptr,vect,size,max); + return; + } + if(vect[size-1]<ptr) + { + fixed_array_push_back(ptr,vect,size,max); + return; + } + + int32_t start=0; + int32_t end=size-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr)return; + if(start==end) + { + if(cptr<ptr) + { + if(start+1>=size)return;//WAS push_back() + else fixed_array_insert(start+1,ptr,vect,size,max); + } + else if(cptr>ptr)fixed_array_insert(start,ptr,vect,size,max); + return; + } + + if(cptr>ptr)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr<ptr) + { + if(start+1>=size)return;//WAS push_back() + else fixed_array_insert(start+1,ptr,vect,size,max); + } + else if(cptr>ptr)fixed_array_insert(start,ptr,vect,size,max); + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr<ptr) + { + if(end+1>=size)return;//WAS push_back() + else fixed_array_insert(end+1,ptr,vect,size,max); + } + else if(cptr>ptr)fixed_array_insert(end,ptr,vect,size,max); + } + //NOTE: NO else CASE HERE BECAUSE IN THE NON-UNIQUE VERSION IT JUST PUSHED BACK + //AND PUSHING BACK IS HANDLED IN THE OPENING FUNCTION +} + +template<class T> void add_to_local_id_vector(T ptr,svector<T> &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return; + } + if(vect[size-1]->local_id<ptr->local_id) + { + vect.push_back(ptr); + return; + } + + int32_t start=0; + int32_t end=size-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->local_id==ptr->local_id)return; + if(start==end) + { + if(cptr->local_id<ptr->local_id) + { + if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED + else vect.insert(start+1,ptr); + } + else if(cptr->local_id>ptr->local_id)vect.insert(start,ptr); + return; + } + + if(cptr->local_id>ptr->local_id)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr->local_id<ptr->local_id) + { + if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED + else vect.insert(start+1,ptr); + } + else if(cptr->local_id>ptr->local_id)vect.insert(start,ptr); + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr->local_id<ptr->local_id) + { + if(end+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED + else vect.insert(end+1,ptr); + } + else if(cptr->local_id>ptr->local_id)vect.insert(end,ptr); + } +} + +template<class T> void remove_from_local_id_vector(T ptr,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr==ptr) + { + vect.erase(mid); + return; + } + + if(cptr->local_id>ptr->local_id)end=mid-1; + else start=mid+1; + } +} + +template<class T> T get_from_local_id_vector(int32_t id,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->local_id==id)return cptr; + else if(cptr->local_id>id)end=mid-1; + else start=mid+1; + } + + return NULL; +} + +template<class T> int32_t get_index_from_local_id_vector(int32_t id,svector<T> &vect) +{ + int32_t start=0; + int32_t end=(int32_t)vect.size()-1; + + T cptr; + int32_t mid; + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->local_id==id)return mid; + else if(cptr->local_id>id)end=mid-1; + else start=mid+1; + } + + return -1; +} + +template<class T> void add_to_short_id_vector(T ptr,svector<T> &vect) +{ + int16_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return; + } + if(vect[size-1]->short_id<ptr->short_id) + { + vect.push_back(ptr); + return; + } + + int16_t start=0; + int16_t end=size-1; + int16_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->short_id==ptr->short_id)return; + if(start==end) + { + if(cptr->short_id<ptr->short_id) + { + if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED + else vect.insert(start+1,ptr); + } + else if(cptr->short_id>ptr->short_id)vect.insert(start,ptr); + return; + } + + if(cptr->short_id>ptr->short_id)end=mid-1; + else start=mid+1; + } + + if(end<0) + { + T cptr=vect[start]; + if(cptr->short_id<ptr->short_id) + { + if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED + else vect.insert(start+1,ptr); + } + else if(cptr->short_id>ptr->short_id)vect.insert(start,ptr); + } + else if(end<size) + { + T cptr=vect[end]; + if(cptr->short_id<ptr->short_id) + { + if(end+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED + else vect.insert(end+1,ptr); + } + else if(cptr->short_id>ptr->short_id)vect.insert(end,ptr); + } +} + +template<class T> void remove_from_short_id_vector(T ptr,svector<T> &vect) +{ + int16_t start=0; + int16_t end=(int16_t)vect.size()-1; + T cptr; + + while(start<=end) + { + int16_t mid=(start+end)>>1; + + T cptr=vect[mid]; + if(cptr==ptr) + { + vect.erase(mid); + return; + } + + if(cptr->short_id>ptr->short_id)end=mid-1; + else start=mid+1; + } +} + +template<class T> T get_from_short_id_vector(int16_t id,svector<T> &vect) +{ + int16_t start=0; + int16_t end=(int16_t)vect.size()-1; + int16_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->short_id==id) + { + return cptr; + } + + if(cptr->short_id>id)end=mid-1; + else start=mid+1; + } + + return NULL; +} + +template<class T> int16_t get_index_from_short_id_vector(int16_t id,svector<T> &vect) +{ + int16_t start=0; + int16_t end=(int16_t)vect.size()-1; + int16_t mid; + T cptr; + + while(start<=end) + { + mid=(start+end)>>1; + + cptr=vect[mid]; + if(cptr->short_id==id) + { + return mid; + } + + if(cptr->short_id>id)end=mid-1; + else start=mid+1; + } + + return -1; +}
\ No newline at end of file diff --git a/g_src/textlines.cpp b/g_src/textlines.cpp new file mode 100755 index 0000000..e56515a --- /dev/null +++ b/g_src/textlines.cpp @@ -0,0 +1,61 @@ +#include "platform.h" +#include <string.h> +#include <math.h> +#include <iosfwd> +#include <iostream> +#include <ios> +#include <streambuf> +#include <istream> +#include <ostream> +#include <iomanip> +#include <sstream> +#include <cstdlib> +#include <fstream> +#include <zlib.h> + +#include "svector.h" +using std::string; + +#include "endian.h" + +#include "files.h" + +#include "enabler.h" + +#include "textlines.h" + +#include "basics.h" + +extern char filecomp_buffer[20000]; +extern char filecomp_buffer2[80000]; +extern char filecomp_buffer_aux[20000]; +extern char filecomp_buffer2_aux[80000]; + + +void textlinesst::load_raw_to_lines(char *filename) +{ + clean_lines(); + + //LOAD THE FILE + std::ifstream fseed(filename); + if(fseed.is_open()) + { + string str; + + while(std::getline(fseed,str)) + { + long end=str.length(); + + while(end>0) + { + if(isspace(str[end-1]))end--; + else break; + } + + str.resize(end); + + if(str.length()>0)text.add_string(str); + } + } + fseed.close(); +}
\ No newline at end of file diff --git a/g_src/textlines.h b/g_src/textlines.h new file mode 100755 index 0000000..de2dbfe --- /dev/null +++ b/g_src/textlines.h @@ -0,0 +1,22 @@ +#ifndef TEXTLINES_H +#define TEXTLINES_H + +struct textlinesst +{ + stringvectst text; + + + + void load_raw_to_lines(char *filename); + + void clean_lines() + { + text.clean(); + } + void copy_from(textlinesst &ot) + { + text.copy_from(ot.text); + } +}; + +#endif
\ No newline at end of file diff --git a/g_src/texture_handler.h b/g_src/texture_handler.h new file mode 100755 index 0000000..50b73d1 --- /dev/null +++ b/g_src/texture_handler.h @@ -0,0 +1,60 @@ +#ifndef TEXTURE_HANDLER_H +#define TEXTURE_HANDLER_H + +#include "textlines.h" + +struct tile_pagest +{ + string token; + + string filename; + short tile_dim_x; + short tile_dim_y; + short page_dim_x; + short page_dim_y; + + svector<int32_t> texpos; + svector<int32_t> datapos; + svector<int32_t> texpos_gs; + svector<int32_t> datapos_gs; + + char loaded; + + + + tile_pagest() + { + loaded=0; + } + + void load_graphics(string &graphics_dir); +}; + +class texture_handlerst +{ + public: + svector<tile_pagest *> page; + + svector<int32_t> texpos; + svector<int32_t> datapos; + + void clean(); + void adopt_new_lines(textlinesst &lines,string &graphics_dir); + + ~texture_handlerst() + { + clean(); + } + + tile_pagest *get_tile_page_by_token(string &tk) + { + int32_t t; + for(t=0;t<page.size();t++) + { + if(page[t]->token==tk)return page[t]; + } + return NULL; + } +}; + +#endif diff --git a/g_src/textures.cpp b/g_src/textures.cpp new file mode 100755 index 0000000..50334ba --- /dev/null +++ b/g_src/textures.cpp @@ -0,0 +1,398 @@ +#include <cassert> + +#include "enabler.h" +#include "init.h" + +// Used to sort textures +struct vsize_pos { + int h, w; + SDL_Surface *s; + long pos; + // Assigned texture-catalog coordinates + int x, y; + + bool operator< (struct vsize_pos y) const { + // sort produces an ascending order. We want descending. Don't argue. + if (h > y.h) return true; + return false; + } +}; + + +// Check whether a particular texture can be sized to some size, +// assuming in RGBA 32-bit format +bool testTextureSize(GLuint texnum, int w, int h) { + GLint gpu_width; + glBindTexture(GL_TEXTURE_2D, texnum); + printGLError(); + glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + printGLError(); + glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &gpu_width); + printGLError(); + + if (gpu_width == w) return true; + return false; +} + +// Texture catalog implementation +void textures::upload_textures() { + if (uploaded) return; // Don't bother + if (!enabler.uses_opengl()) return; // No uploading + glEnable(GL_TEXTURE_2D); + printGLError(); + glGenTextures(1, &gl_catalog); + printGLError(); + + // First, sort the textures by vertical size. We'll want to place the large + // ones first. + // Since we mustn't alter the raws array, first thing is to create a new one. + // We pretend textures are one pixel larger than they actually are in either + // direction, to avoid border scuffles when interpolating. + std::vector<vsize_pos> ordered; + long pos = 0; + for (std::vector<SDL_Surface *>::iterator it = raws.begin(); + it != raws.end(); ++it) { + if (*it) { + vsize_pos item; + item.h = (*it)->h+2; + item.w = (*it)->w+2; + item.s = *it; + item.pos = pos; + ordered.push_back(item); + } + pos++; + } + sort(ordered.begin(), ordered.end()); + + /* Tiling algorithm: + ** + ** Given a particular texture width, we pack tiles from largest to smallest + ** by reserving rows for tiles with a particular height or lower. + ** This does lead to space wastage when a row has, say, one 32x32 tile and + ** fifteen 16x16 tiles, but generally not very much. + ** + ** Possible improvement: Allow for multiple rows of smaller tiles inside + ** a row that's at least twice as high as the smaller tiles are. + */ + + // Set the initial width to the minimum possible + int catalog_width = 0; + for (int i=0; i < ordered.size(); i++) + if (catalog_width < ordered[i].w) catalog_width = ordered[i].w; + const int width_increment = 4; // For speed, not that it matters. + int catalog_height; + // Figure out what the optimal texture width is + // This may not be actually be an approximately square texture, but for the + // moment that's what we're aiming for. On GPUs without the NPOT extension, + // rectangular textures may actulaly use less video memory. + // However, a square one is less likely to run into dimensional limits. + for(;;) { + int catalog_x = 0; + int catalog_y = 0; + int row_height = ordered[0].h; + catalog_height = row_height; + for (int pos = 0; pos < ordered.size(); pos++) { + // Check whether we must start a new row + if (catalog_x + ordered[pos].w > catalog_width) { + catalog_x = 0; + catalog_y = catalog_height; + row_height = ordered[pos].h; + catalog_height += row_height; + } + // Tentatively install tile at catalog_x, catalog_y + ordered[pos].x = catalog_x; + ordered[pos].y = catalog_y; + // Goto next tile + catalog_x += ordered[pos].w; + } + // If we didn't just cross "square", increment width and try again. + if (catalog_height > catalog_width) + catalog_width += width_increment; + else + break; // Otherwise we're done. + } + +#ifdef DEBUG + std::cout << "Ideal catalog size: " << catalog_width << "x" << catalog_height << "\n"; +#endif + + // Check whether the GPU supports non-power-of-two textures + bool npot = false; + if (GLEW_ARB_texture_rectangle && GLEW_ARB_texture_non_power_of_two) + npot=true; + + if (!npot) { + // Use a power-of-two texture catalog + int newx = 1, newy = 1; + while (newx < catalog_width) newx *= 2; + while (newy < catalog_height) newy *= 2; + catalog_width = newx; + catalog_height = newy; + std::cout << "GPU does not support non-power-of-two textures, using " << catalog_width << "x" << catalog_height << " catalog.\n"; + } + // Check whether the GPU will allow a texture of that size + if (!testTextureSize(gl_catalog, catalog_width, catalog_height)) { + MessageBox(NULL,"GPU unable to accommodate texture catalog. Retry without graphical tiles, update your drivers, or better yet update your GPU.", "GL error", MB_OK); + exit(EXIT_FAILURE); + } + + // Guess it will. Well, then, actually upload it + glBindTexture(GL_TEXTURE_2D, gl_catalog); + printGLError(); + char *zeroes = new char[catalog_width*catalog_height*4]; + memset(zeroes,0,sizeof(char)*catalog_width*catalog_height*4); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, catalog_width, catalog_height, 0, GL_RGBA, + GL_UNSIGNED_BYTE, zeroes); + delete[] zeroes; + printGLError(); + glBindTexture(GL_TEXTURE_2D, gl_catalog); + printGLError(); + GLint param = (init.window.flag.has_flag(INIT_WINDOW_FLAG_TEXTURE_LINEAR) ? + GL_LINEAR : GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,param); + printGLError(); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,param); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + printGLError(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + printGLError(); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + printGLError(); + // Performance isn't important here. Let's make sure there are no alignment issues. + glPixelStorei(GL_PACK_ALIGNMENT, 1); + printGLError(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + printGLError(); + // While storing the positions to gl_texpos. + if (gl_texpos) delete[] gl_texpos; + gl_texpos = new struct gl_texpos[raws.size()]; + for (int pos = 0; pos < ordered.size(); pos++) { + long raws_pos = ordered[pos].pos; + SDL_Surface *s = ordered[pos].s; + SDL_PixelFormat *f = s->format; + SDL_LockSurface(s); + // Make /real/ sure we get the GL format right. + unsigned char *pixels = new unsigned char[ordered[pos].w * ordered[pos].h * 4]; + // Recall, ordered[pos].w is 2 larger than s->w because of the border. + for (int bx=0; bx < ordered[pos].w; bx++) { + int x = bx - 1; + if (x == -1) x++; + if (x == s->w) x--; + for (int by=0; by < ordered[pos].h; by++) { + int y = by - 1; + if (y == -1) y++; + if (y == s->h) y--; + // GL textures are loaded upside-down, Y=0 at the bottom + unsigned char *pixel_dst = &pixels[(ordered[pos].h - by - 1)*ordered[pos].w*4 + bx*4]; + unsigned char *pixel_src = &((unsigned char*)s->pixels)[y*s->w*4 + x*4]; + assert (pixel_dst < pixels + ordered[pos].w * ordered[pos].h * 4); + assert (pixel_src < (unsigned char*)s->pixels + s->w * s->h * 4); + // We convert all textures to RGBA format at load-time, further below + for (int i=0; i<4; i++) { + pixel_dst[i] = pixel_src[i]; + } + } + } + // Right. Upload the texture to the catalog. + SDL_UnlockSurface(s); + glBindTexture(GL_TEXTURE_2D, gl_catalog); + printGLError(); + glTexSubImage2D(GL_TEXTURE_2D, 0, ordered[pos].x, ordered[pos].y, ordered[pos].w, ordered[pos].h, + GL_RGBA, GL_UNSIGNED_BYTE, pixels); + delete[] pixels; + printGLError(); + // Compute texture coordinates and store to gl_texpos for later output. + // To make sure the right pixel is chosen when texturing, we must + // pick coordinates that place us in the middle of the pixel we want. + // + // There's no real reason to use double instead of floats here, but + // no reason not to either, and it just might help with precision. + // + // There's a one-pixel border around each tile, so we offset by 1 + gl_texpos[raws_pos].left = ((double)ordered[pos].x+1) / (double)catalog_width; + gl_texpos[raws_pos].right = ((double)ordered[pos].x+1+s->w) / (double)catalog_width; + gl_texpos[raws_pos].top = ((double)ordered[pos].y+1) / (double)catalog_height; + gl_texpos[raws_pos].bottom = ((double)ordered[pos].y+1+s->h) / (double)catalog_height; + } + // And that's that. Locked, loaded and ready for texturing. + printGLError(); + uploaded=true; +} + +void textures::remove_uploaded_textures() { + if (!uploaded) return; // Nothing to do + glDeleteTextures(1, &gl_catalog); + uploaded=false; +} + +SDL_Surface *textures::get_texture_data(long pos) { + if (raws.size() > pos) { + return raws[pos]; + } else { + std::cerr << "Asked for nonexistent texture data\n"; + SDL_Surface *surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 8, 8, 32, 0, 0, 0, 0); + SDL_FillRect(surf, NULL, SDL_MapRGB(surf->format, 255, 0, 255)); + raws.resize(pos+1); + raws[pos] = surf; + return raws[pos]; + } +} + +long textures::clone_texture(long src) { + long tx; + + if (raws.size() > src && raws[src]) { + SDL_Surface *dst = SDL_ConvertSurface(raws[src], raws[src]->format, SDL_SWSURFACE); + tx=add_texture(dst); + } + else { + // Okay, we've been asked to clone a nonexistent texture. Riight... + // Fortunately add_texture doesn't look at the pointer it gets at all. + std::cerr << "Asked to clone nonexistent texture!\n"; + tx=add_texture(NULL); + } + + enabler.reset_textures(); + + return tx; +} + +void textures::grayscale_texture(long pos) { + SDL_Surface *s = get_texture_data(pos); + if (!s) return; + SDL_LockSurface(s); + SDL_PixelFormat *f = s->format; + Uint32 *pixels = (Uint32*)(s->pixels); + if (f->BytesPerPixel != 4) { + std::cerr << "grayscale_texture ran into mysteriously uncanonicalized texture\n"; + goto cleanup; + } + for (int i=0; i < s->w*s->h; i++) { // For each pixel + int r = (pixels[i] & f->Rmask) >> f->Rshift; + int g = (pixels[i] & f->Gmask) >> f->Gshift; + int b = (pixels[i] & f->Bmask) >> f->Bshift; + int alpha = (pixels[i] & f->Amask) >> f->Ashift; +int luminosity=(int)((float)r*0.30f+(float)g*0.59f+(float)b*0.11f); +if(luminosity<0)luminosity=0; +if(luminosity>255)luminosity=255; + pixels[i] = (luminosity << f->Rshift) | + (luminosity << f->Gshift) | + (luminosity << f->Bshift) | + (alpha << f->Ashift); + } + + cleanup: + SDL_UnlockSurface(s); + + enabler.reset_textures(); +} + +// Converts an arbitrary Surface to something like the display format +// (32-bit RGBA), and converts magenta to transparency if convert_magenta is set +// and the source surface didn't already have an alpha channel. +// It also deletes the source surface. +// +// It uses the same pixel format (RGBA, R at lowest address) regardless of +// hardware. +SDL_Surface *canonicalize_format(SDL_Surface *src, bool convert_magenta) { + SDL_PixelFormat fmt; + fmt.palette = NULL; + fmt.BitsPerPixel = 32; + fmt.BytesPerPixel = 4; + fmt.Rloss = fmt.Gloss = fmt.Bloss = fmt.Aloss = 0; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + fmt.Rshift = 24; fmt.Gshift = 16; fmt.Bshift = 8; fmt.Ashift = 0; +#else + fmt.Rshift = 0; fmt.Gshift = 8; fmt.Bshift = 16; fmt.Ashift = 24; +#endif + fmt.Rmask = 255 << fmt.Rshift; + fmt.Gmask = 255 << fmt.Gshift; + fmt.Bmask = 255 << fmt.Bshift; + fmt.Amask = 255 << fmt.Ashift; + fmt.colorkey = 0; + fmt.alpha = 255; + + if (src->format->Amask == 0 && convert_magenta) { // No alpha + SDL_SetColorKey(src, SDL_SRCCOLORKEY, + SDL_MapRGB(src->format, 255, 0, 255)); + } + SDL_Surface *tgt = SDL_ConvertSurface(src, &fmt, SDL_SWSURFACE); + SDL_FreeSurface(src); + return tgt; +} + +// Finds or creates a free spot in the texture array, and inserts +// surface in that spot, then returns the location. +long textures::add_texture(SDL_Surface *surface) { + long sz = raws.size(); + // Look for a free spot + for (long pos=0; pos < sz; pos++) { + if (raws[pos] == NULL) { + raws[pos] = surface; + return pos; + } + } + + // No free spot, make one + raws.push_back(surface); + return sz; +} + +void textures::load_multi_pdim(const string &filename, long *tex_pos, long dimx, + long dimy, bool convert_magenta, + long *disp_x, long *disp_y) { + SDL_Surface *raw = IMG_Load(filename.c_str()); + if (!raw) { + MessageBox(NULL, ("Not found: " + filename).c_str(), "Tileset not found", MB_OK); + exit(1); + } + SDL_Surface *src = canonicalize_format(raw, convert_magenta); + SDL_SetAlpha(src, 0, 255); + *disp_x = src->w / dimx; + *disp_y = src->h / dimy; + long idx = 0; + for (int y=0; y < dimy; y++) { + for (int x=0; x < dimx; x++) { + SDL_Surface *tile = SDL_CreateRGBSurface(SDL_SWSURFACE, *disp_x, *disp_y, + 32, src->format->Rmask, + src->format->Gmask, + src->format->Bmask, + src->format->Amask); + SDL_SetAlpha(tile, 0,255); + SDL_Rect pos_src; + pos_src.x = *disp_x * x; + pos_src.y = *disp_y * y; + pos_src.w = *disp_x; + pos_src.h = *disp_y; + SDL_BlitSurface(src, &pos_src, tile, NULL); + tex_pos[idx++] = add_texture(tile); + } + } + SDL_FreeSurface(src); + // Re-upload textures if necessary + enabler.reset_textures(); +} + +long textures::load(const string &filename, bool convert_magenta) { + SDL_Surface *raw = IMG_Load(filename.c_str()); + if (!raw) { + MessageBox(NULL, ("Not found: " + filename).c_str(), "Image not found", MB_OK); + exit(1); + } + SDL_Surface *tex = canonicalize_format(raw, convert_magenta); + long pos = add_texture(tex); + // Re-upload if necessary + enabler.reset_textures(); + return pos; +} + +void textures::delete_texture(long pos) { + // We can't actually resize the array, as + // (a) it'd be slow, and + // (b) it'd change all the positions. Bad stuff would happen. + if (raws[pos]) { + SDL_FreeSurface(raws[pos]); + raws[pos] = NULL; + } +} diff --git a/g_src/ttf_manager.cpp b/g_src/ttf_manager.cpp new file mode 100755 index 0000000..f873a40 --- /dev/null +++ b/g_src/ttf_manager.cpp @@ -0,0 +1,245 @@ +#include "ttf_manager.hpp" +#include "init.h" +#include <iostream> + +using namespace std; + +ttf_managerst ttf_manager; + +bool ttf_managerst::init(int ceiling, int tile_width) { + // Reset to a known state, clear everything + if ((!TTF_WasInit()) && (TTF_Init() == -1)) { + MessageBox(NULL, TTF_GetError(), "TTF error", MB_OK); + return false; + } + if (font) TTF_CloseFont(font); + handles.clear(); + for (auto it = textures.cbegin(); it != textures.cend(); ++it) + SDL_FreeSurface(it->second); + textures.clear(); + this->tile_width = tile_width; + this->ceiling = ceiling; + // Try progressively smaller point sizes until we find one that fits + for (int sz=20; sz > 0; sz--) { + font = TTF_OpenFont("data/art/font.ttf", sz); + if (!font) continue; + if (TTF_FontHeight(font) <= ceiling) { +#ifdef DEBUG + cout << "Picked font at " << sz << " points for ceiling " << ceiling << endl; + // get the glyph metric for the letter 'M' in a loaded font + cout << "TTF_FontHeight " << TTF_FontHeight(font) << endl; + cout << "TTF_FontAscent " << TTF_FontAscent(font) << endl; + cout << "TTF_FontDescent " << TTF_FontDescent(font) << endl; + cout << "TTF_FontLineSkip " << TTF_FontLineSkip(font) << endl; +#endif + int minx,maxx,miny,maxy,advance; + if (TTF_GlyphMetrics(font, 'M', &minx, &maxx, &miny, &maxy, &advance) == -1) + puts(TTF_GetError()); + else { + em_width = maxx; +#ifdef DEBUG + printf("minx : %d\n",minx); + printf("maxx : %d\n",maxx); + printf("miny : %d\n",miny); + printf("maxy : %d\n",maxy); + printf("advance : %d\n",advance); +#endif + } + return true; + } + TTF_CloseFont(font); + } + // ..fine. + cout << "No font found!" << endl; + font = NULL; + return false; +} + +static void cp437_to_unicode(const string &text, vector<Uint16> &unicode) { + unicode.resize(text.length() + 1); + int i; + for (i=0; i < text.size(); i++) { + const int cp437 = (unsigned char)text[i]; + unicode[i] = charmap[cp437]; + } + unicode[i] = 0; +} + + +int ttf_managerst::size_text(const string &text) { + vector<Uint16> text_unicode; + cp437_to_unicode(text, text_unicode); + int width, height; + TTF_SizeUNICODE(font, &text_unicode[0], &width, &height); + return (width + tile_width - 1) / tile_width; +} + + +ttf_details ttf_managerst::get_handle(const list<ttf_id> &text, justification just) { + // Check for an existing handle + handleid id = {text, just}; + auto it = handles.find(id); + if (it != handles.end()) return it->second; + // Right. Make a new one. + int handle = ++max_handle; + // Split out any tabs + list<ttf_id> split_text; + for (auto it = text.cbegin(); it != text.cend(); ++it) { + int pos = 0; + int tabpos; + while ((tabpos = it->text.find("\t", pos)) != string::npos) { + ttf_id left; + left.fg = it->fg; left.bg = it->bg; left.bold = it->bold; + left.text = it->text.substr(pos, tabpos - pos); + split_text.push_back(left); + ttf_id tabber; + tabber.fg = tabber.bg = tabber.bold = 255; + split_text.push_back(tabber); + pos = tabpos + 1; + } + ttf_id right; + right.fg = it->fg; right.bg = it->bg; right.bold = it->bold; + right.text = it->text.substr(pos); + split_text.push_back(right); + } + // Find the total width of the text + vector<Uint16> text_unicode; + int ttf_width = 0, ttf_height = 0, text_width = 0; + for (auto it = split_text.cbegin(); it != split_text.cend(); ++it) { + if (it->fg == 255 && it->bg == 255 && it->bold == 255) { + // Tab stop + int tabstop = tab_width * em_width; + int tab_width = tabstop - ((ttf_width - 1) % tabstop) + 1; + ttf_width += tab_width; + text_width += 1; + } else { + cp437_to_unicode(it->text, text_unicode); + int slice_width, slice_height; + TTF_SizeUNICODE(font, &text_unicode[0], &slice_width, &slice_height); + ttf_width += slice_width; + text_width += it->text.size(); + } + } + ttf_height = ceiling; + // Compute geometry + double grid_width = double(ttf_width) / tile_width; + double offset = just == justify_right ? text_width - grid_width : + just == justify_center ? (text_width - grid_width) / 2 : + 0; + if (just == justify_center && text_width % 2) + offset += 0.5; // Arbitrary fixup for approximate grid centering + double fraction, integral; + fraction = modf(offset, &integral); + // Outputs: + const int grid_offset = int(integral + 0.001); // Tiles to move to the right in addst + const int pixel_offset = int(fraction * tile_width); // Black columns to add to the left of the image + // const int full_grid_width = int(ceil(double(ttf_width) / double(tile_width) + fraction) + 0.1); // Total width of the image in grid units + const int full_grid_width = text_width; + const int pixel_width = full_grid_width * tile_width; // And pixels + assert(pixel_width >= ttf_width); + // Store for later + ttf_details ret; ret.handle = handle; ret.offset = grid_offset; ret.width = full_grid_width; + handles[id] = ret; + // We do the actual rendering in the render thread, later on. + todo.push_back(todum(handle, split_text, ttf_height, pixel_offset, pixel_width)); + return ret; +} + +SDL_Surface *ttf_managerst::get_texture(int handle) { + // Run any outstanding renders + if (!todo.empty()) { + vector<Uint16> text_unicode; + for (auto it = todo.cbegin(); it != todo.cend(); ++it) { + const int height = it->height; + SDL_Surface *textimg = SDL_CreateRGBSurface(SDL_SWSURFACE, it->pixel_width, height, 32, 0, 0, 0, 0); +// #ifdef DEBUG +// SDL_FillRect(textimg, NULL, SDL_MapRGBA(textimg->format, 255, 0, 0, 255)); +// #endif + // Render each of the text segments + int idx = 0; + int xpos = it->pixel_offset; + for (auto seg = it->text.cbegin(); seg != it->text.cend();) { + const ttf_id &text = *seg; + ++seg; + ++idx; + if (text.fg == 255 && text.bg == 255 && text.bold == 255) { + // Skip to tab stop + int tabstop = tab_width * em_width; + int tab_width = tabstop - ((xpos - 1) % tabstop) + 1; + xpos += tab_width; + continue; + } + if (text.text.size() <= 0) + continue; + cp437_to_unicode(text.text, text_unicode); + const int fg = (text.fg + text.bold * 8) % 16; + SDL_Color fgc = {Uint8(enabler.ccolor[fg][0]*255), + Uint8(enabler.ccolor[fg][1]*255), + Uint8(enabler.ccolor[fg][2]*255)}; + const int bg = text.bg % 16; + Uint32 bgc = SDL_MapRGB(textimg->format, + Uint8(enabler.ccolor[bg][0]*255), + Uint8(enabler.ccolor[bg][1]*255), + Uint8(enabler.ccolor[bg][2]*255)); +#ifdef DEBUG + // SDL_Color white = {255,255,255}; + // Uint32 red = SDL_MapRGB(textimg->format, 255,0,0); + // fgc = white; + // bgc = red; +#endif + if (idx == 0) { + // Fill in the left side + SDL_Rect left = {0, 0, Sint16(xpos), Sint16(height)}; + SDL_FillRect(textimg, &left, bgc); + } else if (seg == it->text.cend()) { + // Fill in the right side + SDL_Rect right = {Sint16(xpos), 0, Sint16(it->pixel_width), Sint16(height)}; + SDL_FillRect(textimg, &right, bgc); + } + // Render the TTF segment + SDL_Surface *textimg_seg = TTF_RenderUNICODE_Blended(font, &text_unicode[0], fgc); + // Fill the background color of this part of the textimg + SDL_Rect dest = {Sint16(xpos), 0, Sint16(textimg_seg->w), Sint16(height)}; + SDL_FillRect(textimg, &dest, + SDL_MapRGB(textimg->format, + // Uint8(255), + // Uint8(255), + // Uint8(255))); + Uint8(enabler.ccolor[bg][0]*255), + Uint8(enabler.ccolor[bg][1]*255), + Uint8(enabler.ccolor[bg][2]*255))); + // And copy the TTF segment over. + SDL_Rect dest2 = {Sint16(xpos), 0, 0, 0}; + SDL_BlitSurface(textimg_seg, NULL, textimg, &dest2); + // Ready for next segment. + xpos += textimg_seg->w; + SDL_FreeSurface(textimg_seg); + } + // ..and make the whole thing display format. Phew! + SDL_Surface *textimg_2 = SDL_DisplayFormat(textimg); +#ifdef DEBUG + // cout << "Rendering \"" << text.text << "\" at height " << box2->h << endl; + // cout << " width " << textimg->w << " in box of " << box->w << endl; +#endif + SDL_FreeSurface(textimg); + // Store it for later. + textures[it->handle] = textimg_2; + } + todo.clear(); + } + // Find the li'l texture + SDL_Surface *tex = textures[handle]; + if (!tex) { + cout << "Missing/broken TTF handle: " << handle << endl; + } + return tex; +} + +void ttf_managerst::gc() { + // Just delete everything, for now. + for (auto it = textures.begin(); it != textures.end(); ++it) + SDL_FreeSurface(it->second); + textures.clear(); + handles.clear(); + todo.clear(); +} diff --git a/g_src/ttf_manager.hpp b/g_src/ttf_manager.hpp new file mode 100755 index 0000000..8316c5a --- /dev/null +++ b/g_src/ttf_manager.hpp @@ -0,0 +1,101 @@ +#ifndef TTF_MANAGER_HPP +#define TTF_MANAGER_HPP + +#include "init.h" +#include "enabler.h" +#ifdef __APPLE__ +#include <SDL_ttf/SDL_ttf.h> +#else +#include <SDL/SDL_ttf.h> +#endif +#include <unordered_map> +#include <list> + +using std::unordered_map; +using std::list; + +struct handleid { + list<ttf_id> text; + justification just; + + bool operator< (const handleid &other) const { + if (text != other.text) return text < other.text; + return just < other.just; + } + + bool operator== (const handleid &other) const { + return just == other.just && text == other.text; + } +}; + +namespace std { + template<> struct hash<struct handleid> { + size_t operator()(handleid val) const { + size_t h = 0; + auto end = val.text.cend(); + for (auto it = val.text.cbegin(); it != end; ++it) { + h += hash<ttf_id>()(*it); + } + return h + val.just; + } + }; +}; + +struct ttf_details { + int handle; + int offset; + int width; +}; + +class ttf_managerst { + TTF_Font *font; + int max_handle; + int tile_width, ceiling; + double tab_width; + int em_width; + unordered_map<handleid, ttf_details> handles; + unordered_map<int, SDL_Surface*> textures; + struct todum { + int handle; + list<ttf_id> text; + int height; + int pixel_offset, pixel_width; + todum(int handle, const list<ttf_id> &t, int h, int po, int pw) : + handle(handle), text(t), height(h), pixel_offset(po), pixel_width(pw) {} + }; + list<todum> todo; +public: + ttf_managerst() { + font = NULL; + max_handle = 1; + tab_width = 2; + em_width = 8; + } + ~ttf_managerst() { + for (auto it = textures.cbegin(); it != textures.cend(); ++it) + SDL_FreeSurface(it->second); + if (font) TTF_CloseFont(font); + } + bool init(int ceiling, int tile_width); + bool was_init() const { return font != NULL; } + // Return the expected size of a bit of text, in tiles. + int size_text(const string &text); + ttf_details get_handle(const list<ttf_id> &text, justification just); + // Returns rendered text. Renders too, if necessary. + // The returned SDL_Surface is owned by the ttf_managerst. + SDL_Surface *get_texture(int handle); + // Garbage-collect ttf surfaces + void gc(); + // Set tab-stop width (in ems, i.e. tile widths) + void set_tab_width(double width) { tab_width = width; } + // Check if TTF is currently active + bool ttf_active() const { + return was_init() && + (::init.font.use_ttf == ttf_on || + (::init.font.use_ttf == ttf_auto && ::init.font.ttf_limit <= ceiling)); + } +}; + +extern ttf_managerst ttf_manager; + +#endif diff --git a/g_src/win32_compat.cpp b/g_src/win32_compat.cpp new file mode 100755 index 0000000..44d6ace --- /dev/null +++ b/g_src/win32_compat.cpp @@ -0,0 +1,184 @@ +#include <string> + +#include "enabler.h" +#include "platform.h" +#ifndef WIN32 +# include <sys/types.h> +# include <sys/stat.h> +# include <sys/time.h> +# include <signal.h> +# include <errno.h> +# include <stdio.h> +# include <string.h> +# ifdef __APPLE__ +# include "osx_messagebox.h" +# elif defined(unix) +# include <gtk/gtk.h> +# endif +#endif + +#ifndef WIN32 +BOOL CreateDirectory(const char* pathname, void*) +{ + if (mkdir(pathname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) { + if (errno != EEXIST) { + std::string emsg = "mkdir("; + emsg.append(pathname); + emsg.append(") failed"); + perror(emsg.c_str()); + } + return FALSE; + } else { + return TRUE; + } +} + +BOOL DeleteFile(const char* filename) +{ + return !unlink(filename); +} + +void ZeroMemory(void* dest, int len) +{ + memset(dest, 0, len); +} + +/* Returns milliseconds since 1970 + * Wraps every 24 days (assuming 32-bit signed dwords) + */ +DWORD GetTickCount() +{ + struct timeval tp; + gettimeofday(&tp, NULL); + return (tp.tv_sec * 1000) + (tp.tv_usec / 1000); +} + +char* itoa(int value, char* result, int base) +{ + // check that the base is valid + if (base < 2 || base > 16) { *result = 0; return result; } + + char* out = result; + int quot = value; + + do + { + *out = "0123456789abcdef"[ /*std::*/abs(quot % base) ]; + ++out; + quot /= base; + } + while (quot); + + if (value < 0) *out++ = '-'; + + std::reverse(result, out); + *out = 0; + return result; +} + +// Fills performanceCount with microseconds passed since 1970 +// Wraps in twenty-nine thousand years or so +BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount) +{ + struct timeval tp; + gettimeofday(&tp, NULL); + performanceCount->QuadPart = ((long long)tp.tv_sec * 1000000) + tp.tv_usec; + return TRUE; +} + +BOOL QueryPerformanceFrequency(LARGE_INTEGER* performanceCount) +{ + /* A constant, 10^6, as we give microseconds since 1970 in + * QueryPerformanceCounter. */ + performanceCount->QuadPart = 1000000; + + return TRUE; +} + +int MessageBox(HWND *dummy, const char *text, const char *caption, UINT type) +{ + bool toggle_screen = false; + int ret = IDOK; + if (enabler.is_fullscreen()) { + enabler.toggle_fullscreen(); + toggle_screen = true; + } +# ifdef __APPLE__ // Cocoa code + if (type & MB_YESNO) { + ret = CocoaAlertPanel(caption, text, "Yes", "No", NULL); + ret = (ret == 0 ? IDNO : IDYES); + } else { + CocoaAlertPanel(caption, text, "OK", NULL, NULL); + } +# else // GTK code + if (getenv("DISPLAY")) { + // Have X, will dialog + GtkWidget *dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + type & MB_YESNO ? + GTK_MESSAGE_QUESTION : + GTK_MESSAGE_ERROR, + type & MB_YESNO ? + GTK_BUTTONS_YES_NO : + GTK_BUTTONS_OK, + "%s", text); + gtk_window_set_position((GtkWindow*)dialog, GTK_WIN_POS_CENTER_ALWAYS); + gtk_window_set_title((GtkWindow*)dialog, caption); + gint dialog_ret = gtk_dialog_run(GTK_DIALOG(dialog)); + gtk_widget_destroy(dialog); + while (gtk_events_pending()) + gtk_main_iteration(); + + if (type & MB_YESNO) { + switch (dialog_ret) { + default: + case GTK_RESPONSE_DELETE_EVENT: + case GTK_RESPONSE_NO: + ret = IDNO; + break; + case GTK_RESPONSE_YES: + ret = IDYES; + break; + } + } + } else { + // Use curses + init_curses(); + erase(); + gps.force_full_display_count = 1; + wattrset(*stdscr_p, A_NORMAL | COLOR_PAIR(1)); + + mvwaddstr(*stdscr_p, 0, 5, caption); + mvwaddstr(*stdscr_p, 2, 2, text); + nodelay(*stdscr_p, false); + if (type & MB_YESNO) { + mvwaddstr(*stdscr_p, 5, 0, "Press 'y' or 'n'."); + refresh(); + while (1) { + char i = wgetch(*stdscr_p); + if (i == 'y') { + ret = IDYES; + break; + } + else if (i == 'n') { + ret = IDNO; + break; + } + } + } + else { + mvwaddstr(*stdscr_p, 5, 0, "Press any key to continue."); + refresh(); + wgetch(*stdscr_p); + } + nodelay(*stdscr_p, -1); + } +# endif + + if (toggle_screen) { + enabler.toggle_fullscreen(); + } + + return ret; +} +#endif |