From ea76b6988ccafaa6a4d4ed90f2489d0e49e1f180 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sat, 5 Sep 2015 09:32:30 -0400 Subject: Imported Upstream version 0.40.24 --- g_src/KeybindingScreen.cpp | 409 +++++ g_src/KeybindingScreen.h | 69 + g_src/ViewBase.cpp | 38 + g_src/ViewBase.h | 197 +++ g_src/basics.cpp | 792 ++++++++++ g_src/basics.h | 117 ++ g_src/bimap.h | 17 + g_src/command_line.cpp | 132 ++ g_src/command_line.h | 25 + g_src/curses.h | 28 + g_src/enabler.cpp | 968 ++++++++++++ g_src/enabler.h | 1027 +++++++++++++ g_src/enabler_input.cpp | 1095 ++++++++++++++ g_src/enabler_input.h | 137 ++ g_src/endian.h | 42 + g_src/files.cpp | 428 ++++++ g_src/files.h | 368 +++++ g_src/find_files.cpp | 180 +++ g_src/find_files.h | 6 + g_src/find_files_posix.cpp | 185 +++ g_src/g_basics.h | 33 + g_src/graphics.cpp | 566 +++++++ g_src/graphics.h | 252 +++ g_src/init.cpp | 685 +++++++++ g_src/init.h | 166 ++ g_src/interface.cpp | 1777 ++++++++++++++++++++++ g_src/interface.h | 149 ++ g_src/keybindings.cpp | 3115 ++++++++++++++++++++++++++++++++++++++ g_src/keybindings.h | 1524 +++++++++++++++++++ g_src/mail.hpp | 155 ++ g_src/music_and_sound_fmodex.cpp | 308 ++++ g_src/music_and_sound_fmodex.h | 102 ++ g_src/music_and_sound_g.h | 13 + g_src/music_and_sound_openal.cpp | 688 +++++++++ g_src/music_and_sound_openal.h | 82 + g_src/music_and_sound_v.h | 11 + g_src/platform.h | 102 ++ g_src/random.cpp | 206 +++ g_src/random.h | 40 + g_src/renderer_2d.hpp | 352 +++++ g_src/renderer_curses.cpp | 369 +++++ g_src/renderer_offscreen.cpp | 86 ++ g_src/renderer_opengl.hpp | 609 ++++++++ g_src/resize++.cpp | 269 ++++ g_src/resize++.h | 68 + g_src/svector.h | 28 + g_src/template.h | 1235 +++++++++++++++ g_src/textlines.cpp | 61 + g_src/textlines.h | 22 + g_src/texture_handler.h | 60 + g_src/textures.cpp | 398 +++++ g_src/ttf_manager.cpp | 245 +++ g_src/ttf_manager.hpp | 101 ++ g_src/win32_compat.cpp | 184 +++ 54 files changed, 20321 insertions(+) create mode 100755 g_src/KeybindingScreen.cpp create mode 100755 g_src/KeybindingScreen.h create mode 100755 g_src/ViewBase.cpp create mode 100755 g_src/ViewBase.h create mode 100755 g_src/basics.cpp create mode 100755 g_src/basics.h create mode 100755 g_src/bimap.h create mode 100755 g_src/command_line.cpp create mode 100755 g_src/command_line.h create mode 100755 g_src/curses.h create mode 100755 g_src/enabler.cpp create mode 100755 g_src/enabler.h create mode 100755 g_src/enabler_input.cpp create mode 100755 g_src/enabler_input.h create mode 100755 g_src/endian.h create mode 100755 g_src/files.cpp create mode 100755 g_src/files.h create mode 100755 g_src/find_files.cpp create mode 100755 g_src/find_files.h create mode 100755 g_src/find_files_posix.cpp create mode 100755 g_src/g_basics.h create mode 100755 g_src/graphics.cpp create mode 100755 g_src/graphics.h create mode 100755 g_src/init.cpp create mode 100755 g_src/init.h create mode 100755 g_src/interface.cpp create mode 100755 g_src/interface.h create mode 100755 g_src/keybindings.cpp create mode 100755 g_src/keybindings.h create mode 100755 g_src/mail.hpp create mode 100755 g_src/music_and_sound_fmodex.cpp create mode 100755 g_src/music_and_sound_fmodex.h create mode 100755 g_src/music_and_sound_g.h create mode 100755 g_src/music_and_sound_openal.cpp create mode 100755 g_src/music_and_sound_openal.h create mode 100755 g_src/music_and_sound_v.h create mode 100755 g_src/platform.h create mode 100755 g_src/random.cpp create mode 100755 g_src/random.h create mode 100755 g_src/renderer_2d.hpp create mode 100755 g_src/renderer_curses.cpp create mode 100755 g_src/renderer_offscreen.cpp create mode 100755 g_src/renderer_opengl.hpp create mode 100755 g_src/resize++.cpp create mode 100755 g_src/resize++.h create mode 100755 g_src/svector.h create mode 100755 g_src/template.h create mode 100755 g_src/textlines.cpp create mode 100755 g_src/textlines.h create mode 100755 g_src/texture_handler.h create mode 100755 g_src/textures.cpp create mode 100755 g_src/ttf_manager.cpp create mode 100755 g_src/ttf_manager.hpp create mode 100755 g_src/win32_compat.cpp (limited to 'g_src') 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 +#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 +#include +#include +#include +#include + +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 &input) { + enabler.flag|=ENABLERFLAG_RENDER; + if (input.count(INTERFACEKEY_KEYBINDING_COMPLETE)) { + list keys = enabler.getRegisteredKey(); + if (keys.size() == 0) { + puts("No keys registered ?!"); + mode = mode_keyR; + } else { + keyRegister.clear(); + list keys = enabler.getRegisteredKey(); + for (list::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 macros = enabler.list_macros(); + for (list::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 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::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 macros = enabler.list_macros(); + width = 10; + if (!macros.size()) { + menu.add("No macros!", ""); + height = 1; + } else + height = macros.size(); + + for (list::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 &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 &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 +#include + +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 main; // Representing main_selector + widgets::menu keyL; + widgets::menu keyR; + widgets::menu macro; + widgets::menu 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 &events); + virtual void render(); + virtual void help(); + virtual void logic(); + virtual char is_option_screen() { return 2; } +}; + +class MacroScreenLoad : public viewscreenst { + widgets::menu menu; + int width, height; + + public: + MacroScreenLoad(); + virtual void logic(); + virtual void render(); + virtual void feed(std::set &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 &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 +#include +#include "ViewBase.h" + +using namespace std; +using namespace widgets; + +void textbox::feed(set &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::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 +#include +#include + +#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 &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 + class menu { + typedef map > dict; + dict lines; + int selection; + int last_displayheight; + bool bleached; + map > 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 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 &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 >::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 &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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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<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(pos2); +} + +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(pos0); +} + +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(;s0); +} + +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(;s0); +} + +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(;s0); +} + +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;s0); +} + + +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='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='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='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;s0) + { + 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;s0) + { + 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 +#endif +#include +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 + +template +struct bimap { + std::map left; + std::map right; + + void insert(A a, B b) { + left.insert(std::pair(a,b)); + right.insert(std::pair(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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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;ldat); + } +} + +char command_linest::grab_arg(string &source,long &pos) +{ + string dest; + + while(pos +#endif +# undef COLOR_BLUE +# undef COLOR_CYAN +# undef COLOR_RED +# undef COLOR_YELLOW +# include +#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 +#endif + +#include + +#include "platform.h" +#include "enabler.h" +#include "random.h" +#include "init.h" +#include "music_and_sound_g.h" + +#ifdef unix +# include +#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 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(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(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 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 &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;curposdat.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 +#include +#ifdef __APPLE__ +# include +# include +#else +# include +# include +#endif + +#include "GL/glew.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 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;sdat); + } + } + void write_file(file_compressorst &filecomp) + { + long dummy=str.size(); + filecomp.write_file(dummy); + + long s; + for(s=0;sdat); + } + } + + 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>3; + if(slot>=0&&slot>3; + if(slot>=0&&slot>3; + if(slot>=0&&slot0) + { + long ind; + for(ind=0;ind0) + { + //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;indfilename = 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 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 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 { + 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()(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 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 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 > overridden_grid_sizes; + + class renderer *renderer; + void eventLoop_SDL(); +#ifdef CURSES + void eventLoop_ncurses(); +#endif + + // Framerate calculations + int calculated_fps, calculated_gfps; + queue 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 &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_tobox; // Messages to the simulation thread + Chan async_frombox; // Messages from the simulation thread, and acknowledgements of those to + Chan async_zoom; // Zoom commands (from the simulation thread) + Chan 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 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 +#include +#include +#include +#include +#include +#include +#include +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 timeline; // A timeline of pending key events (for next get_input) +static set 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 keymap; +static map repeatmap; +static map > keydisplay; // Used only for display, not for meaning + +// Macro recording +static bool macro_recording = false; +static macro active_macro; // Active macro +static map 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 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 >::iterator it = keydisplay.find(binding); + if (it == keydisplay.end()) { + set 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::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 &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 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::iterator line = lines.begin(); + vector match; + + while (line != lines.end()) { + if (parse_line(*line, bind, match)) { + map::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::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(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(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 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::iterator it = keymap.begin(); it != keymap.end(); ++it) + map.insert(pair(it->second,it->first)); + // Insert an empty line for the benefit of note/wordpad + s << endl; + // And write. + for (multimap::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::iterator pkit; + list > 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 >::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 events = key_translation(sdl); + for (set::iterator k = events.begin(); k != events.end(); ++k) { + e.serial = serial; + e.k = *k; + timeline.insert(e); + } + } + if (uni.unicode) { + set events = key_translation(uni); + for (set::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 keys = key_translation(e.match); + if (e.release) { + set::iterator it = timeline.begin(); + while (it != timeline.end()) { + set::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::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::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::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 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 input; + set::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::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 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 enabler_inputst::key_translation(EventMatch &match) { + set bindings; + pair::iterator,multimap::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 >::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::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::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::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::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 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::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::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::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::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 enabler_inputst::list_macros() { + // First, check for unloaded macros + svector 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 ret; + for (map::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::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 enabler_inputst::getRegisteredKey() { + key_registering = false; + list ret; + for (list::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::iterator it = stored_keys.begin(); it != stored_keys.end(); ++it) { + if (it->type == type) { + keymap.insert(pair(*it, key)); + update_keydisplay(key, display(*it)); + } + } +} + +bool enabler_inputst::is_registering() { + return key_registering; +} + + +list enabler_inputst::list_keys(InterfaceKey key) { + list ret; + // Oh, now this is inefficient. + for (multimap::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::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 >::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 +#include +#include +#include + +#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 > macro; + +struct RegisteredKey { + MatchType type; + string display; +}; + +class enabler_inputst { + std::set 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 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 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 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 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include + +extern "C" { +#include +#ifndef WIN32 +# include +# include +# include +# include +#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_size0) + { + 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_size0) + { + //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< +using std::string; + +#include +#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 &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 &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 &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s=vect.size(); + write_file(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b &vect) + { + long s; + read_file(s); + vect.resize(s); + auto i_b=vect.begin(),i_e=vect.end(); + for(;i_b& 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& 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& vec); +void find_files_by_pattern_with_exception(const char* pattern, svector& 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" { +#include +#ifndef WIN32 +# include +# include +# include +# include +#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 +#include +#include +#include +#include + +void find_files_by_pattern(const char* pattern, svector& 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& 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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())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 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=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 # 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 +#include +#include +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 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#else +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#include + +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=maxmoviepos&& + maxmoviepos+half_frame_size*20) + { + 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>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;ldat); + } + + int frame=gview.supermovie_pos/4000,sd; + for(e=0;e=0&&sddat); + 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 &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=52&&sx<=78&&sy>=0&&sy=0&&sy=0&&editing_selected_sounddat,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;fchild=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 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;sdat.c_str()); + f.write(buf,sizeof(char)*50); + } + + int i1,i2; + for(i1=0;i1<200;i1++) + { + for(i2=0;i2movie_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;sdat; + 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=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 &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 &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()='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 +using std::string; +#include +#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 &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 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 &events,short &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag=0); +char standardscrolling(std::set &events,int32_t &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag=0); +char secondaryscrolling(std::set &events,short &scroll,int32_t min,int32_t max,int32_t jump,uint32_t flag=0); +char secondaryscrolling(std::set &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 &events); +char standardstringentry(string &str,int maxlen,unsigned int flag,std::set &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 + +using namespace std; + +bimap bindingNames; +bimap displayNames; +bimap 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 +#include +#include + +#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 bindingNames; +extern bimap displayNames; +extern bimap 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 +#include +#include + +template +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 +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 +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 +class Chan { + MVar > 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 { + 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 +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(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(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(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(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(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 +#include + +#ifndef NO_FMOD + +#include +#include + +/* 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 +#include +#include + +#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::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::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 +#include + +// HACKY HACKY HACK +// Fixes sndfile.h, until the bug is properly fixed +#include +#include +#define _MSCVER +typedef int64_t __int64; +#include +#undef _MSCVER +// END HACKY HACKY HACK + +#include +#include +#include +#include +#include +#include + +#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 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 buffers; // OpenAL buffers + std::map sources; // And sources + std::map slot_buffer; // Mappings from DF slots to openal + std::map 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 +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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>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>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>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>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 +#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 +using namespace std; + +void report_error(const char*, const char*); + +class renderer_2d_base : public renderer { +protected: + SDL_Surface *screen; + map 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::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 > 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 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 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 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 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::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 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 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,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 color) { + map,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(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 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(realloc(vertexes, sizeof(GLfloat) * tiles * 2 * 6)); + assert(vertexes); + fg = static_cast(realloc(fg, sizeof(GLfloat) * tiles * 4 * 6)); + assert(fg); + bg = static_cast(realloc(bg, sizeof(GLfloat) * tiles * 4 * 6)); + assert(bg); + tex = static_cast(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 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 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 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 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 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 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 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 +#include + +#include + +#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 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 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; yh; ++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; xw; x++) + { + for (size_t n=0; npixels + 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_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 +#include + +template > +class svector : public std::vector { +#ifndef WIN32 + public: + using std::vector::begin; +#endif + +#ifdef WIN32 + public: +#endif + void erase(typename std::vector::size_type i) { + std::vector &vec = *this; + vec.erase(begin() + i); + } + void insert(typename std::vector::size_type i, const T &v) { + + std::vector &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 int32_t get_vector_sum(svector &vec) +{ + T total=0; + auto ii_s=vec.begin(),ii_e=vec.end(); + for(;ii_s int32_t get_random_biased_index(svector &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 void zero_vector(svector &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 bool positive_vector(svector &vc) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + for(;ii_s0)return true; + } + return false; +} + +template void add_unique_to_vector(T nl,svector &vc) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + for(;ii_s void add_dual_unique_to_vectors(T nl,T2 nl2,svector &vc,svector &vc2) +{ + auto ii_s=vc.begin(),ii_e=vc.end(); + auto ii_s2=vc2.begin(),ii_e2=vc2.end(); + for(;ii_s void add_quad_unique_to_vectors(T nl,T2 nl2,T3 nl3,T4 nl4, + svector &vc,svector &vc2,svector &vc3,svector &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 void remove_all_from_vector(T nl,svector &vc) +{ + int32_t i; + for(i=(int32_t)vc.size()-1;i>=0;i--) + { + if(vc[i]==nl)vc.erase(i); + } +} + +template void remove_all_from_dual_vectors(T nl,T2 nl2,svector &vc,svector &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 int32_t get_vector_index(T a,svector &v) +{ + auto ii_s=v.begin(),ii_e=v.end(); + auto ii_b=ii_s; + for(;ii_s int32_t get_dual_vector_index(T a1,T2 a2,svector &vc,svector &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 int32_t get_quad_vector_index(T a1,T2 a2,T3 a3,T4 a4, + svector &vc,svector &vc2, + svector &vc3,svector &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 void merge_vectors(T &master, T &merger) +{ + auto ii_s=merger.begin(),ii_e=merger.end(); + for(;ii_s=ii_e2) + { + master.push_back((*ii_s)); + } + } +} + +template 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 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_e3) + { + master.push_back((*ii_s)); + master2.push_back((*ii_s2)); + } + } +} + +template 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_e5) + { + master.push_back((*ii_s)); + master2.push_back((*ii_s2)); + master3.push_back((*ii_s3)); + master4.push_back((*ii_s4)); + } + } +} + +template 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 void push_on_vector(T &master,T &new_stuff) +{ + auto ii_s=new_stuff.begin(),ii_e=new_stuff.end(); + for(;ii_s VIndex add_to_global_id_vector(T ptr,svector &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return 1; + } + if(vect[size-1]->global_idglobal_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_idglobal_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_idglobal_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(endglobal_idglobal_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 void remove_from_global_id_vector(T ptr,svector &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 void remove_from_global_id_vector_by_id(int32_t id,svector &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 T get_from_global_id_vector(int32_t id,svector &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 int32_t get_index_from_global_id_vector(int32_t id,svector &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 VIndex add_to_binary_vector(T ptr,svector &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return 0; + } + if(vect[size-1]>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=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=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)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 VIndex add_unique_to_binary_vector(T ptr,svector &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return 0; + } + if(vect[size-1]>1; + + cptr=vect[mid]; + if(cptr==ptr)return -1;//ALREADY IN VECTOR + if(start==end) + { + if(cptr=(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=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)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 VIndex add_unique_to_binary_vector_always_index(T ptr,svector &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]>1; + + cptr=vect[mid]; + if(cptr==ptr){was_present=true;return mid;}//ALREADY IN VECTOR + if(start==end) + { + if(cptr=(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=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)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 void remove_from_binary_vector(T ptr,svector &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 int32_t get_index_from_binary_vector(T id,svector &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 int32_t get_floor_index_from_binary_vector(T ptr,svector &vect) +{ + int32_t size=vect.size(); + if(size==0)return -1; + if(vect[size-1]>1; + + cptr=vect[mid]; + if(cptr==ptr) + { + while(mid>0) + { + if(vect[mid-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=size)return start; + else return start; + } + else if(cptr>ptr) + { + if(start<=0)return 0; + else return start-1; + } + } + else if(end=size)return end; + else return end; + } + else if(cptr>ptr) + { + if(end<=0)return 0; + else return end-1; + } + } + return start; +} + +template void fixed_array_push_back(T ptr,T *vect,int32_t &size,int32_t max) +{ + if(size>=max)return; + vect[size]=ptr; + size++; +} + +template 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 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]>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=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=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)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 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]>1; + + cptr=vect[mid]; + if(cptr==ptr)return; + if(start==end) + { + if(cptr=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=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)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 void add_to_local_id_vector(T ptr,svector &vect) +{ + int32_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return; + } + if(vect[size-1]->local_idlocal_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_idlocal_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_idlocal_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(endlocal_idlocal_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 void remove_from_local_id_vector(T ptr,svector &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 T get_from_local_id_vector(int32_t id,svector &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 int32_t get_index_from_local_id_vector(int32_t id,svector &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 void add_to_short_id_vector(T ptr,svector &vect) +{ + int16_t size=vect.size(); + if(size==0) + { + vect.push_back(ptr); + return; + } + if(vect[size-1]->short_idshort_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_idshort_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_idshort_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(endshort_idshort_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 void remove_from_short_id_vector(T ptr,svector &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 T get_from_short_id_vector(int16_t id,svector &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 int16_t get_index_from_short_id_vector(int16_t id,svector &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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 texpos; + svector datapos; + svector texpos_gs; + svector datapos_gs; + + char loaded; + + + + tile_pagest() + { + loaded=0; + } + + void load_graphics(string &graphics_dir); +}; + +class texture_handlerst +{ + public: + svector page; + + svector texpos; + svector 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;ttoken==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 + +#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 ordered; + long pos = 0; + for (std::vector::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 + +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 &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 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 &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 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 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 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 +#else +#include +#endif +#include +#include + +using std::unordered_map; +using std::list; + +struct handleid { + list 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 { + 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()(*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 handles; + unordered_map textures; + struct todum { + int handle; + list text; + int height; + int pixel_offset, pixel_width; + todum(int handle, const list &t, int h, int po, int pw) : + handle(handle), text(t), height(h), pixel_offset(po), pixel_width(pw) {} + }; + list 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 &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 + +#include "enabler.h" +#include "platform.h" +#ifndef WIN32 +# include +# include +# include +# include +# include +# include +# include +# ifdef __APPLE__ +# include "osx_messagebox.h" +# elif defined(unix) +# include +# 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 -- cgit v1.2.3