summaryrefslogtreecommitdiff
path: root/g_src
diff options
context:
space:
mode:
Diffstat (limited to 'g_src')
-rwxr-xr-xg_src/KeybindingScreen.cpp409
-rwxr-xr-xg_src/KeybindingScreen.h69
-rwxr-xr-xg_src/ViewBase.cpp38
-rwxr-xr-xg_src/ViewBase.h197
-rwxr-xr-xg_src/basics.cpp792
-rwxr-xr-xg_src/basics.h117
-rwxr-xr-xg_src/bimap.h17
-rwxr-xr-xg_src/command_line.cpp132
-rwxr-xr-xg_src/command_line.h25
-rwxr-xr-xg_src/curses.h28
-rwxr-xr-xg_src/enabler.cpp968
-rwxr-xr-xg_src/enabler.h1027
-rwxr-xr-xg_src/enabler_input.cpp1095
-rwxr-xr-xg_src/enabler_input.h137
-rwxr-xr-xg_src/endian.h42
-rwxr-xr-xg_src/files.cpp428
-rwxr-xr-xg_src/files.h368
-rwxr-xr-xg_src/find_files.cpp180
-rwxr-xr-xg_src/find_files.h6
-rwxr-xr-xg_src/find_files_posix.cpp185
-rwxr-xr-xg_src/g_basics.h33
-rwxr-xr-xg_src/graphics.cpp566
-rwxr-xr-xg_src/graphics.h252
-rwxr-xr-xg_src/init.cpp685
-rwxr-xr-xg_src/init.h166
-rwxr-xr-xg_src/interface.cpp1777
-rwxr-xr-xg_src/interface.h149
-rwxr-xr-xg_src/keybindings.cpp3115
-rwxr-xr-xg_src/keybindings.h1524
-rwxr-xr-xg_src/mail.hpp155
-rwxr-xr-xg_src/music_and_sound_fmodex.cpp308
-rwxr-xr-xg_src/music_and_sound_fmodex.h102
-rwxr-xr-xg_src/music_and_sound_g.h13
-rwxr-xr-xg_src/music_and_sound_openal.cpp688
-rwxr-xr-xg_src/music_and_sound_openal.h82
-rwxr-xr-xg_src/music_and_sound_v.h11
-rwxr-xr-xg_src/platform.h102
-rwxr-xr-xg_src/random.cpp206
-rwxr-xr-xg_src/random.h40
-rwxr-xr-xg_src/renderer_2d.hpp352
-rwxr-xr-xg_src/renderer_curses.cpp369
-rwxr-xr-xg_src/renderer_offscreen.cpp86
-rwxr-xr-xg_src/renderer_opengl.hpp609
-rwxr-xr-xg_src/resize++.cpp269
-rwxr-xr-xg_src/resize++.h68
-rwxr-xr-xg_src/svector.h28
-rwxr-xr-xg_src/template.h1235
-rwxr-xr-xg_src/textlines.cpp61
-rwxr-xr-xg_src/textlines.h22
-rwxr-xr-xg_src/texture_handler.h60
-rwxr-xr-xg_src/textures.cpp398
-rwxr-xr-xg_src/ttf_manager.cpp245
-rwxr-xr-xg_src/ttf_manager.hpp101
-rwxr-xr-xg_src/win32_compat.cpp184
54 files changed, 20321 insertions, 0 deletions
diff --git a/g_src/KeybindingScreen.cpp b/g_src/KeybindingScreen.cpp
new file mode 100755
index 0000000..02cbd81
--- /dev/null
+++ b/g_src/KeybindingScreen.cpp
@@ -0,0 +1,409 @@
+#ifdef __APPLE__
+# include "osx_messagebox.h"
+#elif defined(unix)
+# include <gtk/gtk.h>
+#endif
+
+#include "GL/glew.h"
+
+#ifdef WIN32
+
+#ifndef INTEGER_TYPES
+ #define INTEGER_TYPES
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned long long uint64_t;
+#endif
+
+typedef int32_t VIndex;
+typedef int32_t Ordinal;
+
+#endif
+
+#include "graphics.h"
+#include "init.h"
+#include "keybindings.h"
+#include "KeybindingScreen.h"
+
+#include <list>
+#include <map>
+#include <iostream>
+#include <sstream>
+#include <ctype.h>
+
+using namespace std;
+
+struct BindingGroup {
+ string name;
+ InterfaceKey start, end;
+};
+
+const BindingGroup groups[] = {
+ {"General" , INTERFACEKEY_NONE, WORLDKEY_START-1},
+ {"World" , WORLDKEY_START, ADVENTURERKEY_START-1},
+ {"Adventurer" , ADVENTURERKEY_START, EMBARKKEY_START-1},
+ {"Dwarf mode" , DWARFMAINKEY_START, MILITIAKEY_START-1},
+ {"Embark" , EMBARKKEY_START, BUILDINGKEY_START-1},
+ {"Building" , BUILDINGKEY_START, WORKSHOPKEY_START-1},
+ {"Workshop" , WORKSHOPKEY_START, PILEZONEKEY_START-1},
+ {"Pilezone" , PILEZONEKEY_START, STOCKORDERKEY_START-1},
+ {"Stockorder" , STOCKORDERKEY_START, DWARFMAINKEY_START-1},
+ {"Militia" , MILITIAKEY_START, INTERFACEKEY_STRING_A000-1},
+ {"Text entry" , INTERFACEKEY_STRING_A000, INTERFACEKEY_STRING_A255}
+};
+
+KeybindingScreen::KeybindingScreen() {
+ gview.addscreen(this, INTERFACE_PUSH_AT_BACK, NULL); // HACK
+ mode = mode_main;
+
+ main.add("Macros", sel_macros);
+ for (int i = 0; i < ARRSZ(groups); i++)
+ main.set(i+2, groups[i].name, sel_first_group + i);
+ main.set(ARRSZ(groups)+3, "Save and exit", sel_save_exit);
+ main.add("Exit, discard changes when DF quits", sel_just_exit);
+ enabler.flag |= ENABLERFLAG_RENDER;
+}
+
+void KeybindingScreen::feed(set<InterfaceKey> &input) {
+ enabler.flag|=ENABLERFLAG_RENDER;
+ if (input.count(INTERFACEKEY_KEYBINDING_COMPLETE)) {
+ list<RegisteredKey> keys = enabler.getRegisteredKey();
+ if (keys.size() == 0) {
+ puts("No keys registered ?!");
+ mode = mode_keyR;
+ } else {
+ keyRegister.clear();
+ list<RegisteredKey> keys = enabler.getRegisteredKey();
+ for (list<RegisteredKey>::iterator it = keys.begin(); it != keys.end(); ++it) {
+ string display;
+ switch (it->type) {
+ case type_button: display = "Mouse button: "; break;
+ case type_key: display = "By position: "; break;
+ case type_unicode: display = "By letter: "; break;
+ }
+ keyRegister.add(display + it->display, it->type);
+ }
+ }
+ } else if (input.count(INTERFACEKEY_STANDARDSCROLL_PAGEUP) ||
+ input.count(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN) ||
+ input.count(INTERFACEKEY_STANDARDSCROLL_UP) ||
+ input.count(INTERFACEKEY_STANDARDSCROLL_DOWN)) {
+ switch (mode) {
+ case mode_main: main.feed(input); break;
+ case mode_keyL: keyL.feed(input); reset_keyR(); break;
+ case mode_keyR: keyR.feed(input); break;
+ case mode_macro: macro.feed(input); break;
+ case mode_register: keyRegister.feed(input); break;
+ }
+ } else if (mode == mode_keyL && input.count(INTERFACEKEY_STANDARDSCROLL_RIGHT))
+ mode = mode_keyR;
+ else if (mode == mode_main && input.count(INTERFACEKEY_STANDARDSCROLL_RIGHT)) {
+ if (main.get_selection() == sel_macros) enter_macros();
+ if (main.get_selection() >= sel_first_group)
+ enter_key(main.get_selection() - sel_first_group);
+ } else if (mode == mode_keyR && input.count(INTERFACEKEY_STANDARDSCROLL_LEFT))
+ mode = mode_keyL;
+ else if ((mode == mode_keyL || mode == mode_macro) && input.count(INTERFACEKEY_STANDARDSCROLL_LEFT))
+ mode = mode_main;
+ else if (input.count(INTERFACEKEY_STRING_A000)) { // Backspace: Delete something.
+ switch (mode) {
+ case mode_macro:
+ if (macro.get_selection() != "") {
+ enabler.delete_macro(macro.get_selection());
+ macro.del_selection();
+ if (!macro.size())
+ macro.add("No macros!", "");
+ }
+ break;
+ case mode_keyR:
+ keyR_selector sel = keyR.get_selection();
+ if (sel.sel == sel_event) {
+ enabler.remove_key(keyL.get_selection(), sel.event);
+ reset_keyR();
+ }
+ break;
+ }
+ } else if (input.count(INTERFACEKEY_SELECT)) {
+ switch (mode) {
+ case mode_main:
+ if (main.get_selection() == sel_macros) { // Macros
+ enter_macros();
+ } else if (main.get_selection() == sel_save_exit) { // Save and exit
+ enabler.save_keybindings();
+ breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN;
+ return;
+ } else if (main.get_selection() == sel_just_exit) { // Just exit
+ breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN;
+ return;
+ } else { // Some key-binding group
+ enter_key(main.get_selection() - sel_first_group);
+ }
+ break;
+ case mode_keyR: {
+ InterfaceKey key = keyL.get_selection();
+ switch (keyR.get_selection().sel) {
+ case sel_add:
+ enabler.register_key();
+ mode = mode_register;
+ break;
+ case sel_rep_none:
+ enabler.key_repeat(key, REPEAT_NOT);
+ reset_keyR();
+ break;
+ case sel_rep_slow:
+ enabler.key_repeat(key, REPEAT_SLOW);
+ reset_keyR();
+ break;
+ case sel_rep_fast:
+ enabler.key_repeat(key, REPEAT_FAST);
+ reset_keyR();
+ break;
+ }}
+ break;
+ case mode_register:
+ enabler.bindRegisteredKey(keyRegister.get_selection(), keyL.get_selection());
+ mode = mode_keyR;
+ reset_keyR();
+ break;
+ }
+ } else if (input.count(INTERFACEKEY_LEAVESCREEN) || input.count(INTERFACEKEY_OPTIONS)) {
+ if (mode == mode_register)
+ mode = mode_keyR;
+ else
+ mode = mode_main;
+ }
+}
+
+void KeybindingScreen::logic() {
+ if (mode == mode_register)
+ enabler.flag|=ENABLERFLAG_RENDER;
+}
+
+void KeybindingScreen::enter_macros() {
+ mode = mode_macro;
+ macro.clear();
+ list<string> macros = enabler.list_macros();
+ for (list<string>::iterator it = macros.begin(); it != macros.end(); ++it)
+ macro.add(*it, *it);
+ if (!macros.size())
+ macro.add("No macros!", "");
+}
+
+void KeybindingScreen::enter_key(int group) {
+ mode = mode_keyL;
+ keyL.clear();
+ for (InterfaceKey i = groups[group].start; i <= groups[group].end; i++) {
+ if (i != INTERFACEKEY_NONE)
+ keyL.add(enabler.GetBindingTextDisplay(i), i);
+ }
+ reset_keyR();
+}
+
+void KeybindingScreen::reset_keyR() {
+ int lastpos = keyR.get_pos();
+ keyR.clear();
+ struct keyR_selector sel;
+ sel.sel = sel_add;
+ keyR.add("Add binding", sel);
+ InterfaceKey key = keyL.get_selection();
+ list<EventMatch> matchers = enabler.list_keys(key);
+ Repeat rep = enabler.key_repeat(key);
+ sel.sel = sel_rep_none;
+ keyR.set(2, "Don't repeat", sel);
+ if (rep == REPEAT_NOT) keyR.set_color(2, 4, 0);
+ sel.sel = sel_rep_slow;
+ keyR.set(3, "Delayed repeat", sel);
+ if (rep == REPEAT_SLOW) keyR.set_color(3, 4, 0);
+ sel.sel = sel_rep_fast;
+ keyR.set(4, "Immediate repeat", sel);
+ if (rep == REPEAT_FAST) keyR.set_color(4, 4, 0);
+ int i = 6;
+ for (list<EventMatch>::iterator it = matchers.begin(); it != matchers.end(); ++it, ++i) {
+ ostringstream desc;
+ switch (it->type) {
+ case type_unicode:
+ desc << "By letter: ";
+ if (it->unicode < 256 && isgraph(it->unicode)) // Is it printable?
+ desc << (char)it->unicode;
+ else
+ desc << "U+" << hex << uppercase << it->unicode;
+ break;
+ case type_key:
+ desc << "By position: " << translate_mod(it->mod) << sdlNames.left[it->key];
+ break;
+ case type_button:
+ desc << "Mouse: " << (int)it->button;
+ break;
+ }
+ sel.sel = sel_event;
+ sel.event = *it;
+ keyR.set(i, desc.str(), sel);
+ }
+ keyR.set_pos(lastpos);
+}
+
+void KeybindingScreen::render_macro() {
+ drawborder("Macros");
+ gps.locate(3, 3);
+ gps.changecolor(4,0,1);
+ gps.addst("Select a macro, then press " + enabler.GetKeyDisplay(INTERFACEKEY_STRING_A000) + " to delete.");
+ macro.render(6, init.display.grid_x-2, 5, init.display.grid_y-2);
+}
+
+void KeybindingScreen::render_key() {
+ if (enabler.is_registering()) {
+ gps.changecolor(4,0,1);
+ drawborder("Keybinding - currently registering new key");
+ } else
+ drawborder("Keybinding");
+ gps.locate(3, 6);
+ gps.changecolor(4,0,1);
+ gps.addst("Select a binding, then press " + enabler.GetKeyDisplay(INTERFACEKEY_STRING_A000) + " to delete.");
+ keyL.render(6, init.display.grid_x/2 - 1, 5, init.display.grid_y-2);
+ if (mode == mode_keyL || mode == mode_register)
+ keyR.bleach(true);
+ else
+ keyR.bleach(false);
+ keyR.render(init.display.grid_x/2 + 1, init.display.grid_x-2, 5, init.display.grid_y-2);
+}
+
+void KeybindingScreen::render_register() {
+ int x1 = init.display.grid_x / 2 - 20,
+ x2 = init.display.grid_x / 2 + 20,
+ y1 = init.display.grid_y / 2 - 1,
+ y2 = init.display.grid_y / 2 + 1;
+ if (!enabler.is_registering()) {
+ y2 = y1 + keyRegister.size() + 1;
+ }
+ gps.erasescreen_rect(x1, x2, y1, y2);
+ gps.changecolor(1,1,1);
+ for (int x = x1; x <= x2; x++) {
+ gps.locate(y1, x); gps.addchar(' ');
+ gps.locate(y2, x); gps.addchar(' ');
+ }
+ for (int y = y1 + 1; y < y2; y++) {
+ gps.locate(y, x1); gps.addchar(' ');
+ gps.locate(y, x2); gps.addchar(' ');
+ }
+ if (enabler.is_registering()) {
+ gps.changecolor(7,0,1);
+ gps.locate(y1+1, x1+2);
+ gps.addst(translate_mod(getModState()));
+ } else {
+ keyRegister.render(x1+1, x2-1, y1+1, y2-1);
+ gps.locate(y2, x1+2);
+ gps.changecolor(7,1,1);
+ gps.addst("Select binding, or press " + enabler.GetKeyDisplay(INTERFACEKEY_LEAVESCREEN) + " to abort");
+ }
+}
+
+// Render the main menu
+void KeybindingScreen::render_main() {
+ drawborder("Key binding & macro center");
+ main.render(6, init.display.grid_x - 3, 3, init.display.grid_y - 4);
+}
+
+void KeybindingScreen::render() {
+ switch(mode) {
+ case mode_main: render_main(); break;
+ case mode_keyL: case mode_keyR: render_key(); break;
+ case mode_macro: render_macro(); break;
+ case mode_register:
+ render_key();
+ render_register();
+ break;
+ }
+}
+
+void KeybindingScreen::help() {
+}
+
+
+MacroScreenLoad::MacroScreenLoad() {
+ list<string> macros = enabler.list_macros();
+ width = 10;
+ if (!macros.size()) {
+ menu.add("No macros!", "");
+ height = 1;
+ } else
+ height = macros.size();
+
+ for (list<string>::iterator it = macros.begin(); it != macros.end(); ++it) {
+ if (it->length() > width) width = it->length();
+ menu.add(*it, *it);
+ }
+ enabler.flag |= ENABLERFLAG_RENDER;
+ // render();
+ // gps.renewscreen();
+}
+
+void MacroScreenLoad::feed(set<InterfaceKey> &input) {
+ enabler.flag|=ENABLERFLAG_RENDER;
+ if (input.count(INTERFACEKEY_SELECT)) {
+ string id = menu.get_selection();
+ if (id != "") enabler.load_macro(id);
+ breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN;
+ return;
+ } else if (input.count(INTERFACEKEY_LEAVESCREEN)) {
+ breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN;
+ return;
+ } else {
+ menu.feed(input);
+ }
+ if (input.count(INTERFACEKEY_OPTIONS)) {
+ breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN;
+ }
+}
+
+void MacroScreenLoad::logic() {
+}
+
+void MacroScreenLoad::render() {
+ if (parent) parent->render();
+ const int x1 = MAX(init.display.grid_x/2 - ((width + 2) / 2), 0);
+ const int x2 = MIN(x1+width+1, init.display.grid_x-1);
+ const int y1 = MAX(init.display.grid_y/2 - ((height + 2) / 2), 0);
+ const int y2 = MIN(y1 + height + 1, init.display.grid_y-1);
+ gps.changecolor(0,3,1);
+ gps.draw_border(x1, x2, y1, y2);
+ menu.render(x1+1, x2-1, y1+1, y2-1);
+ // gps.renewscreen();
+}
+
+MacroScreenSave::MacroScreenSave() {
+ enabler.flag |= ENABLERFLAG_RENDER;
+}
+
+void MacroScreenSave::logic() {
+}
+
+void MacroScreenSave::feed(set<InterfaceKey> &input) {
+ enabler.flag|=ENABLERFLAG_RENDER;
+ id.feed(input);
+ if (input.count(INTERFACEKEY_SELECT)) {
+ string n = id.get_text();
+ if (n.length())
+ enabler.save_macro(n);
+ breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN;
+ return;
+ }
+ if (input.count(INTERFACEKEY_OPTIONS)) {
+ breakdownlevel = INTERFACE_BREAKDOWN_STOPSCREEN;
+ }
+}
+
+void MacroScreenSave::render() {
+ if (parent) parent->render();
+ const int x1 = 3,
+ x2 = init.display.grid_x-4,
+ y1 = init.display.grid_y/2-1,
+ y2 = init.display.grid_y/2+1;
+ gps.changecolor(0,3,1);
+ gps.draw_border(x1, x2, y1, y2);
+ id.render(x1+1,x2-1,y1+1,y2-1);
+ // gps.renewscreen();
+}
+
diff --git a/g_src/KeybindingScreen.h b/g_src/KeybindingScreen.h
new file mode 100755
index 0000000..fc29f2e
--- /dev/null
+++ b/g_src/KeybindingScreen.h
@@ -0,0 +1,69 @@
+#ifndef KEYBINDINGSCREEN_H
+#define KEYBINDINGSCREEN_H
+
+#include "interface.h"
+#include "ViewBase.h"
+#include "enabler.h"
+
+#include <set>
+#include <string>
+
+class KeybindingScreen : public viewscreenst {
+ enum { mode_main, mode_keyL, mode_keyR, mode_macro, mode_register } mode;
+ enum keyR_type { sel_add, sel_rep_none, sel_rep_slow, sel_rep_fast, sel_event };
+ enum main_selector { sel_macros, sel_just_exit, sel_save_exit, sel_first_group };
+
+ struct keyR_selector {
+ keyR_type sel;
+ EventMatch event; // Uninitialized if sel != sel_event
+ };
+
+ widgets::menu<int> main; // Representing main_selector
+ widgets::menu<InterfaceKey> keyL;
+ widgets::menu<keyR_selector> keyR;
+ widgets::menu<std::string> macro;
+ widgets::menu<MatchType> keyRegister;
+
+ void render_main();
+ void render_macro();
+ void render_key();
+ void render_register();
+
+ void reset_keyR();
+
+ void enter_key(int group);
+ void enter_macros();
+
+public:
+ KeybindingScreen();
+ virtual void feed(std::set<InterfaceKey> &events);
+ virtual void render();
+ virtual void help();
+ virtual void logic();
+ virtual char is_option_screen() { return 2; }
+};
+
+class MacroScreenLoad : public viewscreenst {
+ widgets::menu<string> menu;
+ int width, height;
+
+ public:
+ MacroScreenLoad();
+ virtual void logic();
+ virtual void render();
+ virtual void feed(std::set<InterfaceKey> &events);
+ virtual char is_option_screen() { return 1; }
+};
+
+class MacroScreenSave : public viewscreenst {
+ widgets::textbox id;
+public:
+ MacroScreenSave();
+ virtual void logic();
+ virtual void render();
+ virtual void feed(std::set<InterfaceKey> &events);
+ virtual char is_option_screen() { return 1; }
+};
+
+
+#endif
diff --git a/g_src/ViewBase.cpp b/g_src/ViewBase.cpp
new file mode 100755
index 0000000..6063732
--- /dev/null
+++ b/g_src/ViewBase.cpp
@@ -0,0 +1,38 @@
+#include <assert.h>
+#include <iostream>
+#include "ViewBase.h"
+
+using namespace std;
+using namespace widgets;
+
+void textbox::feed(set<InterfaceKey> &input) {
+ // Backspace
+ if (input.count(INTERFACEKEY_STRING_A000) && text.size())
+ text.resize(text.size() - 1);
+ // Hopefully we'll never get multiple characters in one input set,
+ // but it's possible. We deal with this by inserting them in
+ // alphabetical order.
+ for (set<InterfaceKey>::iterator it = input.lower_bound(INTERFACEKEY_STRING_A001);
+ it != input.end() && *it <= INTERFACEKEY_STRING_A255;
+ ++it) {
+ if (keep == false) {
+ keep = true;
+ text.clear();
+ }
+ char c = *it - INTERFACEKEY_STRING_A000;
+ text += c;
+ }
+}
+
+void textbox::render(int x1, int x2, int y1, int y2) {
+ // We need to do some kind of line-breaking for multi-line text
+ // entry boxes. This shall be implemented at need, and there is none
+ // yet.
+ assert(y1 == y2);
+ gps.erasescreen_rect(x1,x2,y1,y2);
+ gps.locate(y1,x1);
+ gps.changecolor(7,0,keep);
+ int width = x2 - x1 + 1;
+ int start = text.length() - width;
+ gps.addst(text.substr(MAX(start,0)));
+}
diff --git a/g_src/ViewBase.h b/g_src/ViewBase.h
new file mode 100755
index 0000000..315abf3
--- /dev/null
+++ b/g_src/ViewBase.h
@@ -0,0 +1,197 @@
+#ifndef VIEWBASE_H
+#define VIEWBASE_H
+
+#include <set>
+#include <map>
+#include <string>
+
+#include "keybindings.h"
+#include "graphics.h"
+
+enum InterfaceBreakdownTypes
+{
+ INTERFACE_BREAKDOWN_NONE,
+ INTERFACE_BREAKDOWN_QUIT,
+ INTERFACE_BREAKDOWN_STOPSCREEN,
+ INTERFACE_BREAKDOWN_TOFIRST,
+ INTERFACE_BREAKDOWNNUM
+};
+
+class viewscreenst
+{
+ public:
+ viewscreenst *child;
+ viewscreenst *parent;
+ char breakdownlevel;
+
+ char option_key_pressed;
+ virtual void feed(std::set<InterfaceKey> &events){}
+ virtual void logic(){}
+ virtual void render(){}
+ virtual void resize(int w, int h){}
+
+ virtual void help();
+ virtual char movies_okay(){return 1;}
+ virtual char is_option_screen(){return 0;}
+ virtual char is_save_screen(){return 0;}
+ viewscreenst()
+ {
+ child=0;
+ parent=0;
+ breakdownlevel=INTERFACE_BREAKDOWN_NONE;
+ option_key_pressed=0;
+ }
+ virtual ~viewscreenst(){}
+
+ virtual bool key_conflict(InterfaceKey test_key);
+};
+
+namespace widgets {
+
+ using namespace std;
+
+ template <typename T>
+ class menu {
+ typedef map<int,pair<string, T> > dict;
+ dict lines;
+ int selection;
+ int last_displayheight;
+ bool bleached;
+ map<int, pair<int,int> > colors;
+
+ // Given 'total' lines, with 'sel' selected, and 'space' to draw in,
+ // returns the first line that should be drawn.
+ int first_line(int total, int sel, int space) {
+ // There is no doubt some clever math to do this, but I'm tired and don't care.
+ for (int start = 0;; start += space / 2) {
+ if (start + space/2 >= sel) return start;
+ if (start + space >= total) return start;
+ }
+ }
+ pair<string,T> mp(string s, T t) { return make_pair(s,t); }
+
+ // Scrolls N lines up/down; positive = down
+ void scroll(int n) {
+ typename dict::iterator it = lines.find(selection);
+ for (int i = 0; i < abs(n); i++) {
+ if (n < 0 && it == lines.begin()) { // We've hit the top
+ if (i) break;
+ else {
+ it = --(lines.end());
+ break;
+ }
+ }
+ if (n < 0) --it; else ++it; // Scroll one line
+ if (it == lines.end()) { // We've hit the bottom
+ if (i) {
+ --it;
+ break;
+ }
+ else {
+ it = lines.begin();
+ break;
+ }
+ }
+ // If we hit neither the top nor bottom, loop.
+ }
+
+ selection = it->first;
+ }
+
+ public:
+ menu() { clear(); }
+ int size() { return lines.size(); }
+ // Adds a line just past the last taken position
+ void add(string text, T token) {
+ if (!lines.size()) {
+ lines[0] = mp(text,token);
+ } else {
+ typename dict::iterator it = --(lines.end());
+ lines[it->first + 1] = mp(text,token);
+ }
+ }
+ // (Re)sets the text of the given line
+ void set(int line, string text, T token) {
+ lines[line] = mp(text,token);
+ }
+ // Set the color of a line
+ void set_color(int line, int fg, int bg) {
+ colors[line] = make_pair(fg,bg);
+ }
+ // Handles (page) up/down
+ void feed(std::set<InterfaceKey> &input) {
+ if (!lines.size()) return;
+ if (input.count(INTERFACEKEY_STANDARDSCROLL_UP)) scroll(-1);
+ if (input.count(INTERFACEKEY_STANDARDSCROLL_DOWN)) scroll(1);
+ if (input.count(INTERFACEKEY_STANDARDSCROLL_PAGEUP)) scroll(-(last_displayheight / 2));
+ if (input.count(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN)) scroll(last_displayheight / 2);
+ }
+ void render(int x1, int x2, int y1, int y2) {
+ gps.erasescreen_rect(x1,x2,y1,y2);
+ int h = y2 - y1 + 1,
+ w = x2 - x1 + 1,
+ x = x1, y = y1;
+ last_displayheight = h;
+ if (!lines.size()) return;
+ int total = (--lines.end())->first + 1;
+ int first = first_line(total, selection, h);
+ typename dict::iterator it = lines.lower_bound(first);
+ for (; it != lines.end() && it->first - first < h; ++it) {
+ gps.locate(it->first - first + y, x);
+ map<int,pair<int,int> >::iterator color = colors.find(it->first - first);
+ int fg = 7, bg = 0;
+ if (color != colors.end()) {
+ fg = color->second.first;
+ bg = color->second.second;
+ }
+ gps.changecolor(fg, bg, it->first == selection && !bleached);
+ gps.addst(it->second.first.substr(0, w));
+ }
+ }
+ // Read out the current selection
+ T get_selection() { return lines[selection].second; }
+ int get_pos() { return selection; }
+ // Set the position by line
+ void set_pos(int pos) {
+ if (pos < size())
+ selection = pos;
+ }
+ // Delete the currently selected line
+ void del_selection() {
+ typename dict::iterator it = lines.find(selection);
+ typename dict::iterator newsel = it;
+ ++newsel;
+ if (newsel == lines.end()) {
+ newsel = it;
+ --newsel;
+ }
+ lines.erase(it);
+ if (lines.size()) selection = newsel->first;
+ }
+ // If true, don't draw a highlight
+ void bleach(bool b) { bleached = b; }
+ // Reset the menu
+ void clear() {
+ selection = 0;
+ lines.clear();
+ last_displayheight = 10;
+ bleached = false;
+ colors.clear();
+ }
+ };
+
+ class textbox {
+ string text;
+ bool keep;
+ public:
+ textbox() { textbox("", false); }
+ textbox(string initializer, bool keep) { this->keep = keep; text = initializer; }
+ string get_text() { return text; }
+ // Only cares about INTERFACEKEY_STRING events
+ void feed(std::set<InterfaceKey> &input);
+ void render(int x1, int x2, int y1, int y2);
+ };
+
+}
+
+#endif
diff --git a/g_src/basics.cpp b/g_src/basics.cpp
new file mode 100755
index 0000000..a56145d
--- /dev/null
+++ b/g_src/basics.cpp
@@ -0,0 +1,792 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+using std::endl;
+using std::ofstream;
+
+#include "endian.h"
+
+#ifdef WIN32
+
+#ifndef INTEGER_TYPES
+ #define INTEGER_TYPES
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned long long uint64_t;
+#endif
+
+typedef int32_t VIndex;
+typedef int32_t Ordinal;
+
+#endif
+
+#include "ttf_manager.hpp"
+#include "init.h"
+#include "basics.h"
+
+extern string errorlog_prefix;
+
+void errorlog_string(const string &str)
+{
+ if(str.empty())return;
+
+ //SAVE AN ERROR TO THE LOG FILE
+ std::ofstream fseed("errorlog.txt", std::ios::out | std::ios::app);
+ if(fseed.is_open())
+ {
+ if(!errorlog_prefix.empty())
+ {
+ fseed<<errorlog_prefix.c_str()<<std::endl;
+ errorlog_prefix.clear();
+ }
+ fseed<<str.c_str()<<std::endl;
+ }
+ fseed.close();
+}
+
+void gamelog_string(const string &str)
+{
+ if(str.empty())return;
+
+ //SAVE AN ERROR TO THE LOG FILE
+ std::ofstream fseed("gamelog.txt",std::ios::out | std::ios::app);
+ if(fseed.is_open())
+ {
+ fseed<<str.c_str()<<std::endl;
+ }
+ fseed.close();
+}
+
+void errorlog_string(const char *ptr)
+{
+ if(ptr==NULL)return;
+
+ //SAVE AN ERROR TO THE LOG FILE
+ std::ofstream fseed("errorlog.txt", std::ios::out | std::ios::app);
+ if(fseed.is_open())
+ {
+ if(!errorlog_prefix.empty())
+ {
+ fseed<<errorlog_prefix.c_str()<<std::endl;
+ errorlog_prefix.clear();
+ }
+ fseed<<ptr<<std::endl;
+ }
+ fseed.close();
+}
+
+int32_t convert_string_to_long(string &str)
+{
+ return atoi(str.c_str());
+}
+
+uint32_t convert_string_to_ulong(string &str)
+{
+ return strtoul(str.c_str(),NULL,0);
+}
+
+void add_long_to_string(int32_t n,string &str)
+{
+ string str2;
+ convert_long_to_string(n,str2);
+ str+=str2;
+}
+
+void convert_long_to_string(int32_t n,string &str)
+{
+ std::ostringstream o;
+ o << n;
+ str = o.str();
+}
+
+void convert_ulong_to_string(uint32_t n,string &str)
+{
+ std::ostringstream o;
+ o << n;
+ str = o.str();
+}
+
+char grab_variable_token(string &str,string &token,char sec_comp,int32_t &pos,int32_t i_pos)
+{
+ token.erase();
+
+ for(pos=i_pos;pos<str.length();pos++)
+ {
+ if((str[pos]=='['&&pos+1<str.length())||sec_comp)
+ {
+ if(str[pos]=='['&&!sec_comp)pos++;
+ grab_token_string_pos(token,str,pos,':');
+ pos--;
+
+ if(token.length()>0)return 1;
+ }
+ }
+
+ return 0;
+}
+
+bool grab_token_expression(string &dest,string &source,int32_t &pos,char compc)
+{
+ dest.erase();
+ dest+="[";
+
+ string token1;
+ while(grab_token_string(token1,source,pos))
+ {
+ if(dest.length()>1)dest+=":";
+ dest+=token1;
+
+ if(pos<source.length())
+ {
+ if(source[pos]==']')break;//grab_token_string CAN'T HANDLE THESE
+ }
+ }
+ dest+="]";
+
+ return (dest.length()>2);
+}
+
+bool grab_token_list_as_string(string &dest,string &source,int32_t &pos,char compc)
+{
+ dest.erase();
+
+ string token1;
+ while(grab_token_string(token1,source,pos))
+ {
+ if(dest.length()>0)dest+=":";
+ dest+=token1;
+
+ if(pos<source.length())
+ {
+ if(source[pos]==']')break;//grab_token_string CAN'T HANDLE THESE
+ }
+ }
+
+ return (dest.length()>0);
+}
+
+bool grab_token_string(string &dest,string &source,int32_t &pos,char compc)
+{
+ dest.erase();
+ if(source.length()==0)return false;
+
+ pos++;//GET RID OF FIRST [ OR compc THAT IS ASSUMED TO BE THERE
+ if(pos>source.size())return false;
+
+ //GO UNTIL YOU HIT A compc, ], or the end
+ auto s=source.begin(),e=source.end();
+ s+=pos;
+ for(;s<e;++s)
+ {
+ if((*s)==compc||(*s)==']')break;
+ dest+=(*s);
+ pos++;
+ }
+ return (dest.length()>0);
+}
+
+bool grab_token_string(string &dest,string &source,char compc)
+{
+ dest.erase();
+ if(source.length()==0)return false;
+
+ //GO UNTIL YOU HIT A :, ], or the end
+ auto s=source.begin(),e=source.end();
+ for(;s<e;++s)
+ {
+ if((*s)==compc||(*s)==']')break;
+ dest+=(*s);
+ }
+ return (dest.length()>0);
+}
+
+bool grab_token_string_pos(string &dest,string &source,int32_t pos,char compc)
+{
+ dest.erase();
+ if(source.length()==0)return false;
+ if(pos>source.length())return false;
+
+ //GO UNTIL YOU HIT A :, ], or the end
+ auto s=source.begin(),e=source.end();
+ s+=pos;
+ for(;s<e;++s)
+ {
+ if((*s)==compc||(*s)==']')break;
+ dest+=(*s);
+ }
+ return (dest.length()>0);
+}
+
+bool grab_token_string(string &dest,const char *source,char compc)
+{
+ dest.erase();
+ int32_t sz=strlen(source);
+ if(sz==0)return false;
+
+ //GO UNTIL YOU HIT A :, ], or the end
+ int32_t s;
+ for(s=0;s<sz;s++)
+ {
+ if(source[s]==compc||source[s]==']')break;
+ dest+=source[s];
+ }
+ return (dest.length()>0);
+}
+
+
+void replace_token_string(string &token,string &str,int32_t pos,char compc,string &nw,char repc)
+{
+ string rep;
+ if(repc!=0)rep=repc;
+ rep+=token;
+ if(compc!=0)rep+=compc;
+
+ string::size_type wpos;
+
+ if ((wpos = str.find(rep)) != string::npos)
+ {
+ str.replace(wpos,rep.size(),nw);
+ }
+}
+
+void simplify_string(string &str)
+{
+ int32_t s;
+ for(s=0;s<str.length();s++)
+ {
+ //CAPITALIZE
+ if(str[s]>='A'&&str[s]<='Z')
+ {
+ str[s]-='A';
+ str[s]+='a';
+ }
+ switch(str[s])
+ {
+ case (char)129:
+ case (char)150:
+ case (char)151:
+ case (char)154:
+ case (char)163:
+ str[s]='u';
+ break;
+ case (char)152:
+ str[s]='y';
+ break;
+ case (char)164:
+ case (char)165:
+ str[s]='n';
+ break;
+ case (char)131:
+ case (char)132:
+ case (char)133:
+ case (char)134:
+ case (char)142:
+ case (char)143:
+ case (char)145:
+ case (char)146:
+ case (char)160:
+ str[s]='a';
+ break;
+ case (char)130:
+ case (char)136:
+ case (char)137:
+ case (char)138:
+ case (char)144:
+ str[s]='e';
+ break;
+ case (char)139:
+ case (char)140:
+ case (char)141:
+ case (char)161:
+ str[s]='i';
+ break;
+ case (char)147:
+ case (char)148:
+ case (char)149:
+ case (char)153:
+ case (char)162:
+ str[s]='o';
+ break;
+ case (char)128:
+ case (char)135:
+ str[s]='c';
+ break;
+ }
+ }
+}
+
+void lower_case_string(string &str)
+{
+ int32_t s;
+ for(s=0;s<str.length();s++)
+ {
+ //CAPITALIZE
+ if(str[s]>='A'&&str[s]<='Z')
+ {
+ str[s]-='A';
+ str[s]+='a';
+ }
+ switch(str[s])
+ {
+ case (char)154:str[s]=(char)129;break;
+ case (char)165:str[s]=(char)164;break;
+ case (char)142:str[s]=(char)132;break;
+ case (char)143:str[s]=(char)134;break;
+ case (char)144:str[s]=(char)130;break;
+ case (char)153:str[s]=(char)148;break;
+ case (char)128:str[s]=(char)135;break;
+ case (char)146:str[s]=(char)145;break;
+ }
+ }
+}
+
+void upper_case_string(string &str)
+{
+ int32_t s;
+ for(s=0;s<str.length();s++)
+ {
+ //CAPITALIZE
+ if(str[s]>='a'&&str[s]<='z')
+ {
+ str[s]-='a';
+ str[s]+='A';
+ }
+ switch(str[s])
+ {
+ case (char)129:str[s]=(char)154;break;
+ case (char)164:str[s]=(char)165;break;
+ case (char)132:str[s]=(char)142;break;
+ case (char)134:str[s]=(char)143;break;
+ case (char)130:str[s]=(char)144;break;
+ case (char)148:str[s]=(char)153;break;
+ case (char)135:str[s]=(char)128;break;
+ case (char)145:str[s]=(char)146;break;
+ }
+ }
+}
+
+void capitalize_string_words(string &str)
+{
+ char conf;
+ int32_t s;
+ for(s=0;s<str.length();s++)
+ {
+ conf=0;
+ if(s>0)
+ {
+ if(str[s-1]==' '||
+ str[s-1]=='\"')conf=1;
+ if(str[s-1]=='\'')
+ {
+ //DISCOUNT SINGLE QUOTE IF IT ISN'T PRECEDED BY SPACE, COMMA OR NOTHING
+ if(s<=0)conf=1;
+ else if(s>=2)
+ {
+ if(str[s-2]==' '||
+ str[s-2]==',')conf=1;
+ }
+ }
+ }
+ if(s==0||conf)
+ {
+ //CAPITALIZE
+ if(str[s]>='a'&&str[s]<='z')
+ {
+ str[s]-='a';
+ str[s]+='A';
+ }
+ switch(str[s])
+ {
+ case (char)129:str[s]=(char)154;break;
+ case (char)164:str[s]=(char)165;break;
+ case (char)132:str[s]=(char)142;break;
+ case (char)134:str[s]=(char)143;break;
+ case (char)130:str[s]=(char)144;break;
+ case (char)148:str[s]=(char)153;break;
+ case (char)135:str[s]=(char)128;break;
+ case (char)145:str[s]=(char)146;break;
+ }
+ }
+ }
+}
+
+void capitalize_string_first_word(string &str)
+{
+ char conf;
+ int32_t s;
+ for(s=0;s<str.length();s++)
+ {
+ conf=0;
+ if(s>0)
+ {
+ if(str[s-1]==' '||
+ str[s-1]=='\"')conf=1;
+ if(str[s-1]=='\'')
+ {
+ //DISCOUNT SINGLE QUOTE IF IT ISN'T PRECEDED BY SPACE, COMMA OR NOTHING
+ if(s<=0)conf=1;
+ else if(s>=2)
+ {
+ if(str[s-2]==' '||
+ str[s-2]==',')conf=1;
+ }
+ }
+ }
+ if(s==0||conf)
+ {
+ //CAPITALIZE
+ if(str[s]>='a'&&str[s]<='z')
+ {
+ str[s]-='a';
+ str[s]+='A';
+ return;
+ }
+ switch(str[s])
+ {
+ case (char)129:str[s]=(char)154;return;
+ case (char)164:str[s]=(char)165;return;
+ case (char)132:str[s]=(char)142;return;
+ case (char)134:str[s]=(char)143;return;
+ case (char)130:str[s]=(char)144;return;
+ case (char)148:str[s]=(char)153;return;
+ case (char)135:str[s]=(char)128;return;
+ case (char)145:str[s]=(char)146;return;
+ }
+ if(str[s]!=' '&&str[s]!='\"')return;
+ }
+ }
+}
+
+static void abbreviate_string_helper(string &str, int len) {
+ if(str.length()>=2)
+ {
+ if((str[0]=='A'||str[0]=='a')&&
+ str[1]==' ')
+ {
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+
+ if(str.length()>=3)
+ {
+ if((str[0]=='A'||str[0]=='a')&&
+ (str[1]=='N'||str[1]=='n')&&
+ str[2]==' ')
+ {
+ str.erase(str.begin()+2);
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+
+ if(str.length()>=4)
+ {
+ if((str[0]=='T'||str[0]=='t')&&
+ (str[1]=='H'||str[1]=='h')&&
+ (str[2]=='E'||str[2]=='e')&&
+ str[3]==' ')
+ {
+ str.erase(str.begin()+3);
+ str.erase(str.begin()+2);
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+ }
+ }
+ }
+
+ int32_t l;
+ for(l=(int32_t)str.length()-1;l>=1;l--)
+ {
+ if(str[l-1]==' ')continue;
+
+ if(str[l]=='a'||
+ str[l]=='e'||
+ str[l]=='i'||
+ str[l]=='o'||
+ str[l]=='u'||
+ str[l]=='A'||
+ str[l]=='E'||
+ str[l]=='I'||
+ str[l]=='O'||
+ str[l]=='U')
+ {
+ str.erase(str.begin()+l);
+ if(str.length()<=len)return;
+ }
+ }
+
+ if(str.length()>len)str.resize(len);
+}
+
+
+void abbreviate_string(string &str, int32_t len)
+{
+ if (ttf_manager.ttf_active()) {
+ // We'll need to use TTF-aware text shrinking.
+ while (ttf_manager.size_text(str) > len)
+ abbreviate_string_helper(str, str.length() - 1);
+ } else if(str.length()>len){
+ // 1 letter = 1 tile.
+ abbreviate_string_helper(str, len);
+ }
+}
+
+
+
+void get_number(int32_t number,string &str)
+{
+ str.erase();
+
+ if(number<0)
+ {
+ number*=-1;
+ str="negative ";
+ }
+ switch(number)
+ {
+ case 0:str="zero";break;
+ case 1:str="one";break;
+ case 2:str="two";break;
+ case 3:str="three";break;
+ case 4:str="four";break;
+ case 5:str="five";break;
+ case 6:str="six";break;
+ case 7:str="seven";break;
+ case 8:str="eight";break;
+ case 9:str="nine";break;
+ case 10:str="ten";break;
+ case 11:str="eleven";break;
+ case 12:str="twelve";break;
+ case 13:str="thirteen";break;
+ case 14:str="fourteen";break;
+ case 15:str="fifteen";break;
+ case 16:str="sixteen";break;
+ case 17:str="seventeen";break;
+ case 18:str="eighteen";break;
+ case 19:str="nineteen";break;
+ default:
+ {
+ if(number>=1000000000)
+ {
+ string nm;
+ get_number(number/1000000000,nm);
+ str+=nm;
+ str+=" billion";
+ if(number%1000000000!=0)
+ {
+ str+=" ";
+ get_number(number%1000000000,nm);
+ str+=nm;
+ }
+ return;
+ }
+ if(number>=1000000&&number<1000000000)
+ {
+ string nm;
+ get_number(number/1000000,nm);
+ str+=nm;
+ str+=" million";
+ if(number%1000000!=0)
+ {
+ str+=" ";
+ get_number(number%1000000,nm);
+ str+=nm;
+ }
+ return;
+ }
+ if(number>=1000&&number<1000000)
+ {
+ string nm;
+ get_number(number/1000,nm);
+ str+=nm;
+ str+=" thousand";
+ if(number%1000!=0)
+ {
+ str+=" ";
+ get_number(number%1000,nm);
+ str+=nm;
+ }
+ return;
+ }
+ if(number>=100&&number<1000)
+ {
+ string nm;
+ get_number(number/100,nm);
+ str+=nm;
+ str+=" hundred";
+ if(number%100!=0)
+ {
+ str+=" ";
+ get_number(number%100,nm);
+ str+=nm;
+ }
+ return;
+ }
+ if(number>=20&&number<100)
+ {
+ switch(number/10)
+ {
+ case 2:str="twenty";break;
+ case 3:str="thirty";break;
+ case 4:str="forty";break;
+ case 5:str="fifty";break;
+ case 6:str="sixty";break;
+ case 7:str="seventy";break;
+ case 8:str="eighty";break;
+ case 9:str="ninety";break;
+ }
+ if(number%10!=0)
+ {
+ str+="-";
+ string nm;
+ get_number(number%10,nm);
+ str+=nm;
+ }
+ return;
+ }
+ add_long_to_string(number,str);
+ break;
+ }
+ }
+}
+
+void get_ordinal(int32_t number,string &str,bool shorten)
+{
+ str.erase();
+
+ if(shorten)
+ {
+ if(number<0)
+ {
+ number*=-1;
+ str="-";
+ }
+ add_long_to_string(number,str);
+ switch(number%10)
+ {
+ case 1:
+ if(number%100==11)str+="th";
+ else str+="st";
+ break;
+ case 2:
+ if(number%100==12)str+="th";
+ else str+="nd";
+ break;
+ case 3:
+ if(number%100==13)str+="th";
+ else str+="rd";
+ break;
+ default:
+ str+="th";
+ break;
+ }
+ return;
+ }
+
+
+ if(number<0)
+ {
+ number*=-1;
+ str="Negative ";
+ }
+ switch(number)
+ {
+ case 0:str="Zeroth";break;
+ case 1:str="First";break;
+ case 2:str="Second";break;
+ case 3:str="Third";break;
+ case 4:str="Fourth";break;
+ case 5:str="Fifth";break;
+ case 6:str="Sixth";break;
+ case 7:str="Seventh";break;
+ case 8:str="Eighth";break;
+ case 9:str="Ninth";break;
+ case 10:str="Tenth";break;
+ case 11:str="Eleventh";break;
+ case 12:str="Twelfth";break;
+ case 13:str="Thirteenth";break;
+ case 14:str="Fourteenth";break;
+ case 15:str="Fifteenth";break;
+ case 16:str="Sixteenth";break;
+ case 17:str="Seventeenth";break;
+ case 18:str="Eighteenth";break;
+ case 19:str="Nineteenth";break;
+ default:
+ add_long_to_string(number,str);
+ switch(number%10)
+ {
+ case 1:
+ if(number%100==11)str+="th";
+ else str+="st";
+ break;
+ case 2:
+ if(number%100==12)str+="th";
+ else str+="nd";
+ break;
+ case 3:
+ if(number%100==13)str+="th";
+ else str+="rd";
+ break;
+ default:
+ str+="th";
+ break;
+ }
+ break;
+ }
+}
+
+// Map DF's CP437 to Unicode
+// see: http://dwarffortresswiki.net/index.php/Character_table
+int charmap[256] = {
+ ' ', 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
+ 0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
+ 0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
+ 0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC,
+ /* 0x20 */
+ 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
+ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
+ 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
+ 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
+ 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
+ 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x2302,
+ /* 0x80 */
+ 0xC7, 0xFC, 0xE9, 0xE2, 0xE4, 0xE0, 0xE5, 0xE7,
+ 0xEA, 0xEB, 0xE8, 0xEF, 0xEE, 0xEC, 0xC4, 0xC5,
+ 0xC9, 0xE6, 0xC6, 0xF4, 0xF6, 0xF2, 0xFB, 0xF9,
+ 0xFF, 0xD6, 0xDC, 0xA2, 0xA3, 0xA5, 0x20A7, 0x192,
+ 0xE1, 0xED, 0xF3, 0xFA, 0xF1, 0xD1, 0xAA, 0xBA,
+ 0xBF, 0x2310, 0xAC, 0xBD, 0xBC, 0xA1, 0xAB, 0xBB,
+ 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
+ 0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
+ 0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
+ 0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
+ 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
+ 0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
+ 0x3B1, 0xDF/*yay*/, 0x393, 0x3C0, 0x3A3, 0x3C3, 0xB5, 0x3C4,
+ 0x3A6, 0x398, 0x3A9, 0x3B4, 0x221E, 0x3C6, 0x3B5, 0x2229,
+ 0x2261, 0xB1, 0x2265, 0x2264, 0x2320, 0x2321, 0xF7, 0x2248,
+ 0xB0, 0x2219, 0xB7, 0x221A, 0x207F, 0xB2, 0x25A0, 0xA0
+};
diff --git a/g_src/basics.h b/g_src/basics.h
new file mode 100755
index 0000000..ce3a3a2
--- /dev/null
+++ b/g_src/basics.h
@@ -0,0 +1,117 @@
+#ifndef BASICS_H
+#define BASICS_H
+
+#ifndef WIN32
+#include <stdint.h>
+#endif
+#include <string>
+using std::string;
+
+#ifndef BITS
+
+#define BITS
+
+#define BIT1 1
+#define BIT2 2
+#define BIT3 4
+#define BIT4 8
+#define BIT5 16
+#define BIT6 32
+#define BIT7 64
+#define BIT8 128
+#define BIT9 256
+#define BIT10 512
+#define BIT11 1024
+#define BIT12 2048
+#define BIT13 4096
+#define BIT14 8192
+#define BIT15 16384
+#define BIT16 32768
+#define BIT17 65536UL
+#define BIT18 131072UL
+#define BIT19 262144UL
+#define BIT20 524288UL
+#define BIT21 1048576UL
+#define BIT22 2097152UL
+#define BIT23 4194304UL
+#define BIT24 8388608UL
+#define BIT25 16777216UL
+#define BIT26 33554432UL
+#define BIT27 67108864UL
+#define BIT28 134217728UL
+#define BIT29 268435456UL
+#define BIT30 536870912UL
+#define BIT31 1073741824UL
+#define BIT32 2147483648UL
+
+#endif
+
+void gamelog_string(const string &str);
+void errorlog_string(const string &str);
+void errorlog_string(const char *ptr);
+
+bool grab_token_string(string &dest,string &source,char compc=':');
+bool grab_token_string(string &dest,string &source,int32_t &pos,char compc=':');
+bool grab_token_string_pos(string &dest,string &source,int32_t pos,char compc=':');
+void replace_token_string(string &token,string &str,int32_t pos,char compc,string &nw,char repc);
+bool grab_token_list_as_string(string &dest,string &source,int32_t &pos,char compc=':');
+bool grab_token_expression(string &dest,string &source,int32_t &pos,char compc=':');
+char grab_variable_token(string &str,string &token,char sec_comp,int32_t &pos,int32_t i_pos);
+
+int32_t convert_string_to_long(string &str);
+uint32_t convert_string_to_ulong(string &str);
+void add_long_to_string(int32_t n,string &str);
+void convert_long_to_string(int32_t n,string &str);
+void convert_ulong_to_string(uint32_t n,string &str);
+
+void lower_case_string(string &str);
+void upper_case_string(string &str);
+void simplify_string(string &str);
+void capitalize_string_words(string &str);
+void capitalize_string_first_word(string &str);
+void abbreviate_string(string &str,int32_t len);
+
+void get_number(int32_t number,string &str);
+void get_ordinal(int32_t number,string &str,bool shorten);
+
+enum GameMode
+{
+ GAMEMODE_DWARF,
+ GAMEMODE_ADVENTURE,
+ GAMEMODENUM,
+ GAMEMODE_NONE
+};
+
+enum GameType
+{
+ GAMETYPE_DWARF_MAIN,
+ GAMETYPE_ADVENTURE_MAIN,
+ GAMETYPE_VIEW_LEGENDS,
+ GAMETYPE_DWARF_RECLAIM,
+ GAMETYPE_DWARF_ARENA,
+ GAMETYPE_ADVENTURE_ARENA,
+ GAMETYPE_ADVENTURE_DUNGEON,
+ GAMETYPE_DWARF_TUTORIAL,
+ GAMETYPE_DWARF_UNRETIRE,
+ GAMETYPE_ADVENTURE_WORLD_DEBUG,
+ GAMETYPENUM,
+ GAMETYPE_NONE
+};
+
+enum Song
+{
+ SONG_TITLE,
+ SONG_GAME,
+ SONGNUM
+};
+
+
+enum justification : unsigned char {
+ justify_left, justify_center, justify_right,
+ justify_cont,
+ not_truetype
+};
+
+extern int charmap[256];
+
+#endif
diff --git a/g_src/bimap.h b/g_src/bimap.h
new file mode 100755
index 0000000..968f770
--- /dev/null
+++ b/g_src/bimap.h
@@ -0,0 +1,17 @@
+#ifndef BIMAP_H
+#define BIMAP_H
+
+#include <map>
+
+template<typename A, typename B>
+struct bimap {
+ std::map<A,B> left;
+ std::map<B,A> right;
+
+ void insert(A a, B b) {
+ left.insert(std::pair<A,B>(a,b));
+ right.insert(std::pair<B,A>(b,a));
+ }
+};
+
+#endif
diff --git a/g_src/command_line.cpp b/g_src/command_line.cpp
new file mode 100755
index 0000000..422f88f
--- /dev/null
+++ b/g_src/command_line.cpp
@@ -0,0 +1,132 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "basics.h"
+
+#include "command_line.h"
+
+void command_linest::init(const string &str)
+{
+ original=str;
+
+ //BUILD THE TOKEN LIST
+ long pos=0;
+ while(grab_arg(original,pos));
+
+ //HANDLE EACH TOKEN
+ long l;
+ for(l=0;l<arg_vect.str.size();l++)
+ {
+ handle_arg(arg_vect.str[l]->dat);
+ }
+}
+
+char command_linest::grab_arg(string &source,long &pos)
+{
+ string dest;
+
+ while(pos<source.length())
+ {
+ //HIT A NEW ARGUMENT? RETURN, OTHERWISE SKIP AND START UP
+ if(source[pos]=='-')
+ {
+ if(dest.empty()){pos++;continue;}
+ else
+ {
+ pos++;
+ arg_vect.add_string(dest);
+ return 1;
+ }
+ }
+
+ dest+=source[pos];
+
+ pos++;
+ }
+
+ if(!dest.empty())arg_vect.add_string(dest);
+ return 0;
+}
+
+void command_linest::handle_arg(string &arg)
+{
+ long pos=0;
+ string dest;
+
+ grab_token_string_pos(dest,arg,pos,' ');
+ pos+=dest.length();
+
+ short arg_pos=0;
+ if(dest=="gen")
+ {
+ //KEEP GOING FOR A NUMBER
+ while(pos+1<arg.length())
+ {
+ dest.erase();
+ pos++;
+ auto s=arg.begin(),e=arg.end();
+ s+=pos;
+ bool quote=false;
+ for(;s<e;++s)
+ {
+ if((*s)=='"')
+ {
+ if(quote)break;
+ else quote=true;
+ ++pos;
+ continue;
+ }
+ else if((*s)==' '&&!quote)break;
+ dest+=(*s);
+ }
+ pos+=dest.length();
+
+
+ if(!dest.empty())
+ {
+ if(arg_pos==0)gen_id=convert_string_to_long(dest);
+ if(arg_pos==1)
+ {
+ if(dest!="RANDOM")
+ {
+ world_seed=convert_string_to_ulong(dest);
+ use_seed=1;
+ }
+ }
+ if(arg_pos==2)
+ {
+ if(dest!="NONE")
+ {
+ world_param=dest;
+ use_param=1;
+ }
+ }
+
+ arg_pos++;
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/g_src/command_line.h b/g_src/command_line.h
new file mode 100755
index 0000000..e2606fb
--- /dev/null
+++ b/g_src/command_line.h
@@ -0,0 +1,25 @@
+class command_linest
+{
+ public:
+ string original;
+ stringvectst arg_vect;
+
+ long gen_id;
+ unsigned long world_seed;
+ char use_seed;
+ string world_param;
+ char use_param;
+
+
+
+ void init(const string &str);
+ char grab_arg(string &source,long &pos);
+ void handle_arg(string &arg);
+
+ command_linest()
+ {
+ gen_id=-1;
+ use_seed=0;
+ use_param=0;
+ }
+}; \ No newline at end of file
diff --git a/g_src/curses.h b/g_src/curses.h
new file mode 100755
index 0000000..1253f60
--- /dev/null
+++ b/g_src/curses.h
@@ -0,0 +1,28 @@
+#ifndef DF_CURSES_H
+#define DF_CURSES_H
+
+extern "C" {
+#include "GL/glew.h"
+#if defined(__unix__) || defined(__APPLE__)
+#ifdef __APPLE__
+# include "ncursesw/curses.h"
+#else
+# include <ncursesw/curses.h>
+#endif
+# undef COLOR_BLUE
+# undef COLOR_CYAN
+# undef COLOR_RED
+# undef COLOR_YELLOW
+# include <dlfcn.h>
+#endif
+}
+
+#if defined(__unix__) || defined(__APPLE__)
+extern "C" {
+ void init_curses();
+ extern WINDOW **stdscr_p;
+};
+#endif
+
+
+#endif
diff --git a/g_src/enabler.cpp b/g_src/enabler.cpp
new file mode 100755
index 0000000..282eb34
--- /dev/null
+++ b/g_src/enabler.cpp
@@ -0,0 +1,968 @@
+#ifdef __APPLE__
+# include "osx_messagebox.h"
+#elif defined(unix)
+# include <gtk/gtk.h>
+#endif
+
+#include <cassert>
+
+#include "platform.h"
+#include "enabler.h"
+#include "random.h"
+#include "init.h"
+#include "music_and_sound_g.h"
+
+#ifdef unix
+# include <locale.h>
+#endif
+
+using namespace std;
+
+enablerst enabler;
+
+
+// For the printGLError macro
+int glerrorcount = 0;
+
+// Set to 0 when the game wants to quit
+static int loopvar = 1;
+
+// Reports an error to the user, using a MessageBox and stderr.
+void report_error(const char *error_preface, const char *error_message)
+{
+ char *buf = NULL;
+ // +4 = +colon +space +newline +nul
+ buf = new char[strlen(error_preface) + strlen(error_message) + 4];
+ sprintf(buf, "%s: %s\n", error_preface, error_message);
+ MessageBox(NULL, buf, "Error", MB_OK);
+ fprintf(stderr, "%s", buf);
+ delete [] buf;
+}
+
+Either<texture_fullid,texture_ttfid> renderer::screen_to_texid(int x, int y) {
+ const int tile = x * gps.dimy + y;
+ const unsigned char *s = screen + tile*4;
+
+ struct texture_fullid ret;
+ int ch;
+ int bold;
+ int fg;
+ int bg;
+
+ // TTF text does not get the full treatment.
+ if (s[3] == GRAPHICSTYPE_TTF) {
+ texture_ttfid texpos = *((unsigned int *)s) & 0xffffff;
+ return Either<texture_fullid,texture_ttfid>(texpos);
+ } else if (s[3] == GRAPHICSTYPE_TTFCONT) {
+ // TTFCONT means this is a tile that does not have TTF anchored on it, but is covered by TTF.
+ // Since this may actually be stale information, we'll draw it as a blank space,
+ ch = 32;
+ fg = bg = bold = 0;
+ } else {
+ // Otherwise, it's a normal (graphical?) tile.
+ ch = s[0];
+ bold = (s[3] != 0) * 8;
+ fg = (s[1] + bold) % 16;
+ bg = s[2] % 16;
+ }
+
+ static bool use_graphics = init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS);
+
+ if (use_graphics) {
+ const long texpos = screentexpos[tile];
+ const char addcolor = screentexpos_addcolor[tile];
+ const unsigned char grayscale = screentexpos_grayscale[tile];
+ const unsigned char cf = screentexpos_cf[tile];
+ const unsigned char cbr = screentexpos_cbr[tile];
+
+ if (texpos) {
+ ret.texpos = texpos;
+ if (grayscale) {
+ ret.r = enabler.ccolor[cf][0];
+ ret.g = enabler.ccolor[cf][1];
+ ret.b = enabler.ccolor[cf][2];
+ ret.br = enabler.ccolor[cbr][0];
+ ret.bg = enabler.ccolor[cbr][1];
+ ret.bb = enabler.ccolor[cbr][2];
+ } else if (addcolor) {
+ goto use_ch;
+ } else {
+ ret.r = ret.g = ret.b = 1;
+ ret.br = ret.bg = ret.bb = 0;
+ }
+ goto skip_ch;
+ }
+ }
+
+ ret.texpos = enabler.is_fullscreen() ?
+ init.font.large_font_texpos[ch] :
+ init.font.small_font_texpos[ch];
+ use_ch:
+ ret.r = enabler.ccolor[fg][0];
+ ret.g = enabler.ccolor[fg][1];
+ ret.b = enabler.ccolor[fg][2];
+ ret.br = enabler.ccolor[bg][0];
+ ret.bg = enabler.ccolor[bg][1];
+ ret.bb = enabler.ccolor[bg][2];
+
+ skip_ch:
+
+ return Either<texture_fullid,texture_ttfid>(ret);
+}
+
+
+#ifdef CURSES
+# include "renderer_curses.cpp"
+#endif
+#include "renderer_2d.hpp"
+#include "renderer_opengl.hpp"
+
+
+enablerst::enablerst() {
+ fullscreen = false;
+ sync = NULL;
+ renderer = NULL;
+ calculated_fps = calculated_gfps = frame_sum = gframe_sum = frame_last = gframe_last = 0;
+ fps = 100; gfps = 20;
+ fps_per_gfps = fps / gfps;
+ last_tick = 0;
+}
+
+void renderer::display()
+{
+ const int dimx = init.display.grid_x;
+ const int dimy = init.display.grid_y;
+ static bool use_graphics = init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS);
+ if (gps.force_full_display_count) {
+ // Update the entire screen
+ update_all();
+ } else {
+ Uint32 *screenp = (Uint32*)screen, *oldp = (Uint32*)screen_old;
+ if (use_graphics) {
+ int off = 0;
+ for (int x2=0; x2 < dimx; x2++) {
+ for (int y2=0; y2 < dimy; y2++, ++off, ++screenp, ++oldp) {
+ // We don't use pointers for the non-screen arrays because we mostly fail at the
+ // *first* comparison, and having pointers for the others would exceed register
+ // count.
+ // Partial printing (and color-conversion): Big-ass if.
+ if (*screenp == *oldp &&
+ screentexpos[off] == screentexpos_old[off] &&
+ screentexpos_addcolor[off] == screentexpos_addcolor_old[off] &&
+ screentexpos_grayscale[off] == screentexpos_grayscale_old[off] &&
+ screentexpos_cf[off] == screentexpos_cf_old[off] &&
+ screentexpos_cbr[off] == screentexpos_cbr_old[off])
+ {
+ // Nothing's changed, this clause deliberately empty
+ } else {
+ update_tile(x2, y2);
+ }
+ }
+ }
+ } else {
+ for (int x2=0; x2 < dimx; ++x2) {
+ for (int y2=0; y2 < dimy; ++y2, ++screenp, ++oldp) {
+ if (*screenp != *oldp) {
+ update_tile(x2, y2);
+ }
+ }
+ }
+ }
+ }
+ if (gps.force_full_display_count > 0) gps.force_full_display_count--;
+}
+
+void renderer::cleanup_arrays() {
+ if (screen) delete[] screen;
+ if (screentexpos) delete[] screentexpos;
+ if (screentexpos_addcolor) delete[] screentexpos_addcolor;
+ if (screentexpos_grayscale) delete[] screentexpos_grayscale;
+ if (screentexpos_cf) delete[] screentexpos_cf;
+ if (screentexpos_cbr) delete[] screentexpos_cbr;
+ if (screen_old) delete[] screen_old;
+ if (screentexpos_old) delete[] screentexpos_old;
+ if (screentexpos_addcolor_old) delete[] screentexpos_addcolor_old;
+ if (screentexpos_grayscale_old) delete[] screentexpos_grayscale_old;
+ if (screentexpos_cf_old) delete[] screentexpos_cf_old;
+ if (screentexpos_cbr_old) delete[] screentexpos_cbr_old;
+}
+
+void renderer::gps_allocate(int x, int y) {
+ cleanup_arrays();
+
+ gps.screen = screen = new unsigned char[x*y*4];
+ memset(screen, 0, x*y*4);
+ gps.screentexpos = screentexpos = new long[x*y];
+ memset(screentexpos, 0, x*y*sizeof(long));
+ gps.screentexpos_addcolor = screentexpos_addcolor = new char[x*y];
+ memset(screentexpos_addcolor, 0, x*y);
+ gps.screentexpos_grayscale = screentexpos_grayscale = new unsigned char[x*y];
+ memset(screentexpos_grayscale, 0, x*y);
+ gps.screentexpos_cf = screentexpos_cf = new unsigned char[x*y];
+ memset(screentexpos_cf, 0, x*y);
+ gps.screentexpos_cbr = screentexpos_cbr = new unsigned char[x*y];
+ memset(screentexpos_cbr, 0, x*y);
+
+ screen_old = new unsigned char[x*y*4];
+ memset(screen_old, 0, x*y*4);
+ screentexpos_old = new long[x*y];
+ memset(screentexpos_old, 0, x*y*sizeof(long));
+ screentexpos_addcolor_old = new char[x*y];
+ memset(screentexpos_addcolor_old, 0, x*y);
+ screentexpos_grayscale_old = new unsigned char[x*y];
+ memset(screentexpos_grayscale_old, 0, x*y);
+ screentexpos_cf_old = new unsigned char[x*y];
+ memset(screentexpos_cf_old, 0, x*y);
+ screentexpos_cbr_old = new unsigned char[x*y];
+ memset(screentexpos_cbr_old, 0, x*y);
+
+ gps.resize(x,y);
+}
+
+void renderer::swap_arrays() {
+ screen = screen_old; screen_old = gps.screen; gps.screen = screen;
+ screentexpos = screentexpos_old; screentexpos_old = gps.screentexpos; gps.screentexpos = screentexpos;
+ screentexpos_addcolor = screentexpos_addcolor_old; screentexpos_addcolor_old = gps.screentexpos_addcolor; gps.screentexpos_addcolor = screentexpos_addcolor;
+ screentexpos_grayscale = screentexpos_grayscale_old; screentexpos_grayscale_old = gps.screentexpos_grayscale; gps.screentexpos_grayscale = screentexpos_grayscale;
+ screentexpos_cf = screentexpos_cf_old; screentexpos_cf_old = gps.screentexpos_cf; gps.screentexpos_cf = screentexpos_cf;
+ screentexpos_cbr = screentexpos_cbr_old; screentexpos_cbr_old = gps.screentexpos_cbr; gps.screentexpos_cbr = screentexpos_cbr;
+
+ gps.screen_limit = gps.screen + gps.dimx * gps.dimy * 4;
+}
+
+void enablerst::pause_async_loop() {
+ struct async_cmd cmd;
+ cmd.cmd = async_cmd::pause;
+ async_tobox.write(cmd);
+ async_wait();
+}
+
+// Wait until the previous command has been acknowledged, /or/
+// async_loop has quit. Incidentally execute any requests in the
+// meantime.
+void enablerst::async_wait() {
+ if (loopvar == 0) return;
+ async_msg r;
+ bool reset_textures = false;
+ for (;;) {
+ async_frombox.read(r);
+ switch (r.msg) {
+ case async_msg::quit:
+ loopvar = 0;
+ return;
+ case async_msg::complete:
+ if (reset_textures) {
+ puts("Resetting textures");
+ textures.remove_uploaded_textures();
+ textures.upload_textures();
+ }
+ return;
+ case async_msg::set_fps:
+ set_fps(r.fps);
+ async_fromcomplete.write();
+ break;
+ case async_msg::set_gfps:
+ set_gfps(r.fps);
+ async_fromcomplete.write();
+ break;
+ case async_msg::push_resize:
+ override_grid_size(r.x, r.y);
+ async_fromcomplete.write();
+ break;
+ case async_msg::pop_resize:
+ release_grid_size();
+ async_fromcomplete.write();
+ break;
+ case async_msg::reset_textures:
+ reset_textures = true;
+ break;
+ default:
+ puts("EMERGENCY: Unknown case in async_wait");
+ abort();
+ }
+ }
+}
+
+void enablerst::async_loop() {
+ async_paused = false;
+ async_frames = 0;
+ int total_frames = 0;
+ int fps = 100; // Just a thread-local copy
+ for (;;) {
+ // cout << "FRAMES: " << frames << endl;
+ // Check for commands
+ async_cmd cmd;
+ bool have_cmd = true;
+ do {
+ if (async_paused || (async_frames == 0 && !(enabler.flag & ENABLERFLAG_MAXFPS)))
+ async_tobox.read(cmd);
+ else
+ have_cmd = async_tobox.try_read(cmd);
+ // Obey the command, would you kindly.
+ if (have_cmd) {
+ switch (cmd.cmd) {
+ case async_cmd::pause:
+ async_paused = true;
+ // puts("Paused");
+ async_frombox.write(async_msg(async_msg::complete));
+ break;
+ case async_cmd::start:
+ async_paused = false;
+ async_frames = 0;
+ // puts("UNpaused");
+ break;
+ case async_cmd::render:
+ if (flag & ENABLERFLAG_RENDER) {
+ total_frames++;
+ renderer->swap_arrays();
+ if (total_frames % 1800 == 0)
+ ttf_manager.gc();
+ render_things();
+ flag &= ~ENABLERFLAG_RENDER;
+ update_gfps();
+ }
+ async_frombox.write(async_msg(async_msg::complete));
+ break;
+ case async_cmd::inc:
+ async_frames += cmd.val;
+ if (async_frames > fps*3) async_frames = fps*3; // Just in case
+ break;
+ case async_cmd::set_fps:
+ fps = cmd.val;
+ break;
+ }
+ }
+ } while (have_cmd);
+ // Run the main-loop, maybe
+ if (!async_paused && (async_frames || (enabler.flag & ENABLERFLAG_MAXFPS))) {
+ if (mainloop()) {
+ async_frombox.write(async_msg(async_msg::quit));
+ return; // We're done.
+ }
+ simticks.lock();
+ simticks.val++;
+ simticks.unlock();
+ async_frames--;
+ if (async_frames < 0) async_frames = 0;
+ update_fps();
+ }
+ SDL_NumJoysticks(); // Hook for dfhack
+ }
+}
+
+void enablerst::do_frame() {
+ // Check how long it's been, exactly
+ const Uint32 now = SDL_GetTicks();
+ const Uint32 interval = CLAMP(now - last_tick, 0, 1000); // Anything above a second doesn't count
+ // cout << last_tick << " + " << interval << " = " << now << endl;
+ last_tick = now;
+
+ // Update outstanding-frame counts
+ outstanding_frames += interval * fps / 1000;
+ outstanding_gframes += interval * gfps / 1000;
+ if (outstanding_gframes > 3) {
+ outstanding_gframes = 3;
+ }
+ // cout << outstanding_frames << " " << outstanding_gframes << endl;
+
+ // Update the loop's tick-counter suitably
+ if (outstanding_frames >= 1) {
+ async_cmd cmd(async_cmd::inc);
+ cmd.val = outstanding_frames;
+ outstanding_frames -= cmd.val;
+ async_tobox.write(cmd);
+ }
+
+ // Store the current time, for things that are fine with approximations
+ enabler.clock = SDL_GetTicks();
+
+ // If it's time to render..
+ if (outstanding_gframes >= 1 &&
+ (!sync || glClientWaitSync(sync, 0, 0) == GL_ALREADY_SIGNALED)) {
+ // Get the async-loop to render_things
+ async_cmd cmd(async_cmd::render);
+ async_tobox.write(cmd);
+ async_wait();
+ // Then finish here
+ renderer->display();
+ renderer->render();
+ gputicks.lock();
+ gputicks.val++;
+ gputicks.unlock();
+ outstanding_gframes--;
+ }
+
+ // Sleep until the next gframe
+ if (outstanding_gframes < 1) {
+ float fragment = 1 - outstanding_gframes;
+ float milliseconds = fragment / gfps * 1000;
+ // cout << milliseconds << endl;
+ SDL_Delay(milliseconds);
+ }
+}
+
+void enablerst::eventLoop_SDL()
+{
+
+ SDL_Event event;
+ const SDL_Surface *screen = SDL_GetVideoSurface();
+ Uint32 mouse_lastused = 0;
+ SDL_ShowCursor(SDL_DISABLE);
+
+ // Initialize the grid
+ renderer->resize(screen->w, screen->h);
+
+ while (loopvar) {
+ Uint32 now = SDL_GetTicks();
+ bool paused_loop = false;
+
+ // Check for zoom commands
+ zoom_commands zoom;
+ while (async_zoom.try_read(zoom)) {
+ if (overridden_grid_sizes.size())
+ continue; // No zooming in movies
+ if (!paused_loop) {
+ pause_async_loop();
+ paused_loop = true;
+ }
+ if (zoom == zoom_fullscreen)
+ renderer->set_fullscreen();
+ else
+ renderer->zoom(zoom);
+ }
+
+ // Check for SDL events
+ while (SDL_PollEvent(&event)) {
+ // Make sure mainloop isn't running while we're processing input
+ if (!paused_loop) {
+ pause_async_loop();
+ paused_loop = true;
+ }
+ // Handle SDL events
+ switch (event.type) {
+ case SDL_KEYDOWN:
+ // Disable mouse if it's been long enough
+ if (mouse_lastused + 5000 < now) {
+ if(init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_PICTURE)) {
+ // hide the mouse picture
+ // enabler.set_tile(0, TEXTURE_MOUSE, enabler.mouse_x, enabler.mouse_y);
+ }
+ SDL_ShowCursor(SDL_DISABLE);
+ }
+ case SDL_KEYUP:
+ case SDL_QUIT:
+ enabler.add_input(event, now);
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ case SDL_MOUSEBUTTONUP:
+ if (!init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_OFF)) {
+ int isdown = (event.type == SDL_MOUSEBUTTONDOWN);
+ if (event.button.button == SDL_BUTTON_LEFT) {
+ enabler.mouse_lbut = isdown;
+ enabler.mouse_lbut_down = isdown;
+ if (!isdown)
+ enabler.mouse_lbut_lift = 0;
+ } else if (event.button.button == SDL_BUTTON_RIGHT) {
+ enabler.mouse_rbut = isdown;
+ enabler.mouse_rbut_down = isdown;
+ if (!isdown)
+ enabler.mouse_rbut_lift = 0;
+ } else
+ enabler.add_input(event, now);
+ }
+ break;
+ case SDL_MOUSEMOTION:
+ // Deal with the mouse hiding bit
+ mouse_lastused = now;
+ if(init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_PICTURE)) {
+ // turn on mouse picture
+ // enabler.set_tile(gps.tex_pos[TEXTURE_MOUSE], TEXTURE_MOUSE,enabler.mouse_x, enabler.mouse_y);
+ } else {
+ SDL_ShowCursor(SDL_ENABLE);
+ }
+ break;
+ case SDL_ACTIVEEVENT:
+ enabler.clear_input();
+ if (event.active.state & SDL_APPACTIVE) {
+ if (event.active.gain) {
+ enabler.flag|=ENABLERFLAG_RENDER;
+ gps.force_full_display_count++;
+ }
+ }
+ break;
+ case SDL_VIDEOEXPOSE:
+ gps.force_full_display_count++;
+ enabler.flag|=ENABLERFLAG_RENDER;
+ break;
+ case SDL_VIDEORESIZE:
+ if (is_fullscreen());
+ //errorlog << "Caught resize event in fullscreen??\n";
+ else {
+ //gamelog << "Resizing window to " << event.resize.w << "x" << event.resize.h << endl << flush;
+ renderer->resize(event.resize.w, event.resize.h);
+ }
+ break;
+ } // switch (event.type)
+ } //while have event
+
+ // Update mouse state
+ if (!init.input.flag.has_flag(INIT_INPUT_FLAG_MOUSE_OFF)) {
+ int mouse_x = -1, mouse_y = -1, mouse_state;
+ // Check whether the renderer considers this valid input or not, and write it to gps
+ if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) &&
+ renderer->get_mouse_coords(mouse_x, mouse_y)) {
+ mouse_state = 1;
+ } else {
+ mouse_state = 0;
+ }
+ if (mouse_x != gps.mouse_x || mouse_y != gps.mouse_y ||
+ mouse_state != enabler.tracking_on) {
+ // Pause rendering loop and update values
+ if (!paused_loop) {
+ pause_async_loop();
+ paused_loop = true;
+ }
+ enabler.tracking_on = mouse_state;
+ gps.mouse_x = mouse_x;
+ gps.mouse_y = mouse_y;
+ }
+ }
+
+ if (paused_loop)
+ unpause_async_loop();
+
+ do_frame();
+#if !defined(NO_FMOD)
+ // Call FMOD::System.update(). Manages a bunch of sound stuff.
+ musicsound.update();
+#endif
+ }
+}
+
+int enablerst::loop(string cmdline) {
+ command_line = cmdline;
+
+ // Initialize the tick counters
+ simticks.write(0);
+ gputicks.write(0);
+
+ // Call DF's initialization routine
+ if (!beginroutine())
+ exit(EXIT_FAILURE);
+
+ // Allocate a renderer
+ if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) {
+#ifdef CURSES
+ renderer = new renderer_curses();
+#else
+ report_error("PRINT_MODE", "TEXT not supported on windows");
+ exit(EXIT_FAILURE);
+#endif
+ } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_2D)) {
+ renderer = new renderer_2d();
+ } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_ACCUM_BUFFER)) {
+ renderer = new renderer_accum_buffer();
+ } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_FRAME_BUFFER)) {
+ renderer = new renderer_framebuffer();
+ } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT)) {
+ if (init.display.partial_print_count)
+ renderer = new renderer_partial();
+ else
+ renderer = new renderer_once();
+ } else if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_VBO)) {
+ renderer = new renderer_vbo();
+ } else {
+ renderer = new renderer_opengl();
+ }
+
+ // At this point we should have a window that is setup to render DF.
+ if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) {
+#ifdef CURSES
+ eventLoop_ncurses();
+#endif
+ } else {
+ SDL_EnableUNICODE(1);
+ eventLoop_SDL();
+ }
+
+ endroutine();
+
+ // Clean up graphical resources
+ delete renderer;
+}
+
+void enablerst::override_grid_size(int x, int y) {
+ if (SDL_ThreadID() != renderer_threadid) {
+ // Ask the renderer to do it
+ async_msg m(async_msg::push_resize);
+ m.x = x; m.y = y;
+ async_frombox.write(m);
+ async_fromcomplete.read();
+ } else {
+ // We are the renderer; do it.
+ overridden_grid_sizes.push(make_pair(init.display.grid_x,init.display.grid_y));
+ renderer->grid_resize(x, y);
+ }
+}
+
+void enablerst::release_grid_size() {
+ if (SDL_ThreadID() != renderer_threadid) {
+ async_frombox.write(async_msg(async_msg::pop_resize));
+ async_fromcomplete.read();
+ } else {
+ if (!overridden_grid_sizes.size()) return;
+ // FIXME: Find out whatever is causing release to be called too rarely; right now
+ // we're overriding once per movie but apparently only releasing for the last one.
+ pair<int,int> sz;
+ while (overridden_grid_sizes.size()) {
+ sz = overridden_grid_sizes.top();
+ overridden_grid_sizes.pop();
+ }
+ zoom_display(zoom_resetgrid);
+ }
+}
+
+void enablerst::zoom_display(zoom_commands command) {
+ async_zoom.write(command);
+}
+
+int enablerst::calculate_fps() {
+ if (frame_timings.size() < 50)
+ return get_fps();
+ else
+ return calculated_fps;
+}
+int enablerst::calculate_gfps() {
+ if (gframe_timings.size() < 50)
+ return get_gfps();
+ else
+ return calculated_gfps;
+}
+
+void enablerst::do_update_fps(queue<int> &q, int &sum, int &last, int &calc) {
+ while (q.size() > 50 && sum > 10000) {
+ sum -= q.front();
+ q.pop();
+ }
+ const int now = SDL_GetTicks();
+ const int interval = now - last;
+ q.push(interval);
+ sum += interval;
+ last = now;
+ if (sum)
+ calc = q.size() * 1000 / sum;
+}
+
+void enablerst::clear_fps() {
+ while (frame_timings.size())
+ frame_timings.pop();
+ frame_sum = 0;
+ frame_last = SDL_GetTicks();
+ calculated_fps = get_fps();
+}
+
+void enablerst::update_fps() {
+ do_update_fps(frame_timings, frame_sum, frame_last, calculated_fps);
+}
+
+void enablerst::update_gfps() {
+ do_update_fps(gframe_timings, gframe_sum, gframe_last, calculated_gfps);
+}
+
+void enablerst::set_fps(int fps) {
+ if (SDL_ThreadID() != renderer_threadid) {
+ async_msg m(async_msg::set_fps);
+ m.fps = fps;
+ async_paused = true;
+ async_frombox.write(m);
+ async_fromcomplete.read();
+ } else {
+ if (fps == 0)
+ fps = 1048576;
+ this->fps = fps;
+ fps_per_gfps = fps / gfps;
+ struct async_cmd cmd;
+ cmd.cmd = async_cmd::set_fps;
+ cmd.val = fps;
+ async_tobox.write(cmd);
+ async_tobox.write(async_cmd(async_cmd::start));
+ }
+}
+
+void enablerst::set_gfps(int gfps) {
+ if (SDL_ThreadID() != renderer_threadid) {
+ async_msg m(async_msg::set_gfps);
+ m.fps = gfps;
+ async_frombox.write(m);
+ async_fromcomplete.read();
+ } else {
+ if (gfps == 0)
+ gfps = 50;
+ this->gfps = gfps;
+ fps_per_gfps = fps / gfps;
+ }
+}
+
+int call_loop(void *dummy) {
+ enabler.async_loop();
+ return 0;
+}
+
+int main (int argc, char* argv[]) {
+#ifdef unix
+ setlocale(LC_ALL, "");
+#endif
+#if !defined(__APPLE__) && defined(unix)
+ bool gtk_ok = false;
+ if (getenv("DISPLAY"))
+ gtk_ok = gtk_init_check(&argc, &argv);
+#endif
+
+ // Initialise minimal SDL subsystems.
+ int retval = SDL_Init(SDL_INIT_TIMER);
+ // Report failure?
+ if (retval != 0) {
+ report_error("SDL initialization failure", SDL_GetError());
+ return false;
+ }
+ enabler.renderer_threadid = SDL_ThreadID();
+
+ // Spawn simulation thread
+ SDL_CreateThread(call_loop, NULL);
+
+ init.begin(); // Load init.txt settings
+
+#if !defined(__APPLE__) && defined(unix)
+ if (!gtk_ok && !init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) {
+ puts("Display not found and PRINT_MODE not set to TEXT, aborting.");
+ exit(EXIT_FAILURE);
+ }
+ if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT) &&
+ init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS)) {
+ puts("Graphical tiles are not compatible with text output, sorry");
+ exit(EXIT_FAILURE);
+ }
+#endif
+
+ // Initialize video, if we /use/ video
+ retval = SDL_InitSubSystem(init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT) ? 0 : SDL_INIT_VIDEO);
+ if (retval != 0) {
+ report_error("SDL initialization failure", SDL_GetError());
+ return false;
+ }
+
+#ifdef linux
+ if (!init.media.flag.has_flag(INIT_MEDIA_FLAG_SOUND_OFF)) {
+ // Initialize OpenAL
+ if (!musicsound.initsound()) {
+ puts("Initializing OpenAL failed, no sound will be played");
+ init.media.flag.add_flag(INIT_MEDIA_FLAG_SOUND_OFF);
+ }
+ }
+#endif
+
+#ifdef WIN32
+ // Attempt to get as good a timer as possible
+ int ms = 1;
+ while (timeBeginPeriod(ms) != TIMERR_NOERROR) ms++;
+#endif
+
+ // Load keyboard map
+ keybinding_init();
+ enabler.load_keybindings("data/init/interface.txt");
+
+ string cmdLine;
+ for (int i = 1; i < argc; ++i) {
+ char *option = argv[i];
+ string opt=option;
+ if(opt.length()>=1)
+ {
+ //main removes quotes, unlike the winmain version, so it has to be rebuilt
+ if(opt[0]=='-')
+ {
+ cmdLine += opt;
+ cmdLine += " ";
+ }
+ else
+ {
+ cmdLine += "\"";
+ cmdLine += opt;
+ cmdLine += "\"";
+ cmdLine += " ";
+ }
+ }
+ }
+ int result = enabler.loop(cmdLine);
+
+ SDL_Quit();
+
+#ifdef WIN32
+ timeEndPeriod(ms);
+#endif
+
+ return result;
+}
+
+void text_system_file_infost::initialize_info()
+{
+ std::ifstream fseed(filename.c_str());
+ if(fseed.is_open())
+ {
+ string str;
+
+ while(std::getline(fseed,str))
+ {
+ if(str.length()>0)number++;
+ }
+ }
+ else
+ {
+ string str;
+ str="Error Initializing Text: ";
+ str+=filename;
+ errorlog_string(str);
+ }
+ fseed.close();
+}
+
+void text_system_file_infost::get_text(text_infost &text)
+{
+ text.clean();
+
+ if(number==0)return;
+
+ std::ifstream fseed(filename.c_str());
+ if(fseed.is_open())
+ {
+ string str;
+
+ int num=trandom(number);
+
+ //SKIP AHEAD TO THE RIGHT SPOT
+ while(num>0)
+ {
+ std::getline(fseed,str);
+ num--;
+ }
+
+ //PROCESS THE STRING INTO TEXT ELEMENTS
+ if(std::getline(fseed,str))
+ {
+ int curpos;
+ string nextstr;
+ char doing_long=0;
+
+ text_info_elementst *newel;
+ long end=str.length();
+
+ while(end>0)
+ {
+ if(isspace(str[end-1]))end--;
+ else break;
+ }
+
+ str.resize(end);
+
+ for(curpos=0;curpos<end;curpos++)
+ {
+ //HANDLE TOKEN OR ENDING
+ //TWO FILE TOKENS IN A ROW MEANS LONG
+ //ONE MEANS STRING
+ if(str[curpos]==file_token || curpos==end-1)
+ {
+ if(str[curpos]!=file_token)nextstr+=str[curpos];
+
+ //HAVE SOMETHING == SAVE IT
+ if(!nextstr.empty())
+ {
+ if(doing_long)
+ {
+ newel=new text_info_element_longst(atoi(nextstr.c_str()));
+ text.element.push_back(newel);
+ doing_long=0;
+ }
+ else
+ {
+ newel=new text_info_element_stringst(nextstr);
+ text.element.push_back(newel);
+ }
+
+ nextstr.erase();
+ }
+ //STARTING A LONG
+ else
+ {
+ doing_long=1;
+ }
+ }
+ //JUST ADD IN ANYTHING ELSE
+ else
+ {
+ nextstr+=str[curpos];
+ }
+ }
+ }
+ }
+ fseed.close();
+}
+
+void curses_text_boxst::add_paragraph(const string &src,int32_t para_width)
+{
+ stringvectst sp;
+ sp.add_string(src);
+ add_paragraph(sp,para_width);
+}
+
+void curses_text_boxst::add_paragraph(stringvectst &src,int32_t para_width)
+{
+ bool skip_leading_spaces=false;
+
+ //ADD EACH OF THE STRINGS ON IN TURN
+ string curstr;
+ long strlength=0;
+ long s,pos;
+ for(s=0;s<src.str.size();s++)
+ {
+ //GRAB EACH WORD, AND SEE IF IT FITS, IF NOT START A NEW LINE
+ for(pos=0;pos<src.str[s]->dat.size();pos++)
+ {
+ if(skip_leading_spaces)
+ {
+ if(src.str[s]->dat[pos]==' ')continue;
+ else skip_leading_spaces=false;
+ }
+
+ //ADD TO WORD
+ curstr+=src.str[s]->dat[pos];
+
+ //IF TOO LONG, CUT BACK TO FIRST SPACE
+ if(curstr.length()>para_width)
+ {
+ long opos=pos;
+
+ long minus=0;
+ do
+ {
+ pos--;
+ minus++;
+ }while(src.str[s]->dat[pos]!=' '&&pos>0);
+
+ //IF WENT ALL THE WAY BACK, INTRODUCE A SPACE
+ if(minus==curstr.size())
+ {
+ src.str[s]->dat.insert(opos-1," ");
+ }
+ else
+ {
+ curstr.resize(curstr.size()-minus);
+ text.add_string(curstr);
+ skip_leading_spaces=true;
+ }
+ curstr.erase();
+ }
+ }
+ }
+
+ //FLUSH FINAL BIT
+ if(!curstr.empty())text.add_string(curstr);
+}
diff --git a/g_src/enabler.h b/g_src/enabler.h
new file mode 100755
index 0000000..f524e1d
--- /dev/null
+++ b/g_src/enabler.h
@@ -0,0 +1,1027 @@
+//some of this stuff is based on public domain code from nehe or opengl books over the years
+//additions and modifications Copyright (c) 2008, Tarn Adams
+//All rights reserved. See game.cpp or license.txt for more information.
+
+#ifndef ENABLER_H
+#define ENABLER_H
+
+#include "platform.h"
+#include <SDL/SDL.h>
+#include <SDL/SDL_thread.h>
+#ifdef __APPLE__
+# include <SDL_ttf/SDL_ttf.h>
+# include <SDL_image/SDL_image.h>
+#else
+# include <SDL/SDL_ttf.h>
+# include <SDL/SDL_image.h>
+#endif
+
+#include "GL/glew.h"
+
+#include <map>
+#include <vector>
+#include <algorithm>
+#include <utility>
+#include <list>
+#include <iostream>
+#include <sstream>
+#include <stack>
+#include <queue>
+#include <set>
+#include <functional>
+
+using std::vector;
+using std::pair;
+using std::map;
+using std::set;
+using std::list;
+using std::stack;
+using std::queue;
+
+#include "basics.h"
+#include "svector.h"
+#include "endian.h"
+#include "files.h"
+#include "enabler_input.h"
+#include "mail.hpp"
+
+#define ENABLER
+
+#ifndef BITS
+
+#define BITS
+
+#define BIT1 1
+#define BIT2 2
+#define BIT3 4
+#define BIT4 8
+#define BIT5 16
+#define BIT6 32
+#define BIT7 64
+#define BIT8 128
+#define BIT9 256
+#define BIT10 512
+#define BIT11 1024
+#define BIT12 2048
+#define BIT13 4096
+#define BIT14 8192
+#define BIT15 16384
+#define BIT16 32768
+#define BIT17 65536UL
+#define BIT18 131072UL
+#define BIT19 262144UL
+#define BIT20 524288UL
+#define BIT21 1048576UL
+#define BIT22 2097152UL
+#define BIT23 4194304UL
+#define BIT24 8388608UL
+#define BIT25 16777216UL
+#define BIT26 33554432UL
+#define BIT27 67108864UL
+#define BIT28 134217728UL
+#define BIT29 268435456UL
+#define BIT30 536870912UL
+#define BIT31 1073741824UL
+#define BIT32 2147483648UL
+
+#endif
+
+#define GAME_TITLE_STRING "Dwarf Fortress"
+
+class pstringst
+{
+ public:
+ string dat;
+};
+
+class stringvectst
+{
+ public:
+ svector<pstringst *> str;
+
+ void add_string(const string &st)
+ {
+ pstringst *newp=new pstringst;
+ newp->dat=st;
+ str.push_back(newp);
+ }
+
+ long add_unique_string(const string &st)
+ {
+ long i;
+ for(i=(long)str.size()-1;i>=0;i--)
+ {
+ if(str[i]->dat==st)return i;
+ }
+ add_string(st);
+ return (long)str.size()-1;
+ }
+
+ void add_string(const char *st)
+ {
+ if(st!=NULL)
+ {
+ pstringst *newp=new pstringst;
+ newp->dat=st;
+ str.push_back(newp);
+ }
+ }
+
+ void insert_string(long k,const string &st)
+ {
+ pstringst *newp=new pstringst;
+ newp->dat=st;
+ if(str.size()>k)str.insert(k,newp);
+ else str.push_back(newp);
+ }
+
+ ~stringvectst()
+ {
+ clean();
+ }
+
+ void clean()
+ {
+ while(str.size()>0)
+ {
+ delete str[0];
+ str.erase(0);
+ }
+ }
+
+ void read_file(file_compressorst &filecomp,long loadversion)
+ {
+ long dummy;
+ filecomp.read_file(dummy);
+ str.resize(dummy);
+
+ long s;
+ for(s=0;s<dummy;s++)
+ {
+ str[s]=new pstringst;
+ filecomp.read_file(str[s]->dat);
+ }
+ }
+ void write_file(file_compressorst &filecomp)
+ {
+ long dummy=str.size();
+ filecomp.write_file(dummy);
+
+ long s;
+ for(s=0;s<dummy;s++)
+ {
+ filecomp.write_file(str[s]->dat);
+ }
+ }
+
+ void copy_from(stringvectst &src)
+ {
+ clean();
+
+ str.resize(src.str.size());
+
+ long s;
+ for(s=(long)src.str.size()-1;s>=0;s--)
+ {
+ str[s]=new pstringst;
+ str[s]->dat=src.str[s]->dat;
+ }
+ }
+
+ bool has_string(const string &st)
+ {
+ long i;
+ for(i=(long)str.size()-1;i>=0;i--)
+ {
+ if(str[i]->dat==st)return true;
+ }
+ return false;
+ }
+
+ void remove_string(const string &st)
+ {
+ long i;
+ for(i=(long)str.size()-1;i>=0;i--)
+ {
+ if(str[i]->dat==st)
+ {
+ delete str[i];
+ str.erase(i);
+ }
+ }
+ }
+
+ void operator=(stringvectst &two);
+};
+
+class flagarrayst
+{
+ public:
+ flagarrayst()
+ {
+ slotnum=0;
+ array=NULL;
+ }
+ ~flagarrayst()
+ {
+ if(array!=NULL)delete[] array;
+ array=NULL;
+ slotnum=0;
+ }
+
+ void set_size_on_flag_num(long flagnum)
+ {
+ if(flagnum<=0)return;
+
+ set_size(((flagnum-1)>>3)+1);
+ }
+
+ void set_size(long newsize)
+ {
+ if(newsize<=0)return;
+
+ if(array!=NULL)delete[] array;
+ array=new unsigned char[newsize];
+ memset(array,0,sizeof(unsigned char)*newsize);
+
+ slotnum=newsize;
+ }
+
+ void clear_all()
+ {
+ if(slotnum<=0)return;
+
+ if(array!=NULL)memset(array,0,sizeof(unsigned char)*slotnum);
+ }
+
+ void copy_from(flagarrayst &src)
+ {
+ clear_all();
+
+ if(src.slotnum>0)
+ {
+ set_size(src.slotnum);
+ memmove(array,src.array,sizeof(unsigned char)*slotnum);
+ }
+ }
+
+ bool has_flag(long checkflag)
+ {
+ if(checkflag<0)return false;
+ long slot=checkflag>>3;
+ return (slot>=0&&slot<slotnum&&((array[slot] & (1<<(checkflag&7)))!=0));
+ }
+
+ void add_flag(long checkflag)
+ {
+ if(checkflag<0)return;
+ long slot=checkflag>>3;
+ if(slot>=0&&slot<slotnum)array[slot]|=(1<<(checkflag&7));
+ }
+
+ void toggle_flag(long checkflag)
+ {
+ if(checkflag<0)return;
+ long slot=checkflag>>3;
+ if(slot>=0&&slot<slotnum)array[slot]^=(1<<(checkflag&7));
+ }
+
+ void remove_flag(long checkflag)
+ {
+ if(checkflag<0)return;
+ long slot=checkflag>>3;
+ if(slot>=0&&slot<slotnum)array[slot]&=~(1<<(checkflag&7));
+ }
+
+ void write_file(file_compressorst &filecomp)
+ {
+ filecomp.write_file(slotnum);
+ if(slotnum>0)
+ {
+ long ind;
+ for(ind=0;ind<slotnum;ind++)filecomp.write_file(array[ind]);
+ }
+ }
+
+ void read_file(file_compressorst &filecomp,long loadversion)
+ {
+ long newsl;
+ filecomp.read_file(newsl);
+ if(newsl>0)
+ {
+ //AVOID UNNECESSARY DELETE/NEW
+ if(array!=NULL&&slotnum!=newsl)
+ {
+ delete[] array;
+ array=new unsigned char[newsl];
+ }
+ if(array==NULL)array=new unsigned char[newsl];
+
+ long ind;
+ for(ind=0;ind<newsl;ind++)filecomp.read_file(array[ind]);
+
+ slotnum=newsl;
+ }
+ else if(array!=NULL)
+ {
+ delete[] array;
+ array=NULL;
+
+ slotnum=0;
+ }
+ }
+
+ private:
+ unsigned char *array;
+ long slotnum;
+};
+
+#ifdef ENABLER
+
+#define COLOR_BLACK 0
+#define COLOR_BLUE 1
+#define COLOR_GREEN 2
+#define COLOR_CYAN 3
+#define COLOR_RED 4
+#define COLOR_MAGENTA 5
+#define COLOR_YELLOW 6
+#define COLOR_WHITE 7
+
+enum ColorData
+ {
+ COLOR_DATA_WHITE_R,
+ COLOR_DATA_WHITE_G,
+ COLOR_DATA_WHITE_B,
+ COLOR_DATA_RED_R,
+ COLOR_DATA_RED_G,
+ COLOR_DATA_RED_B,
+ COLOR_DATA_GREEN_R,
+ COLOR_DATA_GREEN_G,
+ COLOR_DATA_GREEN_B,
+ COLOR_DATA_BLUE_R,
+ COLOR_DATA_BLUE_G,
+ COLOR_DATA_BLUE_B,
+ COLOR_DATA_YELLOW_R,
+ COLOR_DATA_YELLOW_G,
+ COLOR_DATA_YELLOW_B,
+ COLOR_DATA_MAGENTA_R,
+ COLOR_DATA_MAGENTA_G,
+ COLOR_DATA_MAGENTA_B,
+ COLOR_DATA_CYAN_R,
+ COLOR_DATA_CYAN_G,
+ COLOR_DATA_CYAN_B,
+ COLOR_DATANUM
+ };
+
+#define TILEFLAG_DEAD BIT1
+#define TILEFLAG_ROTATE BIT2
+#define TILEFLAG_PIXRECT BIT3
+#define TILEFLAG_HORFLIP BIT4
+#define TILEFLAG_VERFLIP BIT5
+#define TILEFLAG_LINE BIT6
+#define TILEFLAG_RECT BIT7
+#define TILEFLAG_BUFFER_DRAW BIT8
+#define TILEFLAG_MODEL_PERSPECTIVE BIT9
+#define TILEFLAG_MODEL_ORTHO BIT10
+#define TILEFLAG_MODEL_TRANSLATE BIT11
+#define TILEFLAG_LINE_3D BIT12
+
+#define TRIMAX 9999
+
+enum render_phase {
+ setup, // 0
+ complete,
+ phase_count
+};
+
+class texture_bo {
+ GLuint bo, tbo;
+ public:
+ texture_bo() { bo = tbo = 0; }
+ void reset() {
+ if (bo) {
+ glDeleteBuffers(1, &bo);
+ glDeleteTextures(1, &tbo);
+ bo = tbo = 0;
+ printGLError();
+ }
+ }
+ void buffer(GLvoid *ptr, GLsizeiptr sz) {
+ if (bo) reset();
+ glGenBuffersARB(1, &bo);
+ glGenTextures(1, &tbo);
+ glBindBufferARB(GL_TEXTURE_BUFFER_ARB, bo);
+ glBufferDataARB(GL_TEXTURE_BUFFER_ARB, sz, ptr, GL_STATIC_DRAW_ARB);
+ printGLError();
+ }
+ void bind(GLenum texture_unit, GLenum type) {
+ glActiveTexture(texture_unit);
+ glBindTexture(GL_TEXTURE_BUFFER_ARB, tbo);
+ glTexBufferARB(GL_TEXTURE_BUFFER_ARB, type, bo);
+ printGLError();
+ }
+ GLuint texnum() { return tbo; }
+};
+
+
+class shader {
+ string filename;
+ std::ostringstream lines;
+ public:
+ std::ostringstream header;
+ void load(const string &filename) {
+ this->filename = filename;
+ std::ifstream file(filename.c_str());
+ string version;
+ getline(file, version);
+ header << version << std::endl;
+ while (file.good()) {
+ string line;
+ getline(file, line);
+ lines << line << std::endl;
+ }
+ file.close();
+ }
+ GLuint upload(GLenum type) {
+ GLuint shader = glCreateShader(type);
+ string lines_done = lines.str(), header_done = header.str();
+ const char *ptrs[3];
+ ptrs[0] = header_done.c_str();
+ ptrs[1] = "#line 1 0\n";
+ ptrs[2] = lines_done.c_str();
+ glShaderSource(shader, 3, ptrs, NULL);
+ glCompileShader(shader);
+ // Let's see if this compiled correctly..
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (status == GL_FALSE) { // ..no. Check the compilation log.
+ GLint log_size;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_size);
+ //errorlog << filename << " preprocessed source:" << std::endl;
+ std::cerr << filename << " preprocessed source:" << std::endl;
+ //errorlog << header_done << "#line 1 0\n" << lines_done;
+ std::cerr << header_done << "#line 1 0\n" << lines_done;
+ //errorlog << filename << " shader compilation log (" << log_size << "):" << std::endl;
+ std::cerr << filename << " shader compilation log (" << log_size << "):" << std::endl;
+ char *buf = new char[log_size];
+ glGetShaderInfoLog(shader, log_size, NULL, buf);
+ //errorlog << buf << std::endl;
+ std::cerr << buf << std::endl;
+ //errorlog.flush();
+ delete[] buf;
+ MessageBox(NULL, "Shader compilation failed; details in errorlog.txt", "Critical error", MB_OK);
+ abort();
+ }
+ printGLError();
+ return shader;
+ }
+};
+
+
+class text_info_elementst
+{
+ public:
+ virtual string get_string()
+ {
+ string empty;
+ return empty;
+ }
+ virtual long get_long()
+ {
+ return 0;
+ }
+
+ virtual ~text_info_elementst(){}
+};
+
+class text_info_element_stringst : public text_info_elementst
+{
+ public:
+ virtual string get_string()
+ {
+ return str;
+ }
+ text_info_element_stringst(const string &newstr)
+ {
+ str=newstr;
+ }
+
+ protected:
+ string str;
+};
+
+class text_info_element_longst : public text_info_elementst
+{
+ public:
+ virtual long get_long()
+ {
+ return val;
+ }
+ text_info_element_longst(long nval)
+ {
+ val=nval;
+ }
+
+ protected:
+ long val;
+};
+
+class text_infost
+{
+ public:
+ svector<text_info_elementst *> element;
+
+ void clean()
+ {
+ while(element.size()>0)
+ {
+ delete element[0];
+ element.erase(0);
+ }
+ }
+
+ string get_string(int e)
+ {
+ if(e<0||e>=element.size())
+ {
+ string empty;
+ return empty;
+ }
+ if(element[e]==NULL)
+ {
+ string empty;
+ return empty;
+ }
+ return element[e]->get_string();
+ }
+
+ long get_long(int e)
+ {
+ if(e<0||e>=element.size())
+ {
+ return 0;
+ }
+ if(element[e]==NULL)
+ {
+ return 0;
+ }
+ return element[e]->get_long();
+ }
+
+ ~text_infost()
+ {
+ clean();
+ }
+};
+
+class text_system_file_infost
+{
+ public:
+ long index;
+ string filename;
+
+ static text_system_file_infost *add_file_info(const string &newf,long newi,char newft)
+ {
+ return new text_system_file_infost(newf,newi,newft);
+ }
+
+ void initialize_info();
+ void get_text(text_infost &text);
+ void get_specific_text(text_infost &text,long num);
+
+ protected:
+ char file_token;
+ long number;
+
+ text_system_file_infost(const string &newf,long newi,char newft)
+ {
+ filename=newf;
+ file_token=newft;
+ index=newi;
+ number=0;
+ }
+};
+
+class text_systemst
+{
+ public:
+ void register_file_fixed(const string &file_name,int32_t index,char token,char initialize)
+ {
+ text_system_file_infost *tsfi=text_system_file_infost::add_file_info(file_name,index,token);
+ if(initialize)tsfi->initialize_info();
+ file_info.push_back(tsfi);
+ }
+ void register_file(const string &file_name,int32_t &index,char token,char initialize)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->filename==file_name)
+ {
+ //RESET CALLING INDEX AND BAIL IF THIS FILE IS ALREADY IN THE SYSTEM
+ index=file_info[t]->index;
+ return;
+ }
+ }
+
+ text_system_file_infost *tsfi=text_system_file_infost::add_file_info(file_name,index,token);
+ if(initialize)tsfi->initialize_info();
+ file_info.push_back(tsfi);
+ }
+ void initialize_system()
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)file_info[t]->initialize_info();
+ }
+ void get_text(int32_t index,text_infost &text)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->index==index)
+ {
+ file_info[t]->get_text(text);
+ return;
+ }
+ }
+ }
+ void get_text(const string &file_name,text_infost &text)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->filename==file_name)
+ {
+ file_info[t]->get_text(text);
+ return;
+ }
+ }
+ }
+ void get_specific_text(int32_t index,text_infost &text,int32_t num)
+ {
+ int32_t t;
+ for(t=(int32_t)file_info.size()-1;t>=0;t--)
+ {
+ if(file_info[t]->index==index)
+ {
+ file_info[t]->get_specific_text(text,num);
+ return;
+ }
+ }
+ }
+
+ ~text_systemst()
+ {
+ while(file_info.size()>0)
+ {
+ delete file_info[0];
+ file_info.erase(0);
+ }
+ }
+
+ protected:
+ svector<text_system_file_infost *> file_info;
+};
+
+class curses_text_boxst
+{
+ public:
+ stringvectst text;
+
+ void add_paragraph(stringvectst &src,int32_t para_width);
+ void add_paragraph(const string &src,int32_t para_width);
+
+ void read_file(file_compressorst &filecomp,int32_t loadversion)
+ {
+ text.read_file(filecomp,loadversion);
+ }
+ void write_file(file_compressorst &filecomp)
+ {
+ text.write_file(filecomp);
+ }
+ void clean()
+ {
+ text.clean();
+ }
+};
+
+#define COPYTEXTUREFLAG_HORFLIP BIT1
+#define COPYTEXTUREFLAG_VERFLIP BIT2
+
+#define ENABLERFLAG_RENDER BIT1
+#define ENABLERFLAG_MAXFPS BIT2
+
+// GL texture positions
+struct gl_texpos {
+ GLfloat left, right, top, bottom;
+};
+
+// Covers every allowed permutation of text
+struct ttf_id {
+ std::string text;
+ unsigned char fg, bg, bold;
+
+ bool operator< (const ttf_id &other) const {
+ if (fg != other.fg) return fg < other.fg;
+ if (bg != other.bg) return bg < other.bg;
+ if (bold != other.bold) return bold < other.bold;
+ return text < other.text;
+ }
+
+ bool operator== (const ttf_id &other) const {
+ return fg == other.fg && bg == other.bg && bold == other.bold && text == other.text;
+ }
+};
+
+namespace std {
+ template<> struct hash<ttf_id> {
+ size_t operator()(ttf_id val) const {
+ // Not the ideal hash function, but it'll do. And it's better than GCC's. id? Seriously?
+ return hash<string>()(val.text) + val.fg + (val.bg << 4) + (val.bold << 8);
+ }
+ };
+};
+
+// Being a texture catalog interface, with opengl, sdl and truetype capability
+class textures
+{
+ friend class enablerst;
+ friend class renderer_opengl;
+ private:
+ vector<SDL_Surface *> raws;
+ bool uploaded;
+ long add_texture(SDL_Surface*);
+ protected:
+ GLuint gl_catalog; // texture catalog gennum
+ struct gl_texpos *gl_texpos; // Texture positions in the GL catalog, if any
+ public:
+ // Initialize state variables
+ textures() {
+ uploaded = false;
+ gl_texpos = NULL;
+ }
+ ~textures() {
+ for (auto it = raws.cbegin(); it != raws.cend(); ++it)
+ SDL_FreeSurface(*it);
+}
+ int textureCount() {
+ return raws.size();
+ }
+ // Upload in-memory textures to the GPU
+ // When textures are uploaded, any alteration to a texture
+ // is automatically reflected in the uploaded copy - eg. it's replaced.
+ // This is very expensive in opengl mode. Don't do it often.
+ void upload_textures();
+ // Also, you really should try to remove uploaded textures before
+ // deleting a window, in case of driver memory leaks.
+ void remove_uploaded_textures();
+ // Returns the most recent texture data
+ SDL_Surface *get_texture_data(long pos);
+ // Clone a texture
+ long clone_texture(long src);
+ // Remove all color, but not transparency
+ void grayscale_texture(long pos);
+ // Loads dimx*dimy textures from a file, assuming all tiles
+ // are equally large and arranged in a grid
+ // Texture positions are saved in row-major order to tex_pos
+ // If convert_magenta is true and the file does not have built-in transparency,
+ // any magenta (255,0,255 RGB) is converted to full transparency
+ // The calculated size of individual tiles is saved to disp_x, disp_y
+ void load_multi_pdim(const string &filename,long *tex_pos,long dimx,long dimy,
+ bool convert_magenta,
+ long *disp_x, long *disp_y);
+ // Loads a single texture from a file, returning the handle
+ long load(const string &filename, bool convert_magenta);
+ // To delete a texture..
+ void delete_texture(long pos);
+};
+
+struct tile {
+ int x, y;
+ long tex;
+};
+
+typedef struct { // Window Creation Info
+ char* title; // Window Title
+ int width; // Width
+ int height; // Height
+ int bitsPerPixel; // Bits Per Pixel
+ BOOL isFullScreen; // FullScreen?
+} GL_WindowInit; // GL_WindowInit
+
+typedef struct { // Contains Information Vital To A Window
+ GL_WindowInit init; // Window Init
+ BOOL isVisible; // Window Visible?
+} GL_Window; // GL_Window
+
+enum zoom_commands { zoom_in, zoom_out, zoom_reset, zoom_fullscreen, zoom_resetgrid };
+
+
+struct texture_fullid {
+ int texpos;
+ float r, g, b;
+ float br, bg, bb;
+
+ bool operator< (const struct texture_fullid &other) const {
+ if (texpos != other.texpos) return texpos < other.texpos;
+ if (r != other.r) return r < other.r;
+ if (g != other.g) return g < other.g;
+ if (b != other.b) return b < other.b;
+ if (br != other.br) return br < other.br;
+ if (bg != other.bg) return bg < other.bg;
+ return bb < other.bb;
+ }
+};
+
+typedef int texture_ttfid; // Just the texpos
+
+class renderer {
+ void cleanup_arrays();
+ protected:
+ unsigned char *screen;
+ long *screentexpos;
+ char *screentexpos_addcolor;
+ unsigned char *screentexpos_grayscale;
+ unsigned char *screentexpos_cf;
+ unsigned char *screentexpos_cbr;
+ // For partial printing:
+ unsigned char *screen_old;
+ long *screentexpos_old;
+ char *screentexpos_addcolor_old;
+ unsigned char *screentexpos_grayscale_old;
+ unsigned char *screentexpos_cf_old;
+ unsigned char *screentexpos_cbr_old;
+
+ void gps_allocate(int x, int y);
+ Either<texture_fullid,texture_ttfid> screen_to_texid(int x, int y);
+ public:
+ void display();
+ virtual void update_tile(int x, int y) = 0;
+ virtual void update_all() = 0;
+ virtual void render() = 0;
+ virtual void set_fullscreen() {} // Should read from enabler.is_fullscreen()
+ virtual void zoom(zoom_commands cmd) {};
+ virtual void resize(int w, int h) = 0;
+ virtual void grid_resize(int w, int h) = 0;
+ void swap_arrays();
+ renderer() {
+ screen = NULL;
+ screentexpos = NULL;
+ screentexpos_addcolor = NULL;
+ screentexpos_grayscale = NULL;
+ screentexpos_cf = NULL;
+ screentexpos_cbr = NULL;
+ screen_old = NULL;
+ screentexpos_old = NULL;
+ screentexpos_addcolor_old = NULL;
+ screentexpos_grayscale_old = NULL;
+ screentexpos_cf_old = NULL;
+ screentexpos_cbr_old = NULL;
+ }
+ virtual ~renderer() {
+ cleanup_arrays();
+ }
+ virtual bool get_mouse_coords(int &x, int &y) = 0;
+ virtual bool uses_opengl() { return false; };
+};
+
+class enablerst : public enabler_inputst
+{
+ friend class initst;
+ friend class renderer_2d_base;
+ friend class renderer_2d;
+ friend class renderer_opengl;
+ friend class renderer_curses;
+
+ bool fullscreen;
+ stack<pair<int,int> > overridden_grid_sizes;
+
+ class renderer *renderer;
+ void eventLoop_SDL();
+#ifdef CURSES
+ void eventLoop_ncurses();
+#endif
+
+ // Framerate calculations
+ int calculated_fps, calculated_gfps;
+ queue<int> frame_timings, gframe_timings; // Milisecond lengths of the last few frames
+ int frame_sum, gframe_sum;
+ int frame_last, gframe_last; // SDL_GetTick returns
+ void do_update_fps(queue<int> &q, int &sum, int &last, int &calc);
+
+ public:
+ void clear_fps();
+ private:
+ void update_fps();
+ void update_gfps();
+
+ // Frame timing calculations
+ float fps, gfps;
+ float fps_per_gfps;
+ Uint32 last_tick;
+ float outstanding_frames, outstanding_gframes;
+
+ // Async rendering
+ struct async_cmd {
+ enum cmd_t { pause, start, render, inc, set_fps } cmd;
+ int val; // If async_inc, number of extra frames to run. If set_fps, current value of fps.
+ async_cmd() {}
+ async_cmd(cmd_t c) { cmd = c; }
+ };
+
+ struct async_msg {
+ enum msg_t { quit, complete, set_fps, set_gfps, push_resize, pop_resize, reset_textures } msg;
+ union {
+ int fps; // set_fps, set_gfps
+ struct { // push_resize
+ int x, y;
+ };
+ };
+ async_msg() {}
+ async_msg(msg_t m) { msg = m; }
+ };
+
+ unsigned int async_frames; // Number of frames the async thread has been asked to run
+ bool async_paused;
+ Chan<async_cmd> async_tobox; // Messages to the simulation thread
+ Chan<async_msg> async_frombox; // Messages from the simulation thread, and acknowledgements of those to
+ Chan<zoom_commands> async_zoom; // Zoom commands (from the simulation thread)
+ Chan<void> async_fromcomplete; // Barrier for async_msg requests that require acknowledgement
+ public:
+ Uint32 renderer_threadid;
+ private:
+
+ void pause_async_loop();
+ void async_wait();
+ void unpause_async_loop() {
+ struct async_cmd cmd;
+ cmd.cmd = async_cmd::start;
+ async_tobox.write(cmd);
+ }
+
+ public:
+
+ string command_line;
+
+ float ccolor[16][3]; // The curses-RGB mapping used for non-curses display modes
+
+ enablerst();
+ unsigned long flag; // ENABLERFLAG_RENDER, ENABLERFLAG_MAXFPS
+
+ int loop(string cmdline);
+ void async_loop();
+ void do_frame();
+
+ // Framerate interface
+ void set_fps(int fps);
+ void set_gfps(int gfps);
+ int get_fps() { return (int)fps; }
+ int get_gfps() { return (int)gfps; }
+ int calculate_fps(); // Calculate the actual provided (G)FPS
+ int calculate_gfps();
+
+ // Mouse interface, such as it is
+ char mouse_lbut,mouse_rbut,mouse_lbut_down,mouse_rbut_down,mouse_lbut_lift,mouse_rbut_lift;
+ char tracking_on; // Whether we're tracking the mouse or not
+
+ // OpenGL state (wrappers)
+ class textures textures; // Font/graphics texture catalog
+ GLsync sync; // Rendering barrier
+ void reset_textures() {
+ async_frombox.write(async_msg(async_msg::reset_textures));
+ }
+ bool uses_opengl() {
+ if (!renderer) return false;
+ return renderer->uses_opengl();
+ }
+
+ // Grid-size interface
+ void override_grid_size(int w, int h); // Pick a /particular/ grid-size
+ void release_grid_size(); // Undoes override_grid_size
+ void zoom_display(zoom_commands command);
+
+
+ // Window management
+ bool is_fullscreen() { return fullscreen; }
+ void toggle_fullscreen() {
+ fullscreen = !fullscreen;
+ async_zoom.write(zoom_fullscreen);
+ }
+
+ // Conversations
+ text_systemst text_system;
+
+ // TOADY: MOVE THESE TO "FRAMERATE INTERFACE"
+ MVar<int> simticks, gputicks;
+ Uint32 clock; // An *approximation* of the current time for use in garbage collection thingies, updated every frame or so.
+};
+#endif
+
+// Function prototypes for deep-DF calls
+char beginroutine();
+char mainloop();
+void endroutine();
+
+extern enablerst enabler;
+
+#endif //ENABLER_H
diff --git a/g_src/enabler_input.cpp b/g_src/enabler_input.cpp
new file mode 100755
index 0000000..e16486d
--- /dev/null
+++ b/g_src/enabler_input.cpp
@@ -0,0 +1,1095 @@
+#include <SDL/SDL.h>
+#include <map>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <stdlib.h>
+#include <math.h>
+using namespace std;
+
+#include "enabler_input.h"
+#include "init.h"
+extern initst init;
+#include "platform.h"
+#include "files.h"
+#include "find_files.h"
+#include "svector.h"
+#include "curses.h"
+
+// The timeline events we actually pass back from get_input. Well, no,
+// that's just k, but..
+struct Event {
+ Repeat r;
+ InterfaceKey k;
+ int repeats; // Starts at 0, increments once per repeat
+ int serial;
+ int time;
+ int tick; // The sim-tick at which we last returned this event
+ bool macro; // Created as part of macro playback.
+
+ bool operator== (const Event &other) const {
+ if (r != other.r) return false;
+ if (k != other.k) return false;
+ if (repeats != other.repeats) return false;
+ if (serial != other.serial) return false;
+ if (time != other.time) return false;
+ if (macro != other.macro) return false;
+ return true;
+ }
+
+ // We sort by time first, and then serial number.
+ // The order of the other bits is unimportant.
+ bool operator< (const Event &o) const {
+ if (time != o.time) return time < o.time;
+ if (serial != o.serial) return serial < o.serial;
+ if (r != o.r) return r < o.r;
+ if (k != o.k) return k < o.k;
+ if (repeats != o.repeats) return repeats < o.repeats;
+ if (macro != o.macro) return macro < o.macro;
+ return false;
+ }
+};
+
+// Used to decide which key-binding to display. As a heuristic, we
+// prefer whichever display string is shortest.
+struct less_sz {
+ bool operator() (const string &a, const string &b) const {
+ if (a.size() < b.size()) return true;
+ if (a.size() > b.size()) return false;
+ return a < b;
+ }
+};
+
+// These change dynamically in the normal process of DF
+static int last_serial = 0; // Input serial number, to differentiate distinct physical presses
+static set<Event> timeline; // A timeline of pending key events (for next get_input)
+static set<EventMatch> pressed_keys; // Keys we consider "pressed"
+static int modState; // Modifier state
+
+// These do not change as part of the normal dynamics of DF, only at startup/when editing.
+static multimap<EventMatch,InterfaceKey> keymap;
+static map<InterfaceKey,Repeat> repeatmap;
+static map<InterfaceKey,set<string,less_sz> > keydisplay; // Used only for display, not for meaning
+
+// Macro recording
+static bool macro_recording = false;
+static macro active_macro; // Active macro
+static map<string,macro> macros;
+static Time macro_end = 0; // Time at which the currently playing macro will end
+
+// Prefix command state
+static bool in_prefix_command = false;
+static string prefix_command;
+
+// Keybinding editing
+static bool key_registering = false;
+static list<EventMatch> stored_keys;
+
+// Interface-file last loaded
+static string interfacefile;
+
+
+// Returns an unused serial number
+static Time next_serial() {
+ return ++last_serial;
+}
+
+static void update_keydisplay(InterfaceKey binding, string display) {
+ // Need to filter out space/tab, for obvious reasons.
+ if (display == " ") display = "Space";
+ if (display == "\t") display = "Tab";
+ map<InterfaceKey,set<string,less_sz> >::iterator it = keydisplay.find(binding);
+ if (it == keydisplay.end()) {
+ set<string,less_sz> s; s.insert(display);
+ keydisplay[binding] = s;
+ } else {
+ keydisplay[binding].insert(display);
+ }
+}
+
+static void assertgood(ifstream &s) {
+ if (s.eof())
+ MessageBox(NULL, "EOF while parsing keyboard bindings", 0, 0);
+ else if (!s.good())
+ MessageBox(NULL, "I/O error while parsing keyboard bindings", 0, 0);
+ else
+ return;
+ abort();
+}
+
+// Decodes an UTF-8 encoded string into a /single/ UTF-8 character,
+// discarding any overflow. Returns 0 on parse error.
+int decode_utf8(const string &s) {
+ int unicode = 0, length, i;
+ if (s.length() == 0) return 0;
+ length = decode_utf8_predict_length(s[0]);
+ switch (length) {
+ case 1: unicode = s[0]; break;
+ case 2: unicode = s[0] & 0x1f; break;
+ case 3: unicode = s[0] & 0x0f; break;
+ case 4: unicode = s[0] & 0x07; break;
+ default: return 0;
+ }
+
+ // Concatenate the follow-up bytes
+ if (s.length() < length) return 0;
+ for (i = 1; i < length; i++) {
+ if ((s[i] & 0xc0) != 0x80) return 0;
+ unicode = (unicode << 6) | (s[i] & 0x3f);
+ }
+ return unicode;
+}
+
+// Returns the length of an utf-8 sequence, based on its first byte
+int decode_utf8_predict_length(char byte) {
+ if ((byte & 0x80) == 0) return 1;
+ if ((byte & 0xe0) == 0xc0) return 2;
+ if ((byte & 0xf0) == 0xe0) return 3;
+ if ((byte & 0xf8) == 0xf0) return 4;
+ return 0; // Invalid start byte
+}
+
+// Encode an arbitrary unicode value as a string. Returns an empty
+// string if the value is out of range.
+string encode_utf8(int unicode) {
+ string s;
+ int i;
+ if (unicode < 0 || unicode > 0x10ffff) return ""; // Out of range for utf-8
+ else if (unicode <= 0x007f) { // 1-byte utf-8
+ s.resize(1, 0);
+ }
+ else if (unicode <= 0x07ff) { // 2-byte utf-8
+ s.resize(2, 0);
+ s[0] = 0xc0;
+ }
+ else if (unicode <= 0xffff) { // 3-byte utf-8
+ s.resize(3, 0);
+ s[0] = 0xe0;
+ }
+ else { // 4-byte utf-8
+ s.resize(4, 0);
+ s[0] = 0xf0;
+ }
+
+ // Build up the string, right to left
+ for (i = s.length()-1; i > 0; i--) {
+ s[i] = 0x80 | (unicode & 0x3f);
+ unicode >>= 6;
+ }
+ // Finally, what's left goes in the low bits of s[0]
+ s[0] |= unicode;
+ return s;
+}
+
+string translate_mod(Uint8 mod) {
+ string ret;
+ if (mod & 1) ret += "Shift+";
+ if (mod & 2) ret += "Ctrl+";
+ if (mod & 4) ret += "Alt+";
+ return ret;
+}
+
+static string display(const EventMatch &match) {
+ ostringstream ret;
+ ret << translate_mod(match.mod);
+ switch (match.type) {
+ case type_unicode: ret << (char)match.unicode; break;
+ case type_key: {
+ map<SDLKey,string>::iterator it = sdlNames.left.find(match.key);
+ if (it != sdlNames.left.end())
+ ret << it->second;
+ else
+ ret << "SDL+" << (int)match.key;
+ break;
+ }
+ case type_button:
+ ret << "Button " << (int)match.button;
+ break;
+ }
+ return ret.str();
+}
+
+static string translate_repeat(Repeat r) {
+ switch (r) {
+ case REPEAT_NOT: return "REPEAT_NOT";
+ case REPEAT_SLOW: return "REPEAT_SLOW";
+ case REPEAT_FAST: return "REPEAT_FAST";
+ default: return "REPEAT_BROKEN";
+ }
+}
+
+// Update the modstate, since SDL_getModState doesn't /work/ for alt
+static void update_modstate(const SDL_Event &e) {
+ if (e.type == SDL_KEYUP) {
+ switch (e.key.keysym.sym) {
+ case SDLK_RSHIFT:
+ case SDLK_LSHIFT:
+ modState &= ~1;
+ break;
+ case SDLK_RCTRL:
+ case SDLK_LCTRL:
+ modState &= ~2;
+ break;
+ case SDLK_RALT:
+ case SDLK_LALT:
+ modState &= ~4;
+ break;
+ }
+ } else if (e.type == SDL_KEYDOWN) {
+ switch (e.key.keysym.sym) {
+ case SDLK_RSHIFT:
+ case SDLK_LSHIFT:
+ modState |= 1;
+ break;
+ case SDLK_RCTRL:
+ case SDLK_LCTRL:
+ modState |= 2;
+ break;
+ case SDLK_RALT:
+ case SDLK_LALT:
+ modState |= 4;
+ break;
+ }
+ }
+}
+
+// Converts SDL mod states to ours, collapsing left/right shift/alt/ctrl
+Uint8 getModState() {
+ return modState;
+}
+
+// Not sure what to call this, but it ain't using regexes.
+static bool parse_line(const string &line, const string &regex, vector<string> &parts) {
+ parts.clear();
+ parts.push_back(line);
+ int bytes;
+ for (int l = 0, r = 0; r < regex.length();) {
+ switch (regex[r]) {
+ case '*': // Read until ], : or the end of the line, but at least one character.
+ {
+ const int start = l;
+ for (; l < line.length() && (l == start || (line[l] != ']' && line[l] != ':')); l++)
+ ;
+ parts.push_back(line.substr(start, l - start));
+ r++;
+ }
+ break;
+ default:
+ if (line[l] != regex[r]) return false;
+ r++; l++;
+ break;
+ }
+ }
+ // We've made it this far, clearly the string parsed
+ return true;
+}
+
+void enabler_inputst::load_keybindings(const string &file) {
+ cout << "Loading bindings from " << file << endl;
+ interfacefile = file;
+ ifstream s(file.c_str());
+ if (!s.good()) {
+ MessageBox(NULL, (file + " not found, or I/O error encountered").c_str(), 0, 0);
+ abort();
+ }
+
+ list<string> lines;
+ while (s.good()) {
+ string line;
+ getline(s, line);
+ lines.push_back(line);
+ }
+
+ static const string bind("[BIND:*:*]");
+ static const string sym("[SYM:*:*]");
+ static const string key("[KEY:*]");
+ static const string button("[BUTTON:*:*]");
+
+ list<string>::iterator line = lines.begin();
+ vector<string> match;
+
+ while (line != lines.end()) {
+ if (parse_line(*line, bind, match)) {
+ map<string,InterfaceKey>::iterator it = bindingNames.right.find(match[1]);
+ if (it != bindingNames.right.end()) {
+ InterfaceKey binding = it->second;
+ // Parse repeat data
+ if (match[2] == "REPEAT_FAST")
+ repeatmap[(InterfaceKey)binding] = REPEAT_FAST;
+ else if (match[2] == "REPEAT_SLOW")
+ repeatmap[(InterfaceKey)binding] = REPEAT_SLOW;
+ else if (match[2] == "REPEAT_NOT")
+ repeatmap[(InterfaceKey)binding] = REPEAT_NOT;
+ else {
+ repeatmap[(InterfaceKey)binding] = REPEAT_NOT;
+ cout << "Broken repeat request: " << match[2] << endl;
+ }
+ ++line;
+ // Add symbols/keys/buttons
+ while (line != lines.end()) {
+ EventMatch matcher;
+ // SDL Keys
+ if (parse_line(*line, sym, match)) {
+ map<string,SDLKey>::iterator it = sdlNames.right.find(match[2]);
+ if (it != sdlNames.right.end()) {
+ matcher.mod = atoi(string(match[1]).c_str());
+ matcher.type = type_key;
+ matcher.key = it->second;
+ keymap.insert(pair<EventMatch,InterfaceKey>(matcher, (InterfaceKey)binding));
+ update_keydisplay(binding, display(matcher));
+ } else {
+ cout << "Unknown SDLKey: " << match[2] << endl;
+ }
+ ++line;
+ } // Unicode
+ else if (parse_line(*line, key, match)) {
+ matcher.type = type_unicode;
+ matcher.unicode = decode_utf8(match[1]);
+ matcher.mod = KMOD_NONE;
+ if (matcher.unicode) {
+ keymap.insert(make_pair(matcher, (InterfaceKey)binding));
+ if (matcher.unicode < 256) {
+ // This unicode key is part of the latin-1 mapped portion of unicode, so we can
+ // actually display it. Nice.
+ char c[2] = {char(matcher.unicode), 0};
+ update_keydisplay(binding, display(matcher));
+ }
+ } else {
+ cout << "Broken unicode: " << *line << endl;
+ }
+ ++line;
+ } // Mouse buttons
+ else if (parse_line(*line, button, match)) {
+ matcher.type = type_button;
+ string str = match[2];
+ matcher.button = atoi(str.c_str());
+ if (matcher.button) {
+ matcher.mod = atoi(string(match[1]).c_str());
+ keymap.insert(pair<EventMatch,InterfaceKey>(matcher, (InterfaceKey)binding));
+ update_keydisplay(binding, display(matcher));
+ } else {
+ cout << "Broken button (should be [BUTTON:#:#]): " << *line << endl;
+ }
+ ++line;
+ } else {
+ break;
+ }
+ }
+ } else {
+ cout << "Unknown binding: " << match[1] << endl;
+ ++line;
+ }
+ } else {
+ // Retry with next line
+ ++line;
+ }
+ }
+}
+
+void enabler_inputst::save_keybindings(const string &file) {
+ cout << "Saving bindings to " << file << endl;
+ string temporary = file + ".partial";
+ ofstream s(temporary.c_str());
+ multimap<InterfaceKey,EventMatch> map;
+ InterfaceKey last_key = INTERFACEKEY_NONE;
+
+ if (!s.good()) {
+ string t = "Failed to open " + temporary + " for writing";
+ MessageBox(NULL, t.c_str(), 0, 0);
+ s.close();
+ return;
+ }
+ // Invert keyboard map
+ for (multimap<EventMatch,InterfaceKey>::iterator it = keymap.begin(); it != keymap.end(); ++it)
+ map.insert(pair<InterfaceKey,EventMatch>(it->second,it->first));
+ // Insert an empty line for the benefit of note/wordpad
+ s << endl;
+ // And write.
+ for (multimap<InterfaceKey,EventMatch>::iterator it = map.begin(); it != map.end(); ++it) {
+ if (!s.good()) {
+ MessageBox(NULL, "I/O error while writing keyboard mapping", 0, 0);
+ s.close();
+ return;
+ }
+ if (it->first != last_key) {
+ last_key = it->first;
+ s << "[BIND:" << bindingNames.left[it->first] << ":"
+ << translate_repeat(repeatmap[it->first]) << "]" << endl;
+ }
+ switch (it->second.type) {
+ case type_unicode:
+ s << "[KEY:" << encode_utf8(it->second.unicode) << "]" << endl;
+ break;
+ case type_key:
+ s << "[SYM:" << (int)it->second.mod << ":" << sdlNames.left[it->second.key] << "]" << endl;
+ break;
+ case type_button:
+ s << "[BUTTON:" << (int)it->second.mod << ":" << (int)it->second.button << "]" << endl;
+ break;
+ }
+ }
+ s.close();
+ replace_file(temporary, file);
+}
+
+void enabler_inputst::save_keybindings() {
+ save_keybindings(interfacefile);
+}
+
+void enabler_inputst::add_input(SDL_Event &e, Uint32 now) {
+ // Before we can use this input, there are some issues to deal with:
+ // - SDL provides unicode translations only for key-press events, not
+ // releases. We need to keep track of pressed keys, and generate
+ // unicode release events whenever any modifiers are hit, or if
+ // that raw keycode is released.
+ // - Generally speaking, when modifiers are hit/released, we discard those
+ // events and generate press/release events for all pressed non-modifiers.
+ // - It's possible for multiple events to be generated on the same tick.
+ // These are of course separate keypresses, and must be kept separate.
+ // That's what the serial is for.
+
+ set<EventMatch>::iterator pkit;
+ list<pair<KeyEvent, int> > synthetics;
+ update_modstate(e);
+
+ // Convert modifier state changes
+ if ((e.type == SDL_KEYUP || e.type == SDL_KEYDOWN) &&
+ (e.key.keysym.sym == SDLK_RSHIFT ||
+ e.key.keysym.sym == SDLK_LSHIFT ||
+ e.key.keysym.sym == SDLK_RCTRL ||
+ e.key.keysym.sym == SDLK_LCTRL ||
+ e.key.keysym.sym == SDLK_RALT ||
+ e.key.keysym.sym == SDLK_LALT )) {
+ for (pkit = pressed_keys.begin(); pkit != pressed_keys.end(); ++pkit) {
+ // Release currently pressed keys
+ KeyEvent synth;
+ synth.release = true;
+ synth.match = *pkit;
+ synthetics.push_back(make_pair(synth, next_serial()));
+ // Re-press them, with new modifiers, if they aren't unicode. We can't re-translate unicode.
+ if (synth.match.type != type_unicode) {
+ synth.release = false;
+ synth.match.mod = getModState();
+ if (!key_registering) // We don't want extras when registering keys
+ synthetics.push_back(make_pair(synth, next_serial()));
+ }
+ }
+ } else {
+ // It's not a modifier. If this is a key release, then we still need
+ // to find and release pressed unicode keys with this scancode
+ if (e.type == SDL_KEYUP) {
+ for (pkit = pressed_keys.begin(); pkit != pressed_keys.end(); ++pkit) {
+ if (pkit->type == type_unicode && pkit->scancode == e.key.keysym.scancode) {
+ KeyEvent synth;
+ synth.release = true;
+ synth.match = *pkit;
+ synthetics.push_back(make_pair(synth, next_serial()));
+ }
+ }
+ }
+ // Since it's not a modifier, we also pass on symbolic/button
+ // (always) and unicode (if defined) events
+ //
+ // However, since SDL ignores(?) ctrl and alt when translating to
+ // unicode, we want to ignore unicode events if those are set.
+ const int serial = next_serial();
+
+ KeyEvent real;
+ real.release = (e.type == SDL_KEYUP || e.type == SDL_MOUSEBUTTONUP) ? true : false;
+ real.match.mod = getModState();
+ if (e.type == SDL_MOUSEBUTTONUP || e.type == SDL_MOUSEBUTTONDOWN) {
+ real.match.type = type_button;
+ real.match.scancode = 0;
+ real.match.button = e.button.button;
+ synthetics.push_back(make_pair(real, serial));
+ }
+ if (e.type == SDL_KEYUP || e.type == SDL_KEYDOWN) {
+ real.match.type = type_key;
+ real.match.scancode = e.key.keysym.scancode;
+ real.match.key = e.key.keysym.sym;
+ synthetics.push_back(make_pair(real, serial));
+ }
+ if (e.type == SDL_KEYDOWN && e.key.keysym.unicode && getModState() < 2) {
+ real.match.mod = KMOD_NONE;
+ real.match.type = type_unicode;
+ real.match.scancode = e.key.keysym.scancode;
+ real.match.unicode = e.key.keysym.unicode;
+ synthetics.push_back(make_pair(real, serial));
+ }
+ if (e.type == SDL_QUIT) {
+ // This one, we insert directly into the timeline.
+ Event e = {REPEAT_NOT, (InterfaceKey)INTERFACEKEY_OPTIONS, 0, next_serial(), now, 0};
+ timeline.insert(e);
+ }
+ }
+
+ list<pair<KeyEvent, int> >::iterator lit;
+ for (lit = synthetics.begin(); lit != synthetics.end(); ++lit) {
+ // Add or remove the key from pressed_keys, keeping that up to date
+ if (lit->first.release) pressed_keys.erase(lit->first.match);
+ else pressed_keys.insert(lit->first.match);
+ // And pass the event on deeper.
+ add_input_refined(lit->first, now, lit->second);
+ }
+}
+
+// Input encoding:
+// 1 and up are ncurses symbols, as returned by getch.
+// -1 and down are unicode values.
+// esc is true if this key was part of an escape sequence.
+#ifdef CURSES
+void enabler_inputst::add_input_ncurses(int key, Time now, bool esc) {
+ // TODO: Deal with shifted arrow keys, etc. See man 5 terminfo and tgetent.
+
+ EventMatch sdl, uni; // Each key may provoke an unicode event, an "SDL-key" event, or both
+ const int serial = next_serial();
+ sdl.type = type_key;
+ uni.type = type_unicode;
+ sdl.scancode = uni.scancode = 0; // We don't use this.. hang on, who does? ..nobody. FIXME!
+ sdl.mod = uni.mod = 0;
+ sdl.key = SDLK_UNKNOWN;
+ uni.unicode = 0;
+
+ if (esc) { // Escape sequence, meaning alt was held. I hope.
+ sdl.mod = uni.mod = DFMOD_ALT;
+ }
+
+ if (key == -10) { // Return
+ sdl.key = SDLK_RETURN;
+ uni.unicode = '\n';
+ } else if (key == -9) { // Tab
+ sdl.key = SDLK_TAB;
+ uni.unicode = '\t';
+ } else if (key == -27) { // If we see esc here, it's the actual esc key. Hopefully.
+ sdl.key = SDLK_ESCAPE;
+ } else if (key == -127) { // Backspace/del
+ sdl.key = SDLK_BACKSPACE;
+ } else if (key < 0 && key >= -26) { // Control-a through z (but not ctrl-j, or ctrl-i)
+ sdl.mod |= DFMOD_CTRL;
+ sdl.key = (SDLKey)(SDLK_a + (-key) - 1);
+ } else if (key <= -32 && key >= -126) { // ASCII character set
+ uni.unicode = -key;
+ sdl.key = (SDLKey)-key; // Most of this maps directly to SDL keys, except..
+ if (sdl.key > 64 && sdl.key < 91) { // Uppercase
+ sdl.key = (SDLKey)(sdl.key + 32); // Maps to lowercase, and
+ sdl.mod |= DFMOD_SHIFT; // Add shift.
+ }
+ } else if (key < -127) { // Unicode, no matching SDL keys
+ uni.unicode = -key;
+ } else if (key > 0) { // Symbols such as arrow-keys, etc, no matching unicode.
+ switch (key) {
+ case KEY_DOWN: sdl.key = SDLK_DOWN; break;
+ case KEY_UP: sdl.key = SDLK_UP; break;
+ case KEY_LEFT: sdl.key = SDLK_LEFT; break;
+ case KEY_RIGHT: sdl.key = SDLK_RIGHT; break;
+ case KEY_BACKSPACE: sdl.key = SDLK_BACKSPACE; break;
+ case KEY_F(1): sdl.key = SDLK_F1; break;
+ case KEY_F(2): sdl.key = SDLK_F2; break;
+ case KEY_F(3): sdl.key = SDLK_F3; break;
+ case KEY_F(4): sdl.key = SDLK_F4; break;
+ case KEY_F(5): sdl.key = SDLK_F5; break;
+ case KEY_F(6): sdl.key = SDLK_F6; break;
+ case KEY_F(7): sdl.key = SDLK_F7; break;
+ case KEY_F(8): sdl.key = SDLK_F8; break;
+ case KEY_F(9): sdl.key = SDLK_F9; break;
+ case KEY_F(10): sdl.key = SDLK_F10; break;
+ case KEY_F(11): sdl.key = SDLK_F11; break;
+ case KEY_F(12): sdl.key = SDLK_F12; break;
+ case KEY_F(13): sdl.key = SDLK_F13; break;
+ case KEY_F(14): sdl.key = SDLK_F14; break;
+ case KEY_F(15): sdl.key = SDLK_F15; break;
+ case KEY_DC: sdl.key = SDLK_DELETE; break;
+ case KEY_NPAGE: sdl.key = SDLK_PAGEDOWN; break;
+ case KEY_PPAGE: sdl.key = SDLK_PAGEUP; break;
+ case KEY_ENTER: sdl.key = SDLK_RETURN; break;
+ }
+ }
+
+ // We may be registering a new mapping, in which case we skip the
+ // rest of this function.
+ if (key_registering) {
+ if (uni.unicode) {
+ stored_keys.push_back(uni);
+ }
+ if (sdl.key) {
+ stored_keys.push_back(sdl);
+ }
+ Event e; e.r = REPEAT_NOT; e.repeats = 0; e.time = now; e.serial = serial; e.k = INTERFACEKEY_KEYBINDING_COMPLETE; e.tick = enabler.simticks.read();
+ timeline.insert(e);
+ key_registering = false;
+ return;
+ }
+
+ // Key repeat is handled by the terminal, and we don't get release
+ // events anyway.
+ KeyEvent kev; kev.release = false;
+ Event e; e.r = REPEAT_NOT; e.repeats = 0; e.time = now;
+ if (sdl.key) {
+ set<InterfaceKey> events = key_translation(sdl);
+ for (set<InterfaceKey>::iterator k = events.begin(); k != events.end(); ++k) {
+ e.serial = serial;
+ e.k = *k;
+ timeline.insert(e);
+ }
+ }
+ if (uni.unicode) {
+ set<InterfaceKey> events = key_translation(uni);
+ for (set<InterfaceKey>::iterator k = events.begin(); k != events.end(); ++k) {
+ e.serial = serial;
+ e.k = *k;
+ timeline.insert(e);
+ }
+ }
+}
+#endif
+
+void enabler_inputst::add_input_refined(KeyEvent &e, Uint32 now, int serial) {
+ // We may be registering a new mapping, in which case we skip the
+ // rest of this function.
+ if (key_registering && !e.release) {
+ stored_keys.push_back(e.match);
+ Event e; e.r = REPEAT_NOT; e.repeats = 0; e.time = now; e.serial = serial; e.k = INTERFACEKEY_KEYBINDING_COMPLETE; e.tick = enabler.simticks.read();
+ timeline.insert(e);
+ return;
+ }
+
+ // If this is a key-press event, we add it to the timeline. If it's
+ // a release, we remove any pending repeats, but not those that
+ // haven't repeated yet (which are on their first cycle); those we
+ // just set to non-repeating.
+ set<InterfaceKey> keys = key_translation(e.match);
+ if (e.release) {
+ set<Event>::iterator it = timeline.begin();
+ while (it != timeline.end()) {
+ set<Event>::iterator el = it++;
+ if (keys.count(el->k)) {
+ if (el->repeats) {
+ timeline.erase(el);
+ } else {
+ Event new_el = *el;
+ new_el.r = REPEAT_NOT;
+ timeline.erase(el);
+ timeline.insert(new_el);
+ }
+ }
+ }
+ } else {
+ set<InterfaceKey>::iterator key;
+ // As policy, when the user hits a non-repeating key we'd want to
+ // also cancel any keys that are currently repeating. This allows
+ // for easy recovery from stuck keys.
+ //
+ // Unfortunately, each key may be bound to multiple
+ // commands. So, lacking information on which commands are
+ // accepted at the moment, there is no way we can know if it's
+ // okay to cancel repeats unless /all/ the bindings are
+ // non-repeating.
+ for (set<InterfaceKey>::iterator k = keys.begin(); k != keys.end(); ++k) {
+ Event e = {key_repeat(*k), *k, 0, serial, now, enabler.simticks.read()};
+ timeline.insert(e);
+ }
+ // if (cancel_ok) {
+ // // Set everything on the timeline to non-repeating
+ // multimap<Time,Event>::iterator it;
+ // for (it = timeline.begin(); it != timeline.end(); ++it) {
+ // it->second.r = REPEAT_NOT;
+ // }
+ }
+}
+
+
+void enabler_inputst::clear_input() {
+ timeline.clear();
+ pressed_keys.clear();
+ modState = 0;
+ last_serial = 0;
+}
+
+set<InterfaceKey> enabler_inputst::get_input(Time now) {
+ // We walk the timeline, returning all events corresponding to a
+ // single physical keypress, and inserting repeats relative to the
+ // current time, not when the events we're now returning were
+ // *supposed* to happen.
+
+ set<InterfaceKey> input;
+ set<Event>::iterator ev = timeline.begin();
+ if (ev == timeline.end() || ev->time > now) {
+ return input; // No input (yet).
+ }
+
+ const Time first_time = ev->time;
+ const int first_serial = ev->serial;
+ int simtick = enabler.simticks.read();
+ bool event_from_macro = false;
+ while (ev != timeline.end() && ev->time == first_time && ev->serial == first_serial) {
+ // Avoid recording macro-sources events as macro events.
+ if (ev->macro) event_from_macro = true;
+ // To make sure the user had a chance to cancel (by lifting the key), we require there
+ // to be at least three simulation ticks before the first repeat.
+ if (ev->repeats == 1 && ev->tick > simtick - 3) {
+ } else {
+ input.insert(ev->k);
+ }
+ // Schedule a repeat
+ Event next = *ev;
+ next.repeats++;
+ switch (next.r) {
+ case REPEAT_NOT:
+ break;
+ case REPEAT_SLOW:
+ if (ev->repeats == 0) {
+ next.time = now + init.input.hold_time;
+ timeline.insert(next);
+ break;
+ }
+ case REPEAT_FAST:
+ double accel = 1;
+ if (ev->repeats >= init.input.repeat_accel_start) {
+ // Compute acceleration
+ accel = MIN(init.input.repeat_accel_limit,
+ sqrt(double(next.repeats - init.input.repeat_accel_start) + 16) - 3);
+ }
+ next.time = now + double(init.input.repeat_time) / accel;
+ timeline.insert(next);
+ break;
+ }
+ // Delete the event from the timeline and iterate
+ timeline.erase(ev++);
+ }
+#ifdef DEBUG
+ if (input.size() && !init.display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) {
+ cout << "Returning input:\n";
+ set<InterfaceKey>::iterator it;
+ for (it = input.begin(); it != input.end(); ++it)
+ cout << " " << GetKeyDisplay(*it) << ": " << GetBindingDisplay(*it) << endl;
+ }
+#endif
+ // It could be argued that the "record event" step of recording
+ // belongs in add_input, not here. I don't hold with this
+ // argument. The whole point is to record events as the user seems
+ // them happen.
+ if (macro_recording && !event_from_macro) {
+ set<InterfaceKey> macro_input = input;
+ macro_input.erase(INTERFACEKEY_RECORD_MACRO);
+ macro_input.erase(INTERFACEKEY_PLAY_MACRO);
+ macro_input.erase(INTERFACEKEY_SAVE_MACRO);
+ macro_input.erase(INTERFACEKEY_LOAD_MACRO);
+ if (macro_input.size())
+ active_macro.push_back(macro_input);
+ }
+ return input;
+}
+
+set<InterfaceKey> enabler_inputst::key_translation(EventMatch &match) {
+ set<InterfaceKey> bindings;
+ pair<multimap<EventMatch,InterfaceKey>::iterator,multimap<EventMatch,InterfaceKey>::iterator> its;
+
+ for (its = keymap.equal_range(match); its.first != its.second; ++its.first)
+ bindings.insert((its.first)->second);
+
+ return bindings;
+}
+
+string enabler_inputst::GetKeyDisplay(int binding) {
+ map<InterfaceKey,set<string,less_sz> >::iterator it = keydisplay.find(binding);
+ if (it != keydisplay.end() && it->second.size())
+ return *it->second.begin();
+ else {
+ cout << "Missing binding displayed: " + bindingNames.left[binding] << endl;
+ return "?";
+ }
+}
+
+string enabler_inputst::GetBindingDisplay(int binding) {
+ map<InterfaceKey,string>::iterator it = bindingNames.left.find(binding);
+ if (it != bindingNames.left.end())
+ return it->second;
+ else
+ return "NO BINDING";
+}
+
+string enabler_inputst::GetBindingTextDisplay(int binding) {
+ map<InterfaceKey,string>::iterator it = displayNames.left.find(binding);
+ if (it !=displayNames.left.end())
+ return it->second;
+ else
+ return "NO BINDING";
+}
+
+Repeat enabler_inputst::key_repeat(InterfaceKey binding) {
+ map<InterfaceKey,Repeat>::iterator it = repeatmap.find(binding);
+ if (it != repeatmap.end())
+ return it->second;
+ else
+ return REPEAT_NOT;
+}
+
+void enabler_inputst::key_repeat(InterfaceKey binding, Repeat repeat) {
+ repeatmap[binding] = repeat;
+}
+
+void enabler_inputst::record_input() {
+ active_macro.clear();
+ macro_recording = true;
+}
+
+void enabler_inputst::record_stop() {
+ macro_recording = false;
+}
+
+bool enabler_inputst::is_recording() {
+ return macro_recording;
+}
+
+void enabler_inputst::play_macro() {
+ Time now = SDL_GetTicks();
+ for_each(timeline.begin(), timeline.end(), [&](Event e){
+ now = MAX(now, e.time);
+ });
+ for (macro::iterator sim = active_macro.begin(); sim != active_macro.end(); ++sim) {
+ Event e; e.r = REPEAT_NOT; e.repeats = 0; e.serial = next_serial(); e.time = now;
+ e.macro = true; // Avoid exponential macro blowup.
+ for (set<InterfaceKey>::iterator k = sim->begin(); k != sim->end(); ++k) {
+ e.k = *k;
+ timeline.insert(e);
+ now += init.input.macro_time;
+ }
+ }
+ macro_end = MAX(macro_end, now);
+}
+
+bool enabler_inputst::is_macro_playing() {
+ return SDL_GetTicks() <= macro_end;
+}
+
+// Replaces any illegal letters.
+static string filter_filename(string name, char replacement) {
+ for (int i = 0; i < name.length(); i++) {
+ switch (name[i]) {
+ case '<': name[i] = replacement; break;
+ case '>': name[i] = replacement; break;
+ case ':': name[i] = replacement; break;
+ case '"': name[i] = replacement; break;
+ case '/': name[i] = replacement; break;
+ case '\\': name[i] = replacement; break;
+ case '|': name[i] = replacement; break;
+ case '?': name[i] = replacement; break;
+ case '*': name[i] = replacement; break;
+ }
+ if (name[i] <= 31) name[i] = replacement;
+ }
+ return name;
+}
+
+void enabler_inputst::load_macro_from_file(const string &file) {
+ ifstream s(file.c_str());
+ char buf[100];
+ s.getline(buf, 100);
+ string name(buf);
+ if (macros.find(name) != macros.end()) return; // Already got it.
+
+ macro macro;
+ set<InterfaceKey> group;
+ for(;;) {
+ s.getline(buf, 100);
+ if (!s.good()) {
+ MessageBox(NULL, "I/O error while loading macro", 0, 0);
+ s.close();
+ return;
+ }
+ string line(buf);
+ if (line == "End of macro") {
+ if (group.size()) macro.push_back(group);
+ break;
+ } else if (line == "\tEnd of group") {
+ if (group.size()) macro.push_back(group);
+ group.clear();
+ } else if (line.substr(0,2) != "\t\t" ) {
+ if( line.substr(1).find("\t") != string::npos) {
+ // expecting /t##/tCMD for a repeated command
+ istringstream ss(line.substr(1));
+ int count;
+ string remainingline;
+
+ if(ss >> count) {
+ ss >> remainingline;
+ if(remainingline.size()) {
+ for(int i=0; i < count; i++) {
+ map<string,InterfaceKey>::iterator it = bindingNames.right.find(remainingline);
+ if (it == bindingNames.right.end()) {
+ cout << "Binding name unknown while loading macro: " << line.substr(1) << endl;
+ } else {
+ group.insert(it->second);
+ if (group.size()) macro.push_back(group);
+ group.clear();
+ }
+ }
+ }
+ else {
+ cout << "Binding missing while loading macro: " << line.substr(1) << endl;
+ }
+ } else {
+ cout << "Quantity not numeric or Unexpected tab(s) while loading macro: " << line.substr(1) << endl;
+ }
+ }
+ else
+ {
+ // expecting /tCMD for a non-grouped command
+ map<string,InterfaceKey>::iterator it = bindingNames.right.find(line.substr(1));
+ if (it == bindingNames.right.end()) {
+ cout << "Binding name unknown while loading macro: " << line.substr(1) << endl;
+ } else {
+ group.insert(it->second);
+ if (group.size()) macro.push_back(group);
+ group.clear();
+ }
+ }
+ } else {
+ map<string,InterfaceKey>::iterator it = bindingNames.right.find(line.substr(2));
+ if (it == bindingNames.right.end())
+ cout << "Binding name unknown while loading macro: " << line.substr(2) << endl;
+ else
+ group.insert(it->second);
+ }
+ }
+ if (s.good())
+ macros[name] = macro;
+ else
+ MessageBox(NULL, "I/O error while loading macro", 0, 0);
+ s.close();
+}
+
+void enabler_inputst::save_macro_to_file(const string &file, const string &name, const macro &macro) {
+ ofstream s(file.c_str());
+ s << name << endl;
+ for (macro::const_iterator group = macro.begin(); group != macro.end(); ++group) {
+ for (set<InterfaceKey>::const_iterator key = group->begin(); key != group->end(); ++key)
+ s << "\t\t" << bindingNames.left[*key] << endl;
+ s << "\tEnd of group" << endl;
+ }
+ s << "End of macro" << endl;
+ s.close();
+}
+
+list<string> enabler_inputst::list_macros() {
+ // First, check for unloaded macros
+ svector<char*> files;
+ find_files_by_pattern("data/init/macros/*.mak", files);
+ for (int i = 0; i < files.size(); i++) {
+ string file(files[i]);
+ delete files[i];
+ file = "data/init/macros/" + file;
+ load_macro_from_file(file);
+ }
+ // Then return all in-memory macros
+ list<string> ret;
+ for (map<string,macro>::iterator it = macros.begin(); it != macros.end(); ++it)
+ ret.push_back(it->first);
+ return ret;
+}
+
+void enabler_inputst::load_macro(string name) {
+ if (macros.find(name) != macros.end())
+ active_macro = macros[name];
+ else
+ macros.clear();
+}
+
+void enabler_inputst::save_macro(string name) {
+ macros[name] = active_macro;
+ save_macro_to_file("data/init/macros/" + filter_filename(name, '_') + ".mak", name, active_macro);
+}
+
+void enabler_inputst::delete_macro(string name) {
+ map<string,macro>::iterator it = macros.find(name);
+ if (it != macros.end()) macros.erase(it);
+ // TODO: Store the filename it was loaded from instead
+ string filename = "data/init/macros/" + filter_filename(name, '_') + ".mak";
+ remove(filename.c_str());
+}
+
+
+// Sets the next key-press to be stored instead of executed.
+void enabler_inputst::register_key() {
+ key_registering = true;
+ stored_keys.clear();
+}
+
+// Returns a description of stored keys. Max one of each type.
+list<RegisteredKey> enabler_inputst::getRegisteredKey() {
+ key_registering = false;
+ list<RegisteredKey> ret;
+ for (list<EventMatch>::iterator it = stored_keys.begin(); it != stored_keys.end(); ++it) {
+ struct RegisteredKey r = {it->type, display(*it)};
+ ret.push_back(r);
+ }
+ return ret;
+}
+
+// Binds one of the stored keys to key
+void enabler_inputst::bindRegisteredKey(MatchType type, InterfaceKey key) {
+ for (list<EventMatch>::iterator it = stored_keys.begin(); it != stored_keys.end(); ++it) {
+ if (it->type == type) {
+ keymap.insert(pair<EventMatch,InterfaceKey>(*it, key));
+ update_keydisplay(key, display(*it));
+ }
+ }
+}
+
+bool enabler_inputst::is_registering() {
+ return key_registering;
+}
+
+
+list<EventMatch> enabler_inputst::list_keys(InterfaceKey key) {
+ list<EventMatch> ret;
+ // Oh, now this is inefficient.
+ for (multimap<EventMatch,InterfaceKey>::iterator it = keymap.begin(); it != keymap.end(); ++it)
+ if (it->second == key) ret.push_back(it->first);
+ return ret;
+}
+
+void enabler_inputst::remove_key(InterfaceKey key, EventMatch ev) {
+ for (multimap<EventMatch,InterfaceKey>::iterator it = keymap.find(ev);
+ it != keymap.end() && it->first == ev;
+ ++it) {
+ if (it->second == key) keymap.erase(it++);
+ }
+ // Also remove the key from key displaying, assuming we can find it
+ map<InterfaceKey,set<string,less_sz> >::iterator it = keydisplay.find(key);
+ if (it != keydisplay.end())
+ it->second.erase(display(ev));
+}
+
+bool enabler_inputst::prefix_building() {
+ return in_prefix_command;
+}
+
+void enabler_inputst::prefix_toggle() {
+ in_prefix_command = !in_prefix_command;
+ prefix_command.clear();
+}
+
+void enabler_inputst::prefix_add_digit(char digit) {
+ prefix_command.push_back(digit);
+#ifdef DEBUG
+ cout << "Built prefix to " << prefix_command << endl;
+#endif
+ if (atoi(prefix_command.c_str()) > 99)
+ prefix_command = "99"; // Let's not go overboard here.
+}
+
+int enabler_inputst::prefix_end() {
+ if (prefix_command.size()) {
+ int repeats = atoi(prefix_command.c_str());
+ prefix_toggle();
+ return repeats;
+ } else {
+ return 1;
+ }
+}
+
+string enabler_inputst::prefix() {
+ return prefix_command;
+}
diff --git a/g_src/enabler_input.h b/g_src/enabler_input.h
new file mode 100755
index 0000000..be5f94b
--- /dev/null
+++ b/g_src/enabler_input.h
@@ -0,0 +1,137 @@
+#ifndef ENABLER_INPUT_H
+#define ENABLER_INPUT_H
+
+#ifdef __APPLE__
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+
+#include <SDL/SDL.h>
+#include <string>
+#include <set>
+#include <list>
+
+#include "ViewBase.h"
+#include "keybindings.h"
+#include "curses.h"
+
+typedef Uint32 Time;
+
+enum Repeat {
+ REPEAT_NOT, // Don't repeat at all. Furthermore, cancel other repeats.
+ REPEAT_SLOW, // Repeat normally.
+ REPEAT_FAST // Repeat instantly, without waiting for the first-repeat interval.
+};
+
+enum MatchType { type_unicode, type_key, type_button };
+
+Uint8 getModState();
+std::string translate_mod(Uint8 mod);
+int decode_utf8(const std::string &s);
+int decode_utf8_predict_length(char byte);
+std::string encode_utf8(int unicode);
+
+#define DFMOD_SHIFT 1
+#define DFMOD_CTRL 2
+#define DFMOD_ALT 4
+
+struct EventMatch {
+ MatchType type;
+ Uint8 mod; // not defined for type=unicode. 1: shift, 2: ctrl, 4:alt
+ Uint8 scancode; // not defined for type=button
+ union {
+ Uint16 unicode;
+ SDLKey key;
+ Uint8 button;
+ };
+
+ bool operator== (const EventMatch &other) const {
+ if (mod != other.mod) return false;
+ if (type != other.type) return false;
+ switch (type) {
+ case type_unicode: return unicode == other.unicode;
+ case type_key: return key == other.key;
+ case type_button: return button == other.button;
+ default: return false;
+ }
+ }
+
+ bool operator< (const EventMatch &other) const {
+ if (mod != other.mod) return mod < other.mod;
+ if (type != other.type) return type < other.type;
+ switch (type) {
+ case type_unicode: return unicode < other.unicode;
+ case type_key: return key < other.key;
+ case type_button: return button < other.button;
+ default: return false;
+ }
+ }
+};
+
+struct KeyEvent {
+ bool release;
+ EventMatch match;
+};
+
+typedef std::list<std::set<InterfaceKey> > macro;
+
+struct RegisteredKey {
+ MatchType type;
+ string display;
+};
+
+class enabler_inputst {
+ std::set<InterfaceKey> key_translation(EventMatch &match);
+ public:
+ Repeat key_repeat(InterfaceKey);
+ void key_repeat(InterfaceKey, Repeat);
+ void load_macro_from_file(const std::string &file);
+ void save_macro_to_file(const std::string &file, const std::string &name, const macro &);
+
+ // In practice.. do not use this one.
+ void add_input(SDL_Event &e, Time now);
+ // Use this one. It's much nicer.
+ void add_input_refined(KeyEvent &e, Time now, int serial);
+ // Made specifically for curses. <0 = unicode, >0 = ncurses symbols.
+#ifdef CURSES
+ void add_input_ncurses(int key, Time now, bool esc);
+#endif
+ std::set<InterfaceKey> get_input(Time now);
+ void clear_input();
+
+ void load_keybindings(const std::string &file);
+ void save_keybindings(const std::string &file);
+ void save_keybindings();
+ std::string GetKeyDisplay(int binding);
+ std::string GetBindingDisplay(int binding);
+ std::string GetBindingTextDisplay(int binding);
+
+ // Macros
+ void record_input(); // Records input until such a time as you say stop
+ void record_stop(); // Stops recording, saving it as the active macro
+ bool is_recording();
+ void play_macro(); // Runs the active macro, if any
+ bool is_macro_playing();
+ std::list<string> list_macros();
+ void load_macro(string name); // Loads some macro as the active one
+ void save_macro(string name); // Saves the active macro under some name
+ void delete_macro(string name);
+
+ // Prefix commands
+ bool prefix_building();
+ void prefix_toggle();
+ void prefix_add_digit(char digit);
+ int prefix_end();
+ string prefix();
+
+ // Updating the key-bindings
+ void register_key(); // Sets the next key-press to be stored instead of executed.
+ list<RegisteredKey> getRegisteredKey(); // Returns a description of stored keys. Max one of each type.
+ void bindRegisteredKey(MatchType type, InterfaceKey key); // Binds one of the stored keys to key
+ bool is_registering(); // Returns true if we're still waiting for a key-hit
+
+ std::list<EventMatch> list_keys(InterfaceKey key); // Returns a list of events matching this interfacekey
+ void remove_key(InterfaceKey key, EventMatch ev); // Removes a particular matcher from the keymap.
+};
+
+
+#endif
diff --git a/g_src/endian.h b/g_src/endian.h
new file mode 100755
index 0000000..b56dee4
--- /dev/null
+++ b/g_src/endian.h
@@ -0,0 +1,42 @@
+#ifndef ENDIAN_H
+#define ENDIAN_H
+
+inline unsigned short byteswap(unsigned short x)
+{
+#if defined(__ppc__) || defined(__ppc64__)
+ return (x << 8 | x >> 8);
+#else
+ return x;
+#endif
+}
+
+inline unsigned long byteswap(unsigned long x)
+{
+#if defined(__ppc__) || defined(__ppc64__)
+ return
+ ( (x << 24) & 0xFF000000) |
+ ( (x << 8) & 0x00FF0000) |
+ ( (x >> 8) & 0x0000FF00) |
+ ( (x >> 24) & 0x000000FF) ;
+#else
+ return x;
+#endif
+}
+
+inline unsigned int byteswap(unsigned int x)
+{
+#if defined(__ppc__) || defined(__ppc64__)
+ return
+ ( (x << 24) & 0xFF000000) |
+ ( (x << 8) & 0x00FF0000) |
+ ( (x >> 8) & 0x0000FF00) |
+ ( (x >> 24) & 0x000000FF) ;
+#else
+ return x;
+#endif
+}
+
+inline short byteswap(short x) { return byteswap( (unsigned short) x ); }
+inline long byteswap(long x) { return byteswap( (unsigned long) x ); }
+inline int byteswap(int x) { return byteswap( (unsigned int) x ); }
+#endif
diff --git a/g_src/files.cpp b/g_src/files.cpp
new file mode 100755
index 0000000..581e024
--- /dev/null
+++ b/g_src/files.cpp
@@ -0,0 +1,428 @@
+#include "platform.h"
+#include <cerrno>
+#include <string>
+#include <cstring>
+#include <cmath>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <algorithm>
+#include <map>
+#include <set>
+#include <stdio.h>
+//#include <unistd.h>
+
+extern "C" {
+#include <zlib.h>
+#ifndef WIN32
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/time.h>
+# include <signal.h>
+#endif
+}
+#include "svector.h"
+
+#ifdef WIN32
+
+#ifndef INTEGER_TYPES
+ #define INTEGER_TYPES
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned long long uint64_t;
+#endif
+
+typedef int32_t VIndex;
+typedef int32_t Ordinal;
+
+#endif
+
+#include "random.h"
+
+using std::string;
+
+#include "basics.h"
+#include "endian.h"
+#include "files.h"
+#include "enabler.h"
+#include "find_files.h"
+
+inline void CHECK_ERR(int err, const char* msg)
+{
+ if (err != Z_OK)
+ {
+ MessageBox(NULL, "One of the compressed files on disk has errors in it. Restore from backup if you are able.", 0, 0);
+ exit(1);
+ }
+}
+
+using std::fstream;
+
+char file_compressorst::def_ibuff[FILE_IN_BUFF];
+char file_compressorst::def_obuff[FILE_OUT_BUFF];
+
+char file_compressorst::load_posnull_pointer()
+{
+ char dummy;
+ read_file(dummy);
+
+ if(!dummy)return 0;
+ else return 1;
+}
+
+char file_compressorst::save_posnull_pointer(void *ptr)
+{
+ char dummy;
+
+ if(ptr==NULL)
+ {
+ dummy=0;
+ write_file(dummy);
+ return 0;
+ }
+ else
+ {
+ dummy=1;
+ write_file(dummy);
+ return 1;
+ }
+}
+
+char file_compressorst::write_file(string &str)
+{
+ short ln=str.length();
+ if(ln>=10000||ln<0)ln=0;
+
+ if(!write_file(ln))return 0;
+
+ if(ln==0)return 1;
+
+ if(!write_file((void *)str.c_str(),sizeof(char)*ln))return 0;
+
+ return 1;
+}
+
+char file_compressorst::read_file(string &str)
+{
+ str.erase();
+
+ short ln;
+
+ if(!read_file(ln))return 0;
+
+ if(ln==0)return 1;
+
+ char *strar=new char[ln+1];
+
+ if(!read_file(strar,sizeof(char)*ln))
+ {
+ delete[] strar;
+ return 0;
+ }
+ strar[ln]='\x0';
+
+ str=strar;
+
+ delete[] strar;
+ return 1;
+}
+
+char file_compressorst::write_file(void *write_var,long write_size)
+{
+ if (!f.is_open())return 0;
+
+ if(!compressed)
+ {
+ f.write((char *)write_var,write_size);
+ return 1;
+ }
+
+ //WRITE OUT THE VARIABLE CHUNK BY CHUNK
+ while(write_size>0)
+ {
+ //FLUSH THE BUFFER IF NECESSARY
+ if(in_buffer_amount_loaded>=in_buffersize)
+ {
+ if(!flush_in_buffer())return 0;
+ }
+
+ //SET THE AMOUNT TO COPY
+ long copy_size=in_buffersize-in_buffer_amount_loaded;
+ if(write_size<copy_size)copy_size=write_size;
+
+ //COPY THE NEXT CHUNK INTO THE BUFFER
+ memmove(in_buffer+in_buffer_amount_loaded,write_var,copy_size);
+
+ write_var=((char *)write_var) + copy_size;
+ write_size-=copy_size;
+ in_buffer_amount_loaded+=copy_size;
+ }
+
+ return 1;
+}
+
+char file_compressorst::flush_in_buffer()
+{
+ if (!f.is_open())return 0;
+ if(!compressed)return 1;
+ if(in_buffer_amount_loaded==0)return 1;//EXTRA CALLS TO FLUSH SHOULDN'T KILL YOU
+
+ //TARN: adapted from zlib example files
+
+ //SET UP THE COMPRESSOR
+ z_stream c_stream;
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, 9);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = (Bytef*)out_buffer;
+ c_stream.avail_out = out_buffersize;
+
+ //SEND IT TO THE COMPRESSOR
+ c_stream.next_in = (Bytef*)in_buffer;
+ c_stream.avail_in = in_buffer_amount_loaded;
+
+ while (c_stream.total_in != in_buffer_amount_loaded && c_stream.total_out < out_buffersize)
+ {
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+
+ //FINISH UP THE STREAM
+ while(1)
+ {
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ //SAVE THE COMPRESSED BIT AS A GIANT BLOCK
+ if(c_stream.total_out>0)
+ {
+ long compsize=byteswap((long)(c_stream.total_out));
+
+ //WRITE IT
+ f.write((char*)&compsize,sizeof(long));
+ f.write(out_buffer,c_stream.total_out);
+ }
+
+ in_buffer_position=0;
+ in_buffer_amount_loaded=0;
+
+ return 1;
+}
+
+char file_compressorst::read_file(void *read_var,long read_size)
+{
+ if (!f.is_open())return 0;
+
+ if(!compressed)
+ {
+ f.read((char *)read_var,read_size);
+ return 1;
+ }
+
+ //NOW LOAD INTO read_var UNTIL DONE
+ while(read_size>0)
+ {
+ //GET A BUFFER IF NECESSARY
+ if(in_buffer_amount_loaded==0||
+ in_buffer_position>=in_buffer_amount_loaded)
+ {
+ if(!load_new_in_buffer())return 0;
+ }
+
+ //BAIL IF STILL NO BUFFER LEFT
+ if(in_buffer_amount_loaded==0)return 0;
+
+ //SET THE AMOUNT TO COPY
+ long copy_size=in_buffer_amount_loaded-in_buffer_position;
+ if(read_size<copy_size)copy_size=read_size;
+
+ //COPY
+ memmove(read_var,in_buffer+in_buffer_position,copy_size);
+
+ read_var=((char *)read_var) + copy_size;
+ read_size-=copy_size;
+ in_buffer_position+=copy_size;
+ }
+
+ return 1;
+}
+
+char file_compressorst::load_new_in_buffer()
+{
+ if (!f.is_open())return 0;
+ if(!compressed)return 1;
+
+ in_buffer_position=0;
+ in_buffer_amount_loaded=0;
+
+ //LOAD THE BLOCK OF COMPRESSED DATA
+ f.read((char*)&out_buffer_amount_written,sizeof(long));
+ out_buffer_amount_written=byteswap(out_buffer_amount_written);
+ f.read(out_buffer,out_buffer_amount_written);
+
+ int err;
+
+ if(out_buffer_amount_written>0)
+ {
+ //TARN: adapted from zlib example files
+
+ //UNCOMPRESS
+ z_stream d_stream; // decompression stream
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = (Bytef*)out_buffer;
+ d_stream.avail_in = out_buffer_amount_written;
+
+ err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = (Bytef*)in_buffer;
+ d_stream.avail_out = in_buffersize;
+
+ while (d_stream.total_out < in_buffersize && d_stream.total_in < out_buffer_amount_written)
+ {
+ //d_stream.avail_in = d_stream.avail_out = 1; // force small buffers
+ err = inflate(&d_stream, Z_NO_FLUSH);
+
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ in_buffer_amount_loaded=d_stream.total_out;
+
+ return 1;
+ }
+ else return 0;
+}
+
+void file_compressorst::close_file()
+{
+ if (f.is_open())
+ {
+ f.close();
+ }
+}
+
+char file_compressorst::open_file(const string &filename,char existing_only)
+{
+ if(filename.empty())return 0;
+
+ //RESET DATA
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+ out_buffer_amount_written=0;
+
+/*
+ //CHECK IF FILE ALREADY EXISTS
+ f.open(filename.c_str(), fstream::in);
+ char file_exists = f.is_open();
+ if (file_exists)f.close();
+
+ //OPEN FILE
+ if(!existing_only || file_exists)
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
+ else
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
+*/
+ //if(existing_only)h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
+ //else h=CreateFile(filename.c_str(),GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
+
+ if(f.is_open())f.close();
+ f.clear();
+
+ if(existing_only)
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary);
+ else
+ f.open(filename.c_str(), fstream::in | fstream::out | fstream::binary | fstream::trunc);
+
+ if (f.is_open())return 1;
+ else return 0;
+}
+
+file_compressorst::file_compressorst(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize)
+{
+ compressed=true;
+
+ in_buffer=new_in_buffer;
+ in_buffersize=new_in_buffersize;
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+
+ out_buffer=new_out_buffer;
+ out_buffersize=new_out_buffersize;
+ out_buffer_amount_written=0;
+
+ f.clear();
+}
+
+void file_compressorst::set_buffer_info(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize)
+{
+ in_buffer=new_in_buffer;
+ in_buffersize=new_in_buffersize;
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+
+ out_buffer=new_out_buffer;
+ out_buffersize=new_out_buffersize;
+ out_buffer_amount_written=0;
+
+ f.clear();
+}
+
+
+file_compressorst::file_compressorst()
+{
+ compressed=true;
+
+ in_buffer=def_ibuff;
+ in_buffersize=FILE_IN_BUFF;
+ in_buffer_amount_loaded=0;
+ in_buffer_position=0;
+
+ out_buffer=def_obuff;
+ out_buffersize=FILE_OUT_BUFF;
+ out_buffer_amount_written=0;
+
+ f.clear();
+}
+
+void copy_file(const string &src,const string &dst)
+{
+ std::ifstream in_stream(src.c_str(),std::ios_base::binary);
+ std::ofstream out_stream(dst.c_str(),std::ios_base::binary);
+ if(in_stream.is_open()&&out_stream.is_open())
+ {
+ out_stream<<in_stream.rdbuf();
+ }
+ in_stream.close();
+ out_stream.close();
+}
+
+void replace_file(const string &src, const string &dst) {
+#ifdef WIN32
+ remove(dst.c_str());
+#endif
+ rename(src.c_str(), dst.c_str());
+}
diff --git a/g_src/files.h b/g_src/files.h
new file mode 100755
index 0000000..2f11c72
--- /dev/null
+++ b/g_src/files.h
@@ -0,0 +1,368 @@
+//Copyright (c) 2006, Tarn Adams
+//All rights reserved. See game.cpp or license.txt for more information.
+#ifndef FILES_H
+#define FILES_H
+
+#define FILE_IN_BUFF 1000000
+#define FILE_OUT_BUFF 2000000
+
+#include <string>
+using std::string;
+
+#include <fstream>
+#include "endian.h"
+#include "svector.h"
+
+class file_compressorst
+{
+ public:
+ bool compressed;
+ std::fstream f;
+
+
+ char open_file(const string &filename,char existing_only);
+ void close_file();
+ char write_file(string &str);
+ char read_file(string &str);
+
+ char load_posnull_pointer();
+ char save_posnull_pointer(void *ptr);
+
+ void write_file_fixedlength(char *var)
+ {
+ short len=strlen(var);
+ write_file(len);
+ if(len>0)write_file(var,len*sizeof(char));
+ }
+ void read_file_fixedlength(char *var)
+ {
+ short len;
+ read_file(len);//DO NOT NEED TO ALLOCATE SPACE
+ if(len>0)read_file(var,len*sizeof(char));
+ var[len]='\x0';
+ }
+ char write_file(long var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(long));
+ }
+ char read_file(long &var)
+ {
+ char ret = read_file(&var,sizeof(long));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(int var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(int));
+ }
+ char read_file(int &var)
+ {
+ char ret = read_file(&var,sizeof(int));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(short var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(short));
+ }
+ char read_file(short &var)
+ {
+ char ret = read_file(&var,sizeof(short));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(char var)
+ {
+ return write_file(&var,sizeof(char));
+ }
+ char read_file(char &var)
+ {
+ return read_file(&var,sizeof(char));
+ }
+ char write_file(bool var)
+ {
+ char temp;
+ if(var)temp=1;
+ else temp=0;
+ return write_file(&temp,sizeof(char));
+ }
+ char read_file(bool &var)
+ {
+ char temp;
+ if(!read_file(&temp,sizeof(char)))return 0;
+ var=(temp!=0);
+ return 1;
+ }
+ char write_file(unsigned long var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(unsigned long));
+ }
+ char read_file(unsigned long &var)
+ {
+ char ret = read_file(&var,sizeof(unsigned long));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(unsigned int var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(unsigned int));
+ }
+ char read_file(unsigned int &var)
+ {
+ char ret = read_file(&var,sizeof(unsigned int));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(unsigned short var)
+ {
+ var=byteswap(var);
+ return write_file(&var,sizeof(unsigned short));
+ }
+ char read_file(unsigned short &var)
+ {
+ char ret = read_file(&var,sizeof(unsigned short));
+ var = byteswap(var);
+ return ret;
+ }
+ char write_file(unsigned char var)
+ {
+ return write_file(&var,sizeof(unsigned char));
+ }
+ char read_file(unsigned char &var)
+ {
+ return read_file(&var,sizeof(unsigned char));
+ }
+ void write_file(svector<bool> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ bool bl;//JUST FOR PARITY WITH read BELOW
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ bl=(*i_b);
+ write_file(bl);
+ }
+ }
+ void read_file(svector<bool> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ bool bl;//NO IDEA WHY IT CAN'T JUST TAKE vect[i]
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file(bl);
+ (*i_b)=bl;
+ }
+ }
+ void write_file(svector<short> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<short> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned short> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned short> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned char> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned char> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<char> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<char> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<long> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<long> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned long> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned long> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<int> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<int> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+ void write_file(svector<unsigned int> &vect)
+ {
+ long s=vect.size();
+ write_file(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ write_file((*i_b));
+ }
+ }
+ void read_file(svector<unsigned int> &vect)
+ {
+ long s;
+ read_file(s);
+ vect.resize(s);
+ auto i_b=vect.begin(),i_e=vect.end();
+ for(;i_b<i_e;++i_b)
+ {
+ read_file((*i_b));
+ }
+ }
+
+
+ char load_new_in_buffer();
+ char flush_in_buffer();
+
+ file_compressorst();
+ file_compressorst(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize);
+ ~file_compressorst()
+ {
+ close_file();
+ }
+ void set_buffer_info(char *new_in_buffer,long new_in_buffersize,
+ char *new_out_buffer,long new_out_buffersize);
+
+ private:
+ char write_file(void *write_var,long write_size);
+ char read_file(void *read_var,long read_size);
+
+ char *in_buffer;
+ long in_buffersize;
+ long in_buffer_amount_loaded;
+ long in_buffer_position;
+
+ char *out_buffer;
+ long out_buffersize;
+ long out_buffer_amount_written;
+
+ static char def_ibuff[FILE_IN_BUFF];
+ static char def_obuff[FILE_OUT_BUFF];
+};
+
+void copy_file(const string &src,const string &dst);
+// Replaces dst with src, removing src in the process. Atomic if possible.
+void replace_file(const string &src, const string &dst);
+#endif
diff --git a/g_src/find_files.cpp b/g_src/find_files.cpp
new file mode 100755
index 0000000..059dcc7
--- /dev/null
+++ b/g_src/find_files.cpp
@@ -0,0 +1,180 @@
+#include "../game_g.h"
+#include "../game_extv.h"
+
+void find_files_by_pattern(const char* pattern, svector<char *>& filenames)
+{
+ HANDLE h;
+ WIN32_FIND_DATA finddata;
+ char *c;
+
+ h=FindFirstFile(pattern,&finddata);
+
+ if(h!=INVALID_HANDLE_VALUE)
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,".."))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ c=new char[strlen(finddata.cFileName)+1];
+ strcpy(c,finddata.cFileName);
+ filenames.push_back(c);
+ }
+ }
+
+ while(FindNextFile(h,&finddata))
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,".."))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ c=new char[strlen(finddata.cFileName)+1];
+ strcpy(c,finddata.cFileName);
+ filenames.push_back(c);
+ }
+ }
+ }
+
+ FindClose(h);
+ }
+}
+
+void find_files_by_pattern_with_exception(const char* pattern, svector<char *>& filenames,const char *exception)
+{
+ HANDLE h;
+ WIN32_FIND_DATA finddata;
+ char *c;
+
+ h=FindFirstFile(pattern,&finddata);
+
+ if(h!=INVALID_HANDLE_VALUE)
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ c=new char[strlen(finddata.cFileName)+1];
+ strcpy(c,finddata.cFileName);
+ filenames.push_back(c);
+ }
+ }
+
+ while(FindNextFile(h,&finddata))
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
+ {
+ c=new char[strlen(finddata.cFileName)+1];
+ strcpy(c,finddata.cFileName);
+ filenames.push_back(c);
+ }
+ }
+ }
+
+ FindClose(h);
+ }
+}
+
+void find_files_by_pattern(const char* pattern, stringvectst &filenames)
+{
+ HANDLE h;
+ WIN32_FIND_DATA finddata;
+
+ h=FindFirstFile(pattern,&finddata);
+
+ if(h!=INVALID_HANDLE_VALUE)
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,".."))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName);
+ }
+
+ while(FindNextFile(h,&finddata))
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,".."))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName);
+ }
+ }
+
+ FindClose(h);
+ }
+}
+
+void find_files_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception)
+{
+ HANDLE h;
+ WIN32_FIND_DATA finddata;
+
+ h=FindFirstFile(pattern,&finddata);
+
+ if(h!=INVALID_HANDLE_VALUE)
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName);
+ }
+
+ while(FindNextFile(h,&finddata))
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception))
+ {
+ if(!(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))filenames.add_string(finddata.cFileName);
+ }
+ }
+
+ FindClose(h);
+ }
+}
+
+void find_directories_by_pattern(const char* pattern, stringvectst &filenames)
+{
+ HANDLE h;
+ WIN32_FIND_DATA finddata;
+
+ h=FindFirstFile(pattern,&finddata);
+
+ if(h!=INVALID_HANDLE_VALUE)
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,".."))
+ {
+ if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName);
+ }
+
+ while(FindNextFile(h,&finddata))
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,".."))
+ {
+ if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName);
+ }
+ }
+
+ FindClose(h);
+ }
+}
+
+void find_directories_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception)
+{
+ HANDLE h;
+ WIN32_FIND_DATA finddata;
+
+ h=FindFirstFile(pattern,&finddata);
+
+ if(h!=INVALID_HANDLE_VALUE)
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception))
+ {
+ if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName);
+ }
+
+ while(FindNextFile(h,&finddata))
+ {
+ if(strcmp(finddata.cFileName,".")&&strcmp(finddata.cFileName,"..")&&strcmp(finddata.cFileName,exception))
+ {
+ if(finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)filenames.add_string(finddata.cFileName);
+ }
+ }
+
+ FindClose(h);
+ }
+} \ No newline at end of file
diff --git a/g_src/find_files.h b/g_src/find_files.h
new file mode 100755
index 0000000..3f93e9f
--- /dev/null
+++ b/g_src/find_files.h
@@ -0,0 +1,6 @@
+void find_files_by_pattern(const char* pattern, svector<char *>& vec);
+void find_files_by_pattern_with_exception(const char* pattern, svector<char *>& vec, const char* exception);
+void find_files_by_pattern(const char* pattern, stringvectst &vec);
+void find_files_by_pattern_with_exception(const char* pattern, stringvectst &vec, const char* exception);
+void find_directories_by_pattern(const char* pattern, stringvectst &filenames);
+void find_directories_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception); \ No newline at end of file
diff --git a/g_src/find_files_posix.cpp b/g_src/find_files_posix.cpp
new file mode 100755
index 0000000..bda787b
--- /dev/null
+++ b/g_src/find_files_posix.cpp
@@ -0,0 +1,185 @@
+#include "platform.h"
+#include <cerrno>
+#include <string>
+#include <cstring>
+#include <cmath>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <algorithm>
+#include <map>
+#include <set>
+
+extern "C" {
+#include <zlib.h>
+#ifndef WIN32
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/time.h>
+# include <signal.h>
+#endif
+}
+#include "svector.h"
+#include "random.h"
+
+using std::string;
+
+#include "basics.h"
+#include "endian.h"
+#include "files.h"
+#include "enabler.h"
+#include "find_files.h"
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <glob.h>
+#include <string.h>
+
+void find_files_by_pattern(const char* pattern, svector<char *>& filenames)
+{
+ glob_t g;
+ if (!glob(pattern, 0, NULL, &g))
+ {
+ for (int i = 0; i < g.gl_pathc; ++i)
+ {
+ struct stat cstat;
+ stat(g.gl_pathv[i],&cstat);
+ if(!S_ISREG(cstat.st_mode))continue;
+
+ // don't include the path
+ char* src = strrchr(g.gl_pathv[i], '/');
+ if (src)
+ {
+ int len = strlen(++src);
+ char* c = new char[len + 1]; // caller will free this
+ strcpy(c, src);
+ filenames.push_back(c);
+ }
+ }
+ }
+ globfree(&g);
+}
+
+void find_files_by_pattern_with_exception(const char* pattern, svector<char *>& filenames,const char *exception)
+{
+ glob_t g;
+ if (!glob(pattern, 0, NULL, &g))
+ {
+ for (int i = 0; i < g.gl_pathc; ++i)
+ {
+ struct stat cstat;
+ stat(g.gl_pathv[i],&cstat);
+ if(!S_ISREG(cstat.st_mode))continue;
+
+ // don't include the path
+ char* src = strrchr(g.gl_pathv[i], '/');
+ if (src)
+ {
+ int len = strlen(++src);
+ if(!strcmp(src,exception))continue;
+
+ char* c = new char[len + 1]; // caller will free this
+ strcpy(c, src);
+ filenames.push_back(c);
+ }
+ }
+ }
+ globfree(&g);
+}
+
+void find_files_by_pattern(const char* pattern, stringvectst& filenames)
+{
+ glob_t g;
+ if (!glob(pattern, 0, NULL, &g))
+ {
+ for (int i = 0; i < g.gl_pathc; ++i)
+ {
+ struct stat cstat;
+ stat(g.gl_pathv[i],&cstat);
+ if(!S_ISREG(cstat.st_mode))continue;
+
+ // don't include the path
+ char* src = strrchr(g.gl_pathv[i], '/');
+ if (src)
+ {
+ ++src;
+ filenames.add_string(src);
+ }
+ }
+ }
+ globfree(&g);
+}
+
+void find_files_by_pattern_with_exception(const char* pattern, stringvectst& filenames,const char *exception)
+{
+ glob_t g;
+ if (!glob(pattern, 0, NULL, &g))
+ {
+ for (int i = 0; i < g.gl_pathc; ++i)
+ {
+ struct stat cstat;
+ stat(g.gl_pathv[i],&cstat);
+ if(!S_ISREG(cstat.st_mode))continue;
+
+ // don't include the path
+ char* src = strrchr(g.gl_pathv[i], '/');
+ if (src)
+ {
+ ++src;
+ if(!strcmp(src,exception))continue;
+
+ filenames.add_string(src);
+ }
+ }
+ }
+ globfree(&g);
+}
+
+void find_directories_by_pattern(const char* pattern, stringvectst &filenames)
+{
+ glob_t g;
+ if (!glob(pattern, 0, NULL, &g))
+ {
+ for (int i = 0; i < g.gl_pathc; ++i)
+ {
+ struct stat cstat;
+ stat(g.gl_pathv[i],&cstat);
+ if(!S_ISDIR(cstat.st_mode))continue;
+
+ // don't include the path
+ char* src = strrchr(g.gl_pathv[i], '/');
+ if (src)
+ {
+ ++src;
+ filenames.add_string(src);
+ }
+ }
+ }
+ globfree(&g);
+}
+
+void find_directories_by_pattern_with_exception(const char* pattern, stringvectst &filenames,const char *exception)
+{
+ glob_t g;
+ if (!glob(pattern, 0, NULL, &g))
+ {
+ for (int i = 0; i < g.gl_pathc; ++i)
+ {
+ struct stat cstat;
+ stat(g.gl_pathv[i],&cstat);
+ if(!S_ISDIR(cstat.st_mode))continue;
+
+ // don't include the path
+ char* src = strrchr(g.gl_pathv[i], '/');
+ if (src)
+ {
+ ++src;
+ if(!strcmp(src,exception))continue;
+
+ filenames.add_string(src);
+ }
+ }
+ }
+ globfree(&g);
+}
diff --git a/g_src/g_basics.h b/g_src/g_basics.h
new file mode 100755
index 0000000..eca424c
--- /dev/null
+++ b/g_src/g_basics.h
@@ -0,0 +1,33 @@
+#ifndef G_BASICS_H
+#define G_BASICS_H
+
+#define MAX_GRID_X 256
+#define MAX_GRID_Y 256
+#define MIN_GRID_X 80
+#define MIN_GRID_Y 25
+
+#ifndef MAX
+# define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+#ifndef MIN
+# define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+#ifndef ARRSZ
+# define ARRSZ(arr) (sizeof (arr) / sizeof ((arr)[0]))
+#endif
+#ifndef CLAMP
+#define CLAMP(x,a,b) MIN(MAX((x),(a)),(b))
+#endif
+
+// GL error macro
+extern int glerrorcount;
+
+#ifdef DEBUG
+# define printGLError() do { GLenum err; do { err = glGetError(); if (err && glerrorcount < 40) { printf("GL error: 0x%x in %s:%d\n", err, __FILE__ , __LINE__); glerrorcount++; } } while(err); } while(0);
+# define deputs(str) puts(str)
+#else
+# define printGLError()
+# define deputs(str)
+#endif
+
+#endif
diff --git a/g_src/graphics.cpp b/g_src/graphics.cpp
new file mode 100755
index 0000000..2f3237a
--- /dev/null
+++ b/g_src/graphics.cpp
@@ -0,0 +1,566 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+#include <cassert>
+
+#include "svector.h"
+#include "ttf_manager.hpp"
+
+#ifdef WIN32
+
+/*
+#ifndef INTEGER_TYPES
+ #define INTEGER_TYPES
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned long long uint64_t;
+#endif
+*/
+
+typedef int32_t VIndex;
+typedef int32_t Ordinal;
+
+#endif
+
+#include "random.h"
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "find_files.h"
+
+#include "basics.h"
+
+#include "g_basics.h"
+
+#include "texture_handler.h"
+
+#include "graphics.h"
+
+#include "music_and_sound_g.h"
+
+#include "init.h"
+
+#include "interface.h"
+
+#ifdef __APPLE__
+#define _XOPEN_SOURCE_EXTENDED
+#endif
+
+#include "curses.h"
+
+using namespace std;
+
+
+#pragma comment( lib, "opengl32.lib" ) // Search For OpenGL32.lib While Linking
+#pragma comment( lib, "glu32.lib" ) // Search For GLu32.lib While Linking
+
+extern enablerst enabler;
+extern texture_handlerst texture;
+graphicst gps;
+extern interfacest gview;
+
+extern string errorlog_prefix;
+
+void process_object_lines(textlinesst &lines,string &chktype,string &graphics_dir);
+
+// Add, then increment to the (possible) PBO alignment requirement
+static void align(size_t &sz, off_t inc) {
+ sz += inc;
+ while (sz%64) sz++; // So.. tired.. FIXME.
+}
+
+void graphicst::resize(int x, int y) {
+ dimx = x; dimy = y;
+ init.display.grid_x = x;
+ init.display.grid_y = y;
+ setclipping(0, x-1, 0, y-1);
+ force_full_display_count++;
+ screen_limit = screen + dimx * dimy * 4;
+}
+
+void graphicst::addcoloredst(const char *str,const char *colorstr)
+{
+ const int slen = strlen(str);
+ int s;
+ for(s=0; s < slen && screenx < init.display.grid_x; s++)
+ {
+ if(screenx<0)
+ {
+ s-=screenx;
+ screenx=0;
+ if (s >= slen) break;
+ }
+
+ changecolor((colorstr[s] & 7),((colorstr[s] & 56))>>3,((colorstr[s] & 64))>>6);
+ addchar(str[s]);
+ }
+}
+
+static list<ttf_id> ttfstr;
+
+static void abbreviate_string_helper_hackaroundmissingcode(string &str, int len) {
+ if(str.length()>=2)
+ {
+ if((str[0]=='A'||str[0]=='a')&&
+ str[1]==' ')
+ {
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+
+ if(str.length()>=3)
+ {
+ if((str[0]=='A'||str[0]=='a')&&
+ (str[1]=='N'||str[1]=='n')&&
+ str[2]==' ')
+ {
+ str.erase(str.begin()+2);
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+
+ if(str.length()>=4)
+ {
+ if((str[0]=='T'||str[0]=='t')&&
+ (str[1]=='H'||str[1]=='h')&&
+ (str[2]=='E'||str[2]=='e')&&
+ str[3]==' ')
+ {
+ str.erase(str.begin()+3);
+ str.erase(str.begin()+2);
+ str.erase(str.begin()+1);
+ str.erase(str.begin());
+
+ if(str.length()<=len)return;
+ }
+ }
+ }
+ }
+
+ int32_t l;
+ for(l=(int32_t)str.length()-1;l>=1;l--)
+ {
+ if(str[l-1]==' ')continue;
+
+ if(str[l]=='a'||
+ str[l]=='e'||
+ str[l]=='i'||
+ str[l]=='o'||
+ str[l]=='u'||
+ str[l]=='A'||
+ str[l]=='E'||
+ str[l]=='I'||
+ str[l]=='O'||
+ str[l]=='U')
+ {
+ str.erase(str.begin()+l);
+ if(str.length()<=len)return;
+ }
+ }
+
+ if(str.length()>len)str.resize(len);
+}
+
+
+static void abbreviate_string_hackaroundmissingcode(string &str, int32_t len)
+{
+ if (ttf_manager.ttf_active()) {
+ // We'll need to use TTF-aware text shrinking.
+ while (ttf_manager.size_text(str) > len)
+ abbreviate_string_helper_hackaroundmissingcode(str, str.length() - 1);
+ } else if(str.length()>len){
+ // 1 letter = 1 tile.
+ abbreviate_string_helper_hackaroundmissingcode(str, len);
+ }
+}
+
+
+void graphicst::addst(const string &str_orig, justification just, int space)
+{
+ if (!str_orig.size())
+ return;
+ string str = str_orig;
+ if (space)
+ abbreviate_string_hackaroundmissingcode(str, space);
+ if (just == not_truetype || !ttf_manager.ttf_active()) {
+ int s;
+ for(s=0;s<str.length()&&screenx<init.display.grid_x;s++)
+ {
+ if(screenx<0)
+ {
+ s-=screenx;
+ screenx=0;
+ if(s>=str.length())break;
+ }
+
+ addchar(str[s]);
+ }
+ } else {
+ // Truetype
+ if (str.size() > 2 && str[0] == ':' && str[1] == ' ')
+ str[1] = '\t'; // EVIL HACK
+ struct ttf_id id = {str, screenf, screenb, screenbright};
+ ttfstr.push_back(id);
+ // if (str.size() == 80) {
+ // cout << "(" << int(str[0]) << ") ";
+ // }
+ // cout << screeny << "," << str.size() << ":" << str;
+ // if (just == justify_cont)
+ // cout << "|";
+ // else
+ // cout << endl;
+ if (just == justify_cont)
+ return; // More later
+ // This string is done. Time to render.
+ ttf_details details = ttf_manager.get_handle(ttfstr, just);
+ const int handle = details.handle;
+ const int offset = details.offset;
+ int width = details.width;
+ const int ourx = screenx + offset;
+ unsigned int * const s = ((unsigned int*)screen + ourx*dimy + screeny);
+ if (s < (unsigned int*)screen_limit)
+ s[0] = (((unsigned int)GRAPHICSTYPE_TTF) << 24) | handle;
+ // Also set the other tiles this text covers, but don't write past the end.
+ if (width + ourx >= dimx)
+ width = dimx - ourx - 1;
+ for (int x = 1; x < width; ++x)
+ s[x * dimy] = (((unsigned int)GRAPHICSTYPE_TTFCONT) << 24) | handle;
+ // Clean up, prepare for next string.
+ screenx = ourx + width;
+ ttfstr.clear();
+ }
+}
+
+void graphicst::erasescreen_clip()
+{
+ changecolor(0,0,0);
+ short x2,y2;
+ for(x2=clipx[0];x2<=clipx[1];x2++)
+ {
+ for(y2=clipy[0];y2<=clipy[1];y2++)
+ {
+ locate(y2,x2);
+ addchar(' ');
+ }
+ }
+}
+
+void graphicst::erasescreen_rect(int x1, int x2, int y1, int y2)
+{
+ changecolor(0,0,0);
+ for (int x = x1; x <= x2; x++) {
+ for (int y = y1; y <= y2; y++) {
+ locate(y, x);
+ addchar(' ');
+ }
+ }
+}
+
+void graphicst::erasescreen()
+{
+ memset(screen, 0, dimx*dimy*4);
+
+ memset(screentexpos, 0, dimx*dimy*sizeof(long));
+}
+
+void graphicst::setclipping(long x1,long x2,long y1,long y2)
+{
+ if(x1<0)x1=0;
+ if(x2>init.display.grid_x-1)x2=init.display.grid_x-1;
+ if(y1<0)y1=0;
+ if(y2>init.display.grid_y-1)y2=init.display.grid_y-1;
+
+ clipx[0]=x1;
+ clipx[1]=x2;
+ clipy[0]=y1;
+ clipy[1]=y2;
+}
+
+void graphicst::dim_colors(long x,long y,char dim)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ switch(dim)
+ {
+ case 4:
+ switch(screen[x*dimy*4 + y*4 + 2])
+ {
+ case 4:
+ case 5:
+ case 6:
+ screen[x*dimy*4 + y*4 + 2]=1;
+ break;
+ case 2:
+ case 7:
+ screen[x*dimy*4 + y*4 + 2]=3;
+ break;
+ }
+ switch(screen[x*dimy*4 + y*4 + 1])
+ {
+ case 4:
+ case 5:
+ case 6:
+ screen[x*dimy*4 + y*4 + 1]=1;
+ break;
+ case 2:
+ case 7:
+ screen[x*dimy*4 + y*4 + 1]=3;
+ break;
+ }
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2])screen[x*dimy*4 + y*4 + 1]=0;
+ screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ case 3:
+ switch(screen[x*dimy*4 + y*4 + 2])
+ {
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 2]=6;
+ break;
+ case 2:
+ case 7:
+ screen[x*dimy*4 + y*4 + 2]=3;
+ break;
+ }
+ switch(screen[x*dimy*4 + y*4 + 1])
+ {
+ case 1:
+ screen[x*dimy*4 + y*4 + 3]=0;
+ break;
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 1]=6;
+ break;
+ case 2:
+ screen[x*dimy*4 + y*4 + 1]=3;
+ break;
+ case 7:
+ screen[x*dimy*4 + y*4 + 1]=3;
+ break;
+ }
+ if(screen[x*dimy*4 + y*4 + 1]!=7)screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2]&&
+ screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 1]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ case 2:
+ switch(screen[x*dimy*4 + y*4 + 2])
+ {
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 2]=6;
+ break;
+ }
+ switch(screen[x*dimy*4 + y*4 + 1])
+ {
+ case 4:
+ case 5:
+ screen[x*dimy*4 + y*4 + 1]=6;
+ break;
+ }
+ if(screen[x*dimy*4 + y*4 + 1]!=7)screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2]&&
+ screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 1]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ case 1:
+ if(screen[x*dimy*4 + y*4 + 1]!=7)screen[x*dimy*4 + y*4 + 3]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==screen[x*dimy*4 + y*4 + 2]&&
+ screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 1]=0;
+ if(screen[x*dimy*4 + y*4 + 1]==0&&screen[x*dimy*4 + y*4 + 2]==0&&screen[x*dimy*4 + y*4 + 3]==0)screen[x*dimy*4 + y*4 + 3]=1;
+ break;
+ }
+ }
+}
+
+void graphicst::rain_color_square(long x,long y)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ screen[x*dimy*4 + y*4 + 1]=1;
+ screen[x*dimy*4 + y*4 + 2]=0;
+ screen[x*dimy*4 + y*4 + 3]=1;
+ }
+}
+
+void graphicst::snow_color_square(long x,long y)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ screen[x*dimy*4 + y*4 + 1]=7;
+ screen[x*dimy*4 + y*4 + 2]=0;
+ screen[x*dimy*4 + y*4 + 3]=1;
+ }
+}
+
+void graphicst::color_square(long x,long y,unsigned char f,unsigned char b,unsigned char br)
+{
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ screen[x*dimy*4 + y*4 + 1]=f;
+ screen[x*dimy*4 + y*4 + 2]=b;
+ screen[x*dimy*4 + y*4 + 3]=br;
+ }
+}
+
+void graphicst::prepare_graphics(string &src_dir)
+{
+ if(!init.display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS))return;
+
+ texture.clean();
+
+ //GET READY TO LOAD
+ svector<char *> processfilename;
+ long f;
+ textlinesst setuplines;
+ char str[400];
+
+ //LOAD THE OBJECT FILES UP INTO MEMORY
+ //MUST INSURE THAT THEY ARE LOADED IN THE PROPER ORDER, IN CASE THEY REFER TO EACH OTHER
+ string chk=src_dir;
+ chk+="graphics/graphics_*";
+#ifdef WIN32
+ chk+=".*";
+#endif
+ find_files_by_pattern_with_exception(chk.c_str(),processfilename,"text");
+
+ string chktype="GRAPHICS";
+ for(f=0;f<processfilename.size();f++)
+ {
+ strcpy(str,src_dir.c_str());
+ strcat(str,"graphics/");
+ strcat(str,processfilename[f]);
+ setuplines.load_raw_to_lines(str);
+
+ errorlog_prefix="*** Error(s) found in the file \"";
+ errorlog_prefix+=str;
+ errorlog_prefix+='\"';
+ process_object_lines(setuplines,chktype,src_dir);
+ errorlog_prefix.clear();
+
+
+ delete[] processfilename[f];
+ }
+ processfilename.clear();
+
+ enabler.reset_textures();
+}
+
+void graphicst::add_tile(long texp,char addcolor)
+{
+ if(screenx>=clipx[0]&&screenx<=clipx[1]&&
+ screeny>=clipy[0]&&screeny<=clipy[1])
+ {
+ screentexpos[screenx*dimy + screeny]=texp;
+ screentexpos_addcolor[screenx*dimy + screeny]=addcolor;
+ screentexpos_grayscale[screenx*dimy + screeny]=0;
+ }
+}
+
+void graphicst::add_tile_grayscale(long texp,char cf,char cbr)
+{
+ if(screenx>=clipx[0]&&screenx<=clipx[1]&&
+ screeny>=clipy[0]&&screeny<=clipy[1])
+ {
+ screentexpos[screenx*dimy + screeny]=texp;
+ screentexpos_addcolor[screenx*dimy + screeny]=0;
+ screentexpos_grayscale[screenx*dimy + screeny]=1;
+ screentexpos_cf[screenx*dimy + screeny]=cf;
+ screentexpos_cbr[screenx*dimy + screeny]=cbr;
+ }
+}
+
+void graphicst::draw_border(int x1, int x2, int y1, int y2) {
+ // Upper and lower
+ for (int x = x1; x <= x2; x++) {
+ locate(y1, x);
+ addchar(' ');
+ locate(y2, x);
+ addchar(' ');
+ }
+ // Left and right
+ for (int y = y1+1; y < y2; y++) {
+ locate(y, x1);
+ addchar(' ');
+ locate(y, x2);
+ addchar(' ');
+ }
+}
+
+void graphicst::get_mouse_text_coords(int32_t &mx, int32_t &my) {
+ mx = mouse_x; my = mouse_y;
+}
+
+void render_things()
+{
+ //GRAB CURRENT SCREEN AT THE END OF THE LIST
+ viewscreenst *currentscreen=&gview.view;
+ while(currentscreen->child!=NULL)currentscreen=currentscreen->child;
+
+ //NO INTERFACE LEFT, LEAVE
+ if(currentscreen==&gview.view)return;
+
+ if(currentscreen->breakdownlevel==INTERFACE_BREAKDOWN_NONE)
+ {
+ currentscreen->render();
+ }
+ else gps.erasescreen();
+
+ // Render REC when recording macros. Definitely want this screen-specific. Or do we?
+ const Time now = SDL_GetTicks();
+ if (enabler.is_recording() && now % 1000 > 500) {
+ gps.locate(0, 20);
+ gps.changecolor(4,1,1);
+ gps.addst("REC");
+ }
+ // Render PLAY when playing a macro
+ if (enabler.is_macro_playing() && now % 1000 <= 500) {
+ gps.locate(0,20);
+ gps.changecolor(2,1,1);
+ gps.addst("PLAY");
+ }
+ // Render # <i> when building a repetition prefix
+ if (enabler.prefix_building()) {
+ gps.locate(0,20);
+ gps.changecolor(3,1,1);
+ gps.addst("#" + enabler.prefix());
+ }
+ if (gps.display_frames) {
+ ostringstream fps_stream;
+ fps_stream << "FPS: " << setw(3) << enabler.calculate_fps() << " (" << enabler.calculate_gfps() << ")";
+ string fps = fps_stream.str();
+ gps.changecolor(7,3,1);
+ static gps_locator fps_locator(0, 25);
+ fps_locator(fps.size());
+ gps.addst(fps);
+ }
+}
diff --git a/g_src/graphics.h b/g_src/graphics.h
new file mode 100755
index 0000000..cf3ffee
--- /dev/null
+++ b/g_src/graphics.h
@@ -0,0 +1,252 @@
+#ifndef GRAPHICS_H
+#define GRAPHICS_H
+
+#include <string>
+#include <map>
+#include <cassert>
+using std::string;
+
+#include "GL/glew.h"
+#include "g_basics.h"
+#include "platform.h"
+#include "basics.h"
+
+enum Texture
+{
+ TEXTURE_MOUSE,
+ TEXTURENUM
+};
+
+/* screen array layout
+ *
+ *
+ * X*Y tiles of 4 bytes each in column-major order (FIXME: This is inefficient! It should be row-major!)
+ * For each tile, byte 0 is the character, 1 is foreground color, 2 is bacground, and 3 denotes bold.
+ *
+ * As there are only 8 different colors and bold is a boolean, this leaves a lot of free space. Therefore,
+ * without involving the graphics arrays, out-of-gamut values can be used for designating TTF objects.
+ *
+ * This means setting the bold byte to all 1s (0xff), and then using the other three bytes as a designator.
+ *
+ * Time will tell whether this was a good idea or not.
+ */
+
+// So yeah, we store "type" in the previously bold byte. This means we have quite a lot of free types yet.
+#define GRAPHICSTYPE_TTF 0xff
+// This type denotes a tile that is covered by truetype, but is not the tile it starts on.
+#define GRAPHICSTYPE_TTFCONT 0xfe
+
+
+class graphicst
+{
+ int lookup_pair(std::pair<int,int> color);
+ long calculate_old_fps();
+ public:
+ long screenx,screeny;
+ char screenf,screenb;
+ char screenbright;
+
+ unsigned char *screen;
+ long *screentexpos;
+ char *screentexpos_addcolor;
+ unsigned char *screentexpos_grayscale;
+ unsigned char *screentexpos_cf;
+ unsigned char *screentexpos_cbr;
+
+ // Calling this is not enough in itself. You also need to call swap_front/back.
+ void resize(int x, int y);
+
+ long clipx[2],clipy[2];
+ long tex_pos[TEXTURENUM];
+
+ long rect_id;
+
+ LARGE_INTEGER print_time[100];
+ long print_index;
+ char display_frames;
+
+ short force_full_display_count;
+
+ char original_rect;
+
+ int dimx, dimy;
+
+ graphicst()
+ {
+ print_index=0;
+ display_frames=0;
+ rect_id=-1;
+ force_full_display_count=4;
+ original_rect=1;
+
+ screentexpos = NULL;
+ screentexpos_addcolor = NULL;
+ screentexpos_grayscale = NULL;
+ screentexpos_cf = NULL;
+ screentexpos_cbr = NULL;
+ screen = NULL;
+ }
+
+ void locate(long y,long x)
+ {
+ // No point in clamping here, addchar clamps too.
+ screenx=x;
+ screeny=y;
+ }
+ void changecolor(short f,short b,char bright)
+ {
+ screenf=f;
+ screenb=b;
+ screenbright=bright;
+ }
+ void addchar(unsigned char c,char advance=1)
+ {
+ /* assert (screen_limit == screen + dimy * dimx * 4); */
+ unsigned char *s = screen + screenx*dimy*4 + screeny*4;
+ if (s < screen_limit) {
+ if(screenx>=clipx[0]&&screenx<=clipx[1]&&
+ screeny>=clipy[0]&&screeny<=clipy[1])
+ {
+ *s++ = c;
+ *s++ = screenf;
+ *s++ = screenb;
+ *s++ = screenbright;
+ screentexpos[screenx*dimy + screeny]=0;
+ }
+ }
+ screenx += advance;
+ }
+ void addchar(unsigned int x, unsigned int y, unsigned char c,
+ unsigned char f, unsigned char b, unsigned char bright) {
+ /* assert (screen_limit == screen + dimy * dimx * 4); */
+ unsigned char *s = screen + x*dimy*4 + y*4;
+ if (s >= screen && s < screen_limit) {
+ if(x>=clipx[0]&&x<=clipx[1]&&
+ y>=clipy[0]&&y<=clipy[1])
+ {
+ *s++ = c;
+ *s++ = f;
+ *s++ = b;
+ *s++ = bright;
+ }
+ }
+ }
+ void addcoloredst(const char *str,const char *colorstr);
+ void addst(const string &str, justification just = justify_left, int space=0);
+ void erasescreen_clip();
+ void erasescreen();
+ void erasescreen_rect(int x1, int x2, int y1, int y2);
+ void setclipping(long x1,long x2,long y1,long y2);
+
+ void add_tile(long texp,char addcolor);
+ void add_tile_grayscale(long texp,char cf,char cbr);
+
+ void prepare_graphics(string &src_dir);
+
+ void gray_out_rect(long sx,long ex,long sy,long ey)
+ {
+ long x,y;
+ for(x=sx;x<=ex;x++)
+ {
+ for(y=sy;y<=ey;y++)
+ {
+ screen[x*dimy*4 + y*4 + 1]=0;
+ screen[x*dimy*4 + y*4 + 2]=7;
+ screen[x*dimy*4 + y*4 + 3]=0;
+ }
+ }
+ }
+ void dim_colors(long x,long y,char dim);
+
+ void rain_color_square(long x,long y);
+ void snow_color_square(long x,long y);
+ void color_square(long x,long y,unsigned char f,unsigned char b,unsigned char br);
+
+ long border_start_x(){return 1;}
+ long border_start_y(){return 1;}
+ long border_end_x(){return 78;}
+ long border_end_y(){return 23;}
+ long text_width(){return 1;}
+ long text_height(){return 1;}
+ long window_element_height(long minus,char border)
+ {
+ long height=25;
+ if(border)height-=2;
+ height-=text_height()*minus;
+ return height;
+ }
+
+ int mouse_x, mouse_y;
+ void get_mouse_text_coords(int32_t &mx, int32_t &my);
+ void draw_border(int x1, int x2, int y1, int y2);
+
+ // Instead of doing costly bounds-checking calculations, we cache the end
+ // of the arrays..
+ unsigned char *screen_limit;
+};
+
+extern graphicst gps;
+// From graphics.cpp
+void render_things();
+
+// Locates some area of the screen with free space for writing
+class gps_locator {
+ int y, last_x;
+public:
+ gps_locator(int y, int x) {
+ this->y = y;
+ last_x = x;
+ }
+ bool is_free(int x) {
+ unsigned char c = gps.screen[x*gps.dimy*4 + y*4];
+ switch (c) {
+ case 0:
+ case 20:
+ case 176:
+ case 177:
+ case 178:
+ case 219:
+ case 254:
+ case 255:
+ return true;
+ default:
+ return false;
+ }
+ }
+ void operator()(int sz) {
+ // First, check if our cached slot will still do
+ bool ok = true;
+ for (int x = last_x; x < last_x + sz; x++)
+ if (!is_free(x)) {
+ ok = false;
+ break;
+ }
+ if (ok) {
+ // Yeah, okay
+ gps.locate(y, last_x);
+ } else {
+ // Not so okay. Find a new spot.
+ int run = 0, x = 0;
+ for (; x < gps.dimx; x++) {
+ if (is_free(x))
+ run++;
+ else run = 0;
+ if (run > sz + 2) { // We pad things a bit for cleanliness.
+ ok = true;
+ x -= sz + 1;
+ break;
+ }
+ }
+ if (ok) {
+ // Found a new spot.
+ last_x = x;
+ gps.locate(y, x);
+ } else {
+ // Damn it.
+ gps.locate(y, last_x);
+ }
+ }
+ }
+};
+
+#endif
diff --git a/g_src/init.cpp b/g_src/init.cpp
new file mode 100755
index 0000000..f60b653
--- /dev/null
+++ b/g_src/init.cpp
@@ -0,0 +1,685 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "basics.h"
+
+#include "g_basics.h"
+
+#include "texture_handler.h"
+
+#include "graphics.h"
+
+#include "init.h"
+
+extern enablerst enabler;
+extern graphicst gps;
+
+init_displayst::init_displayst()
+{
+ flag.set_size_on_flag_num(INIT_DISPLAY_FLAGNUM);
+ windowed=INIT_DISPLAY_WINDOW_PROMPT;
+
+ partial_print_count=0;
+}
+
+void initst::begin()
+{
+ static bool called = false;
+ if (called) return;
+ called = true;
+
+ string small_font="data/art/curses_640x300.png";
+ string large_font="data/art/curses_640x300.png";
+ std::ifstream fseed("data/init/init.txt");
+ if(fseed.is_open())
+ {
+ string str;
+
+ while(std::getline(fseed,str))
+ {
+ if(str.length()>1)
+ {
+ string token;
+ string token2;
+
+ grab_token_string_pos(token,str,1);
+ if(str.length()>=token.length()+2)
+ {
+ grab_token_string_pos(token2,str,token.length()+2);
+ }
+ if(!token.compare("TRUETYPE")) {
+ const char *str = token2.c_str();
+ char *endptr;
+ int limit = strtol(str, &endptr, 10);
+ font.ttf_limit = 0;
+ if (endptr != str) {
+ font.use_ttf = ttf_auto;
+ font.ttf_limit = limit;
+ } else if (token2 == "YES") {
+ font.use_ttf = ttf_on;
+ } else {
+ font.use_ttf = ttf_off;
+ }
+ }
+
+ if(!token.compare("FONT"))
+ {
+ small_font="data/art/";
+ small_font+=token2;
+ }
+ if(!token.compare("FULLFONT"))
+ {
+ large_font="data/art/";
+ large_font+=token2;
+ }
+ if(!token.compare("WINDOWEDX"))
+ {
+ display.desired_windowed_width=convert_string_to_long(token2);
+ }
+ if(!token.compare("WINDOWEDY"))
+ {
+ display.desired_windowed_height=convert_string_to_long(token2);
+ }
+ if(!token.compare("RESIZABLE")) {
+ if (token2=="NO")
+ display.flag.add_flag(INIT_DISPLAY_FLAG_NOT_RESIZABLE);
+ }
+ if(!token.compare("FULLSCREENX"))
+ {
+ display.desired_fullscreen_width=convert_string_to_long(token2);
+ }
+ if(!token.compare("FULLSCREENY"))
+ {
+ display.desired_fullscreen_height=convert_string_to_long(token2);
+ }
+
+ if(token=="PRINT_MODE")
+ {
+ if(token2=="PARTIAL")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+
+ string token3;
+ if(str.length()>=token.length()+token2.length()+3)
+ {
+ grab_token_string_pos(token3,str,token.length()+token2.length()+3);
+ }
+ long l=convert_string_to_long(token3);
+ if(l<0)l=0;
+ if(l>100)l=100;
+ display.partial_print_count=(char)l;
+ }
+ if(token2=="PROMPT")
+ {
+ int answer = MessageBox(NULL, "Using only 2D (Click no) is more reliable, but means you lose features and, often, speed. Edit data/init/init.txt PRINT_MODE to avoid this dialog box.", "Use OpenGL?", MB_YESNO);
+ if (answer == IDYES)
+ token2 = "STANDARD";
+ else
+ token2 = "2D";
+ }
+ if(token2=="TEXT") {
+#ifdef CURSES
+ display.flag.add_flag(INIT_DISPLAY_FLAG_TEXT);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+ display.partial_print_count=0;
+#else
+ MessageBox(NULL, "Text mode not supported on your platform, using 2D", 0, 0);
+ token2 = "2D";
+#endif
+ }
+ if(token2=="FRAME_BUFFER")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_FRAME_BUFFER);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+ display.partial_print_count=0;
+ }
+ if(token2=="ACCUM_BUFFER")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_ACCUM_BUFFER);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+ display.partial_print_count=0;
+ }
+ if(token2=="VBO")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_VBO);
+ // display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+ display.partial_print_count=0;
+ }
+ if(token2=="2DSW")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_2D);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+ display.partial_print_count=0;
+ }
+ if(token2=="2D" || token2=="2DHW")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_2D);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_2DHW);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+ display.partial_print_count=0;
+ }
+ if(token2=="2DASYNC")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_2D);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_2DHW);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_2DASYNC);
+ display.flag.add_flag(INIT_DISPLAY_FLAG_PARTIAL_PRINT);
+ display.partial_print_count=0;
+ }
+ if(token2=="SHADER")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_SHADER);
+ }
+ }
+
+ if(token=="SINGLE_BUFFER")
+ {
+ if(token2=="YES")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_SINGLE_BUFFER);
+ }
+ }
+
+ if(display.flag.has_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS))
+ {
+ if(!token.compare("GRAPHICS_FONT"))
+ {
+ small_font="data/art/";
+ small_font+=token2;
+ }
+ if(!token.compare("GRAPHICS_FULLFONT"))
+ {
+ large_font="data/art/";
+ large_font+=token2;
+ }
+ if(!token.compare("GRAPHICS_WINDOWEDX"))
+ {
+ display.desired_windowed_width=convert_string_to_long(token2);
+ }
+ if(!token.compare("GRAPHICS_WINDOWEDY"))
+ {
+ display.desired_windowed_height=convert_string_to_long(token2);
+ }
+ if(!token.compare("GRAPHICS_FULLSCREENX"))
+ {
+ display.desired_fullscreen_width=convert_string_to_long(token2);
+ }
+ if(!token.compare("GRAPHICS_FULLSCREENY"))
+ {
+ display.desired_fullscreen_height=convert_string_to_long(token2);
+ }
+ if(!token.compare("GRAPHICS_BLACK_SPACE"))
+ {
+ if(token2=="YES")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_BLACK_SPACE);
+ }
+ else display.flag.remove_flag(INIT_DISPLAY_FLAG_BLACK_SPACE);
+ }
+ }
+
+ if(!token.compare("GRAPHICS"))
+ {
+ if(token2=="YES")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_USE_GRAPHICS);
+ }
+ }
+
+ if(!token.compare("BLACK_SPACE"))
+ {
+ if(token2=="YES")
+ {
+ display.flag.add_flag(INIT_DISPLAY_FLAG_BLACK_SPACE);
+ }
+ }
+
+ if(token=="ZOOM_SPEED")
+ {
+ input.zoom_speed = convert_string_to_long(token2);
+ }
+ if(token=="MOUSE")
+ {
+ if(token2=="NO")
+ {
+ input.flag.add_flag(INIT_INPUT_FLAG_MOUSE_OFF);
+ }
+ }
+ if(token=="VSYNC")
+ {
+ if(token2=="YES")
+ {
+ window.flag.add_flag(INIT_WINDOW_FLAG_VSYNC_ON);
+ }
+ if(token2=="NO")
+ {
+ window.flag.add_flag(INIT_WINDOW_FLAG_VSYNC_OFF);
+ }
+ }
+ if(token=="ARB_SYNC") {
+ if (token2 == "YES")
+ display.flag.add_flag(INIT_DISPLAY_FLAG_ARB_SYNC);
+ }
+
+#ifdef WIN32
+ if(token=="PRIORITY")
+ {
+ if(token2=="REALTIME")
+ {
+ SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
+ }
+ if(token2=="HIGH")
+ {
+ SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS);
+ }
+ if(token2=="ABOVE_NORMAL")
+ {
+ SetPriorityClass(GetCurrentProcess(),ABOVE_NORMAL_PRIORITY_CLASS);
+ }
+ if(token2=="NORMAL")
+ {
+ SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
+ }
+ if(token2=="BELOW_NORMAL")
+ {
+ SetPriorityClass(GetCurrentProcess(),BELOW_NORMAL_PRIORITY_CLASS);
+ }
+ if(token2=="IDLE")
+ {
+ SetPriorityClass(GetCurrentProcess(),IDLE_PRIORITY_CLASS);
+ }
+ }
+#endif
+
+ if(token=="TEXTURE_PARAM")
+ {
+ if(token2=="LINEAR")
+ {
+ window.flag.add_flag(INIT_WINDOW_FLAG_TEXTURE_LINEAR);
+ }
+ }
+ if(token=="TOPMOST")
+ {
+ if(token2=="YES")
+ {
+ window.flag.add_flag(INIT_WINDOW_FLAG_TOPMOST);
+ }
+ }
+ if(token=="FPS")
+ {
+ if(token2=="YES")
+ {
+ gps.display_frames=1;
+ }
+ }
+ if(token=="MOUSE_PICTURE")
+ {
+ if(token2=="YES")
+ {
+ input.flag.add_flag(INIT_INPUT_FLAG_MOUSE_PICTURE);
+ }
+ }
+ if(!token.compare("FPS_CAP"))
+ {
+ enabler.set_fps(convert_string_to_long(token2));
+ }
+ if(!token.compare("G_FPS_CAP"))
+ {
+ enabler.set_gfps(convert_string_to_long(token2));
+ }
+ if(token=="WINDOWED")
+ {
+ if(token2=="YES")
+ {
+ display.windowed=INIT_DISPLAY_WINDOW_TRUE;
+ }
+ if(token2=="NO")
+ {
+ display.windowed=INIT_DISPLAY_WINDOW_FALSE;
+ }
+ if(token2=="PROMPT")
+ {
+ display.windowed=INIT_DISPLAY_WINDOW_PROMPT;
+ }
+ }
+ if(!token.compare("SOUND"))
+ {
+ if(token2!="YES")
+ {
+ media.flag.add_flag(INIT_MEDIA_FLAG_SOUND_OFF);
+ }
+ }
+ if(!token.compare("INTRO"))
+ {
+ if(token2!="YES")
+ {
+ media.flag.add_flag(INIT_MEDIA_FLAG_INTRO_OFF);
+ }
+ }
+ if(!token.compare("VOLUME"))
+ {
+ media.volume=convert_string_to_long(token2);
+ }
+ if(!token.compare("KEY_HOLD_MS"))
+ {
+ input.hold_time=convert_string_to_long(token2);
+
+ if(input.hold_time<100)input.hold_time=100;
+ }
+ if(token=="KEY_REPEAT_MS")
+ {
+ input.repeat_time=convert_string_to_long(token2);
+
+ if(input.repeat_time<100)input.repeat_time=100;
+ }
+ if(token=="KEY_REPEAT_ACCEL_LIMIT") {
+ input.repeat_accel_limit = convert_string_to_long(token2);
+ if (input.repeat_accel_limit < 1) input.repeat_accel_limit = 1;
+ }
+ if(token=="KEY_REPEAT_ACCEL_START") {
+ input.repeat_accel_start = convert_string_to_long(token2);
+ }
+ if(token=="MACRO_MS")
+ {
+ input.macro_time=convert_string_to_long(token2);
+
+ if(input.macro_time<1)input.macro_time=1;
+ }
+ if(token=="RECENTER_INTERFACE_SHUTDOWN_MS")
+ {
+ input.pause_zoom_no_interface_ms=convert_string_to_long(token2);
+
+ if(input.pause_zoom_no_interface_ms<0)input.pause_zoom_no_interface_ms=0;
+ }
+ if(token=="COMPRESSED_SAVES")
+ {
+ if(token2=="YES")
+ {
+ media.flag.add_flag(INIT_MEDIA_FLAG_COMPRESS_SAVES);
+ }
+ }
+ }
+ }
+ }
+ fseed.close();
+
+ std::ifstream fseed2("data/init/colors.txt");
+ if(fseed2.is_open())
+ {
+ string str;
+
+ while(std::getline(fseed2,str))
+ {
+ if(str.length()>1)
+ {
+ string token;
+ string token2;
+
+ grab_token_string_pos(token,str,1);
+ if(str.length()>=token.length()+2)
+ {
+ grab_token_string_pos(token2,str,token.length()+2);
+ }
+
+ if(!token.compare("BLACK_R"))
+ {
+ enabler.ccolor[0][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BLACK_G"))
+ {
+ enabler.ccolor[0][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BLACK_B"))
+ {
+ enabler.ccolor[0][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BLUE_R"))
+ {
+ enabler.ccolor[1][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BLUE_G"))
+ {
+ enabler.ccolor[1][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BLUE_B"))
+ {
+ enabler.ccolor[1][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("GREEN_R"))
+ {
+ enabler.ccolor[2][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("GREEN_G"))
+ {
+ enabler.ccolor[2][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("GREEN_B"))
+ {
+ enabler.ccolor[2][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("CYAN_R"))
+ {
+ enabler.ccolor[3][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("CYAN_G"))
+ {
+ enabler.ccolor[3][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("CYAN_B"))
+ {
+ enabler.ccolor[3][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("RED_R"))
+ {
+ enabler.ccolor[4][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("RED_G"))
+ {
+ enabler.ccolor[4][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("RED_B"))
+ {
+ enabler.ccolor[4][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("MAGENTA_R"))
+ {
+ enabler.ccolor[5][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("MAGENTA_G"))
+ {
+ enabler.ccolor[5][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("MAGENTA_B"))
+ {
+ enabler.ccolor[5][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BROWN_R"))
+ {
+ enabler.ccolor[6][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BROWN_G"))
+ {
+ enabler.ccolor[6][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("BROWN_B"))
+ {
+ enabler.ccolor[6][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LGRAY_R"))
+ {
+ enabler.ccolor[7][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LGRAY_G"))
+ {
+ enabler.ccolor[7][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LGRAY_B"))
+ {
+ enabler.ccolor[7][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("DGRAY_R"))
+ {
+ enabler.ccolor[8][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("DGRAY_G"))
+ {
+ enabler.ccolor[8][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("DGRAY_B"))
+ {
+ enabler.ccolor[8][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LBLUE_R"))
+ {
+ enabler.ccolor[9][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LBLUE_G"))
+ {
+ enabler.ccolor[9][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LBLUE_B"))
+ {
+ enabler.ccolor[9][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LGREEN_R"))
+ {
+ enabler.ccolor[10][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LGREEN_G"))
+ {
+ enabler.ccolor[10][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LGREEN_B"))
+ {
+ enabler.ccolor[10][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LCYAN_R"))
+ {
+ enabler.ccolor[11][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LCYAN_G"))
+ {
+ enabler.ccolor[11][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LCYAN_B"))
+ {
+ enabler.ccolor[11][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LRED_R"))
+ {
+ enabler.ccolor[12][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LRED_G"))
+ {
+ enabler.ccolor[12][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LRED_B"))
+ {
+ enabler.ccolor[12][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LMAGENTA_R"))
+ {
+ enabler.ccolor[13][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LMAGENTA_G"))
+ {
+ enabler.ccolor[13][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("LMAGENTA_B"))
+ {
+ enabler.ccolor[13][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("YELLOW_R"))
+ {
+ enabler.ccolor[14][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("YELLOW_G"))
+ {
+ enabler.ccolor[14][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("YELLOW_B"))
+ {
+ enabler.ccolor[14][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("WHITE_R"))
+ {
+ enabler.ccolor[15][0]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("WHITE_G"))
+ {
+ enabler.ccolor[15][1]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ if(!token.compare("WHITE_B"))
+ {
+ enabler.ccolor[15][2]=(float)convert_string_to_long(token2)/255.0f;
+ }
+ }
+ }
+ }
+ fseed2.close();
+
+#ifdef _DEBUG
+ enabler.window.isFullScreen = FALSE;
+#else
+
+ //FULL SCREEN QUERY, UNLESS IT'S ALREADY SET IN INIT
+
+ if (!display.flag.has_flag(INIT_DISPLAY_FLAG_TEXT)) {
+ if(enabler.command_line.empty())
+ {
+ if(display.windowed==INIT_DISPLAY_WINDOW_TRUE)
+ {
+ enabler.fullscreen = false;
+ }
+ else if(display.windowed==INIT_DISPLAY_WINDOW_FALSE)
+ {
+ enabler.fullscreen = true;
+ }
+ else
+ {
+ if (MessageBox (NULL, "Run in Fullscreen Mode? You can set your preferences in data\\init\\init.txt.\rUnless you've changed your bindings, you can press F11 to toggle this setting any time.", "Start FullScreen?", MB_YESNO | MB_ICONQUESTION) == IDNO) {
+ enabler.fullscreen = false; // If Not, Run In Windowed Mode
+ } else {
+ enabler.fullscreen = true;
+ }
+ }
+ }
+ else enabler.fullscreen = false;
+ }
+#endif
+
+
+ enabler.textures.load_multi_pdim(small_font,font.small_font_texpos,16,16,true,&font.small_font_dispx,&font.small_font_dispy);
+ enabler.textures.load_multi_pdim(large_font,font.large_font_texpos,16,16,true,&font.large_font_dispx,&font.large_font_dispy);
+
+ // compute the desired window size, if set to auto
+ if (display.desired_windowed_width < MAX_GRID_X && display.desired_windowed_height < MAX_GRID_Y) {
+ int dimx = MAX(display.desired_windowed_width,80);
+ int dimy = MAX(display.desired_windowed_height,25);
+ display.desired_windowed_width = font.small_font_dispx * dimx;
+ display.desired_windowed_height = font.small_font_dispy * dimy;
+ }
+}
diff --git a/g_src/init.h b/g_src/init.h
new file mode 100755
index 0000000..243c5d1
--- /dev/null
+++ b/g_src/init.h
@@ -0,0 +1,166 @@
+#ifndef INIT_H
+#define INIT_H
+
+#include "enabler.h"
+#ifdef __APPLE__
+#include <SDL_ttf/SDL_ttf.h>
+#else
+#include <SDL/SDL_ttf.h>
+#endif
+
+enum ttf_flag {
+ ttf_off, ttf_on, ttf_auto
+};
+
+class init_fontst
+{
+ public:
+ long small_font_texpos[256];
+ long large_font_texpos[256];
+ long small_font_datapos[256];
+ long large_font_datapos[256];
+ float small_font_adjx;
+ float small_font_adjy;
+ float large_font_adjx;
+ float large_font_adjy;
+ long small_font_dispx;
+ long small_font_dispy;
+ long large_font_dispx;
+ long large_font_dispy;
+ ttf_flag use_ttf;
+ int ttf_limit;
+};
+
+enum InitDisplayFlag
+{
+ INIT_DISPLAY_FLAG_USE_GRAPHICS,
+ INIT_DISPLAY_FLAG_BLACK_SPACE,
+ INIT_DISPLAY_FLAG_PARTIAL_PRINT,
+ INIT_DISPLAY_FLAG_FRAME_BUFFER,
+ INIT_DISPLAY_FLAG_SINGLE_BUFFER,
+ INIT_DISPLAY_FLAG_ACCUM_BUFFER,
+ INIT_DISPLAY_FLAG_VBO,
+ INIT_DISPLAY_FLAG_2D,
+ INIT_DISPLAY_FLAG_2DHW,
+ INIT_DISPLAY_FLAG_2DASYNC,
+ INIT_DISPLAY_FLAG_UNUSED_01_08,//
+ INIT_DISPLAY_FLAG_TEXT,
+ INIT_DISPLAY_FLAG_SHADER,
+ INIT_DISPLAY_FLAG_NOT_RESIZABLE,
+ INIT_DISPLAY_FLAG_ARB_SYNC,
+ INIT_DISPLAY_FLAGNUM
+};
+
+enum InitDisplayWindow
+{
+ INIT_DISPLAY_WINDOW_TRUE,
+ INIT_DISPLAY_WINDOW_FALSE,
+ INIT_DISPLAY_WINDOW_PROMPT,
+ INIT_DISPLAY_WINDOWNUM
+};
+
+class init_displayst
+{
+ public:
+ flagarrayst flag;
+ InitDisplayWindow windowed;
+
+ int grid_x, grid_y; // The *current* display grid size, kept up to date
+
+ int desired_fullscreen_width, desired_fullscreen_height;
+ int desired_windowed_width, desired_windowed_height;
+
+
+ char partial_print_count;
+
+ init_displayst();
+};
+
+enum InitMediaFlag
+{
+ INIT_MEDIA_FLAG_SOUND_OFF,
+ INIT_MEDIA_FLAG_INTRO_OFF,
+ INIT_MEDIA_FLAG_COMPRESS_SAVES,
+ INIT_MEDIA_FLAGNUM
+};
+
+class init_mediast
+{
+ public:
+ flagarrayst flag;
+ int32_t volume;
+
+ init_mediast()
+ {
+ flag.set_size_on_flag_num(INIT_MEDIA_FLAGNUM);
+ volume=255;
+ }
+};
+
+enum InitInputFlag
+{
+ INIT_INPUT_FLAG_MOUSE_OFF,
+ INIT_INPUT_FLAG_MOUSE_PICTURE,
+ INIT_INPUT_FLAGNUM
+};
+
+class init_inputst
+{
+ public:
+ long hold_time;
+ long repeat_time;
+ long macro_time;
+ long pause_zoom_no_interface_ms;
+ flagarrayst flag;
+ long zoom_speed;
+ int repeat_accel_start;
+ int repeat_accel_limit;
+
+ init_inputst()
+ {
+ hold_time=150;
+ repeat_time=150;
+ macro_time=75;
+ pause_zoom_no_interface_ms=0;
+ flag.set_size_on_flag_num(INIT_INPUT_FLAGNUM);
+ zoom_speed = 10;
+ repeat_accel_start = 10;
+ repeat_accel_limit = 1;
+ }
+};
+
+enum InitWindowFlag
+{
+ INIT_WINDOW_FLAG_TOPMOST,
+ INIT_WINDOW_FLAG_VSYNC_ON,
+ INIT_WINDOW_FLAG_VSYNC_OFF,
+ INIT_WINDOW_FLAG_TEXTURE_LINEAR,
+ INIT_WINDOW_FLAGNUM
+};
+
+class init_windowst
+{
+ public:
+ flagarrayst flag;
+
+ init_windowst()
+ {
+ flag.set_size_on_flag_num(INIT_WINDOW_FLAGNUM);
+ }
+};
+
+class initst
+{
+ public:
+ init_displayst display;
+ init_mediast media;
+ init_inputst input;
+ init_fontst font;
+ init_windowst window;
+
+ void begin();
+};
+
+extern initst init;
+
+#endif
diff --git a/g_src/interface.cpp b/g_src/interface.cpp
new file mode 100755
index 0000000..11d0464
--- /dev/null
+++ b/g_src/interface.cpp
@@ -0,0 +1,1777 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "find_files.h"
+
+#include "basics.h"
+
+#include "g_basics.h"
+
+#include "music_and_sound_g.h"
+
+#include "graphics.h"
+
+#include "init.h"
+
+#include "keybindings.h"
+#include "interface.h"
+#include "KeybindingScreen.h"
+#include "ttf_manager.hpp"
+
+#include <list>
+#include <set>
+
+void dwarf_end_announcements();
+void dwarf_remove_screen();
+void dwarf_option_screen();
+void drawborder(const char *str,char style,const char *colorstr);
+
+
+inline void CHECK_ERR(int err, const char* msg)
+{
+ if (err != Z_OK)
+ {
+ MessageBox(NULL, "One of the compressed files on disk has errors in it. Restore from backup if you are able.", 0, 0);
+ exit(1);
+ }
+}
+
+using std::fstream;
+using std::ios;
+using std::list;
+using std::set;
+
+extern interfacest gview;
+extern enablerst enabler;
+extern graphicst gps;
+extern initst init;
+#ifndef NO_FMOD
+extern musicsoundst musicsound;
+#endif
+
+extern GameMode gamemode;
+extern GameType gametype;
+
+extern int32_t movie_version;
+
+
+
+
+void viewscreen_movieplayerst::help()
+{
+ if(is_playing)return;
+
+ viewscreenst::help();
+}
+
+void interfacest::finish_movie()
+{
+ supermovie_on=0;
+ currentblocksize=0;
+ nextfilepos=0;
+ supermovie_pos=0;
+ viewscreen_movieplayerst::create(INTERFACE_PUSH_AT_BACK);
+}
+
+void interfacest::use_movie_input()
+{
+ if(supermovie_on)handlemovie(1);
+ finish_movie();
+}
+
+viewscreen_movieplayerst *viewscreen_movieplayerst::create(char pushtype,viewscreenst *scr)
+{
+ viewscreen_movieplayerst *newv=new viewscreen_movieplayerst();
+ gview.addscreen(newv,pushtype,scr);
+
+ return newv;
+}
+
+void viewscreen_movieplayerst::force_play(const string &file)
+{
+ force_file=file;
+ is_forced_play=1;
+}
+
+void viewscreen_movieplayerst::logic()
+{
+ enabler.flag&=~ENABLERFLAG_MAXFPS;
+
+ enabler.flag|=ENABLERFLAG_RENDER;
+
+ if(!force_file.empty()&&!is_playing&&!quit_if_no_play&&is_forced_play)
+ {
+ is_playing=1;
+ quit_if_no_play=1;
+ gview.movie_file=force_file;
+ gview.supermovie_on=0;
+ gview.currentblocksize=0;
+ gview.nextfilepos=0;
+ gview.supermovie_pos=0;
+ maxmoviepos=0;
+ }
+
+ if(!is_playing&&quit_if_no_play)
+ {
+ breakdownlevel=INTERFACE_BREAKDOWN_STOPSCREEN;
+ return;
+ }
+
+ //LOAD A MOVIE BUFFER BY BUFFER
+ if(is_playing)
+ {
+ if(gview.supermovie_pos>=MOVIEBUFFSIZE||gview.currentblocksize==0)
+ {
+ gview.read_movie_chunk(maxmoviepos,is_playing);
+ }
+
+ if(is_playing)
+ {
+ int half_frame_size=init.display.grid_x*init.display.grid_y;
+
+#ifndef NO_FMOD
+ //PLAY ANY RELEVANT SOUNDS
+ if(gview.supermovie_delaystep==gview.supermovie_delayrate)
+ {
+ int fr=gview.supermovie_pos/(half_frame_size*2);
+ if(fr>=0&&fr<200)
+ {
+ int c,sd;
+ for(c=0;c<16;c++)
+ {
+ sd=gview.supermovie_sound_time[fr][c];
+ if(sd>=0&&sd<gview.supermovie_sound.str.size())
+ {
+ musicsound.playsound(sd,c);
+ }
+ }
+ }
+ }
+#endif
+
+ //PRINT THE NEXT FRAME AND ADVANCE POSITION
+ short x2,y2;
+ for(x2=0;x2<init.display.grid_x;x2++)
+ {
+ for(y2=0;y2<init.display.grid_y;y2++)
+ {
+ gview.supermovie_pos++;
+ }
+ }
+ if(gview.supermovie_delaystep==0)
+ {
+ gview.supermovie_pos+=half_frame_size;
+ gview.supermovie_delaystep=gview.supermovie_delayrate;
+ }
+ else
+ {
+ gview.supermovie_pos-=half_frame_size;//RETURN TO LAST FRAME
+ gview.supermovie_delaystep--;
+ }
+
+ //DONE
+ if(gview.supermovie_pos>=maxmoviepos&&
+ maxmoviepos+half_frame_size*2<MOVIEBUFFSIZE)
+ {
+ is_playing=0;
+ //NOTE: THIS CAUSES IT TO LOSE THE LAST FRAME DUE TO CLEARING
+ }
+ }
+ }
+}
+
+void viewscreen_movieplayerst::render()
+{
+ if(breakdownlevel!=INTERFACE_BREAKDOWN_NONE)return;
+
+ if(!is_playing&&is_forced_play)return;
+
+ if(!quit_if_no_play)
+ {
+ if(editing)drawborder(NULL);
+ else drawborder(" Moving Records ");
+ }
+
+ //LOAD A MOVIE BUFFER BY BUFFER
+ if(is_playing)
+ {
+ if(gview.currentblocksize>0)
+ {
+ int32_t half_frame_size=init.display.grid_x*init.display.grid_y;
+
+ //PRINT THE NEXT FRAME AND ADVANCE POSITION
+ drawborder(NULL,-1);
+
+ int32_t curp=gview.supermovie_pos;
+ //HANG ON THE LAST FRAME TO AVOID POSSIBLE OVERRUNS
+ if(gview.supermovie_pos>=MOVIEBUFFSIZE-half_frame_size*2)
+ {
+ curp=MOVIEBUFFSIZE-half_frame_size*4;
+ }
+ short x2,y2;
+ for(x2=0;x2<init.display.grid_x;x2++)
+ {
+ for(y2=0;y2<init.display.grid_y;y2++,++curp)
+ {
+ gps.locate(y2,x2);
+
+ gps.changecolor((gview.supermoviebuffer[curp+half_frame_size] & 7),
+ (gview.supermoviebuffer[curp+half_frame_size] & 56)>>3,
+ (gview.supermoviebuffer[curp+half_frame_size] & 64));
+
+ gps.addchar(gview.supermoviebuffer[curp]);
+ }
+ }
+ }
+ }
+ else if(loading)
+ {
+ int scroll=selfile/21*21;
+ int l;
+ for(l=scroll;l<filelist.size() && l<scroll+21;l++)
+ {
+ if(l==selfile)gps.changecolor(7,0,1);
+ else gps.changecolor(7,0,0);
+ gps.locate(l-scroll+2,2);
+ gps.addst(filelist[l]);
+ }
+ }
+#ifdef DEBUG_MOVIE_EDIT
+ else if(editing)
+ {
+ if(editing_menu)
+ {
+ int tx,ty;
+ unsigned char c=0;
+ for(ty=0;ty<16;ty++)
+ {
+ for(tx=0;tx<16;tx++)
+ {
+ gps.locate(ty,tx);
+ gps.changecolor(editing_screenf,editing_screenb,editing_screenbright);
+ gps.addchar(c);
+ c++;
+ }
+ }
+ gps.locate(18,0);
+ gps.changecolor(editing_screenf,editing_screenb,editing_screenbright);
+ gps.addchar(editing_char);
+ for(ty=0;ty<16;ty++)
+ {
+ for(tx=0;tx<8;tx++)
+ {
+ gps.locate(ty,tx+16);
+ gps.changecolor(ty%8,tx,ty/8);
+ gps.addchar('A');
+ }
+ }
+
+ gps.changecolor(7,0,1);
+ gps.locate(20,0);
+ string str;
+ gps.addst("1/100 sec per frame: ");convert_long_to_string(gview.supermovie_delayrate,str);
+ gps.addst(str);
+
+ int scroll=(editing_selected_sound/25)*25;
+ int e;
+ for(e=scroll;e<scroll+25&&e<gview.supermovie_sound.str.size();e++)
+ {
+ if(e==editing_selected_sound)gps.changecolor(7,0,1);
+ else gps.changecolor(7,0,0);
+ gps.locate(e-scroll,26);
+ gps.addst(gview.supermovie_sound.str[e]->dat);
+ }
+
+ int frame=gview.supermovie_pos/4000,sd;
+ for(e=0;e<SOUND_CHANNELNUM;e++)
+ {
+ gps.changecolor(2,0,1);
+ gps.locate(e-scroll,52);
+ sd=gview.supermovie_sound_time[frame][e];
+ if(sd>=0&&sd<gview.supermovie_sound.str.size())gps.addst(gview.supermovie_sound.str[sd]->dat);
+ else
+ {
+ gps.addst("-----------------");
+ }
+ gps.changecolor(4,0,1);
+ gps.locate(e-scroll,(init.display.grid_x-1));
+ gps.addst("X");
+ }
+ }
+ else
+ {
+ drawborder(NULL,-1);
+
+ int curp=gview.supermovie_pos;
+ int x2,y2;
+ for(x2=0;x2<80;x2++)
+ {
+ for(y2=0;y2<25;y2++)
+ {
+ gps.locate(y2,x2);
+
+ gps.changecolor((gview.supermoviebuffer[curp+2000] & 7),
+ (gview.supermoviebuffer[curp+2000] & 56)>>3,
+ (gview.supermoviebuffer[curp+2000] & 64));
+
+ gps.addchar(gview.supermoviebuffer[curp]);
+
+ curp++;
+ }
+ }
+
+ if(enabler.mouse_y<150)gps.locate(24,0);
+ else gps.locate(0,0);
+ gps.changecolor(2,0,1);
+ gps.addst("Frame: ");
+ string num;
+ convert_long_to_string(gview.supermovie_pos/4000+1,num);
+ gps.addst(num);
+
+ if(enabler.mouse_y<150)gps.locate(24,20);
+ else gps.locate(0,20);
+ gps.changecolor(3,0,1);
+ gps.addst("Copy From: ");
+ convert_long_to_string(editing_copy_from/4000+1,num);
+ gps.addst(num);
+
+ if(enabler.mouse_y<150)gps.locate(24,40);
+ else gps.locate(0,40);
+ gps.changecolor(4,0,1);
+ gps.addst("Ends At: ");
+ convert_long_to_string(end_frame_pos/4000+1,num);
+ gps.addst(num);
+
+ if(enabler.mouse_y<150)gps.locate(24,60);
+ else gps.locate(0,60);
+ int sx,sy;
+ gps.get_mouse_text_coords(sx,sy);
+ gps.changecolor(7,0,1);
+ gps.addst("(");
+ convert_long_to_string(sx,num);
+ gps.addst(num);
+ gps.addst(",");
+ convert_long_to_string(sy,num);
+ gps.addst(num);
+ gps.addst(")");
+ }
+ }
+#endif
+ else
+ {
+ gps.changecolor(7,0,1);
+ gps.locate(2,2);
+ gview.print_interface_token(INTERFACEKEY_MOVIE_RECORD);
+ gps.addst(": Start recording (active record is erased, stops when you return here)");
+ gps.locate(3,2);
+ gview.print_interface_token(INTERFACEKEY_MOVIE_PLAY);
+ gps.addst(": Play the active moving record");
+ gps.locate(4,2);
+ gview.print_interface_token(INTERFACEKEY_MOVIE_SAVE);
+ gps.addst(": Save the active moving record (you will be prompted for a name)");
+ gps.locate(5,2);
+ gview.print_interface_token(INTERFACEKEY_MOVIE_LOAD);
+ gps.addst(": Load a moving record");
+
+#ifdef DEBUG_MOVIE_EDIT
+ gps.locate(7,2);
+ gps.addst("E: Edit");
+#endif
+
+ if(saving)
+ {
+ gps.locate(10,2);
+ gps.addst("Name: ");
+ gps.addst(savename);
+ }
+ }
+}
+
+void viewscreen_movieplayerst::feed(std::set<InterfaceKey> &events)
+{
+ if(events.count(INTERFACEKEY_LEAVESCREEN))
+ {
+ events.clear();
+
+ if(is_playing)
+ {
+ is_playing=0;
+ enabler.release_grid_size();
+ if (gview.original_fps)
+ enabler.set_fps(gview.original_fps);
+ gview.supermovie_on=0;
+ gview.currentblocksize=0;
+ gview.nextfilepos=0;
+ gview.supermovie_pos=0;
+ maxmoviepos=0;
+
+#ifndef NO_FMOD
+ musicsound.stop_sound();
+#endif
+ }
+ else if(saving)saving=0;
+ else if(loading)loading=0;
+#ifdef DEBUG_MOVIE_EDIT
+ else if(editing)editing=0;
+#endif
+ else
+ {
+ is_playing=0;
+ enabler.release_grid_size();
+ if (gview.original_fps)
+ enabler.set_fps(gview.original_fps);
+ gview.supermovie_on=0;
+ gview.currentblocksize=0;
+ gview.nextfilepos=0;
+ gview.supermovie_pos=0;
+ maxmoviepos=0;
+
+ breakdownlevel=INTERFACE_BREAKDOWN_STOPSCREEN;
+ return;
+ }
+ }
+ else if(saving)
+ {
+ standardstringentry(savename,39,STRINGENTRY_LETTERS|STRINGENTRY_SPACE|STRINGENTRY_NUMBERS|STRINGENTRY_SYMBOLS,events);
+
+ if(events.count(INTERFACEKEY_SELECT))
+ {
+ string filename;
+ filename="data/movies/";
+ filename+=savename;
+ filename+=".cmv";
+
+ copy_file(gview.movie_file,filename);
+ saving=0;
+ }
+ }
+ else if(loading)
+ {
+ if(events.count(INTERFACEKEY_SELECT))
+ {
+ string filename;
+ filename="data/movies/";
+ filename+=filelist[selfile];
+
+ if(filename!=gview.movie_file)
+ {
+ copy_file(filename,gview.movie_file);
+ }
+ loading=0;
+ }
+
+ standardscrolling(events,selfile,0,filelist.size()-1,21);
+ }
+#ifdef DEBUG_MOVIE_EDIT
+ else if(editing)
+ {
+ char entering=0;
+
+ if(editing_menu)
+ {
+ if(enabler.mouse_lbut&&enabler.tracking_on)
+ {
+ int sx,sy;
+ gps.get_mouse_text_coords(sx,sy);
+
+ if(sx>=0&&sx<80&&sy>=0&&sy<25)
+ {
+ if(sx>=0&&sx<16&&sy>=0&&sy<16)
+ {
+ editing_char=sx+sy*16;
+ }
+ if(sx>=16&&sx<24&&sy>=0&&sy<16)
+ {
+ editing_screenf=sy%8;
+ editing_screenb=sx-16;
+ editing_screenbright=sy/8;
+ }
+ if(sx>=26&&sx<=51&&sy>=0&&sy<SOUND_CHANNELNUM)
+ {
+ editing_selected_sound=sy;
+ }
+ int frame=gview.supermovie_pos/4000;
+ if(sx>=52&&sx<=78&&sy>=0&&sy<SOUND_CHANNELNUM)
+ {
+ gview.supermovie_sound_time[frame][sy]=editing_selected_sound;
+ }
+ if(sx==(init.display.grid_x-1)&&sy>=0&&sy<SOUND_CHANNELNUM)
+ {
+ gview.supermovie_sound_time[frame][sy]=-1;
+ }
+ }
+
+ enabler.mouse_lbut=0;
+ }
+
+ if(enabler.mouse_rbut&&enabler.tracking_on)
+ {
+ editing_menu=0;
+ enabler.mouse_rbut=0;
+ }
+
+ if(editing_selected_sound>=0&&editing_selected_sound<gview.supermovie_sound.str.size())
+ {
+ if(gview.c== '%')
+ {
+ delete gview.supermovie_sound.str[editing_selected_sound];
+ gview.supermovie_sound.str.erase(editing_selected_sound);
+ }
+ else
+ {
+ standardstringentry(events,gview.supermovie_sound.str[editing_selected_sound]->dat,26,STRINGENTRY_LETTERS|STRINGENTRY_SPACE|STRINGENTRY_NUMBERS|STRINGENTRY_SYMBOLS);
+ entering=1;
+ }
+ }
+ else
+ {
+ if(gview.c== '#')gview.supermovie_sound.add_string("new_sound");
+ if(gview.c== '+')gview.supermovie_delayrate++;
+ if(gview.c== '-')gview.supermovie_delayrate--;
+ if(gview.c== 'T')text_mode=1-text_mode;
+ }
+ if(gview.supermovie_delayrate<0)gview.supermovie_delayrate=0;
+ if(gview.supermovie_delayrate>10)gview.supermovie_delayrate=10;
+ }
+ else
+ {
+ if(text_mode)
+ {
+ if(gview.c!=0)
+ {
+ int sx,sy;
+ gps.get_mouse_text_coords(sx,sy);
+
+ if(sx>=0&&sx<80&&sy>=0&&sy<25)
+ {
+ int curpos=gview.supermovie_pos+sy+sx*25;
+ gview.supermoviebuffer[curpos]=gview.c;
+ gview.supermoviebuffer[curpos+2000]=(editing_screenf&7)+((editing_screenb&7)<<3);
+ if(editing_screenbright)gview.supermoviebuffer[curpos+2000]+=64;
+ }
+ }
+ }
+ else
+ {
+ if(gview.c== 'a')
+ {
+ int x2,y2;
+ for(x2=0;x2<80;x2++)
+ {
+ for(y2=0;y2<25;y2++)
+ {
+ if(x2>0)
+ {
+ gview.supermoviebuffer[gview.supermovie_pos+y2+(x2-1)*25]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25];
+ gview.supermoviebuffer[gview.supermovie_pos+y2+(x2-1)*25+2000]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25+2000];
+ }
+ if(x2==(init.display.grid_x-1))gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25]=0;
+ }
+ }
+ }
+ if(gview.c== 'd')
+ {
+ int x2,y2;
+ for(x2=(init.display.grid_x-1);x2>=0;x2--)
+ {
+ for(y2=0;y2<(init.display.grid_y-1);y2++)
+ {
+ if(x2<(init.display.grid_x-1))
+ {
+ gview.supermoviebuffer[gview.supermovie_pos+y2+(x2+1)*25]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25];
+ gview.supermoviebuffer[gview.supermovie_pos+y2+(x2+1)*25+2000]=gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25+2000];
+ }
+ if(x2==0)gview.supermoviebuffer[gview.supermovie_pos+y2+x2*25]=0;
+ }
+ }
+ }
+ if(gview.c== 'E')end_frame_pos=gview.supermovie_pos;
+ if(gview.c== 'c')editing_copy_from=gview.supermovie_pos;
+ if(gview.c== 'p')
+ {
+ int i;
+ for(i=0;i<4000;i++)
+ {
+ gview.supermoviebuffer[gview.supermovie_pos+i]=gview.supermoviebuffer[editing_copy_from+i];
+ }
+ }
+ if(gview.c== '+')gview.supermovie_pos+=4000;
+ if(gview.c== '-')gview.supermovie_pos-=4000;
+ if(gview.c== '/')gview.supermovie_pos-=40000;
+ if(gview.c== '*')gview.supermovie_pos+=40000;
+ if(gview.supermovie_pos<0)gview.supermovie_pos=0;
+ if(gview.supermovie_pos>=MOVIEBUFFSIZE)gview.supermovie_pos=MOVIEBUFFSIZE-4000;
+ }
+
+ if(enabler.mouse_lbut&&enabler.tracking_on)
+ {
+ int sx,sy;
+ gps.get_mouse_text_coords(sx,sy);
+
+ if(sx>=0&&sx<80&&sy>=0&&sy<25)
+ {
+ int curpos=gview.supermovie_pos+sy+sx*25;
+ gview.supermoviebuffer[curpos]=editing_char;
+ gview.supermoviebuffer[curpos+2000]=(editing_screenf&7)+((editing_screenb&7)<<3);
+ if(editing_screenbright)gview.supermoviebuffer[curpos+2000]+=64;
+ }
+ }
+ if(enabler.mouse_rbut&&enabler.tracking_on)
+ {
+ editing_menu=1;
+ enabler.mouse_rbut=0;
+ }
+ }
+
+ if(!entering&&gview.c== 'S')
+ {
+ int opos=gview.supermovie_pos;
+ gview.first_movie_write=1;
+ gview.supermovie_pos=end_frame_pos+4000;
+
+ gview.write_movie_chunk();
+
+ gview.supermovie_pos=opos;
+ }
+ }
+#endif
+ else
+ {
+ if(is_playing)
+ {
+ }
+ else
+ {
+#ifdef DEBUG_MOVIE_EDIT
+ if(gview.c== 'E')
+ {
+ editing=1;
+ gview.supermovie_pos=0;
+ }
+#endif
+
+ if(events.count(INTERFACEKEY_MOVIE_RECORD))
+ {
+ //TURN ON THE MOVIE RECORDER
+ is_playing=0;
+ enabler.release_grid_size();
+ if (gview.original_fps)
+ enabler.set_fps(gview.original_fps);
+ gview.supermovie_on=1;
+ gview.currentblocksize=0;
+ gview.nextfilepos=0;
+ gview.supermovie_pos=0;
+ gview.supermovie_delayrate=0;
+ gview.first_movie_write=1;
+ maxmoviepos=0;
+
+ breakdownlevel=INTERFACE_BREAKDOWN_STOPSCREEN;
+ }
+ if(events.count(INTERFACEKEY_MOVIE_PLAY))
+ {
+ is_playing=1;
+ gview.supermovie_on=0;
+ gview.currentblocksize=0;
+ gview.nextfilepos=0;
+ gview.supermovie_pos=0;
+ maxmoviepos=0;
+ }
+ if(events.count(INTERFACEKEY_MOVIE_SAVE))
+ {
+ savename.erase();
+ saving=1;
+ }
+ if(events.count(INTERFACEKEY_MOVIE_LOAD))
+ {
+ selfile=0;
+
+ clearfilelist();
+
+ find_files_by_pattern("data/movies/*.cmv",filelist);
+
+ if(filelist.size()>0)loading=1;
+ }
+ }
+ }
+}
+
+void viewscreen_movieplayerst::clearfilelist()
+{
+ int f;
+ for(f=0;f<filelist.size();f++)delete[] filelist[f];
+ filelist.clear();
+}
+
+viewscreen_movieplayerst::viewscreen_movieplayerst()
+{
+ force_file.erase();
+ gview.movie_file="data/movies/last_record.cmv";
+ is_playing=0;
+ enabler.release_grid_size();
+ if (gview.original_fps)
+ enabler.set_fps(gview.original_fps);
+ is_forced_play=0;
+ quit_if_no_play=0;
+ gview.supermovie_on=0;
+ gview.currentblocksize=0;
+ gview.nextfilepos=0;
+ gview.supermovie_pos=0;
+ maxmoviepos=0;
+ saving=0;
+ loading=0;
+ editing=0;
+ text_mode=0;
+ editing_copy_from=0;
+ editing_char=219;
+ editing_screenf=7;
+ editing_screenb=0;
+ editing_screenbright=0;
+ editing_menu=0;
+ editing_selected_sound=0;
+ end_frame_pos=0;
+ gview.supermovie_sound.clean();
+#ifndef NO_FMOD
+ int i,c;
+ for(i=0;i<200;i++)
+ {
+ for(c=0;c<SOUND_CHANNELNUM;c++)gview.supermovie_sound_time[i][c]=-1;
+ }
+#endif
+}
+
+interfacest::interfacest()
+{
+ original_fps = 0;
+ shutdown_interface_for_ms=0;
+ shutdown_interface_tickcount=0;
+ flag=0;
+ supermovie_on=0;
+ supermovie_pos=0;
+ supermovie_delayrate=0;
+}
+
+interfacest::~interfacest()
+{
+ //GO AHEAD
+ while(view.child!=NULL)
+ {
+ removescreen(view.child);
+ }
+}
+
+void interfacest::addscreen(viewscreenst *scr,char pushtype,viewscreenst *relate)
+{
+ gps.force_full_display_count+=2;
+
+ switch(pushtype)
+ {
+ case INTERFACE_PUSH_AS_PARENT:insertscreen_as_parent(scr,relate);break;
+ case INTERFACE_PUSH_AS_CHILD:insertscreen_as_child(scr,relate);break;
+ case INTERFACE_PUSH_AT_FRONT:insertscreen_at_front(scr);break;
+ default:insertscreen_at_back(scr);break;
+ }
+
+ //WHENEVER A SCREEN IS ADDED, END ANNOUNCEMENTS
+ if(gamemode==GAMEMODE_DWARF)dwarf_end_announcements();
+}
+
+void interfacest::insertscreen_as_parent(viewscreenst *scr,viewscreenst *child)
+{
+ if(child==NULL)
+ {
+ insertscreen_at_back(scr);
+ return;
+ }
+
+ scr->child=child;
+ scr->parent=child->parent;
+
+ if(scr->parent!=NULL)scr->parent->child=scr;
+ child->parent=scr;
+}
+
+void interfacest::insertscreen_as_child(viewscreenst *scr,viewscreenst *parent)
+{
+ if(parent==NULL)
+ {
+ insertscreen_at_back(scr);
+ return;
+ }
+
+ scr->child=parent->child;
+ scr->parent=parent;
+
+ if(scr->child!=NULL)scr->child->parent=scr;
+ parent->child=scr;
+}
+
+void interfacest::insertscreen_at_back(viewscreenst *scr)
+{
+ //GRAB CURRENT SCREEN AT THE END OF THE LIST
+ viewscreenst *currentscreen=&view;
+ while(currentscreen->child!=NULL)currentscreen=currentscreen->child;
+
+ //PUT IT ON TO THE BACK SCREEN
+ insertscreen_as_child(scr,currentscreen);
+}
+
+void interfacest::insertscreen_at_front(viewscreenst *scr)
+{
+ //PUT IT ON TO THE BASE
+ insertscreen_as_child(scr,&view);
+}
+
+viewscreenst *interfacest::grab_lastscreen() {
+ viewscreenst *currentscreen = &view;
+ while (currentscreen->child) currentscreen = currentscreen->child;
+ return currentscreen;
+}
+
+char interfacest::loop() {
+ //NO INTERFACE LEFT, QUIT
+ if(view.child==0)return 1;
+
+ //GRAB CURRENT SCREEN AT THE END OF THE LIST
+ viewscreenst *currentscreen = grab_lastscreen();
+ //MOVE SCREENS BACK
+ switch(currentscreen->breakdownlevel) {
+ case INTERFACE_BREAKDOWN_NONE: {
+
+ currentscreen->logic();
+
+ if(currentscreen->movies_okay())
+ {
+ //HANDLE MOVIES
+ handlemovie(0);
+ }
+
+ const Time now = SDL_GetTicks();
+ // Process as much input as possible. Some screens can't handle multiple input events
+ // per logic call (retain_nonzero_input, and any alteration to the window setup
+ // requires us to stop until the next logic call.
+ for (;;) {
+ if (currentscreen->child || currentscreen->breakdownlevel != INTERFACE_BREAKDOWN_NONE)
+ break; // Some previous input or logic had the effect of switching screens
+
+ if (flag & INTERFACEFLAG_RETAIN_NONZERO_INPUT) {
+ flag&=~INTERFACEFLAG_RETAIN_NONZERO_INPUT;
+ break;
+ } else {
+ set<InterfaceKey> era = enabler.get_input(now);
+ if (era.size() == 0) {
+ if(enabler.mouse_lbut || enabler.mouse_rbut) currentscreen->feed(era);
+ break;
+ }
+
+ if (era.count(INTERFACEKEY_OPTIONS)&&!currentscreen->key_conflict(INTERFACEKEY_OPTIONS)) {
+ //PEEL BACK ALL SCREENS TO THE CURRENT OPTION SCREEN IF THERE IS ONE
+ //UNLESS THERE IS A BLOCKING SCREEN LIKE THE REGION MAKER
+ viewscreenst *opscreen=&view;
+ while(opscreen!=NULL) {
+ if(opscreen->is_option_screen()) {
+ opscreen->option_key_pressed=1;
+ while(opscreen->child!=NULL) {
+ if(opscreen->child->is_option_screen()==2) {
+ opscreen->child->option_key_pressed=1;
+ opscreen->option_key_pressed=0;
+ break;
+ }
+ removescreen(opscreen->child);
+ }
+ break;
+ }
+ opscreen = opscreen->child;
+ }
+ //NEED A NEW OPTIONS SCREEN?
+ if(opscreen==NULL) dwarf_option_screen();
+
+ era.clear();
+ continue;
+ }
+ //DO MOVIE COMMANDS
+ if (era.count(INTERFACEKEY_MOVIES)&&!currentscreen->key_conflict(INTERFACEKEY_MOVIES))
+ if(currentscreen->movies_okay()) use_movie_input();
+ if (era.count(INTERFACEKEY_HELP)&&!currentscreen->key_conflict(INTERFACEKEY_HELP))
+ currentscreen->help();
+ // Prefix commands
+ // Most prefix commands we don't want to touch game management commands,
+ // i.e. what's in here. Macro playback is a notable exception.
+ if (era.count(INTERFACEKEY_PREFIX))
+ enabler.prefix_toggle();
+ int repeats = 1; // If this input ends a prefix command, we'll want to repeat it.
+ if (enabler.prefix_building()) {
+ // TODO: OMGWTFBBQ
+ char c = 0;
+ if (era.count(INTERFACEKEY_STRING_A048)) c = '0';
+ else if (era.count(INTERFACEKEY_STRING_A049)) c = '1';
+ else if (era.count(INTERFACEKEY_STRING_A050)) c = '2';
+ else if (era.count(INTERFACEKEY_STRING_A051)) c = '3';
+ else if (era.count(INTERFACEKEY_STRING_A052)) c = '4';
+ else if (era.count(INTERFACEKEY_STRING_A053)) c = '5';
+ else if (era.count(INTERFACEKEY_STRING_A054)) c = '6';
+ else if (era.count(INTERFACEKEY_STRING_A055)) c = '7';
+ else if (era.count(INTERFACEKEY_STRING_A056)) c = '8';
+ else if (era.count(INTERFACEKEY_STRING_A057)) c = '9';
+
+ if (c) {
+ enabler.prefix_add_digit(c);
+ era.clear();
+ } else {
+ repeats = enabler.prefix_end();
+ }
+ }
+ // TTF toggle
+ if (era.count(INTERFACEKEY_TOGGLE_TTF)) {
+ if (init.font.use_ttf == ttf_auto) {
+ // Do whatever produces a visible result.
+ if (ttf_manager.ttf_active())
+ init.font.use_ttf = ttf_off;
+ else
+ init.font.use_ttf = ttf_on;
+ } else if (init.font.use_ttf == ttf_on) {
+ init.font.use_ttf = ttf_off;
+ } else {
+ init.font.use_ttf = ttf_on;
+ }
+ gps.force_full_display_count++;
+ }
+ // Zoom commands
+ if (era.count(INTERFACEKEY_ZOOM_IN))
+ enabler.zoom_display(zoom_in);
+ if (era.count(INTERFACEKEY_ZOOM_OUT))
+ enabler.zoom_display(zoom_out);
+ if (era.count(INTERFACEKEY_ZOOM_RESET))
+ enabler.zoom_display(zoom_reset);
+ // Macro commands
+ if (era.count(INTERFACEKEY_RECORD_MACRO)) {
+ if (enabler.is_recording())
+ enabler.record_stop();
+ else
+ enabler.record_input();
+ }
+ if (era.count(INTERFACEKEY_PLAY_MACRO)) {
+ for (int i = 0; i < repeats; i++)
+ enabler.play_macro();
+ }
+ if (era.count(INTERFACEKEY_SAVE_MACRO))
+ gview.addscreen(new MacroScreenSave(), INTERFACE_PUSH_AT_BACK, NULL);
+ if (era.count(INTERFACEKEY_LOAD_MACRO))
+ gview.addscreen(new MacroScreenLoad(), INTERFACE_PUSH_AT_BACK, NULL);
+ // Feed input
+ for (int i = 0; i < repeats; i++)
+ currentscreen->feed(era);
+ if (era.count(INTERFACEKEY_TOGGLE_FULLSCREEN)) {
+ enabler.toggle_fullscreen();
+ }
+ if (era.count(INTERFACEKEY_FPS_UP)) {
+ int fps = enabler.get_fps();
+ enabler.set_fps(fps + fps/10);
+ enabler.clear_fps();
+ }
+ if (era.count(INTERFACEKEY_FPS_DOWN)) {
+ int fps = enabler.get_fps();
+ enabler.set_fps(fps - fps/10);
+ enabler.clear_fps();
+ }
+ }
+ }
+ break;
+ } // case INTERFACE_BREAKDOWN_NONE
+
+ case INTERFACE_BREAKDOWN_QUIT:
+ {
+ handlemovie(1);
+ return 1;
+ }
+ case INTERFACE_BREAKDOWN_STOPSCREEN:
+ if(currentscreen->movies_okay())
+ {
+ //HANDLE MOVIES
+ handlemovie(0);
+ }
+
+ removescreen(currentscreen);
+ break;
+ case INTERFACE_BREAKDOWN_TOFIRST:
+ if(currentscreen->movies_okay())
+ {
+ //HANDLE MOVIES
+ handlemovie(0);
+ }
+
+ remove_to_first();
+ break;
+ }
+
+ return 0;
+}
+
+void interfacest::remove_to_first()
+{
+ //GRAB LAST SCREEN AT THE END OF THE LIST
+ viewscreenst *lastscreen=&view;
+ while(lastscreen->child!=NULL)lastscreen=lastscreen->child;
+
+ //NO INTERFACE LEFT
+ if(lastscreen==&view)return;
+
+ //GO AHEAD
+ while(lastscreen->parent!=&view)
+ {
+ viewscreenst *par=lastscreen->parent;
+ removescreen(lastscreen);
+ lastscreen=par;
+ }
+}
+
+void interfacest::removescreen(viewscreenst *scr)
+{
+ //THE MINIMAP IS EXPENSIVE, SO WE REFRESH IT WHENEVER INTERFACE GETS IN THE WAY
+ if(gamemode==GAMEMODE_DWARF)dwarf_remove_screen();
+
+ //FIX LINKS
+ if(scr->parent!=NULL)scr->parent->child=scr->child;
+ if(scr->child!=NULL)scr->child->parent=scr->parent;
+
+ //WASTE SCREEN
+ delete scr;
+}
+
+int interfacest::write_movie_chunk()
+{
+ int inputsize=supermovie_pos;
+ if(inputsize>MOVIEBUFFSIZE)inputsize=MOVIEBUFFSIZE;
+
+ //DUMP CURRENT BUFFER INTO A COMPRESSION STREAM
+ z_stream c_stream;
+ int err;
+
+ c_stream.zalloc = (alloc_func)0;
+ c_stream.zfree = (free_func)0;
+ c_stream.opaque = (voidpf)0;
+
+ err = deflateInit(&c_stream, 9);
+ CHECK_ERR(err, "deflateInit");
+
+ c_stream.next_out = (Bytef*)supermoviebuffer_comp;
+ c_stream.avail_out = COMPMOVIEBUFFSIZE;
+
+ c_stream.next_in = (Bytef*)supermoviebuffer;
+ c_stream.avail_in = inputsize;
+
+ while (c_stream.total_in != inputsize && c_stream.total_out < COMPMOVIEBUFFSIZE) {
+ //c_stream.avail_in = c_stream.avail_out = 1; // force small buffers
+ err = deflate(&c_stream, Z_NO_FLUSH);
+ CHECK_ERR(err, "deflate");
+ }
+
+ // Finish the stream, still forcing small buffers:
+ for (;;) {
+ err = deflate(&c_stream, Z_FINISH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "deflate");
+ }
+
+ err = deflateEnd(&c_stream);
+ CHECK_ERR(err, "deflateEnd");
+
+ int length=0;
+
+ if(c_stream.total_out>0)
+ {
+ if(first_movie_write)
+ {
+ //GET RID OF ANY EXISTING MOVIES IF THIS IS THE FIRST TIME THROUGH
+ unlink(movie_file.c_str());
+ }
+
+ //OPEN UP THE MOVIE FILE AND APPEND
+ std::fstream f;
+ f.open(movie_file.c_str(), fstream::out | fstream::binary | fstream::app);
+
+ if(f.is_open())
+ {
+ //WRITE A HEADER
+ if(first_movie_write)
+ {
+ int swp_l=byteswap(movie_version);
+ f.write((const char *)&swp_l,sizeof(int));
+
+
+ cursesmovie_headerst cmh;
+ cmh.dimx=init.display.grid_x;
+ cmh.dimy=init.display.grid_y;
+ cmh.delayrate=supermovie_delayrate;
+ cmh.dimx=byteswap(cmh.dimx);
+ cmh.dimy=byteswap(cmh.dimy);
+ cmh.delayrate=byteswap(cmh.delayrate);
+ f.write((const char *)&cmh,sizeof(cursesmovie_headerst));
+
+ int s;
+ s=byteswap(gview.supermovie_sound.str.size());
+ f.write((const char *)&s,sizeof(int));
+ char buf[50];
+ for(s=0;s<gview.supermovie_sound.str.size();s++)
+ {
+ strcpy(buf,gview.supermovie_sound.str[s]->dat.c_str());
+ f.write(buf,sizeof(char)*50);
+ }
+
+ int i1,i2;
+ for(i1=0;i1<200;i1++)
+ {
+ for(i2=0;i2<SOUND_CHANNELNUM;i2++)
+ {
+#ifndef NO_FMOD
+ swp_l=byteswap(gview.supermovie_sound_time[i1][i2]);
+#else
+ swp_l=-1;
+#endif
+ f.write((const char *)&swp_l,sizeof(int));
+ }
+ }
+ }
+
+ //WRITE IT
+ int compsize=byteswap(c_stream.total_out);
+ f.write((const char *)&compsize,sizeof(int));
+ f.write((const char *)supermoviebuffer_comp,c_stream.total_out);
+
+ f.seekg(0,ios::beg);
+ int beg=f.tellg();
+ f.seekg(0,ios::end);
+ int end=f.tellg();
+ length=end-beg;
+
+ f.close();
+ }
+ else supermovie_on=0;
+
+ first_movie_write=0;
+ }
+
+ return length;
+}
+
+void interfacest::read_movie_chunk(int &maxmoviepos,char &is_playing)
+{
+ //OPEN UP THE MOVIE FILE AND MOVE TO CORRECT POSITION
+ std::fstream f;
+ f.open(movie_file.c_str(), fstream::in | fstream::binary);
+
+ if(f.is_open())
+ {
+ f.seekg(0,ios::beg);
+ int beg=f.tellg();
+ f.seekg(0,ios::end);
+ int end=f.tellg();
+ int file_size=end-beg;
+
+ if(gview.nextfilepos<file_size)
+ {
+ f.seekg(gview.nextfilepos,ios::beg);
+
+ //LOAD THE HEADER
+ char fail=0;
+ if(gview.nextfilepos==0)
+ {
+ int loadversion;
+ f.read((char *)&loadversion,sizeof(int));
+ loadversion=byteswap(loadversion);
+
+ if(loadversion>movie_version)fail=1;
+
+ cursesmovie_headerst cmh;
+ f.read((char *)&cmh,sizeof(cursesmovie_headerst));
+ cmh.dimx=byteswap(cmh.dimx);
+ cmh.dimy=byteswap(cmh.dimy);
+ cmh.delayrate=byteswap(cmh.delayrate);
+
+ enabler.override_grid_size(cmh.dimx, cmh.dimy);
+ if (!gview.original_fps)
+ gview.original_fps = enabler.get_fps();
+ enabler.set_fps(100);
+
+ gview.supermovie_delayrate=cmh.delayrate;
+ gview.supermovie_delaystep=cmh.delayrate;
+
+ gview.supermovie_sound.clean();
+ if(loadversion>=10001)
+ {
+ int num;
+ f.read((char *)&num,sizeof(int));
+ num=byteswap(num);
+ gview.nextfilepos+=sizeof(int);
+ char buf[50];
+ int s;
+ for(s=0;s<num;s++)
+ {
+ f.read(buf,sizeof(char)*50);
+ string str=buf;
+ gview.supermovie_sound.add_string(str);
+ gview.nextfilepos+=sizeof(char)*50;
+ }
+
+ int i1,i2,swp_l;
+ for(i1=0;i1<200;i1++)
+ {
+ for(i2=0;i2<SOUND_CHANNELNUM;i2++)
+ {
+ f.read((char *)&swp_l,sizeof(int));
+#ifndef NO_FMOD
+ gview.supermovie_sound_time[i1][i2]=byteswap(swp_l);
+#endif
+ }
+ }
+
+ gview.nextfilepos+=sizeof(int)*200*SOUND_CHANNELNUM;
+ }
+ else
+ {
+#ifndef NO_FMOD
+ int i,c;
+ for(i=0;i<200;i++)
+ {
+ for(c=0;c<SOUND_CHANNELNUM;c++)gview.supermovie_sound_time[i][c]=-1;
+ }
+#endif
+ }
+
+ gview.nextfilepos+=sizeof(int)+sizeof(cursesmovie_headerst);
+
+#ifndef NO_FMOD
+ //HANDLE SOUND LOADING
+ int s;
+ for(s=0;s<gview.supermovie_sound.str.size();s++)
+ {
+ string filename="data/sound/";
+ filename+=gview.supermovie_sound.str[s]->dat;
+ filename+=".ogg";
+
+ musicsound.set_sound(filename,s);
+ }
+#endif
+ }
+
+ if(!fail)
+ {
+ //READ IT
+ f.read((char *)&gview.currentblocksize,sizeof(int));
+ gview.currentblocksize=byteswap(gview.currentblocksize);
+ f.read((char *)gview.supermoviebuffer_comp,gview.currentblocksize);
+
+ gview.nextfilepos+=gview.currentblocksize+sizeof(int);
+
+ //UNCOMPRESS IT
+ z_stream d_stream; // decompression stream
+
+ d_stream.zalloc = (alloc_func)0;
+ d_stream.zfree = (free_func)0;
+ d_stream.opaque = (voidpf)0;
+
+ d_stream.next_in = (Bytef*)gview.supermoviebuffer_comp;
+ d_stream.avail_in = gview.currentblocksize;
+
+ int err = inflateInit(&d_stream);
+ CHECK_ERR(err, "inflateInit");
+
+ d_stream.next_out = gview.supermoviebuffer;
+ d_stream.avail_out = MOVIEBUFFSIZE;
+
+ while (d_stream.total_out < MOVIEBUFFSIZE && d_stream.total_in < gview.currentblocksize) {
+ //d_stream.avail_in = d_stream.avail_out = 1; // force small buffers
+ err = inflate(&d_stream, Z_NO_FLUSH);
+ if (err == Z_STREAM_END) break;
+ CHECK_ERR(err, "inflate");
+ }
+
+ err = inflateEnd(&d_stream);
+ CHECK_ERR(err, "inflateEnd");
+
+ gview.supermovie_pos=0;
+ maxmoviepos=d_stream.total_out;
+ }
+ else
+ {
+ is_playing=0;
+ enabler.release_grid_size();
+ if (gview.original_fps)
+ enabler.set_fps(gview.original_fps);
+ }
+ }
+ else
+ {
+ is_playing=0;
+ enabler.release_grid_size();
+ if (gview.original_fps)
+ enabler.set_fps(gview.original_fps);
+ }
+
+ f.close();
+ }
+ else
+ {
+ is_playing=0;
+ enabler.release_grid_size();
+ if (gview.original_fps)
+ enabler.set_fps(gview.original_fps);
+ }
+}
+
+void interfacest::handlemovie(char flushall)
+{
+ //SAVE A MOVIE FRAME INTO THE CURRENT MOVIE BUFFER
+ if(supermovie_on==1)
+ {
+ if(supermovie_delaystep>0&&!flushall)supermovie_delaystep--;
+ else
+ {
+ if(!flushall)supermovie_delaystep=supermovie_delayrate;
+
+ if(!flushall||supermovie_delaystep==0)
+ {
+ //SAVING CHARACTERS, THEN COLORS
+ short x2,y2;
+ for(x2=0;x2<init.display.grid_x;x2++)
+ {
+ for(y2=0;y2<init.display.grid_y;y2++)
+ {
+ supermoviebuffer[supermovie_pos]=gps.screen[x2*gps.dimy*4 + y2*4 + 0];
+
+ supermovie_pos++;
+ }
+ }
+ char frame_col;
+ for(x2=0;x2<init.display.grid_x;x2++)
+ {
+ for(y2=0;y2<init.display.grid_y;y2++)
+ {
+ frame_col=gps.screen[x2*gps.dimy*4 + y2*4 + 1];
+ frame_col|=(gps.screen[x2*gps.dimy*4 + y2*4 + 2]<<3);
+ if(gps.screen[x2*gps.dimy*4 + y2*4 + 3])frame_col|=64;
+ supermoviebuffer[supermovie_pos]=frame_col;
+
+ supermovie_pos++;
+ }
+ }
+ }
+
+ int frame_size=init.display.grid_x*init.display.grid_y*2;
+ if(supermovie_pos+frame_size>=MOVIEBUFFSIZE||flushall)
+ {
+ int length=write_movie_chunk();
+
+ if(length>5000000)
+ {
+ finish_movie();
+ }
+ else supermovie_pos=0;
+ }
+ }
+ }
+}
+
+void interfacest::print_interface_token(InterfaceKey key,justification just)
+{
+ short o_screenf=gps.screenf,o_screenb=gps.screenb,o_screenbright=gps.screenbright;
+ gps.changecolor(2,0,1);
+ string tok = enabler.GetKeyDisplay(key);
+ gps.addst(tok,just);
+ gps.changecolor(o_screenf,o_screenb,o_screenbright);
+}
+
+char standardstringentry(char *str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events)
+{
+ string str2;
+ str2=str;
+ char ret=standardstringentry(str2,maxlen,flag,events);
+ strcpy(str,str2.c_str());
+ return ret;
+}
+
+char standardstringentry(string &str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events)
+{
+ unsigned char entry=255;
+ if(flag & STRINGENTRY_LETTERS)
+ {
+ if(events.count(INTERFACEKEY_STRING_A097))entry='a';
+ if(events.count(INTERFACEKEY_STRING_A098))entry='b';
+ if(events.count(INTERFACEKEY_STRING_A099))entry='c';
+ if(events.count(INTERFACEKEY_STRING_A100))entry='d';
+ if(events.count(INTERFACEKEY_STRING_A101))entry='e';
+ if(events.count(INTERFACEKEY_STRING_A102))entry='f';
+ if(events.count(INTERFACEKEY_STRING_A103))entry='g';
+ if(events.count(INTERFACEKEY_STRING_A104))entry='h';
+ if(events.count(INTERFACEKEY_STRING_A105))entry='i';
+ if(events.count(INTERFACEKEY_STRING_A106))entry='j';
+ if(events.count(INTERFACEKEY_STRING_A107))entry='k';
+ if(events.count(INTERFACEKEY_STRING_A108))entry='l';
+ if(events.count(INTERFACEKEY_STRING_A109))entry='m';
+ if(events.count(INTERFACEKEY_STRING_A110))entry='n';
+ if(events.count(INTERFACEKEY_STRING_A111))entry='o';
+ if(events.count(INTERFACEKEY_STRING_A112))entry='p';
+ if(events.count(INTERFACEKEY_STRING_A113))entry='q';
+ if(events.count(INTERFACEKEY_STRING_A114))entry='r';
+ if(events.count(INTERFACEKEY_STRING_A115))entry='s';
+ if(events.count(INTERFACEKEY_STRING_A116))entry='t';
+ if(events.count(INTERFACEKEY_STRING_A117))entry='u';
+ if(events.count(INTERFACEKEY_STRING_A118))entry='v';
+ if(events.count(INTERFACEKEY_STRING_A119))entry='w';
+ if(events.count(INTERFACEKEY_STRING_A120))entry='x';
+ if(events.count(INTERFACEKEY_STRING_A121))entry='y';
+ if(events.count(INTERFACEKEY_STRING_A122))entry='z';
+ if(events.count(INTERFACEKEY_STRING_A065))entry='A';
+ if(events.count(INTERFACEKEY_STRING_A066))entry='B';
+ if(events.count(INTERFACEKEY_STRING_A067))entry='C';
+ if(events.count(INTERFACEKEY_STRING_A068))entry='D';
+ if(events.count(INTERFACEKEY_STRING_A069))entry='E';
+ if(events.count(INTERFACEKEY_STRING_A070))entry='F';
+ if(events.count(INTERFACEKEY_STRING_A071))entry='G';
+ if(events.count(INTERFACEKEY_STRING_A072))entry='H';
+ if(events.count(INTERFACEKEY_STRING_A073))entry='I';
+ if(events.count(INTERFACEKEY_STRING_A074))entry='J';
+ if(events.count(INTERFACEKEY_STRING_A075))entry='K';
+ if(events.count(INTERFACEKEY_STRING_A076))entry='L';
+ if(events.count(INTERFACEKEY_STRING_A077))entry='M';
+ if(events.count(INTERFACEKEY_STRING_A078))entry='N';
+ if(events.count(INTERFACEKEY_STRING_A079))entry='O';
+ if(events.count(INTERFACEKEY_STRING_A080))entry='P';
+ if(events.count(INTERFACEKEY_STRING_A081))entry='Q';
+ if(events.count(INTERFACEKEY_STRING_A082))entry='R';
+ if(events.count(INTERFACEKEY_STRING_A083))entry='S';
+ if(events.count(INTERFACEKEY_STRING_A084))entry='T';
+ if(events.count(INTERFACEKEY_STRING_A085))entry='U';
+ if(events.count(INTERFACEKEY_STRING_A086))entry='V';
+ if(events.count(INTERFACEKEY_STRING_A087))entry='W';
+ if(events.count(INTERFACEKEY_STRING_A088))entry='X';
+ if(events.count(INTERFACEKEY_STRING_A089))entry='Y';
+ if(events.count(INTERFACEKEY_STRING_A090))entry='Z';
+ }
+ if(flag & STRINGENTRY_SPACE)
+ {
+ if(events.count(INTERFACEKEY_STRING_A032))entry=' ';
+ }
+ if(events.count(INTERFACEKEY_STRING_A000))entry='\x0';
+ if(flag & STRINGENTRY_NUMBERS)
+ {
+ if(events.count(INTERFACEKEY_STRING_A048))entry='0';
+ if(events.count(INTERFACEKEY_STRING_A049))entry='1';
+ if(events.count(INTERFACEKEY_STRING_A050))entry='2';
+ if(events.count(INTERFACEKEY_STRING_A051))entry='3';
+ if(events.count(INTERFACEKEY_STRING_A052))entry='4';
+ if(events.count(INTERFACEKEY_STRING_A053))entry='5';
+ if(events.count(INTERFACEKEY_STRING_A054))entry='6';
+ if(events.count(INTERFACEKEY_STRING_A055))entry='7';
+ if(events.count(INTERFACEKEY_STRING_A056))entry='8';
+ if(events.count(INTERFACEKEY_STRING_A057))entry='9';
+ }
+ if(flag & STRINGENTRY_SYMBOLS)
+ {
+ if(events.count(INTERFACEKEY_STRING_A000))entry=0;
+ if(events.count(INTERFACEKEY_STRING_A001))entry=1;
+ if(events.count(INTERFACEKEY_STRING_A002))entry=2;
+ if(events.count(INTERFACEKEY_STRING_A003))entry=3;
+ if(events.count(INTERFACEKEY_STRING_A004))entry=4;
+ if(events.count(INTERFACEKEY_STRING_A005))entry=5;
+ if(events.count(INTERFACEKEY_STRING_A006))entry=6;
+ if(events.count(INTERFACEKEY_STRING_A007))entry=7;
+ if(events.count(INTERFACEKEY_STRING_A008))entry=8;
+ if(events.count(INTERFACEKEY_STRING_A009))entry=9;
+ if(events.count(INTERFACEKEY_STRING_A010))entry=10;
+ if(events.count(INTERFACEKEY_STRING_A011))entry=11;
+ if(events.count(INTERFACEKEY_STRING_A012))entry=12;
+ if(events.count(INTERFACEKEY_STRING_A013))entry=13;
+ if(events.count(INTERFACEKEY_STRING_A014))entry=14;
+ if(events.count(INTERFACEKEY_STRING_A015))entry=15;
+ if(events.count(INTERFACEKEY_STRING_A016))entry=16;
+ if(events.count(INTERFACEKEY_STRING_A017))entry=17;
+ if(events.count(INTERFACEKEY_STRING_A018))entry=18;
+ if(events.count(INTERFACEKEY_STRING_A019))entry=19;
+ if(events.count(INTERFACEKEY_STRING_A020))entry=20;
+ if(events.count(INTERFACEKEY_STRING_A021))entry=21;
+ if(events.count(INTERFACEKEY_STRING_A022))entry=22;
+ if(events.count(INTERFACEKEY_STRING_A023))entry=23;
+ if(events.count(INTERFACEKEY_STRING_A024))entry=24;
+ if(events.count(INTERFACEKEY_STRING_A025))entry=25;
+ if(events.count(INTERFACEKEY_STRING_A026))entry=26;
+ if(events.count(INTERFACEKEY_STRING_A027))entry=27;
+ if(events.count(INTERFACEKEY_STRING_A028))entry=28;
+ if(events.count(INTERFACEKEY_STRING_A029))entry=29;
+ if(events.count(INTERFACEKEY_STRING_A030))entry=30;
+ if(events.count(INTERFACEKEY_STRING_A031))entry=31;
+ if(events.count(INTERFACEKEY_STRING_A032))entry=32;
+ if(events.count(INTERFACEKEY_STRING_A033))entry=33;
+ if(events.count(INTERFACEKEY_STRING_A034))entry=34;
+ if(events.count(INTERFACEKEY_STRING_A035))entry=35;
+ if(events.count(INTERFACEKEY_STRING_A036))entry=36;
+ if(events.count(INTERFACEKEY_STRING_A037))entry=37;
+ if(events.count(INTERFACEKEY_STRING_A038))entry=38;
+ if(events.count(INTERFACEKEY_STRING_A039))entry=39;
+ if(events.count(INTERFACEKEY_STRING_A040))entry=40;
+ if(events.count(INTERFACEKEY_STRING_A041))entry=41;
+ if(events.count(INTERFACEKEY_STRING_A042))entry=42;
+ if(events.count(INTERFACEKEY_STRING_A043))entry=43;
+ if(events.count(INTERFACEKEY_STRING_A044))entry=44;
+ if(events.count(INTERFACEKEY_STRING_A045))entry=45;
+ if(events.count(INTERFACEKEY_STRING_A046))entry=46;
+ if(events.count(INTERFACEKEY_STRING_A047))entry=47;
+ if(events.count(INTERFACEKEY_STRING_A048))entry=48;
+ if(events.count(INTERFACEKEY_STRING_A049))entry=49;
+ if(events.count(INTERFACEKEY_STRING_A050))entry=50;
+ if(events.count(INTERFACEKEY_STRING_A051))entry=51;
+ if(events.count(INTERFACEKEY_STRING_A052))entry=52;
+ if(events.count(INTERFACEKEY_STRING_A053))entry=53;
+ if(events.count(INTERFACEKEY_STRING_A054))entry=54;
+ if(events.count(INTERFACEKEY_STRING_A055))entry=55;
+ if(events.count(INTERFACEKEY_STRING_A056))entry=56;
+ if(events.count(INTERFACEKEY_STRING_A057))entry=57;
+ if(events.count(INTERFACEKEY_STRING_A058))entry=58;
+ if(events.count(INTERFACEKEY_STRING_A059))entry=59;
+ if(events.count(INTERFACEKEY_STRING_A060))entry=60;
+ if(events.count(INTERFACEKEY_STRING_A061))entry=61;
+ if(events.count(INTERFACEKEY_STRING_A062))entry=62;
+ if(events.count(INTERFACEKEY_STRING_A063))entry=63;
+ if(events.count(INTERFACEKEY_STRING_A064))entry=64;
+ if(events.count(INTERFACEKEY_STRING_A065))entry=65;
+ if(events.count(INTERFACEKEY_STRING_A066))entry=66;
+ if(events.count(INTERFACEKEY_STRING_A067))entry=67;
+ if(events.count(INTERFACEKEY_STRING_A068))entry=68;
+ if(events.count(INTERFACEKEY_STRING_A069))entry=69;
+ if(events.count(INTERFACEKEY_STRING_A070))entry=70;
+ if(events.count(INTERFACEKEY_STRING_A071))entry=71;
+ if(events.count(INTERFACEKEY_STRING_A072))entry=72;
+ if(events.count(INTERFACEKEY_STRING_A073))entry=73;
+ if(events.count(INTERFACEKEY_STRING_A074))entry=74;
+ if(events.count(INTERFACEKEY_STRING_A075))entry=75;
+ if(events.count(INTERFACEKEY_STRING_A076))entry=76;
+ if(events.count(INTERFACEKEY_STRING_A077))entry=77;
+ if(events.count(INTERFACEKEY_STRING_A078))entry=78;
+ if(events.count(INTERFACEKEY_STRING_A079))entry=79;
+ if(events.count(INTERFACEKEY_STRING_A080))entry=80;
+ if(events.count(INTERFACEKEY_STRING_A081))entry=81;
+ if(events.count(INTERFACEKEY_STRING_A082))entry=82;
+ if(events.count(INTERFACEKEY_STRING_A083))entry=83;
+ if(events.count(INTERFACEKEY_STRING_A084))entry=84;
+ if(events.count(INTERFACEKEY_STRING_A085))entry=85;
+ if(events.count(INTERFACEKEY_STRING_A086))entry=86;
+ if(events.count(INTERFACEKEY_STRING_A087))entry=87;
+ if(events.count(INTERFACEKEY_STRING_A088))entry=88;
+ if(events.count(INTERFACEKEY_STRING_A089))entry=89;
+ if(events.count(INTERFACEKEY_STRING_A090))entry=90;
+ if(events.count(INTERFACEKEY_STRING_A091))entry=91;
+ if(events.count(INTERFACEKEY_STRING_A092))entry=92;
+ if(events.count(INTERFACEKEY_STRING_A093))entry=93;
+ if(events.count(INTERFACEKEY_STRING_A094))entry=94;
+ if(events.count(INTERFACEKEY_STRING_A095))entry=95;
+ if(events.count(INTERFACEKEY_STRING_A096))entry=96;
+ if(events.count(INTERFACEKEY_STRING_A097))entry=97;
+ if(events.count(INTERFACEKEY_STRING_A098))entry=98;
+ if(events.count(INTERFACEKEY_STRING_A099))entry=99;
+ if(events.count(INTERFACEKEY_STRING_A100))entry=100;
+ if(events.count(INTERFACEKEY_STRING_A101))entry=101;
+ if(events.count(INTERFACEKEY_STRING_A102))entry=102;
+ if(events.count(INTERFACEKEY_STRING_A103))entry=103;
+ if(events.count(INTERFACEKEY_STRING_A104))entry=104;
+ if(events.count(INTERFACEKEY_STRING_A105))entry=105;
+ if(events.count(INTERFACEKEY_STRING_A106))entry=106;
+ if(events.count(INTERFACEKEY_STRING_A107))entry=107;
+ if(events.count(INTERFACEKEY_STRING_A108))entry=108;
+ if(events.count(INTERFACEKEY_STRING_A109))entry=109;
+ if(events.count(INTERFACEKEY_STRING_A110))entry=110;
+ if(events.count(INTERFACEKEY_STRING_A111))entry=111;
+ if(events.count(INTERFACEKEY_STRING_A112))entry=112;
+ if(events.count(INTERFACEKEY_STRING_A113))entry=113;
+ if(events.count(INTERFACEKEY_STRING_A114))entry=114;
+ if(events.count(INTERFACEKEY_STRING_A115))entry=115;
+ if(events.count(INTERFACEKEY_STRING_A116))entry=116;
+ if(events.count(INTERFACEKEY_STRING_A117))entry=117;
+ if(events.count(INTERFACEKEY_STRING_A118))entry=118;
+ if(events.count(INTERFACEKEY_STRING_A119))entry=119;
+ if(events.count(INTERFACEKEY_STRING_A120))entry=120;
+ if(events.count(INTERFACEKEY_STRING_A121))entry=121;
+ if(events.count(INTERFACEKEY_STRING_A122))entry=122;
+ if(events.count(INTERFACEKEY_STRING_A123))entry=123;
+ if(events.count(INTERFACEKEY_STRING_A124))entry=124;
+ if(events.count(INTERFACEKEY_STRING_A125))entry=125;
+ if(events.count(INTERFACEKEY_STRING_A126))entry=126;
+ if(events.count(INTERFACEKEY_STRING_A128))entry=128;
+ if(events.count(INTERFACEKEY_STRING_A129))entry=129;
+ if(events.count(INTERFACEKEY_STRING_A130))entry=130;
+ if(events.count(INTERFACEKEY_STRING_A131))entry=131;
+ if(events.count(INTERFACEKEY_STRING_A132))entry=132;
+ if(events.count(INTERFACEKEY_STRING_A133))entry=133;
+ if(events.count(INTERFACEKEY_STRING_A134))entry=134;
+ if(events.count(INTERFACEKEY_STRING_A135))entry=135;
+ if(events.count(INTERFACEKEY_STRING_A136))entry=136;
+ if(events.count(INTERFACEKEY_STRING_A137))entry=137;
+ if(events.count(INTERFACEKEY_STRING_A138))entry=138;
+ if(events.count(INTERFACEKEY_STRING_A139))entry=139;
+ if(events.count(INTERFACEKEY_STRING_A140))entry=140;
+ if(events.count(INTERFACEKEY_STRING_A141))entry=141;
+ if(events.count(INTERFACEKEY_STRING_A142))entry=142;
+ if(events.count(INTERFACEKEY_STRING_A143))entry=143;
+ if(events.count(INTERFACEKEY_STRING_A144))entry=144;
+ if(events.count(INTERFACEKEY_STRING_A145))entry=145;
+ if(events.count(INTERFACEKEY_STRING_A146))entry=146;
+ if(events.count(INTERFACEKEY_STRING_A147))entry=147;
+ if(events.count(INTERFACEKEY_STRING_A148))entry=148;
+ if(events.count(INTERFACEKEY_STRING_A149))entry=149;
+ if(events.count(INTERFACEKEY_STRING_A150))entry=150;
+ if(events.count(INTERFACEKEY_STRING_A151))entry=151;
+ if(events.count(INTERFACEKEY_STRING_A152))entry=152;
+ if(events.count(INTERFACEKEY_STRING_A153))entry=153;
+ if(events.count(INTERFACEKEY_STRING_A154))entry=154;
+ if(events.count(INTERFACEKEY_STRING_A155))entry=155;
+ if(events.count(INTERFACEKEY_STRING_A156))entry=156;
+ if(events.count(INTERFACEKEY_STRING_A157))entry=157;
+ if(events.count(INTERFACEKEY_STRING_A158))entry=158;
+ if(events.count(INTERFACEKEY_STRING_A159))entry=159;
+ if(events.count(INTERFACEKEY_STRING_A160))entry=160;
+ if(events.count(INTERFACEKEY_STRING_A161))entry=161;
+ if(events.count(INTERFACEKEY_STRING_A162))entry=162;
+ if(events.count(INTERFACEKEY_STRING_A163))entry=163;
+ if(events.count(INTERFACEKEY_STRING_A164))entry=164;
+ if(events.count(INTERFACEKEY_STRING_A165))entry=165;
+ if(events.count(INTERFACEKEY_STRING_A166))entry=166;
+ if(events.count(INTERFACEKEY_STRING_A167))entry=167;
+ if(events.count(INTERFACEKEY_STRING_A168))entry=168;
+ if(events.count(INTERFACEKEY_STRING_A169))entry=169;
+ if(events.count(INTERFACEKEY_STRING_A170))entry=170;
+ if(events.count(INTERFACEKEY_STRING_A171))entry=171;
+ if(events.count(INTERFACEKEY_STRING_A172))entry=172;
+ if(events.count(INTERFACEKEY_STRING_A173))entry=173;
+ if(events.count(INTERFACEKEY_STRING_A174))entry=174;
+ if(events.count(INTERFACEKEY_STRING_A175))entry=175;
+ if(events.count(INTERFACEKEY_STRING_A176))entry=176;
+ if(events.count(INTERFACEKEY_STRING_A177))entry=177;
+ if(events.count(INTERFACEKEY_STRING_A178))entry=178;
+ if(events.count(INTERFACEKEY_STRING_A179))entry=179;
+ if(events.count(INTERFACEKEY_STRING_A180))entry=180;
+ if(events.count(INTERFACEKEY_STRING_A181))entry=181;
+ if(events.count(INTERFACEKEY_STRING_A182))entry=182;
+ if(events.count(INTERFACEKEY_STRING_A183))entry=183;
+ if(events.count(INTERFACEKEY_STRING_A184))entry=184;
+ if(events.count(INTERFACEKEY_STRING_A185))entry=185;
+ if(events.count(INTERFACEKEY_STRING_A186))entry=186;
+ if(events.count(INTERFACEKEY_STRING_A187))entry=187;
+ if(events.count(INTERFACEKEY_STRING_A188))entry=188;
+ if(events.count(INTERFACEKEY_STRING_A189))entry=189;
+ if(events.count(INTERFACEKEY_STRING_A190))entry=190;
+ if(events.count(INTERFACEKEY_STRING_A191))entry=191;
+ if(events.count(INTERFACEKEY_STRING_A192))entry=192;
+ if(events.count(INTERFACEKEY_STRING_A193))entry=193;
+ if(events.count(INTERFACEKEY_STRING_A194))entry=194;
+ if(events.count(INTERFACEKEY_STRING_A195))entry=195;
+ if(events.count(INTERFACEKEY_STRING_A196))entry=196;
+ if(events.count(INTERFACEKEY_STRING_A197))entry=197;
+ if(events.count(INTERFACEKEY_STRING_A198))entry=198;
+ if(events.count(INTERFACEKEY_STRING_A199))entry=199;
+ if(events.count(INTERFACEKEY_STRING_A200))entry=200;
+ if(events.count(INTERFACEKEY_STRING_A201))entry=201;
+ if(events.count(INTERFACEKEY_STRING_A202))entry=202;
+ if(events.count(INTERFACEKEY_STRING_A203))entry=203;
+ if(events.count(INTERFACEKEY_STRING_A204))entry=204;
+ if(events.count(INTERFACEKEY_STRING_A205))entry=205;
+ if(events.count(INTERFACEKEY_STRING_A206))entry=206;
+ if(events.count(INTERFACEKEY_STRING_A207))entry=207;
+ if(events.count(INTERFACEKEY_STRING_A208))entry=208;
+ if(events.count(INTERFACEKEY_STRING_A209))entry=209;
+ if(events.count(INTERFACEKEY_STRING_A210))entry=210;
+ if(events.count(INTERFACEKEY_STRING_A211))entry=211;
+ if(events.count(INTERFACEKEY_STRING_A212))entry=212;
+ if(events.count(INTERFACEKEY_STRING_A213))entry=213;
+ if(events.count(INTERFACEKEY_STRING_A214))entry=214;
+ if(events.count(INTERFACEKEY_STRING_A215))entry=215;
+ if(events.count(INTERFACEKEY_STRING_A216))entry=216;
+ if(events.count(INTERFACEKEY_STRING_A217))entry=217;
+ if(events.count(INTERFACEKEY_STRING_A218))entry=218;
+ if(events.count(INTERFACEKEY_STRING_A219))entry=219;
+ if(events.count(INTERFACEKEY_STRING_A220))entry=220;
+ if(events.count(INTERFACEKEY_STRING_A221))entry=221;
+ if(events.count(INTERFACEKEY_STRING_A222))entry=222;
+ if(events.count(INTERFACEKEY_STRING_A223))entry=223;
+ if(events.count(INTERFACEKEY_STRING_A224))entry=224;
+ if(events.count(INTERFACEKEY_STRING_A225))entry=225;
+ if(events.count(INTERFACEKEY_STRING_A226))entry=226;
+ if(events.count(INTERFACEKEY_STRING_A227))entry=227;
+ if(events.count(INTERFACEKEY_STRING_A228))entry=228;
+ if(events.count(INTERFACEKEY_STRING_A229))entry=229;
+ if(events.count(INTERFACEKEY_STRING_A230))entry=230;
+ if(events.count(INTERFACEKEY_STRING_A231))entry=231;
+ if(events.count(INTERFACEKEY_STRING_A232))entry=232;
+ if(events.count(INTERFACEKEY_STRING_A233))entry=233;
+ if(events.count(INTERFACEKEY_STRING_A234))entry=234;
+ if(events.count(INTERFACEKEY_STRING_A235))entry=235;
+ if(events.count(INTERFACEKEY_STRING_A236))entry=236;
+ if(events.count(INTERFACEKEY_STRING_A237))entry=237;
+ if(events.count(INTERFACEKEY_STRING_A238))entry=238;
+ if(events.count(INTERFACEKEY_STRING_A239))entry=239;
+ if(events.count(INTERFACEKEY_STRING_A240))entry=240;
+ if(events.count(INTERFACEKEY_STRING_A241))entry=241;
+ if(events.count(INTERFACEKEY_STRING_A242))entry=242;
+ if(events.count(INTERFACEKEY_STRING_A243))entry=243;
+ if(events.count(INTERFACEKEY_STRING_A244))entry=244;
+ if(events.count(INTERFACEKEY_STRING_A245))entry=245;
+ if(events.count(INTERFACEKEY_STRING_A246))entry=246;
+ if(events.count(INTERFACEKEY_STRING_A247))entry=247;
+ if(events.count(INTERFACEKEY_STRING_A248))entry=248;
+ if(events.count(INTERFACEKEY_STRING_A249))entry=249;
+ if(events.count(INTERFACEKEY_STRING_A250))entry=250;
+ if(events.count(INTERFACEKEY_STRING_A251))entry=251;
+ if(events.count(INTERFACEKEY_STRING_A252))entry=252;
+ if(events.count(INTERFACEKEY_STRING_A253))entry=253;
+ if(events.count(INTERFACEKEY_STRING_A254))entry=254;
+ if(events.count(INTERFACEKEY_STRING_A255))entry=255;
+ }
+
+ if(entry!=255)
+ {
+ if(entry=='\x0')
+ {
+ if(str.length()>0)str.resize(str.length()-1);
+ }
+ else
+ {
+ int cursor=str.length();
+ if(cursor>=maxlen)cursor=maxlen-1;
+ if(cursor<0)cursor=0;
+
+ if(str.length()<cursor+1)str.resize(cursor+1);
+
+ if(entry>='a'&&entry<='z'&&(flag & STRINGENTRY_CAPS))str[cursor]=entry+'A'-'a';
+ else str[cursor]=entry;
+ }
+
+
+ return 1;
+ }
+
+ return 0;
+}
+
+//To Do
+//get the gview.c references inside the DEBUG_MOVIE defines
+//make scrolling and stringentry use newer pressed functions for better speed
diff --git a/g_src/interface.h b/g_src/interface.h
new file mode 100755
index 0000000..6df8fdd
--- /dev/null
+++ b/g_src/interface.h
@@ -0,0 +1,149 @@
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+#include <string>
+using std::string;
+#include <set>
+#include "svector.h"
+#include "ViewBase.h"
+#include "keybindings.h"
+#include "enabler.h"
+#include "music_and_sound_g.h"
+
+struct cursesmovie_headerst
+{
+ int dimx,dimy;
+ int delayrate;
+};
+
+class viewscreen_movieplayerst : viewscreenst
+{
+ public:
+ static viewscreen_movieplayerst *create(char pushtype,viewscreenst *scr=NULL);
+ virtual void help();
+ virtual void feed(std::set<InterfaceKey> &events);
+ virtual void logic();
+ virtual void render();
+ virtual char movies_okay(){return 0;}
+ void clearfilelist();
+ void force_play(const string &file);
+
+ virtual char is_option_screen(){if(is_playing)return 2;else return 0;}
+
+ protected:
+ char saving;
+ char loading;
+ char editing;
+ char text_mode;
+ unsigned char editing_char;
+ int editing_copy_from;
+ short editing_screenf;
+ short editing_screenb;
+ short editing_screenbright;
+ int editing_selected_sound;
+ char editing_menu;
+ string savename;
+ string force_file;
+ char is_playing;
+ char is_forced_play;
+ char quit_if_no_play;
+ int maxmoviepos;
+ int end_frame_pos;
+
+ int32_t selfile;
+ svector<char *> filelist;
+
+ viewscreen_movieplayerst();
+ virtual ~viewscreen_movieplayerst(){clearfilelist();};
+};
+
+enum InterfacePushType
+{
+ INTERFACE_PUSH_AS_PARENT,
+ INTERFACE_PUSH_AS_CHILD,
+ INTERFACE_PUSH_AT_BACK,
+ INTERFACE_PUSH_AT_FRONT,
+ INTERFACE_PUSHNUM
+};
+
+#define INTERFACEFLAG_RETAIN_NONZERO_INPUT BIT1
+
+#define MOVIEBUFFSIZE 800000
+#define COMPMOVIEBUFFSIZE 1000000
+
+class interfacest
+{
+ int original_fps;
+ viewscreenst *grab_lastscreen();
+ friend class viewscreen_movieplayerst;
+
+ public:
+ viewscreenst view;
+ unsigned int flag;
+
+ int shutdown_interface_tickcount;
+ int shutdown_interface_for_ms;
+
+ char loop();
+ void remove_to_first();
+ void removescreen(viewscreenst *scr);
+ void addscreen(viewscreenst *scr,char pushtype,viewscreenst *relate);
+ char is_supermovie_on()
+ {
+ return supermovie_on;
+ }
+
+ void print_interface_token(InterfaceKey key,justification just=justify_left);
+
+ interfacest();
+ ~interfacest();
+
+ protected:
+ char supermovie_on;
+ int supermovie_pos;
+ int supermovie_delayrate;
+ int supermovie_delaystep;
+ stringvectst supermovie_sound;
+#ifndef NO_FMOD
+ int supermovie_sound_time[200][SOUND_CHANNELNUM];
+#endif
+ unsigned char supermoviebuffer[MOVIEBUFFSIZE];
+ unsigned char supermoviebuffer_comp[COMPMOVIEBUFFSIZE];
+ int currentblocksize;
+ int nextfilepos;
+ char first_movie_write;
+ string movie_file;
+
+ void insertscreen_as_parent(viewscreenst *scr,viewscreenst *child);
+ void insertscreen_as_child(viewscreenst *scr,viewscreenst *parent);
+ void insertscreen_at_back(viewscreenst *scr);
+ void insertscreen_at_front(viewscreenst *scr);
+ void handlemovie(char flushall);
+ void finish_movie();
+ void use_movie_input();
+
+ int write_movie_chunk();
+ void read_movie_chunk(int &maxmoviepos,char &is_playing);
+};
+
+#define SCROLLING_NOSELECT BIT1
+#define SCROLLING_NO_WRAP BIT2
+#define SCROLLING_REVERSE BIT3
+void finishscrolling(int32_t &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag,char littlekey);
+char standardscrolling(std::set<InterfaceKey> &events,short &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+char standardscrolling(std::set<InterfaceKey> &events,int32_t &selection,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+char secondaryscrolling(std::set<InterfaceKey> &events,short &scroll,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+char secondaryscrolling(std::set<InterfaceKey> &events,int32_t &scroll,int32_t min,int32_t max,int32_t jump,uint32_t flag=0);
+#define STRINGENTRY_LETTERS BIT1
+#define STRINGENTRY_SPACE BIT2
+#define STRINGENTRY_NUMBERS BIT3
+#define STRINGENTRY_CAPS BIT4
+#define STRINGENTRY_SYMBOLS BIT5
+char standardstringentry(char *str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events);
+char standardstringentry(string &str,int maxlen,unsigned int flag,std::set<InterfaceKey> &events);
+
+void drawborder(const char *str,char style=0,const char *colorstr=NULL);
+
+extern interfacest gview;
+
+#endif
diff --git a/g_src/keybindings.cpp b/g_src/keybindings.cpp
new file mode 100755
index 0000000..d22b035
--- /dev/null
+++ b/g_src/keybindings.cpp
@@ -0,0 +1,3115 @@
+#include "keybindings.h"
+
+#include <SDL/SDL.h>
+
+using namespace std;
+
+bimap<InterfaceKey,std::string> bindingNames;
+bimap<InterfaceKey,std::string> displayNames;
+bimap<SDLKey,std::string> sdlNames;
+
+void keybinding_init() {
+ bindingNames.insert(INTERFACEKEY_NONE, "NONE");
+ bindingNames.insert(INTERFACEKEY_SELECT, "SELECT");
+ bindingNames.insert(INTERFACEKEY_SEC_SELECT, "SEC_SELECT");
+ bindingNames.insert(INTERFACEKEY_DESELECT, "DESELECT");
+ bindingNames.insert(INTERFACEKEY_SELECT_ALL, "SELECT_ALL");
+ bindingNames.insert(INTERFACEKEY_DESELECT_ALL, "DESELECT_ALL");
+ bindingNames.insert(INTERFACEKEY_LEAVESCREEN, "LEAVESCREEN");
+ bindingNames.insert(INTERFACEKEY_LEAVESCREEN_ALL, "LEAVESCREEN_ALL");
+ bindingNames.insert(INTERFACEKEY_CLOSE_MEGA_ANNOUNCEMENT, "CLOSE_MEGA_ANNOUNCEMENT");
+ bindingNames.insert(INTERFACEKEY_TOGGLE_FULLSCREEN, "TOGGLE_FULLSCREEN");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_ADD, "WORLD_PARAM_ADD");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_COPY, "WORLD_PARAM_COPY");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DELETE, "WORLD_PARAM_DELETE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_TITLE, "WORLD_PARAM_TITLE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_RANDOM, "WORLD_PARAM_NAME_RANDOM");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_ENTER, "WORLD_PARAM_NAME_ENTER");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_RANDOM, "WORLD_PARAM_SEED_RANDOM");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_ENTER, "WORLD_PARAM_SEED_ENTER");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_LOAD, "WORLD_PARAM_LOAD");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SAVE, "WORLD_PARAM_SAVE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_UP, "WORLD_PARAM_DIM_X_UP");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_DOWN, "WORLD_PARAM_DIM_X_DOWN");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_UP, "WORLD_PARAM_DIM_Y_UP");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_DOWN, "WORLD_PARAM_DIM_Y_DOWN");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_SET, "WORLD_PARAM_SET");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_INCREASE, "WORLD_PARAM_INCREASE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_DECREASE, "WORLD_PARAM_DECREASE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_ENTER_VALUE, "WORLD_PARAM_ENTER_VALUE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_NULLIFY, "WORLD_PARAM_NULLIFY");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_PRESET, "WORLD_PARAM_PRESET");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_CONTINUE, "WORLD_PARAM_REJECT_CONTINUE");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ABORT, "WORLD_PARAM_REJECT_ABORT");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_THIS, "WORLD_PARAM_REJECT_ALLOW_THIS");
+ bindingNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_ALL, "WORLD_PARAM_REJECT_ALLOW_ALL");
+ bindingNames.insert(INTERFACEKEY_WORLD_GEN_CONTINUE, "WORLD_GEN_CONTINUE");
+ bindingNames.insert(INTERFACEKEY_WORLD_GEN_USE, "WORLD_GEN_USE");
+ bindingNames.insert(INTERFACEKEY_WORLD_GEN_ABORT, "WORLD_GEN_ABORT");
+ bindingNames.insert(INTERFACEKEY_SETUP_EMBARK, "SETUP_EMBARK");
+ bindingNames.insert(INTERFACEKEY_SETUP_NAME_FORT, "SETUP_NAME_FORT");
+ bindingNames.insert(INTERFACEKEY_SETUP_NAME_GROUP, "SETUP_NAME_GROUP");
+ bindingNames.insert(INTERFACEKEY_SETUP_RECLAIM, "SETUP_RECLAIM");
+ bindingNames.insert(INTERFACEKEY_SETUP_FIND, "SETUP_FIND");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES, "SETUP_NOTES");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_TAKE_NOTES, "SETUP_NOTES_TAKE_NOTES");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_DELETE_NOTE, "SETUP_NOTES_DELETE_NOTE");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_CHANGE_SYMBOL_SELECTION, "SETUP_NOTES_CHANGE_SYMBOL_SELECTION");
+ bindingNames.insert(INTERFACEKEY_SETUP_NOTES_ADOPT_SYMBOL, "SETUP_NOTES_ADOPT_SYMBOL");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_UP, "SETUP_LOCAL_Y_UP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_DOWN, "SETUP_LOCAL_Y_DOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_UP, "SETUP_LOCAL_X_UP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_DOWN, "SETUP_LOCAL_X_DOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MUP, "SETUP_LOCAL_Y_MUP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MDOWN, "SETUP_LOCAL_Y_MDOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MUP, "SETUP_LOCAL_X_MUP");
+ bindingNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MDOWN, "SETUP_LOCAL_X_MDOWN");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_1, "SETUP_BIOME_1");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_2, "SETUP_BIOME_2");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_3, "SETUP_BIOME_3");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_4, "SETUP_BIOME_4");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_5, "SETUP_BIOME_5");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_6, "SETUP_BIOME_6");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_7, "SETUP_BIOME_7");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_8, "SETUP_BIOME_8");
+ bindingNames.insert(INTERFACEKEY_SETUP_BIOME_9, "SETUP_BIOME_9");
+ bindingNames.insert(INTERFACEKEY_CHOOSE_NAME_RANDOM, "CHOOSE_NAME_RANDOM");
+ bindingNames.insert(INTERFACEKEY_CHOOSE_NAME_CLEAR, "CHOOSE_NAME_CLEAR");
+ bindingNames.insert(INTERFACEKEY_CHOOSE_NAME_TYPE, "CHOOSE_NAME_TYPE");
+ bindingNames.insert(INTERFACEKEY_ITEM_DESCRIPTION, "ITEM_DESCRIPTION");
+ bindingNames.insert(INTERFACEKEY_ITEM_FORBID, "ITEM_FORBID");
+ bindingNames.insert(INTERFACEKEY_ITEM_MELT, "ITEM_MELT");
+ bindingNames.insert(INTERFACEKEY_ITEM_DUMP, "ITEM_DUMP");
+ bindingNames.insert(INTERFACEKEY_ITEM_HIDE, "ITEM_HIDE");
+ bindingNames.insert(INTERFACEKEY_HELP, "HELP");
+ bindingNames.insert(INTERFACEKEY_MOVIES, "MOVIES");
+ bindingNames.insert(INTERFACEKEY_OPTIONS, "OPTIONS");
+ bindingNames.insert(INTERFACEKEY_OPTION_EXPORT, "OPTION_EXPORT");
+ bindingNames.insert(INTERFACEKEY_CHANGETAB, "CHANGETAB");
+ bindingNames.insert(INTERFACEKEY_SEC_CHANGETAB, "SEC_CHANGETAB");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_LEFT, "STANDARDSCROLL_LEFT");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_RIGHT, "STANDARDSCROLL_RIGHT");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_UP, "STANDARDSCROLL_UP");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_DOWN, "STANDARDSCROLL_DOWN");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEUP, "STANDARDSCROLL_PAGEUP");
+ bindingNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN, "STANDARDSCROLL_PAGEDOWN");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_UP, "SECONDSCROLL_UP");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_DOWN, "SECONDSCROLL_DOWN");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEUP, "SECONDSCROLL_PAGEUP");
+ bindingNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEDOWN, "SECONDSCROLL_PAGEDOWN");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP, "CURSOR_UP");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN, "CURSOR_DOWN");
+ bindingNames.insert(INTERFACEKEY_CURSOR_LEFT, "CURSOR_LEFT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_RIGHT, "CURSOR_RIGHT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPLEFT, "CURSOR_UPLEFT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPRIGHT, "CURSOR_UPRIGHT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT, "CURSOR_DOWNLEFT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT, "CURSOR_DOWNRIGHT");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP_FAST, "CURSOR_UP_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN_FAST, "CURSOR_DOWN_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_LEFT_FAST, "CURSOR_LEFT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_RIGHT_FAST, "CURSOR_RIGHT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPLEFT_FAST, "CURSOR_UPLEFT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UPRIGHT_FAST, "CURSOR_UPRIGHT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT_FAST, "CURSOR_DOWNLEFT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT_FAST, "CURSOR_DOWNRIGHT_FAST");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP_Z, "CURSOR_UP_Z");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN_Z, "CURSOR_DOWN_Z");
+ bindingNames.insert(INTERFACEKEY_CURSOR_UP_Z_AUX, "CURSOR_UP_Z_AUX");
+ bindingNames.insert(INTERFACEKEY_CURSOR_DOWN_Z_AUX, "CURSOR_DOWN_Z_AUX");
+ bindingNames.insert(INTERFACEKEY_A_RETURN_TO_ARENA, "A_RETURN_TO_ARENA");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_N, "A_MOVE_N");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_S, "A_MOVE_S");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_E, "A_MOVE_E");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_W, "A_MOVE_W");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NW, "A_MOVE_NW");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NE, "A_MOVE_NE");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SW, "A_MOVE_SW");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SE, "A_MOVE_SE");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SAME_SQUARE, "A_MOVE_SAME_SQUARE");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_N, "A_CARE_MOVE_N");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_S, "A_CARE_MOVE_S");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_E, "A_CARE_MOVE_E");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_W, "A_CARE_MOVE_W");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_NW, "A_CARE_MOVE_NW");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_NE, "A_CARE_MOVE_NE");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_SW, "A_CARE_MOVE_SW");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_SE, "A_CARE_MOVE_SE");
+ bindingNames.insert(INTERFACEKEY_A_CARE_MOVE_UPDOWN, "A_CARE_MOVE_UPDOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_N_UP, "A_MOVE_N_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_S_UP, "A_MOVE_S_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_E_UP, "A_MOVE_E_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_W_UP, "A_MOVE_W_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NW_UP, "A_MOVE_NW_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NE_UP, "A_MOVE_NE_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SW_UP, "A_MOVE_SW_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SE_UP, "A_MOVE_SE_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_UP, "A_MOVE_UP");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_N_DOWN, "A_MOVE_N_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_S_DOWN, "A_MOVE_S_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_E_DOWN, "A_MOVE_E_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_W_DOWN, "A_MOVE_W_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NW_DOWN, "A_MOVE_NW_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_NE_DOWN, "A_MOVE_NE_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SW_DOWN, "A_MOVE_SW_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_SE_DOWN, "A_MOVE_SE_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_DOWN, "A_MOVE_DOWN");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_UP_AUX, "A_MOVE_UP_AUX");
+ bindingNames.insert(INTERFACEKEY_A_MOVE_DOWN_AUX, "A_MOVE_DOWN_AUX");
+ bindingNames.insert(INTERFACEKEY_WORLDGEN_EXPORT_MAP, "WORLDGEN_EXPORT_MAP");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_EXPORT_MAP, "LEGENDS_EXPORT_MAP");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_EXPORT_XML, "LEGENDS_EXPORT_XML");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_EXPORT_DETAILED_MAP, "LEGENDS_EXPORT_DETAILED_MAP");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_TOGGLE_CIVSITE, "LEGENDS_TOGGLE_CIVSITE");
+ bindingNames.insert(INTERFACEKEY_LEGENDS_STRING_FILTER, "LEGENDS_STRING_FILTER");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT_ATTACK, "A_COMBAT_ATTACK");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT_DODGE, "A_COMBAT_DODGE");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT_CHARGEDEF, "A_COMBAT_CHARGEDEF");
+ bindingNames.insert(INTERFACEKEY_A_STATUS, "A_STATUS");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_WRESTLE, "A_STATUS_WRESTLE");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_CUSTOMIZE, "A_STATUS_CUSTOMIZE");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_KILLS, "A_STATUS_KILLS");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_HEALTH, "A_STATUS_HEALTH");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_ATT_SKILL, "A_STATUS_ATT_SKILL");
+ bindingNames.insert(INTERFACEKEY_A_STATUS_DESC, "A_STATUS_DESC");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_CUSTOMIZE, "UNITVIEW_CUSTOMIZE");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_HEALTH, "UNITVIEW_HEALTH");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS, "UNITVIEW_RELATIONSHIPS");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_ZOOM, "UNITVIEW_RELATIONSHIPS_ZOOM");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_VIEW, "UNITVIEW_RELATIONSHIPS_VIEW");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_KILLS, "UNITVIEW_KILLS");
+ bindingNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_NICKNAME, "CUSTOMIZE_UNIT_NICKNAME");
+ bindingNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_PROFNAME, "CUSTOMIZE_UNIT_PROFNAME");
+ bindingNames.insert(INTERFACEKEY_A_CLEAR_ANNOUNCEMENTS, "A_CLEAR_ANNOUNCEMENTS");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP, "A_SLEEP");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP_SLEEP, "A_SLEEP_SLEEP");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP_WAIT, "A_SLEEP_WAIT");
+ bindingNames.insert(INTERFACEKEY_A_SLEEP_DAWN, "A_SLEEP_DAWN");
+ bindingNames.insert(INTERFACEKEY_A_WAIT, "A_WAIT");
+ bindingNames.insert(INTERFACEKEY_A_SHORT_WAIT, "A_SHORT_WAIT");
+ bindingNames.insert(INTERFACEKEY_A_ATTACK, "A_ATTACK");
+ bindingNames.insert(INTERFACEKEY_A_ATTACK_CONFIRM, "A_ATTACK_CONFIRM");
+ bindingNames.insert(INTERFACEKEY_QUICK_ATTACK, "QUICK_ATTACK");
+ bindingNames.insert(INTERFACEKEY_HEAVY_ATTACK, "HEAVY_ATTACK");
+ bindingNames.insert(INTERFACEKEY_WILD_ATTACK, "WILD_ATTACK");
+ bindingNames.insert(INTERFACEKEY_PRECISE_ATTACK, "PRECISE_ATTACK");
+ bindingNames.insert(INTERFACEKEY_CHARGE_ATTACK, "CHARGE_ATTACK");
+ bindingNames.insert(INTERFACEKEY_MULTI_ATTACK, "MULTI_ATTACK");
+ bindingNames.insert(INTERFACEKEY_A_LOOK, "A_LOOK");
+ bindingNames.insert(INTERFACEKEY_A_SEARCH, "A_SEARCH");
+ bindingNames.insert(INTERFACEKEY_A_ODOR,"A_ODOR");
+ bindingNames.insert(INTERFACEKEY_A_DISPLAY_ODOR,"A_DISPLAY_ODOR");
+ bindingNames.insert(INTERFACEKEY_A_YIELD,"A_YIELD");
+ bindingNames.insert(INTERFACEKEY_A_DISPLAY_TRACKS,"A_DISPLAY_TRACKS");
+ bindingNames.insert(INTERFACEKEY_A_FRESHEST_TRACK,"A_FRESHEST_TRACK");
+ bindingNames.insert(INTERFACEKEY_A_INV_DRAW_WEAPON,"A_INV_DRAW_WEAPON");
+ bindingNames.insert(INTERFACEKEY_A_JUMP,"A_JUMP");
+ bindingNames.insert(INTERFACEKEY_A_HOLD,"A_HOLD");
+ bindingNames.insert(INTERFACEKEY_A_TALK, "A_TALK");
+ bindingNames.insert(INTERFACEKEY_A_INTERACT, "A_INTERACT");
+ bindingNames.insert(INTERFACEKEY_A_ACTION, "A_ACTION");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_CREATE, "A_ACTION_CREATE");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_BUTCHER, "A_ACTION_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_ABILITY, "A_ACTION_ABILITY");
+ bindingNames.insert(INTERFACEKEY_A_ACTION_POWER, "A_ACTION_POWER");
+ bindingNames.insert(INTERFACEKEY_A_INV_LOOK, "A_INV_LOOK");
+ bindingNames.insert(INTERFACEKEY_A_INV_REMOVE, "A_INV_REMOVE");
+ bindingNames.insert(INTERFACEKEY_A_INV_WEAR, "A_INV_WEAR");
+ bindingNames.insert(INTERFACEKEY_A_INV_EATDRINK, "A_INV_EATDRINK");
+ bindingNames.insert(INTERFACEKEY_A_INV_PUTIN, "A_INV_PUTIN");
+ bindingNames.insert(INTERFACEKEY_A_INV_DROP, "A_INV_DROP");
+ bindingNames.insert(INTERFACEKEY_A_GROUND, "A_GROUND");
+ bindingNames.insert(INTERFACEKEY_A_THROW, "A_THROW");
+ bindingNames.insert(INTERFACEKEY_A_SHOOT, "A_SHOOT");
+ bindingNames.insert(INTERFACEKEY_A_ANNOUNCEMENTS, "A_ANNOUNCEMENTS");
+ bindingNames.insert(INTERFACEKEY_A_COMBAT, "A_COMBAT");
+ bindingNames.insert(INTERFACEKEY_A_MOVEMENT, "A_MOVEMENT");
+ bindingNames.insert(INTERFACEKEY_A_MOVEMENT_SWIM, "A_MOVEMENT_SWIM");
+ bindingNames.insert(INTERFACEKEY_A_SNEAK, "A_SNEAK");
+ bindingNames.insert(INTERFACEKEY_A_SPEED_SNEAK, "A_SPEED_SNEAK");
+ bindingNames.insert(INTERFACEKEY_A_CENTER, "A_CENTER");
+ bindingNames.insert(INTERFACEKEY_A_COMPANIONS, "A_COMPANIONS");
+ bindingNames.insert(INTERFACEKEY_A_BUILDING, "A_BUILDING");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL, "A_TRAVEL");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_SLEEP, "A_TRAVEL_SLEEP");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_MAP, "A_TRAVEL_MAP");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_HIDE_INSTRUCTIONS, "A_TRAVEL_HIDE_INSTRUCTIONS");
+ bindingNames.insert(INTERFACEKEY_A_DATE, "A_DATE");
+ bindingNames.insert(INTERFACEKEY_A_WEATHER, "A_WEATHER");
+ bindingNames.insert(INTERFACEKEY_A_TEMPERATURE, "A_TEMPERATURE");
+ bindingNames.insert(INTERFACEKEY_A_STANCE, "A_STANCE");
+ bindingNames.insert(INTERFACEKEY_OPTION1, "OPTION1");
+ bindingNames.insert(INTERFACEKEY_OPTION2, "OPTION2");
+ bindingNames.insert(INTERFACEKEY_OPTION3, "OPTION3");
+ bindingNames.insert(INTERFACEKEY_OPTION4, "OPTION4");
+ bindingNames.insert(INTERFACEKEY_OPTION5, "OPTION5");
+ bindingNames.insert(INTERFACEKEY_OPTION6, "OPTION6");
+ bindingNames.insert(INTERFACEKEY_OPTION7, "OPTION7");
+ bindingNames.insert(INTERFACEKEY_OPTION8, "OPTION8");
+ bindingNames.insert(INTERFACEKEY_OPTION9, "OPTION9");
+ bindingNames.insert(INTERFACEKEY_OPTION10, "OPTION10");
+ bindingNames.insert(INTERFACEKEY_OPTION11, "OPTION11");
+ bindingNames.insert(INTERFACEKEY_OPTION12, "OPTION12");
+ bindingNames.insert(INTERFACEKEY_OPTION13, "OPTION13");
+ bindingNames.insert(INTERFACEKEY_OPTION14, "OPTION14");
+ bindingNames.insert(INTERFACEKEY_OPTION15, "OPTION15");
+ bindingNames.insert(INTERFACEKEY_OPTION16, "OPTION16");
+ bindingNames.insert(INTERFACEKEY_OPTION17, "OPTION17");
+ bindingNames.insert(INTERFACEKEY_OPTION18, "OPTION18");
+ bindingNames.insert(INTERFACEKEY_OPTION19, "OPTION19");
+ bindingNames.insert(INTERFACEKEY_OPTION20, "OPTION20");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION1, "SEC_OPTION1");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION2, "SEC_OPTION2");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION3, "SEC_OPTION3");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION4, "SEC_OPTION4");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION5, "SEC_OPTION5");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION6, "SEC_OPTION6");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION7, "SEC_OPTION7");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION8, "SEC_OPTION8");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION9, "SEC_OPTION9");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION10, "SEC_OPTION10");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION11, "SEC_OPTION11");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION12, "SEC_OPTION12");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION13, "SEC_OPTION13");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION14, "SEC_OPTION14");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION15, "SEC_OPTION15");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION16, "SEC_OPTION16");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION17, "SEC_OPTION17");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION18, "SEC_OPTION18");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION19, "SEC_OPTION19");
+ bindingNames.insert(INTERFACEKEY_SEC_OPTION20, "SEC_OPTION20");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MAKE_ASH, "HOTKEY_MAKE_ASH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MAKE_CHARCOAL, "HOTKEY_MAKE_CHARCOAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MELT_OBJECT, "HOTKEY_MELT_OBJECT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_GREEN, "HOTKEY_GLASS_GREEN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CLEAR, "HOTKEY_GLASS_CLEAR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CRYSTAL, "HOTKEY_GLASS_CRYSTAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_COLLECT_SAND, "HOTKEY_COLLECT_SAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_COLLECT_CLAY, "HOTKEY_COLLECT_CLAY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_ROUGH, "HOTKEY_GLASS_ROUGH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_ARMORSTAND, "HOTKEY_GLASS_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_BOX, "HOTKEY_GLASS_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CABINET, "HOTKEY_GLASS_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_COFFIN, "HOTKEY_GLASS_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLOODGATE, "HOTKEY_GLASS_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_HATCH_COVER, "HOTKEY_GLASS_HATCH_COVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_GRATE, "HOTKEY_GLASS_GRATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_GOBLET, "HOTKEY_GLASS_GOBLET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_TOY, "HOTKEY_GLASS_TOY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_INSTRUMENT, "HOTKEY_GLASS_INSTRUMENT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_DOOR, "HOTKEY_GLASS_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_STATUE, "HOTKEY_GLASS_STATUE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_TABLE, "HOTKEY_GLASS_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CAGE, "HOTKEY_GLASS_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_CHAIR, "HOTKEY_GLASS_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_BLOCKS, "HOTKEY_GLASS_BLOCKS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLASK, "HOTKEY_GLASS_FLASK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_WEAPONRACK, "HOTKEY_GLASS_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_GLASS_WINDOW, "HOTKEY_GLASS_WINDOW");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ASHERY_LYE, "HOTKEY_ASHERY_LYE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH, "HOTKEY_ASHERY_POTASH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH_DIRECT, "HOTKEY_ASHERY_POTASH_DIRECT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BARREL, "HOTKEY_CARPENTER_BARREL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BLOCKS, "HOTKEY_CARPENTER_BLOCKS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BUCKET, "HOTKEY_CARPENTER_BUCKET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TRAP_ANIMAL, "HOTKEY_CARPENTER_TRAP_ANIMAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CAGE, "HOTKEY_CARPENTER_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_ARMORSTAND, "HOTKEY_CARPENTER_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BED, "HOTKEY_CARPENTER_BED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CHAIR, "HOTKEY_CARPENTER_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_COFFIN, "HOTKEY_CARPENTER_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_DOOR, "HOTKEY_CARPENTER_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_FLOODGATE, "HOTKEY_CARPENTER_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_HATCH_COVER, "HOTKEY_CARPENTER_HATCH_COVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_GRATE, "HOTKEY_CARPENTER_GRATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CABINET, "HOTKEY_CARPENTER_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BIN, "HOTKEY_CARPENTER_BIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BOX, "HOTKEY_CARPENTER_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_WEAPONRACK, "HOTKEY_CARPENTER_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TABLE, "HOTKEY_CARPENTER_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SIEGE_BALLISTA, "HOTKEY_SIEGE_BALLISTA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SIEGE_CATAPULT, "HOTKEY_SIEGE_CATAPULT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BOX, "HOTKEY_LEATHER_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_FLASK, "HOTKEY_LEATHER_FLASK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_SHIRT, "HOTKEY_LEATHER_SHIRT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_CLOAK, "HOTKEY_LEATHER_CLOAK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BACKPACK, "HOTKEY_LEATHER_BACKPACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_QUIVER, "HOTKEY_LEATHER_QUIVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LEATHER_IMAGE, "HOTKEY_LEATHER_IMAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_PLANT, "HOTKEY_CLOTHES_MAT_PLANT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_SILK, "HOTKEY_CLOTHES_MAT_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_YARN, "HOTKEY_CLOTHES_MAT_YARN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_SHIRT, "HOTKEY_CLOTHES_SHIRT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CLOAK, "HOTKEY_CLOTHES_CLOAK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_BOX, "HOTKEY_CLOTHES_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CHAIN, "HOTKEY_CLOTHES_CHAIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_IMAGE, "HOTKEY_CLOTHES_IMAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_STONE, "HOTKEY_CRAFTS_MAT_STONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_WOOD, "HOTKEY_CRAFTS_MAT_WOOD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_BONE, "HOTKEY_CRAFTS_DEC_BONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_SHELL, "HOTKEY_CRAFTS_DEC_SHELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_TOOTH, "HOTKEY_CRAFTS_DEC_TOOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_HORN, "HOTKEY_CRAFTS_DEC_HORN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_PEARL, "HOTKEY_CRAFTS_DEC_PEARL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOTEM, "HOTKEY_CRAFTS_TOTEM");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_CLOTH, "HOTKEY_CRAFTS_CLOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SILK, "HOTKEY_CRAFTS_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_YARN, "HOTKEY_CRAFTS_YARN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_WOOD, "HOTKEY_CRAFTS_SEL_WOOD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_BONE, "HOTKEY_CRAFTS_SEL_BONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_SHELL, "HOTKEY_CRAFTS_SEL_SHELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SHELL, "HOTKEY_CRAFTS_SHELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOOTH, "HOTKEY_CRAFTS_TOOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_HORN, "HOTKEY_CRAFTS_HORN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_PEARL, "HOTKEY_CRAFTS_PEARL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_BONE, "HOTKEY_CRAFTS_BONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_LEATHER, "HOTKEY_CRAFTS_LEATHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SLAB, "HOTKEY_CRAFTS_SLAB");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_CRAFTS, "HOTKEY_CRAFTS_MAT_CRAFTS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_GOBLET, "HOTKEY_CRAFTS_MAT_GOBLET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_INSTRUMENT, "HOTKEY_CRAFTS_MAT_INSTRUMENT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_TOY, "HOTKEY_CRAFTS_MAT_TOY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_WEAPON, "HOTKEY_SMITH_WEAPON");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_ARMOR, "HOTKEY_SMITH_ARMOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_FURNITURE, "HOTKEY_SMITH_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_SIEGE, "HOTKEY_SMITH_SIEGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_TRAP, "HOTKEY_SMITH_TRAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_OTHER, "HOTKEY_SMITH_OTHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_SMITH_METAL, "HOTKEY_SMITH_METAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARMORSTAND, "HOTKEY_BUILDING_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BED, "HOTKEY_BUILDING_BED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRACTION_BENCH, "HOTKEY_BUILDING_TRACTION_BENCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SLAB, "HOTKEY_BUILDING_SLAB");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_NEST_BOX, "HOTKEY_BUILDING_NEST_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HIVE, "HOTKEY_BUILDING_HIVE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIR, "HOTKEY_BUILDING_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_COFFIN, "HOTKEY_BUILDING_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_DOOR, "HOTKEY_BUILDING_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FLOODGATE, "HOTKEY_BUILDING_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HATCH, "HOTKEY_BUILDING_HATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_WALL, "HOTKEY_BUILDING_GRATE_WALL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_FLOOR, "HOTKEY_BUILDING_GRATE_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_VERTICAL, "HOTKEY_BUILDING_BARS_VERTICAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_FLOOR, "HOTKEY_BUILDING_BARS_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CABINET, "HOTKEY_BUILDING_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BOX, "HOTKEY_BUILDING_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_KENNEL, "HOTKEY_BUILDING_KENNEL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FARMPLOT, "HOTKEY_BUILDING_FARMPLOT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WEAPONRACK, "HOTKEY_BUILDING_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_STATUE, "HOTKEY_BUILDING_STATUE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TABLE, "HOTKEY_BUILDING_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_DIRT, "HOTKEY_BUILDING_ROAD_DIRT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_PAVED, "HOTKEY_BUILDING_ROAD_PAVED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BRIDGE, "HOTKEY_BUILDING_BRIDGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WELL, "HOTKEY_BUILDING_WELL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE, "HOTKEY_BUILDING_SIEGEENGINE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP, "HOTKEY_BUILDING_WORKSHOP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE, "HOTKEY_BUILDING_FURNACE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GLASS, "HOTKEY_BUILDING_WINDOW_GLASS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GEM, "HOTKEY_BUILDING_WINDOW_GEM");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SHOP, "HOTKEY_BUILDING_SHOP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ANIMALTRAP, "HOTKEY_BUILDING_ANIMALTRAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIN, "HOTKEY_BUILDING_CHAIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CAGE, "HOTKEY_BUILDING_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRADEDEPOT, "HOTKEY_BUILDING_TRADEDEPOT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP, "HOTKEY_BUILDING_TRAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE, "HOTKEY_BUILDING_MACHINE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SUPPORT, "HOTKEY_BUILDING_SUPPORT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARCHERYTARGET, "HOTKEY_BUILDING_ARCHERYTARGET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_SCREW_PUMP, "HOTKEY_BUILDING_MACHINE_SCREW_PUMP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WATER_WHEEL, "HOTKEY_BUILDING_MACHINE_WATER_WHEEL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WINDMILL, "HOTKEY_BUILDING_MACHINE_WINDMILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY, "HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL, "HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL, "HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_ROLLERS, "HOTKEY_BUILDING_MACHINE_ROLLERS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_BALLISTA, "HOTKEY_BUILDING_SIEGEENGINE_BALLISTA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_CATAPULT, "HOTKEY_BUILDING_SIEGEENGINE_CATAPULT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_STONE, "HOTKEY_BUILDING_TRAP_STONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_WEAPON, "HOTKEY_BUILDING_TRAP_WEAPON");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_LEVER, "HOTKEY_BUILDING_TRAP_LEVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_TRIGGER, "HOTKEY_BUILDING_TRAP_TRIGGER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_CAGE, "HOTKEY_BUILDING_TRAP_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_SPIKE, "HOTKEY_BUILDING_TRAP_SPIKE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION, "HOTKEY_BUILDING_CONSTRUCTION");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION, "HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_WALL, "HOTKEY_BUILDING_CONSTRUCTION_WALL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FLOOR, "HOTKEY_BUILDING_CONSTRUCTION_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_RAMP, "HOTKEY_BUILDING_CONSTRUCTION_RAMP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP, "HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN, "HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN, "HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK, "HOTKEY_BUILDING_CONSTRUCTION_TRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP, "HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LEATHER, "HOTKEY_BUILDING_WORKSHOP_LEATHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_QUERN, "HOTKEY_BUILDING_WORKSHOP_QUERN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MILLSTONE, "HOTKEY_BUILDING_WORKSHOP_MILLSTONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LOOM, "HOTKEY_BUILDING_WORKSHOP_LOOM");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CLOTHES, "HOTKEY_BUILDING_WORKSHOP_CLOTHES");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BOWYER, "HOTKEY_BUILDING_WORKSHOP_BOWYER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CARPENTER, "HOTKEY_BUILDING_WORKSHOP_CARPENTER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_METALSMITH, "HOTKEY_BUILDING_WORKSHOP_METALSMITH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LAVAMILL, "HOTKEY_BUILDING_WORKSHOP_LAVAMILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_JEWELER, "HOTKEY_BUILDING_WORKSHOP_JEWELER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MASON, "HOTKEY_BUILDING_WORKSHOP_MASON");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BUTCHER, "HOTKEY_BUILDING_WORKSHOP_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_TANNER, "HOTKEY_BUILDING_WORKSHOP_TANNER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_DYER, "HOTKEY_BUILDING_WORKSHOP_DYER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN, "HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_SIEGE, "HOTKEY_BUILDING_WORKSHOP_SIEGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MECHANIC, "HOTKEY_BUILDING_WORKSHOP_MECHANIC");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_STILL, "HOTKEY_BUILDING_WORKSHOP_STILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FARMER, "HOTKEY_BUILDING_WORKSHOP_FARMER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_KITCHEN, "HOTKEY_BUILDING_WORKSHOP_KITCHEN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FISHERY, "HOTKEY_BUILDING_WORKSHOP_FISHERY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_ASHERY, "HOTKEY_BUILDING_WORKSHOP_ASHERY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_WOOD, "HOTKEY_BUILDING_FURNACE_WOOD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER, "HOTKEY_BUILDING_FURNACE_SMELTER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS, "HOTKEY_BUILDING_FURNACE_GLASS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN, "HOTKEY_BUILDING_FURNACE_KILN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER_LAVA, "HOTKEY_BUILDING_FURNACE_SMELTER_LAVA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS_LAVA, "HOTKEY_BUILDING_FURNACE_GLASS_LAVA");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN_LAVA, "HOTKEY_BUILDING_FURNACE_KILN_LAVA");
+ bindingNames.insert(INTERFACEKEY_HIVE_INSTALL_COLONY, "HIVE_INSTALL_COLONY");
+ bindingNames.insert(INTERFACEKEY_HIVE_GATHER_PRODUCTS, "HIVE_GATHER_PRODUCTS");
+ bindingNames.insert(INTERFACEKEY_D_ONESTEP, "D_ONESTEP");
+ bindingNames.insert(INTERFACEKEY_D_PAUSE, "D_PAUSE");
+ bindingNames.insert(INTERFACEKEY_D_DEPOT, "D_DEPOT");
+ bindingNames.insert(INTERFACEKEY_D_HOT_KEYS, "D_HOT_KEYS");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY1, "D_HOTKEY1");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY2, "D_HOTKEY2");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY3, "D_HOTKEY3");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY4, "D_HOTKEY4");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY5, "D_HOTKEY5");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY6, "D_HOTKEY6");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY7, "D_HOTKEY7");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY8, "D_HOTKEY8");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY9, "D_HOTKEY9");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY10, "D_HOTKEY10");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY11, "D_HOTKEY11");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY12, "D_HOTKEY12");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY13, "D_HOTKEY13");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY14, "D_HOTKEY14");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY15, "D_HOTKEY15");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY16, "D_HOTKEY16");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY_CHANGE_NAME, "D_HOTKEY_CHANGE_NAME");
+ bindingNames.insert(INTERFACEKEY_D_HOTKEY_ZOOM, "D_HOTKEY_ZOOM");
+ bindingNames.insert(INTERFACEKEY_D_ANNOUNCE, "D_ANNOUNCE");
+ bindingNames.insert(INTERFACEKEY_D_REPORTS, "D_REPORTS");
+ bindingNames.insert(INTERFACEKEY_D_BUILDING, "D_BUILDING");
+ bindingNames.insert(INTERFACEKEY_D_CIVLIST, "D_CIVLIST");
+ bindingNames.insert(INTERFACEKEY_D_DESIGNATE, "D_DESIGNATE");
+ bindingNames.insert(INTERFACEKEY_D_ARTLIST, "D_ARTLIST");
+ bindingNames.insert(INTERFACEKEY_D_NOBLES, "D_NOBLES");
+ bindingNames.insert(INTERFACEKEY_D_ORDERS, "D_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY, "D_MILITARY");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SQUAD, "D_MILITARY_CREATE_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_DISBAND_SQUAD, "D_MILITARY_DISBAND_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SUB_SQUAD, "D_MILITARY_CREATE_SUB_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_CANCEL_ORDERS, "D_MILITARY_CANCEL_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_POSITIONS, "D_MILITARY_POSITIONS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS, "D_MILITARY_ALERTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_ADD, "D_MILITARY_ALERTS_ADD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_DELETE, "D_MILITARY_ALERTS_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET, "D_MILITARY_ALERTS_SET");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_NAME, "D_MILITARY_ALERTS_NAME");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET_RETAIN, "D_MILITARY_ALERTS_SET_RETAIN");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP, "D_MILITARY_EQUIP");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_CUSTOMIZE, "D_MILITARY_EQUIP_CUSTOMIZE");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_UNIFORM, "D_MILITARY_EQUIP_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_PRIORITY, "D_MILITARY_EQUIP_PRIORITY");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_UNIFORMS, "D_MILITARY_UNIFORMS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES, "D_MILITARY_SUPPLIES");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_DOWN, "D_MILITARY_SUPPLIES_WATER_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_UP, "D_MILITARY_SUPPLIES_WATER_UP");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_DOWN, "D_MILITARY_SUPPLIES_FOOD_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_UP, "D_MILITARY_SUPPLIES_FOOD_UP");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION, "D_MILITARY_AMMUNITION");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_ADD_ITEM, "D_MILITARY_AMMUNITION_ADD_ITEM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_REMOVE_ITEM, "D_MILITARY_AMMUNITION_REMOVE_ITEM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT, "D_MILITARY_AMMUNITION_LOWER_AMOUNT");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT, "D_MILITARY_AMMUNITION_RAISE_AMOUNT");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS, "D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS, "D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_MATERIAL, "D_MILITARY_AMMUNITION_MATERIAL");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_COMBAT, "D_MILITARY_AMMUNITION_COMBAT");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_TRAINING, "D_MILITARY_AMMUNITION_TRAINING");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_TRAINING, "D_MILITARY_TRAINING");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_SCHEDULE, "D_MILITARY_SCHEDULE");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_UNIFORM, "D_MILITARY_ADD_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_DELETE_UNIFORM, "D_MILITARY_DELETE_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_NAME_UNIFORM, "D_MILITARY_NAME_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_NAME_SQUAD, "D_MILITARY_NAME_SQUAD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_ARMOR, "D_MILITARY_ADD_ARMOR");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_PANTS, "D_MILITARY_ADD_PANTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_HELM, "D_MILITARY_ADD_HELM");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_GLOVES, "D_MILITARY_ADD_GLOVES");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_BOOTS, "D_MILITARY_ADD_BOOTS");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_SHIELD, "D_MILITARY_ADD_SHIELD");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_WEAPON, "D_MILITARY_ADD_WEAPON");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_MATERIAL, "D_MILITARY_ADD_MATERIAL");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_ADD_COLOR, "D_MILITARY_ADD_COLOR");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_REPLACE_CLOTHING, "D_MILITARY_REPLACE_CLOTHING");
+ bindingNames.insert(INTERFACEKEY_D_MILITARY_EXACT_MATCH, "D_MILITARY_EXACT_MATCH");
+ bindingNames.insert(INTERFACEKEY_D_ROOMS, "D_ROOMS");
+ bindingNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_T, "BUILDINGLIST_ZOOM_T");
+ bindingNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_Q, "BUILDINGLIST_ZOOM_Q");
+ bindingNames.insert(INTERFACEKEY_RECENTER_ON_LEVER, "RECENTER_ON_LEVER");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS, "D_SQUADS");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_MOVE, "D_SQUADS_MOVE");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_KILL, "D_SQUADS_KILL");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_KILL_LIST, "D_SQUADS_KILL_LIST");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_KILL_RECT, "D_SQUADS_KILL_RECT");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_SCHEDULE, "D_SQUADS_SCHEDULE");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_CANCEL_ORDER, "D_SQUADS_CANCEL_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_ALERT, "D_SQUADS_ALERT");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_SELECT_INDIVIDUALS, "D_SQUADS_SELECT_INDIVIDUALS");
+ bindingNames.insert(INTERFACEKEY_D_SQUADS_CENTER, "D_SQUADS_CENTER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_SLEEP, "D_SQUAD_SCH_SLEEP");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_CIVILIAN_UNIFORM, "D_SQUAD_SCH_CIVILIAN_UNIFORM");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_GIVE_ORDER, "D_SQUAD_SCH_GIVE_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_EDIT_ORDER, "D_SQUAD_SCH_EDIT_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_CANCEL_ORDER, "D_SQUAD_SCH_CANCEL_ORDER");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_COPY_ORDERS, "D_SQUAD_SCH_COPY_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_PASTE_ORDERS, "D_SQUAD_SCH_PASTE_ORDERS");
+ bindingNames.insert(INTERFACEKEY_D_SQUAD_SCH_MS_NAME, "D_SQUAD_SCH_MS_NAME");
+ bindingNames.insert(INTERFACEKEY_D_STOCKPILES, "D_STOCKPILES");
+ bindingNames.insert(INTERFACEKEY_D_CIVZONE, "D_CIVZONE");
+ bindingNames.insert(INTERFACEKEY_D_VIEWUNIT, "D_VIEWUNIT");
+ bindingNames.insert(INTERFACEKEY_D_JOBLIST, "D_JOBLIST");
+ bindingNames.insert(INTERFACEKEY_D_UNITLIST, "D_UNITLIST");
+ bindingNames.insert(INTERFACEKEY_D_LOOK, "D_LOOK");
+ bindingNames.insert(INTERFACEKEY_D_HAULING, "D_HAULING");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_NEW_ROUTE, "D_HAULING_NEW_ROUTE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_NEW_STOP, "D_HAULING_NEW_STOP");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_REMOVE, "D_HAULING_REMOVE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_PROMOTE, "D_HAULING_PROMOTE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_VEHICLE, "D_HAULING_VEHICLE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_NICKNAME, "D_HAULING_NICKNAME");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_DEPART, "D_HAULING_STOP_NEW_DEPART");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_LINK, "D_HAULING_STOP_NEW_LINK");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_REMOVE, "D_HAULING_STOP_REMOVE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_SELECT_PILE, "D_HAULING_STOP_SL_SELECT_PILE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_TAKE_GIVE, "D_HAULING_STOP_SL_TAKE_GIVE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DIR, "D_HAULING_STOP_LC_DIR");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MODE, "D_HAULING_STOP_LC_MODE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_UP, "D_HAULING_STOP_LC_TIMER_UP");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_DOWN, "D_HAULING_STOP_LC_TIMER_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_UP, "D_HAULING_STOP_LC_FULLNESS_UP");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_DOWN, "D_HAULING_STOP_LC_FULLNESS_DOWN");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MORE_LESS, "D_HAULING_STOP_LC_MORE_LESS");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DESIRED_TOTAL, "D_HAULING_STOP_LC_DESIRED_TOTAL");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_CHANGE, "D_HAULING_STOP_LC_CHANGE");
+ bindingNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_ADVANCED, "D_HAULING_STOP_LC_ADVANCED");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS, "D_BURROWS");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_ADD, "D_BURROWS_ADD");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_DELETE, "D_BURROWS_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_DEFINE, "D_BURROWS_DEFINE");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_ADD_UNIT, "D_BURROWS_ADD_UNIT");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_WORKSHOP_LIMIT, "D_BURROWS_WORKSHOP_LIMIT");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_CENTER, "D_BURROWS_CENTER");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_NAME, "D_BURROWS_NAME");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_CHANGE_SELECTION, "D_BURROWS_CHANGE_SELECTION");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_BRUSH, "D_BURROWS_BRUSH");
+ bindingNames.insert(INTERFACEKEY_D_BURROWS_REMOVE, "D_BURROWS_REMOVE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE, "D_NOTE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_PLACE, "D_NOTE_PLACE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_DELETE, "D_NOTE_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_NAME, "D_NOTE_NAME");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ENTER, "D_NOTE_ENTER");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ADOPT_SYMBOL, "D_NOTE_ADOPT_SYMBOL");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_CHANGE_SELECTION, "D_NOTE_CHANGE_SELECTION");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_POINTS, "D_NOTE_POINTS");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE, "D_NOTE_ROUTE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_ADD, "D_NOTE_ROUTE_ADD");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_EDIT, "D_NOTE_ROUTE_EDIT");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_DELETE, "D_NOTE_ROUTE_DELETE");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_CENTER, "D_NOTE_ROUTE_CENTER");
+ bindingNames.insert(INTERFACEKEY_D_NOTE_ROUTE_NAME, "D_NOTE_ROUTE_NAME");
+ bindingNames.insert(INTERFACEKEY_D_BUILDJOB, "D_BUILDJOB");
+ bindingNames.insert(INTERFACEKEY_D_STATUS, "D_STATUS");
+ bindingNames.insert(INTERFACEKEY_D_STATUS_OVERALL_HEALTH_RECENTER, "D_STATUS_OVERALL_HEALTH_RECENTER");
+ bindingNames.insert(INTERFACEKEY_D_BUILDITEM, "D_BUILDITEM");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_FORBID, "D_BITEM_FORBID");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_DUMP, "D_BITEM_DUMP");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_HIDE, "D_BITEM_HIDE");
+ bindingNames.insert(INTERFACEKEY_D_BITEM_MELT, "D_BITEM_MELT");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_FORBID, "D_LOOK_FORBID");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_DUMP, "D_LOOK_DUMP");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_MELT, "D_LOOK_MELT");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_HIDE, "D_LOOK_HIDE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_FOLLOW, "D_LOOK_FOLLOW");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_CREATURE, "D_LOOK_ARENA_CREATURE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_ADV_MODE, "D_LOOK_ARENA_ADV_MODE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_WATER, "D_LOOK_ARENA_WATER");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_MAGMA, "D_LOOK_ARENA_MAGMA");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_DOWN, "ARENA_CREATURE_SIDE_DOWN");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_UP, "ARENA_CREATURE_SIDE_UP");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_NEW_ITEM, "ARENA_CREATURE_NEW_ITEM");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_BLANK_LIST, "ARENA_CREATURE_BLANK_LIST");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_REMOVE_ITEM, "ARENA_CREATURE_REMOVE_ITEM");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_UNDEAD, "ARENA_CREATURE_UNDEAD");
+ bindingNames.insert(INTERFACEKEY_ARENA_CREATURE_STRING, "ARENA_CREATURE_STRING");
+ bindingNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_1, "ARENA_CONFLICT_STATE_1");
+ bindingNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_2, "ARENA_CONFLICT_STATE_2");
+ bindingNames.insert(INTERFACEKEY_ARENA_MORALE, "ARENA_MORALE");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER, "ARENA_WEATHER");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER_SNOW, "ARENA_WEATHER_SNOW");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER_MUD, "ARENA_WEATHER_MUD");
+ bindingNames.insert(INTERFACEKEY_ARENA_WEATHER_CLEAR_SPATTER, "ARENA_WEATHER_CLEAR_SPATTER");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_TREE, "D_LOOK_ARENA_TREE");
+ bindingNames.insert(INTERFACEKEY_ARENA_TREE_FILTER, "ARENA_TREE_FILTER");
+ bindingNames.insert(INTERFACEKEY_ARENA_TREE_AGE, "ARENA_TREE_AGE");
+ bindingNames.insert(INTERFACEKEY_D_LOOK_ARENA_MOUNT, "D_LOOK_ARENA_MOUNT");
+ bindingNames.insert(INTERFACEKEY_A_ENTER_NAME, "A_ENTER_NAME");
+ bindingNames.insert(INTERFACEKEY_A_CUST_NAME, "A_CUST_NAME");
+ bindingNames.insert(INTERFACEKEY_A_RANDOM_NAME, "A_RANDOM_NAME");
+ bindingNames.insert(INTERFACEKEY_A_CHANGE_GENDER, "A_CHANGE_GENDER");
+ bindingNames.insert(INTERFACEKEY_A_END_TRAVEL, "A_END_TRAVEL");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_CLOUDS, "A_TRAVEL_CLOUDS");
+ bindingNames.insert(INTERFACEKEY_A_LOG, "A_LOG");
+ bindingNames.insert(INTERFACEKEY_A_TRAVEL_LOG, "A_TRAVEL_LOG");
+ bindingNames.insert(INTERFACEKEY_A_LOG_TASKS, "A_LOG_TASKS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_ENTITIES, "A_LOG_ENTITIES");
+ bindingNames.insert(INTERFACEKEY_A_LOG_SITES, "A_LOG_SITES");
+ bindingNames.insert(INTERFACEKEY_A_LOG_SUBREGIONS, "A_LOG_SUBREGIONS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_FEATURE_LAYERS, "A_LOG_FEATURE_LAYERS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_PEOPLE, "A_LOG_PEOPLE");
+ bindingNames.insert(INTERFACEKEY_A_LOG_AGREEMENTS, "A_LOG_AGREEMENTS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_EVENTS, "A_LOG_EVENTS");
+ bindingNames.insert(INTERFACEKEY_A_LOG_BESTIARY, "A_LOG_BESTIARY");
+ bindingNames.insert(INTERFACEKEY_A_LOG_FILTER, "A_LOG_FILTER");
+ bindingNames.insert(INTERFACEKEY_A_LOG_ZOOM_CURRENT_LOCATION, "A_LOG_ZOOM_CURRENT_LOCATION");
+ bindingNames.insert(INTERFACEKEY_A_LOG_ZOOM_SELECTED, "A_LOG_ZOOM_SELECTED");
+ bindingNames.insert(INTERFACEKEY_A_LOG_LINE, "A_LOG_LINE");
+ bindingNames.insert(INTERFACEKEY_A_LOG_MAP, "A_LOG_MAP");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTOFORBID, "ORDERS_AUTOFORBID");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_PROJECTILE, "ORDERS_FORBID_PROJECTILE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_CORPSE, "ORDERS_FORBID_YOUR_CORPSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_ITEMS, "ORDERS_FORBID_YOUR_ITEMS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_CORPSE, "ORDERS_FORBID_OTHER_CORPSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_ITEMS, "ORDERS_FORBID_OTHER_ITEMS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_GATHER, "ORDERS_REFUSE_GATHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE, "ORDERS_REFUSE_OUTSIDE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE_VERMIN, "ORDERS_REFUSE_OUTSIDE_VERMIN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_CORPSE, "ORDERS_REFUSE_DUMP_CORPSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKULL, "ORDERS_REFUSE_DUMP_SKULL");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKIN, "ORDERS_REFUSE_DUMP_SKIN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_BONE, "ORDERS_REFUSE_DUMP_BONE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SHELL, "ORDERS_REFUSE_DUMP_SHELL");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_OTHER, "ORDERS_REFUSE_DUMP_OTHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_STRAND_TISSUE, "ORDERS_REFUSE_DUMP_STRAND_TISSUE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_FURNITURE, "ORDERS_GATHER_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_ANIMALS, "ORDERS_GATHER_ANIMALS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_FOOD, "ORDERS_GATHER_FOOD");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_BODIES, "ORDERS_GATHER_BODIES");
+ bindingNames.insert(INTERFACEKEY_ORDERS_REFUSE, "ORDERS_REFUSE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_STONE, "ORDERS_GATHER_STONE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_GATHER_WOOD, "ORDERS_GATHER_WOOD");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ALL_HARVEST, "ORDERS_ALL_HARVEST");
+ bindingNames.insert(INTERFACEKEY_ORDERS_SAMEPILE, "ORDERS_SAMEPILE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_MIXFOODS, "ORDERS_MIXFOODS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_EXCEPTIONS, "ORDERS_EXCEPTIONS");
+ bindingNames.insert(INTERFACEKEY_ORDERS_LOOM, "ORDERS_LOOM");
+ bindingNames.insert(INTERFACEKEY_ORDERS_DYED_CLOTH, "ORDERS_DYED_CLOTH");
+ bindingNames.insert(INTERFACEKEY_ORDERS_WORKSHOP, "ORDERS_WORKSHOP");
+ bindingNames.insert(INTERFACEKEY_ORDERS_COLLECT_WEB, "ORDERS_COLLECT_WEB");
+ bindingNames.insert(INTERFACEKEY_ORDERS_SLAUGHTER, "ORDERS_SLAUGHTER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_BUTCHER, "ORDERS_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_TAN, "ORDERS_TAN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_FISHERY, "ORDERS_AUTO_FISHERY");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_KITCHEN, "ORDERS_AUTO_KITCHEN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_KILN, "ORDERS_AUTO_KILN");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_SMELTER, "ORDERS_AUTO_SMELTER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_AUTO_OTHER, "ORDERS_AUTO_OTHER");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ZONE, "ORDERS_ZONE");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ZONE_DRINKING, "ORDERS_ZONE_DRINKING");
+ bindingNames.insert(INTERFACEKEY_ORDERS_ZONE_FISHING, "ORDERS_ZONE_FISHING");
+ bindingNames.insert(INTERFACEKEY_DESTROYBUILDING, "DESTROYBUILDING");
+ bindingNames.insert(INTERFACEKEY_SUSPENDBUILDING, "SUSPENDBUILDING");
+ bindingNames.insert(INTERFACEKEY_MENU_CONFIRM, "MENU_CONFIRM");
+ bindingNames.insert(INTERFACEKEY_SAVE_BINDINGS, "SAVE_BINDINGS");
+ bindingNames.insert(INTERFACEKEY_LOAD_BINDINGS, "LOAD_BINDINGS");
+ bindingNames.insert(INTERFACEKEY_KEYBINDING_COMPLETE, "KEYBINDING_COMPLETE");
+ bindingNames.insert(INTERFACEKEY_ZOOM_IN, "ZOOM_IN");
+ bindingNames.insert(INTERFACEKEY_ZOOM_OUT, "ZOOM_OUT");
+ bindingNames.insert(INTERFACEKEY_ZOOM_TOGGLE, "ZOOM_TOGGLE");
+ bindingNames.insert(INTERFACEKEY_ZOOM_RESET, "ZOOM_RESET");
+ bindingNames.insert(INTERFACEKEY_MACRO_BREAK, "MACRO_BREAK");
+ bindingNames.insert(INTERFACEKEY_RECORD_MACRO, "RECORD_MACRO");
+ bindingNames.insert(INTERFACEKEY_PLAY_MACRO, "PLAY_MACRO");
+ bindingNames.insert(INTERFACEKEY_SAVE_MACRO, "SAVE_MACRO");
+ bindingNames.insert(INTERFACEKEY_LOAD_MACRO, "LOAD_MACRO");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_ALCHEMIST_SOAP, "HOTKEY_ALCHEMIST_SOAP");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_STILL_BREW, "HOTKEY_STILL_BREW");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_STILL_EXTRACT, "HOTKEY_STILL_EXTRACT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_COLLECT_SILK, "HOTKEY_LOOM_COLLECT_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_CLOTH, "HOTKEY_LOOM_WEAVE_CLOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_SILK, "HOTKEY_LOOM_WEAVE_SILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_YARN, "HOTKEY_LOOM_WEAVE_YARN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_METAL, "HOTKEY_LOOM_WEAVE_METAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_2, "HOTKEY_KITCHEN_COOK_2");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_3, "HOTKEY_KITCHEN_COOK_3");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_4, "HOTKEY_KITCHEN_COOK_4");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_RENDER_FAT, "HOTKEY_KITCHEN_RENDER_FAT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS, "HOTKEY_FARMER_PROCESS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_VIAL, "HOTKEY_FARMER_PROCESS_VIAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BAG, "HOTKEY_FARMER_PROCESS_BAG");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BARREL, "HOTKEY_FARMER_PROCESS_BARREL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_CHEESE, "HOTKEY_FARMER_CHEESE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_MILK, "HOTKEY_FARMER_MILK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_SHEAR_CREATURE, "HOTKEY_FARMER_SHEAR_CREATURE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FARMER_SPIN_THREAD, "HOTKEY_FARMER_SPIN_THREAD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MILL_MILL, "HOTKEY_MILL_MILL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KENNEL_CATCH_VERMIN, "HOTKEY_KENNEL_CATCH_VERMIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_KENNEL_TAME_VERMIN, "HOTKEY_KENNEL_TAME_VERMIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FISHERY_PROCESS, "HOTKEY_FISHERY_PROCESS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FISHERY_EXTRACT, "HOTKEY_FISHERY_EXTRACT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_FISHERY_CATCH, "HOTKEY_FISHERY_CATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_BUTCHER, "HOTKEY_BUTCHER_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_EXTRACT, "HOTKEY_BUTCHER_EXTRACT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_CATCH, "HOTKEY_BUTCHER_CATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TANNER_TAN, "HOTKEY_TANNER_TAN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_DYER_THREAD, "HOTKEY_DYER_THREAD");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_DYER_CLOTH, "HOTKEY_DYER_CLOTH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FURNITURE, "HOTKEY_JEWELER_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FINISHED, "HOTKEY_JEWELER_FINISHED");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_AMMO, "HOTKEY_JEWELER_AMMO");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_CUT, "HOTKEY_JEWELER_CUT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_JEWELER_ENCRUST, "HOTKEY_JEWELER_ENCRUST");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_PARTS, "HOTKEY_MECHANIC_PARTS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_TRACTION_BENCH, "HOTKEY_MECHANIC_TRACTION_BENCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_ARMORSTAND, "HOTKEY_MASON_ARMORSTAND");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_BLOCKS, "HOTKEY_MASON_BLOCKS");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_CHAIR, "HOTKEY_MASON_CHAIR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_COFFIN, "HOTKEY_MASON_COFFIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_DOOR, "HOTKEY_MASON_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_FLOODGATE, "HOTKEY_MASON_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_HATCH_COVER, "HOTKEY_MASON_HATCH_COVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_GRATE, "HOTKEY_MASON_GRATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_CABINET, "HOTKEY_MASON_CABINET");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_BOX, "HOTKEY_MASON_BOX");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_STATUE, "HOTKEY_MASON_STATUE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_QUERN, "HOTKEY_MASON_QUERN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_MILLSTONE, "HOTKEY_MASON_MILLSTONE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_TABLE, "HOTKEY_MASON_TABLE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_WEAPONRACK, "HOTKEY_MASON_WEAPONRACK");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_MASON_SLAB, "HOTKEY_MASON_SLAB");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_BRIDGE, "HOTKEY_TRAP_BRIDGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_GEAR_ASSEMBLY, "HOTKEY_TRAP_GEAR_ASSEMBLY");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_DOOR, "HOTKEY_TRAP_DOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_FLOODGATE, "HOTKEY_TRAP_FLOODGATE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_SPIKE, "HOTKEY_TRAP_SPIKE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_HATCH, "HOTKEY_TRAP_HATCH");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_WALL, "HOTKEY_TRAP_GRATE_WALL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_FLOOR, "HOTKEY_TRAP_GRATE_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_VERTICAL, "HOTKEY_TRAP_BARS_VERTICAL");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_FLOOR, "HOTKEY_TRAP_BARS_FLOOR");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_SUPPORT, "HOTKEY_TRAP_SUPPORT");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_CHAIN, "HOTKEY_TRAP_CHAIN");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_CAGE, "HOTKEY_TRAP_CAGE");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_PULL_LEVER, "HOTKEY_TRAP_PULL_LEVER");
+ bindingNames.insert(INTERFACEKEY_HOTKEY_TRAP_TRACK_STOP, "HOTKEY_TRAP_TRACK_STOP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ADD, "BUILDJOB_ADD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CANCEL, "BUILDJOB_CANCEL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_PROMOTE, "BUILDJOB_PROMOTE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_NOW, "BUILDJOB_NOW");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_REPEAT, "BUILDJOB_REPEAT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_SUSPEND, "BUILDJOB_SUSPEND");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_WORKSHOP_PROFILE, "BUILDJOB_WORKSHOP_PROFILE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_WELL_FREE, "BUILDJOB_WELL_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_WELL_SIZE, "BUILDJOB_WELL_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_FREE, "BUILDJOB_TARGET_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_SIZE, "BUILDJOB_TARGET_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_DOWN, "BUILDJOB_TARGET_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_UP, "BUILDJOB_TARGET_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_RIGHT, "BUILDJOB_TARGET_RIGHT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TARGET_LEFT, "BUILDJOB_TARGET_LEFT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STATUE_ASSIGN, "BUILDJOB_STATUE_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STATUE_FREE, "BUILDJOB_STATUE_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STATUE_SIZE, "BUILDJOB_STATUE_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_JUSTICE, "BUILDJOB_CAGE_JUSTICE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_FREE, "BUILDJOB_CAGE_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_SIZE, "BUILDJOB_CAGE_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN_OCC, "BUILDJOB_CAGE_ASSIGN_OCC");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_WATER, "BUILDJOB_CAGE_WATER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN, "BUILDJOB_CAGE_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN_OCC, "BUILDJOB_CHAIN_ASSIGN_OCC");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_JUSTICE, "BUILDJOB_CHAIN_JUSTICE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN, "BUILDJOB_CHAIN_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_FREE, "BUILDJOB_CHAIN_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_SIZE, "BUILDJOB_CHAIN_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_FIRING, "BUILDJOB_SIEGE_FIRING");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_ORIENT, "BUILDJOB_SIEGE_ORIENT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DOOR_INTERNAL, "BUILDJOB_DOOR_INTERNAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DOOR_LOCK, "BUILDJOB_DOOR_LOCK");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DOOR_AJAR, "BUILDJOB_DOOR_AJAR");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_ASSIGN, "BUILDJOB_COFFIN_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_FREE, "BUILDJOB_COFFIN_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_SIZE, "BUILDJOB_COFFIN_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_BURIAL, "BUILDJOB_COFFIN_BURIAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_CIV, "BUILDJOB_COFFIN_CIV");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_PET, "BUILDJOB_COFFIN_PET");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_ASSIGN, "BUILDJOB_CHAIR_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_FREE, "BUILDJOB_CHAIR_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_SIZE, "BUILDJOB_CHAIR_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_ASSIGN, "BUILDJOB_TABLE_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_HALL, "BUILDJOB_TABLE_HALL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_FREE, "BUILDJOB_TABLE_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_TABLE_SIZE, "BUILDJOB_TABLE_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_ASSIGN, "BUILDJOB_BED_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_FREE, "BUILDJOB_BED_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_BARRACKS, "BUILDJOB_BED_BARRACKS");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_DORMITORY, "BUILDJOB_BED_DORMITORY");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_RENT, "BUILDJOB_BED_RENT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_SIZE, "BUILDJOB_BED_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_NAME, "BUILDJOB_BED_NAME");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_SLEEP, "BUILDJOB_BED_SLEEP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_TRAIN, "BUILDJOB_BED_TRAIN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_INDIV_EQ, "BUILDJOB_BED_INDIV_EQ");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_SQUAD_EQ, "BUILDJOB_BED_SQUAD_EQ");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_BED_POSITION, "BUILDJOB_BED_POSITION");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BRING, "BUILDJOB_DEPOT_BRING");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_TRADE, "BUILDJOB_DEPOT_TRADE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_REQUEST_TRADER, "BUILDJOB_DEPOT_REQUEST_TRADER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BROKER_ONLY, "BUILDJOB_DEPOT_BROKER_ONLY");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_NONE, "BUILDJOB_ANIMALTRAP_BAIT_NONE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_MEAT, "BUILDJOB_ANIMALTRAP_BAIT_MEAT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_FISH, "BUILDJOB_ANIMALTRAP_BAIT_FISH");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_GEM, "BUILDJOB_ANIMALTRAP_BAIT_GEM");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_FALLOW, "BUILDJOB_FARM_FALLOW");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_FERTILIZE, "BUILDJOB_FARM_FERTILIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_SEASFERT, "BUILDJOB_FARM_SEASFERT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_SPRING, "BUILDJOB_FARM_SPRING");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_SUMMER, "BUILDJOB_FARM_SUMMER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_AUTUMN, "BUILDJOB_FARM_AUTUMN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_FARM_WINTER, "BUILDJOB_FARM_WINTER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_MASTER, "BUILDJOB_STOCKPILE_MASTER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_LINK_ANYWHERE, "BUILDJOB_STOCKPILE_LINK_ANYWHERE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_GIVE_TO, "BUILDJOB_STOCKPILE_GIVE_TO");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_WHEELBARROW, "BUILDJOB_STOCKPILE_WHEELBARROW");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_DELETE_CHILD, "BUILDJOB_STOCKPILE_DELETE_CHILD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_SETTINGS, "BUILDJOB_STOCKPILE_SETTINGS");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_UP, "BUILDJOB_STOCKPILE_BARREL_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_DOWN, "BUILDJOB_STOCKPILE_BARREL_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_ZERO, "BUILDJOB_STOCKPILE_BARREL_ZERO");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_MAX, "BUILDJOB_STOCKPILE_BARREL_MAX");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_UP, "BUILDJOB_STOCKPILE_BIN_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_DOWN, "BUILDJOB_STOCKPILE_BIN_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_ZERO, "BUILDJOB_STOCKPILE_BIN_ZERO");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_MAX, "BUILDJOB_STOCKPILE_BIN_MAX");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BONE, "BUILDJOB_RACK_MAT_BONE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BRONZE, "BUILDJOB_RACK_MAT_BRONZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_COPPER, "BUILDJOB_RACK_MAT_COPPER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_IRON, "BUILDJOB_RACK_MAT_IRON");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_STEEL, "BUILDJOB_RACK_MAT_STEEL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_WOOD, "BUILDJOB_RACK_MAT_WOOD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_METAL, "BUILDJOB_RACK_MAT_METAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BONE, "BUILDJOB_STAND_MAT_BONE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_LEATHER, "BUILDJOB_STAND_MAT_LEATHER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_COPPER, "BUILDJOB_STAND_MAT_COPPER");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BRONZE, "BUILDJOB_STAND_MAT_BRONZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_STEEL, "BUILDJOB_STAND_MAT_STEEL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_IRON, "BUILDJOB_STAND_MAT_IRON");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_WOOD, "BUILDJOB_STAND_MAT_WOOD");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_METAL, "BUILDJOB_STAND_MAT_METAL");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ASSIGN, "BUILDJOB_RACKSTAND_ASSIGN");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_FREE, "BUILDJOB_RACKSTAND_FREE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_SIZE, "BUILDJOB_RACKSTAND_SIZE");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ITEM, "BUILDJOB_RACKSTAND_ITEM");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_MAT, "BUILDJOB_RACKSTAND_MAT");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS1, "BUILDJOB_RACKSTAND_DEFAULTS1");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL1, "BUILDJOB_RACKSTAND_KILL1");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS2, "BUILDJOB_RACKSTAND_DEFAULTS2");
+ bindingNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL2, "BUILDJOB_RACKSTAND_KILL2");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_ENABLE, "STOCKPILE_SETTINGS_ENABLE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_DISABLE, "STOCKPILE_SETTINGS_DISABLE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_ALL, "STOCKPILE_SETTINGS_PERMIT_ALL");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_ALL, "STOCKPILE_SETTINGS_FORBID_ALL");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_SUB, "STOCKPILE_SETTINGS_PERMIT_SUB");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_SUB, "STOCKPILE_SETTINGS_FORBID_SUB");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC1, "STOCKPILE_SETTINGS_SPECIFIC1");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC2, "STOCKPILE_SETTINGS_SPECIFIC2");
+ bindingNames.insert(INTERFACEKEY_MOVIE_RECORD, "MOVIE_RECORD");
+ bindingNames.insert(INTERFACEKEY_MOVIE_PLAY, "MOVIE_PLAY");
+ bindingNames.insert(INTERFACEKEY_MOVIE_SAVE, "MOVIE_SAVE");
+ bindingNames.insert(INTERFACEKEY_MOVIE_LOAD, "MOVIE_LOAD");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_VIEW, "ASSIGNTRADE_VIEW");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_STRING, "ASSIGNTRADE_STRING");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_EXCLUDE_PROHIBITED, "ASSIGNTRADE_EXCLUDE_PROHIBITED");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_PENDING, "ASSIGNTRADE_PENDING");
+ bindingNames.insert(INTERFACEKEY_ASSIGNTRADE_SORT, "ASSIGNTRADE_SORT");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_REPLACE, "NOBLELIST_REPLACE");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_SETTINGS, "NOBLELIST_SETTINGS");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_CAPITAL, "NOBLELIST_CAPITAL");
+ bindingNames.insert(INTERFACEKEY_NOBLELIST_VIEW_CANDIDATE, "NOBLELIST_VIEW_CANDIDATE");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_VIEW, "A_BARTER_VIEW");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_1, "A_BARTER_CURRENCY_1");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_2, "A_BARTER_CURRENCY_2");
+ bindingNames.insert(INTERFACEKEY_A_BARTER_TRADE, "A_BARTER_TRADE");
+ bindingNames.insert(INTERFACEKEY_TRADE_VIEW, "TRADE_VIEW");
+ bindingNames.insert(INTERFACEKEY_TRADE_TRADE, "TRADE_TRADE");
+ bindingNames.insert(INTERFACEKEY_TRADE_OFFER, "TRADE_OFFER");
+ bindingNames.insert(INTERFACEKEY_TRADE_SEIZE, "TRADE_SEIZE");
+ bindingNames.insert(INTERFACEKEY_STORES_VIEW, "STORES_VIEW");
+ bindingNames.insert(INTERFACEKEY_STORES_ZOOM, "STORES_ZOOM");
+ bindingNames.insert(INTERFACEKEY_STORES_FORBID, "STORES_FORBID");
+ bindingNames.insert(INTERFACEKEY_STORES_MELT, "STORES_MELT");
+ bindingNames.insert(INTERFACEKEY_STORES_DUMP, "STORES_DUMP");
+ bindingNames.insert(INTERFACEKEY_STORES_HIDE, "STORES_HIDE");
+ bindingNames.insert(INTERFACEKEY_MILITARY_ACTIVATE, "MILITARY_ACTIVATE");
+ bindingNames.insert(INTERFACEKEY_MILITARY_VIEW, "MILITARY_VIEW");
+ bindingNames.insert(INTERFACEKEY_MILITARY_WEAPON, "MILITARY_WEAPON");
+ bindingNames.insert(INTERFACEKEY_MILITARY_ZOOM, "MILITARY_ZOOM");
+ bindingNames.insert(INTERFACEKEY_ANNOUNCE_ZOOM, "ANNOUNCE_ZOOM");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_REMOVE_CRE, "UNITJOB_REMOVE_CRE");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_ZOOM_CRE, "UNITJOB_ZOOM_CRE");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_ZOOM_BUILD, "UNITJOB_ZOOM_BUILD");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_VIEW, "UNITJOB_VIEW");
+ bindingNames.insert(INTERFACEKEY_UNITJOB_MANAGER, "UNITJOB_MANAGER");
+ bindingNames.insert(INTERFACEKEY_MANAGER_NEW_ORDER, "MANAGER_NEW_ORDER");
+ bindingNames.insert(INTERFACEKEY_MANAGER_REMOVE, "MANAGER_REMOVE");
+ bindingNames.insert(INTERFACEKEY_MANAGER_PROMOTE, "MANAGER_PROMOTE");
+ bindingNames.insert(INTERFACEKEY_MANAGER_MAX, "MANAGER_MAX");
+ bindingNames.insert(INTERFACEKEY_MANAGER_WAGES, "MANAGER_WAGES");
+ bindingNames.insert(INTERFACEKEY_PET_BUTCHER, "PET_BUTCHER");
+ bindingNames.insert(INTERFACEKEY_PET_GELD, "PET_GELD");
+ bindingNames.insert(INTERFACEKEY_ANIMAL_SELECT_TRAINER, "ANIMAL_SELECT_TRAINER");
+ bindingNames.insert(INTERFACEKEY_ANIMAL_WAR_TRAINING, "ANIMAL_WAR_TRAINING");
+ bindingNames.insert(INTERFACEKEY_ANIMAL_HUNTING_TRAINING, "ANIMAL_HUNTING_TRAINING");
+ bindingNames.insert(INTERFACEKEY_KITCHEN_COOK, "KITCHEN_COOK");
+ bindingNames.insert(INTERFACEKEY_KITCHEN_BREW, "KITCHEN_BREW");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_NEW, "SETUPGAME_NEW");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_VIEW, "SETUPGAME_VIEW");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_CUSTOMIZE_UNIT, "SETUPGAME_CUSTOMIZE_UNIT");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE, "SETUPGAME_SAVE_PROFILE");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_ABORT, "SETUPGAME_SAVE_PROFILE_ABORT");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_GO, "SETUPGAME_SAVE_PROFILE_GO");
+ bindingNames.insert(INTERFACEKEY_SETUPGAME_VIEW_PROFILE_PROBLEMS, "SETUPGAME_VIEW_PROFILE_PROBLEMS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_REMOVE, "CIVZONE_REMOVE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_REMOVE_ZONE, "CIVZONE_REMOVE_ZONE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_SHAPE, "CIVZONE_SHAPE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_NEXT, "CIVZONE_NEXT");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_POND_OPTIONS, "CIVZONE_POND_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL_OPTIONS, "CIVZONE_HOSPITAL_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS, "CIVZONE_GATHER_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_TREES, "CIVZONE_GATHER_OPTIONS_PICK_TREES");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_SHRUBS, "CIVZONE_GATHER_OPTIONS_PICK_SHRUBS");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_GATHER_FALLEN, "CIVZONE_GATHER_OPTIONS_GATHER_FALLEN");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_WATER_SOURCE, "CIVZONE_WATER_SOURCE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_FISH, "CIVZONE_FISH");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_GATHER, "CIVZONE_GATHER");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_DUMP, "CIVZONE_DUMP");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_POND, "CIVZONE_POND");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL, "CIVZONE_HOSPITAL");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_SAND_COLLECT, "CIVZONE_SAND_COLLECT");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_CLAY_COLLECT, "CIVZONE_CLAY_COLLECT");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_ACTIVE, "CIVZONE_ACTIVE");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_MEETING, "CIVZONE_MEETING");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_ANIMAL_TRAINING, "CIVZONE_ANIMAL_TRAINING");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_POND_WATER, "CIVZONE_POND_WATER");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_PEN, "CIVZONE_PEN");
+ bindingNames.insert(INTERFACEKEY_CIVZONE_PEN_OPTIONS, "CIVZONE_PEN_OPTIONS");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_ANIMAL, "STOCKPILE_ANIMAL");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_FOOD, "STOCKPILE_FOOD");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_WEAPON, "STOCKPILE_WEAPON");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_ARMOR, "STOCKPILE_ARMOR");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM, "STOCKPILE_CUSTOM");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM_SETTINGS, "STOCKPILE_CUSTOM_SETTINGS");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_FURNITURE, "STOCKPILE_FURNITURE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_GRAVEYARD, "STOCKPILE_GRAVEYARD");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_REFUSE, "STOCKPILE_REFUSE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_WOOD, "STOCKPILE_WOOD");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_STONE, "STOCKPILE_STONE");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_GEM, "STOCKPILE_GEM");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_BARBLOCK, "STOCKPILE_BARBLOCK");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_CLOTH, "STOCKPILE_CLOTH");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_LEATHER, "STOCKPILE_LEATHER");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_AMMO, "STOCKPILE_AMMO");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_COINS, "STOCKPILE_COINS");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_FINISHED, "STOCKPILE_FINISHED");
+ bindingNames.insert(INTERFACEKEY_STOCKPILE_NONE, "STOCKPILE_NONE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_BITEM, "DESIGNATE_BITEM");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_CLAIM, "DESIGNATE_CLAIM");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_UNCLAIM, "DESIGNATE_UNCLAIM");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_MELT, "DESIGNATE_MELT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_NO_MELT, "DESIGNATE_NO_MELT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_DUMP, "DESIGNATE_DUMP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_NO_DUMP, "DESIGNATE_NO_DUMP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_HIDE, "DESIGNATE_HIDE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_NO_HIDE, "DESIGNATE_NO_HIDE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC, "DESIGNATE_TRAFFIC");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_HIGH, "DESIGNATE_TRAFFIC_HIGH");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_NORMAL, "DESIGNATE_TRAFFIC_NORMAL");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_LOW, "DESIGNATE_TRAFFIC_LOW");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_RESTRICTED, "DESIGNATE_TRAFFIC_RESTRICTED");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT, "DESIGNATE_TRAFFIC_INCREASE_WEIGHT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT, "DESIGNATE_TRAFFIC_DECREASE_WEIGHT");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE, "DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE, "DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_DIG, "DESIGNATE_DIG");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_DIG_REMOVE_STAIRS_RAMPS, "DESIGNATE_DIG_REMOVE_STAIRS_RAMPS");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UP, "DESIGNATE_STAIR_UP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STAIR_DOWN, "DESIGNATE_STAIR_DOWN");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UPDOWN, "DESIGNATE_STAIR_UPDOWN");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_RAMP, "DESIGNATE_RAMP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_CHANNEL, "DESIGNATE_CHANNEL");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_CHOP, "DESIGNATE_CHOP");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_PLANTS, "DESIGNATE_PLANTS");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_SMOOTH, "DESIGNATE_SMOOTH");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_ENGRAVE, "DESIGNATE_ENGRAVE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_FORTIFY, "DESIGNATE_FORTIFY");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TRACK, "DESIGNATE_TRACK");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_ENGRAVING, "DESIGNATE_TOGGLE_ENGRAVING");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_STANDARD_MARKER, "DESIGNATE_STANDARD_MARKER");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_MINE_MODE, "DESIGNATE_MINE_MODE");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_MARKER, "DESIGNATE_TOGGLE_MARKER");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_UNDO, "DESIGNATE_UNDO");
+ bindingNames.insert(INTERFACEKEY_DESIGNATE_REMOVE_CONSTRUCTION, "DESIGNATE_REMOVE_CONSTRUCTION");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_Y_UP, "BUILDING_DIM_Y_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_Y_DOWN, "BUILDING_DIM_Y_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_X_UP, "BUILDING_DIM_X_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_DIM_X_DOWN, "BUILDING_DIM_X_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_UP, "BUILDING_ORIENT_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_LEFT, "BUILDING_ORIENT_LEFT");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_RIGHT, "BUILDING_ORIENT_RIGHT");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_DOWN, "BUILDING_ORIENT_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ORIENT_NONE, "BUILDING_ORIENT_NONE");
+ bindingNames.insert(INTERFACEKEY_BUILDING_VIEW_ITEM, "BUILDING_VIEW_ITEM");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ADVANCE_STAGE, "BUILDING_ADVANCE_STAGE");
+ bindingNames.insert(INTERFACEKEY_BUILDING_EXPAND_CONTRACT, "BUILDING_EXPAND_CONTRACT");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_WATER, "BUILDING_TRIGGER_ENABLE_WATER");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_UP, "BUILDING_TRIGGER_MIN_WATER_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_DOWN, "BUILDING_TRIGGER_MIN_WATER_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_UP, "BUILDING_TRIGGER_MAX_WATER_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_DOWN, "BUILDING_TRIGGER_MAX_WATER_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_MAGMA, "BUILDING_TRIGGER_ENABLE_MAGMA");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_UP, "BUILDING_TRIGGER_MIN_MAGMA_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_DOWN, "BUILDING_TRIGGER_MIN_MAGMA_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_UP, "BUILDING_TRIGGER_MAX_MAGMA_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_DOWN, "BUILDING_TRIGGER_MAX_MAGMA_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_TRACK_CART, "BUILDING_TRIGGER_ENABLE_TRACK_CART");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_DOWN, "BUILDING_TRIGGER_MIN_TRACK_CART_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_UP, "BUILDING_TRIGGER_MIN_TRACK_CART_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_DOWN, "BUILDING_TRIGGER_MAX_TRACK_CART_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_UP, "BUILDING_TRIGGER_MAX_TRACK_CART_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_UP, "BUILDING_ROLLERS_SPEED_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_DOWN, "BUILDING_ROLLERS_SPEED_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_UP, "BUILDING_TRACK_STOP_FRICTION_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_DOWN, "BUILDING_TRACK_STOP_FRICTION_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_DUMP, "BUILDING_TRACK_STOP_DUMP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_CREATURE, "BUILDING_TRIGGER_ENABLE_CREATURE");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_LOCALS, "BUILDING_TRIGGER_ENABLE_LOCALS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_RESETS, "BUILDING_TRIGGER_RESETS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP, "BUILDING_TRIGGER_MIN_SIZE_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN, "BUILDING_TRIGGER_MIN_SIZE_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP, "BUILDING_TRIGGER_MAX_SIZE_UP");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN, "BUILDING_TRIGGER_MAX_SIZE_DOWN");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP_PLUS, "BUILDING_TRIGGER_MIN_SIZE_UP_PLUS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS, "BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP_PLUS, "BUILDING_TRIGGER_MAX_SIZE_UP_PLUS");
+ bindingNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS, "BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN, "UNITVIEW_GEN");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_INV, "UNITVIEW_INV");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF, "UNITVIEW_PRF");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_WND, "UNITVIEW_WND");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_FOLLOW, "UNITVIEW_FOLLOW");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_NEXT, "UNITVIEW_NEXT");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_SLAUGHTER, "UNITVIEW_SLAUGHTER");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GELD, "UNITVIEW_GELD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN_COMBAT, "UNITVIEW_GEN_COMBAT");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN_LABOR, "UNITVIEW_GEN_LABOR");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_GEN_MISC, "UNITVIEW_GEN_MISC");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_PROF, "UNITVIEW_PRF_PROF");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_PET, "UNITVIEW_PRF_PET");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_VIEW, "UNITVIEW_PRF_VIEW");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_NEW_SQUAD, "UNITVIEW_PRF_NEW_SQUAD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_REMOVE_FROM_SQUAD, "UNITVIEW_PRF_REMOVE_FROM_SQUAD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_CURRENT_SQUAD, "UNITVIEW_PRF_NAME_CURRENT_SQUAD");
+ bindingNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_SELECTED_SQUAD, "UNITVIEW_PRF_NAME_SELECTED_SQUAD");
+
+ bindingNames.insert(INTERFACEKEY_STRING_A000, "STRING_A000");
+ bindingNames.insert(INTERFACEKEY_STRING_A001, "STRING_A001");
+ bindingNames.insert(INTERFACEKEY_STRING_A002, "STRING_A002");
+ bindingNames.insert(INTERFACEKEY_STRING_A003, "STRING_A003");
+ bindingNames.insert(INTERFACEKEY_STRING_A004, "STRING_A004");
+ bindingNames.insert(INTERFACEKEY_STRING_A005, "STRING_A005");
+ bindingNames.insert(INTERFACEKEY_STRING_A006, "STRING_A006");
+ bindingNames.insert(INTERFACEKEY_STRING_A007, "STRING_A007");
+ bindingNames.insert(INTERFACEKEY_STRING_A008, "STRING_A008");
+ bindingNames.insert(INTERFACEKEY_STRING_A009, "STRING_A009");
+ bindingNames.insert(INTERFACEKEY_STRING_A010, "STRING_A010");
+ bindingNames.insert(INTERFACEKEY_STRING_A011, "STRING_A011");
+ bindingNames.insert(INTERFACEKEY_STRING_A012, "STRING_A012");
+ bindingNames.insert(INTERFACEKEY_STRING_A013, "STRING_A013");
+ bindingNames.insert(INTERFACEKEY_STRING_A014, "STRING_A014");
+ bindingNames.insert(INTERFACEKEY_STRING_A015, "STRING_A015");
+ bindingNames.insert(INTERFACEKEY_STRING_A016, "STRING_A016");
+ bindingNames.insert(INTERFACEKEY_STRING_A017, "STRING_A017");
+ bindingNames.insert(INTERFACEKEY_STRING_A018, "STRING_A018");
+ bindingNames.insert(INTERFACEKEY_STRING_A019, "STRING_A019");
+ bindingNames.insert(INTERFACEKEY_STRING_A020, "STRING_A020");
+ bindingNames.insert(INTERFACEKEY_STRING_A021, "STRING_A021");
+ bindingNames.insert(INTERFACEKEY_STRING_A022, "STRING_A022");
+ bindingNames.insert(INTERFACEKEY_STRING_A023, "STRING_A023");
+ bindingNames.insert(INTERFACEKEY_STRING_A024, "STRING_A024");
+ bindingNames.insert(INTERFACEKEY_STRING_A025, "STRING_A025");
+ bindingNames.insert(INTERFACEKEY_STRING_A026, "STRING_A026");
+ bindingNames.insert(INTERFACEKEY_STRING_A027, "STRING_A027");
+ bindingNames.insert(INTERFACEKEY_STRING_A028, "STRING_A028");
+ bindingNames.insert(INTERFACEKEY_STRING_A029, "STRING_A029");
+ bindingNames.insert(INTERFACEKEY_STRING_A030, "STRING_A030");
+ bindingNames.insert(INTERFACEKEY_STRING_A031, "STRING_A031");
+ bindingNames.insert(INTERFACEKEY_STRING_A032, "STRING_A032");
+ bindingNames.insert(INTERFACEKEY_STRING_A033, "STRING_A033");
+ bindingNames.insert(INTERFACEKEY_STRING_A034, "STRING_A034");
+ bindingNames.insert(INTERFACEKEY_STRING_A035, "STRING_A035");
+ bindingNames.insert(INTERFACEKEY_STRING_A036, "STRING_A036");
+ bindingNames.insert(INTERFACEKEY_STRING_A037, "STRING_A037");
+ bindingNames.insert(INTERFACEKEY_STRING_A038, "STRING_A038");
+ bindingNames.insert(INTERFACEKEY_STRING_A039, "STRING_A039");
+ bindingNames.insert(INTERFACEKEY_STRING_A040, "STRING_A040");
+ bindingNames.insert(INTERFACEKEY_STRING_A041, "STRING_A041");
+ bindingNames.insert(INTERFACEKEY_STRING_A042, "STRING_A042");
+ bindingNames.insert(INTERFACEKEY_STRING_A043, "STRING_A043");
+ bindingNames.insert(INTERFACEKEY_STRING_A044, "STRING_A044");
+ bindingNames.insert(INTERFACEKEY_STRING_A045, "STRING_A045");
+ bindingNames.insert(INTERFACEKEY_STRING_A046, "STRING_A046");
+ bindingNames.insert(INTERFACEKEY_STRING_A047, "STRING_A047");
+ bindingNames.insert(INTERFACEKEY_STRING_A048, "STRING_A048");
+ bindingNames.insert(INTERFACEKEY_STRING_A049, "STRING_A049");
+ bindingNames.insert(INTERFACEKEY_STRING_A050, "STRING_A050");
+ bindingNames.insert(INTERFACEKEY_STRING_A051, "STRING_A051");
+ bindingNames.insert(INTERFACEKEY_STRING_A052, "STRING_A052");
+ bindingNames.insert(INTERFACEKEY_STRING_A053, "STRING_A053");
+ bindingNames.insert(INTERFACEKEY_STRING_A054, "STRING_A054");
+ bindingNames.insert(INTERFACEKEY_STRING_A055, "STRING_A055");
+ bindingNames.insert(INTERFACEKEY_STRING_A056, "STRING_A056");
+ bindingNames.insert(INTERFACEKEY_STRING_A057, "STRING_A057");
+ bindingNames.insert(INTERFACEKEY_STRING_A058, "STRING_A058");
+ bindingNames.insert(INTERFACEKEY_STRING_A059, "STRING_A059");
+ bindingNames.insert(INTERFACEKEY_STRING_A060, "STRING_A060");
+ bindingNames.insert(INTERFACEKEY_STRING_A061, "STRING_A061");
+ bindingNames.insert(INTERFACEKEY_STRING_A062, "STRING_A062");
+ bindingNames.insert(INTERFACEKEY_STRING_A063, "STRING_A063");
+ bindingNames.insert(INTERFACEKEY_STRING_A064, "STRING_A064");
+ bindingNames.insert(INTERFACEKEY_STRING_A065, "STRING_A065");
+ bindingNames.insert(INTERFACEKEY_STRING_A066, "STRING_A066");
+ bindingNames.insert(INTERFACEKEY_STRING_A067, "STRING_A067");
+ bindingNames.insert(INTERFACEKEY_STRING_A068, "STRING_A068");
+ bindingNames.insert(INTERFACEKEY_STRING_A069, "STRING_A069");
+ bindingNames.insert(INTERFACEKEY_STRING_A070, "STRING_A070");
+ bindingNames.insert(INTERFACEKEY_STRING_A071, "STRING_A071");
+ bindingNames.insert(INTERFACEKEY_STRING_A072, "STRING_A072");
+ bindingNames.insert(INTERFACEKEY_STRING_A073, "STRING_A073");
+ bindingNames.insert(INTERFACEKEY_STRING_A074, "STRING_A074");
+ bindingNames.insert(INTERFACEKEY_STRING_A075, "STRING_A075");
+ bindingNames.insert(INTERFACEKEY_STRING_A076, "STRING_A076");
+ bindingNames.insert(INTERFACEKEY_STRING_A077, "STRING_A077");
+ bindingNames.insert(INTERFACEKEY_STRING_A078, "STRING_A078");
+ bindingNames.insert(INTERFACEKEY_STRING_A079, "STRING_A079");
+ bindingNames.insert(INTERFACEKEY_STRING_A080, "STRING_A080");
+ bindingNames.insert(INTERFACEKEY_STRING_A081, "STRING_A081");
+ bindingNames.insert(INTERFACEKEY_STRING_A082, "STRING_A082");
+ bindingNames.insert(INTERFACEKEY_STRING_A083, "STRING_A083");
+ bindingNames.insert(INTERFACEKEY_STRING_A084, "STRING_A084");
+ bindingNames.insert(INTERFACEKEY_STRING_A085, "STRING_A085");
+ bindingNames.insert(INTERFACEKEY_STRING_A086, "STRING_A086");
+ bindingNames.insert(INTERFACEKEY_STRING_A087, "STRING_A087");
+ bindingNames.insert(INTERFACEKEY_STRING_A088, "STRING_A088");
+ bindingNames.insert(INTERFACEKEY_STRING_A089, "STRING_A089");
+ bindingNames.insert(INTERFACEKEY_STRING_A090, "STRING_A090");
+ bindingNames.insert(INTERFACEKEY_STRING_A091, "STRING_A091");
+ bindingNames.insert(INTERFACEKEY_STRING_A092, "STRING_A092");
+ bindingNames.insert(INTERFACEKEY_STRING_A093, "STRING_A093");
+ bindingNames.insert(INTERFACEKEY_STRING_A094, "STRING_A094");
+ bindingNames.insert(INTERFACEKEY_STRING_A095, "STRING_A095");
+ bindingNames.insert(INTERFACEKEY_STRING_A096, "STRING_A096");
+ bindingNames.insert(INTERFACEKEY_STRING_A097, "STRING_A097");
+ bindingNames.insert(INTERFACEKEY_STRING_A098, "STRING_A098");
+ bindingNames.insert(INTERFACEKEY_STRING_A099, "STRING_A099");
+ bindingNames.insert(INTERFACEKEY_STRING_A100, "STRING_A100");
+ bindingNames.insert(INTERFACEKEY_STRING_A101, "STRING_A101");
+ bindingNames.insert(INTERFACEKEY_STRING_A102, "STRING_A102");
+ bindingNames.insert(INTERFACEKEY_STRING_A103, "STRING_A103");
+ bindingNames.insert(INTERFACEKEY_STRING_A104, "STRING_A104");
+ bindingNames.insert(INTERFACEKEY_STRING_A105, "STRING_A105");
+ bindingNames.insert(INTERFACEKEY_STRING_A106, "STRING_A106");
+ bindingNames.insert(INTERFACEKEY_STRING_A107, "STRING_A107");
+ bindingNames.insert(INTERFACEKEY_STRING_A108, "STRING_A108");
+ bindingNames.insert(INTERFACEKEY_STRING_A109, "STRING_A109");
+ bindingNames.insert(INTERFACEKEY_STRING_A110, "STRING_A110");
+ bindingNames.insert(INTERFACEKEY_STRING_A111, "STRING_A111");
+ bindingNames.insert(INTERFACEKEY_STRING_A112, "STRING_A112");
+ bindingNames.insert(INTERFACEKEY_STRING_A113, "STRING_A113");
+ bindingNames.insert(INTERFACEKEY_STRING_A114, "STRING_A114");
+ bindingNames.insert(INTERFACEKEY_STRING_A115, "STRING_A115");
+ bindingNames.insert(INTERFACEKEY_STRING_A116, "STRING_A116");
+ bindingNames.insert(INTERFACEKEY_STRING_A117, "STRING_A117");
+ bindingNames.insert(INTERFACEKEY_STRING_A118, "STRING_A118");
+ bindingNames.insert(INTERFACEKEY_STRING_A119, "STRING_A119");
+ bindingNames.insert(INTERFACEKEY_STRING_A120, "STRING_A120");
+ bindingNames.insert(INTERFACEKEY_STRING_A121, "STRING_A121");
+ bindingNames.insert(INTERFACEKEY_STRING_A122, "STRING_A122");
+ bindingNames.insert(INTERFACEKEY_STRING_A123, "STRING_A123");
+ bindingNames.insert(INTERFACEKEY_STRING_A124, "STRING_A124");
+ bindingNames.insert(INTERFACEKEY_STRING_A125, "STRING_A125");
+ bindingNames.insert(INTERFACEKEY_STRING_A126, "STRING_A126");
+ bindingNames.insert(INTERFACEKEY_STRING_A128, "STRING_A128");
+ bindingNames.insert(INTERFACEKEY_STRING_A129, "STRING_A129");
+ bindingNames.insert(INTERFACEKEY_STRING_A130, "STRING_A130");
+ bindingNames.insert(INTERFACEKEY_STRING_A131, "STRING_A131");
+ bindingNames.insert(INTERFACEKEY_STRING_A132, "STRING_A132");
+ bindingNames.insert(INTERFACEKEY_STRING_A133, "STRING_A133");
+ bindingNames.insert(INTERFACEKEY_STRING_A134, "STRING_A134");
+ bindingNames.insert(INTERFACEKEY_STRING_A135, "STRING_A135");
+ bindingNames.insert(INTERFACEKEY_STRING_A136, "STRING_A136");
+ bindingNames.insert(INTERFACEKEY_STRING_A137, "STRING_A137");
+ bindingNames.insert(INTERFACEKEY_STRING_A138, "STRING_A138");
+ bindingNames.insert(INTERFACEKEY_STRING_A139, "STRING_A139");
+ bindingNames.insert(INTERFACEKEY_STRING_A140, "STRING_A140");
+ bindingNames.insert(INTERFACEKEY_STRING_A141, "STRING_A141");
+ bindingNames.insert(INTERFACEKEY_STRING_A142, "STRING_A142");
+ bindingNames.insert(INTERFACEKEY_STRING_A143, "STRING_A143");
+ bindingNames.insert(INTERFACEKEY_STRING_A144, "STRING_A144");
+ bindingNames.insert(INTERFACEKEY_STRING_A145, "STRING_A145");
+ bindingNames.insert(INTERFACEKEY_STRING_A146, "STRING_A146");
+ bindingNames.insert(INTERFACEKEY_STRING_A147, "STRING_A147");
+ bindingNames.insert(INTERFACEKEY_STRING_A148, "STRING_A148");
+ bindingNames.insert(INTERFACEKEY_STRING_A149, "STRING_A149");
+ bindingNames.insert(INTERFACEKEY_STRING_A150, "STRING_A150");
+ bindingNames.insert(INTERFACEKEY_STRING_A151, "STRING_A151");
+ bindingNames.insert(INTERFACEKEY_STRING_A152, "STRING_A152");
+ bindingNames.insert(INTERFACEKEY_STRING_A153, "STRING_A153");
+ bindingNames.insert(INTERFACEKEY_STRING_A154, "STRING_A154");
+ bindingNames.insert(INTERFACEKEY_STRING_A155, "STRING_A155");
+ bindingNames.insert(INTERFACEKEY_STRING_A156, "STRING_A156");
+ bindingNames.insert(INTERFACEKEY_STRING_A157, "STRING_A157");
+ bindingNames.insert(INTERFACEKEY_STRING_A158, "STRING_A158");
+ bindingNames.insert(INTERFACEKEY_STRING_A159, "STRING_A159");
+ bindingNames.insert(INTERFACEKEY_STRING_A160, "STRING_A160");
+ bindingNames.insert(INTERFACEKEY_STRING_A161, "STRING_A161");
+ bindingNames.insert(INTERFACEKEY_STRING_A162, "STRING_A162");
+ bindingNames.insert(INTERFACEKEY_STRING_A163, "STRING_A163");
+ bindingNames.insert(INTERFACEKEY_STRING_A164, "STRING_A164");
+ bindingNames.insert(INTERFACEKEY_STRING_A165, "STRING_A165");
+ bindingNames.insert(INTERFACEKEY_STRING_A166, "STRING_A166");
+ bindingNames.insert(INTERFACEKEY_STRING_A167, "STRING_A167");
+ bindingNames.insert(INTERFACEKEY_STRING_A168, "STRING_A168");
+ bindingNames.insert(INTERFACEKEY_STRING_A169, "STRING_A169");
+ bindingNames.insert(INTERFACEKEY_STRING_A170, "STRING_A170");
+ bindingNames.insert(INTERFACEKEY_STRING_A171, "STRING_A171");
+ bindingNames.insert(INTERFACEKEY_STRING_A172, "STRING_A172");
+ bindingNames.insert(INTERFACEKEY_STRING_A173, "STRING_A173");
+ bindingNames.insert(INTERFACEKEY_STRING_A174, "STRING_A174");
+ bindingNames.insert(INTERFACEKEY_STRING_A175, "STRING_A175");
+ bindingNames.insert(INTERFACEKEY_STRING_A176, "STRING_A176");
+ bindingNames.insert(INTERFACEKEY_STRING_A177, "STRING_A177");
+ bindingNames.insert(INTERFACEKEY_STRING_A178, "STRING_A178");
+ bindingNames.insert(INTERFACEKEY_STRING_A179, "STRING_A179");
+ bindingNames.insert(INTERFACEKEY_STRING_A180, "STRING_A180");
+ bindingNames.insert(INTERFACEKEY_STRING_A181, "STRING_A181");
+ bindingNames.insert(INTERFACEKEY_STRING_A182, "STRING_A182");
+ bindingNames.insert(INTERFACEKEY_STRING_A183, "STRING_A183");
+ bindingNames.insert(INTERFACEKEY_STRING_A184, "STRING_A184");
+ bindingNames.insert(INTERFACEKEY_STRING_A185, "STRING_A185");
+ bindingNames.insert(INTERFACEKEY_STRING_A186, "STRING_A186");
+ bindingNames.insert(INTERFACEKEY_STRING_A187, "STRING_A187");
+ bindingNames.insert(INTERFACEKEY_STRING_A188, "STRING_A188");
+ bindingNames.insert(INTERFACEKEY_STRING_A189, "STRING_A189");
+ bindingNames.insert(INTERFACEKEY_STRING_A190, "STRING_A190");
+ bindingNames.insert(INTERFACEKEY_STRING_A191, "STRING_A191");
+ bindingNames.insert(INTERFACEKEY_STRING_A192, "STRING_A192");
+ bindingNames.insert(INTERFACEKEY_STRING_A193, "STRING_A193");
+ bindingNames.insert(INTERFACEKEY_STRING_A194, "STRING_A194");
+ bindingNames.insert(INTERFACEKEY_STRING_A195, "STRING_A195");
+ bindingNames.insert(INTERFACEKEY_STRING_A196, "STRING_A196");
+ bindingNames.insert(INTERFACEKEY_STRING_A197, "STRING_A197");
+ bindingNames.insert(INTERFACEKEY_STRING_A198, "STRING_A198");
+ bindingNames.insert(INTERFACEKEY_STRING_A199, "STRING_A199");
+ bindingNames.insert(INTERFACEKEY_STRING_A200, "STRING_A200");
+ bindingNames.insert(INTERFACEKEY_STRING_A201, "STRING_A201");
+ bindingNames.insert(INTERFACEKEY_STRING_A202, "STRING_A202");
+ bindingNames.insert(INTERFACEKEY_STRING_A203, "STRING_A203");
+ bindingNames.insert(INTERFACEKEY_STRING_A204, "STRING_A204");
+ bindingNames.insert(INTERFACEKEY_STRING_A205, "STRING_A205");
+ bindingNames.insert(INTERFACEKEY_STRING_A206, "STRING_A206");
+ bindingNames.insert(INTERFACEKEY_STRING_A207, "STRING_A207");
+ bindingNames.insert(INTERFACEKEY_STRING_A208, "STRING_A208");
+ bindingNames.insert(INTERFACEKEY_STRING_A209, "STRING_A209");
+ bindingNames.insert(INTERFACEKEY_STRING_A210, "STRING_A210");
+ bindingNames.insert(INTERFACEKEY_STRING_A211, "STRING_A211");
+ bindingNames.insert(INTERFACEKEY_STRING_A212, "STRING_A212");
+ bindingNames.insert(INTERFACEKEY_STRING_A213, "STRING_A213");
+ bindingNames.insert(INTERFACEKEY_STRING_A214, "STRING_A214");
+ bindingNames.insert(INTERFACEKEY_STRING_A215, "STRING_A215");
+ bindingNames.insert(INTERFACEKEY_STRING_A216, "STRING_A216");
+ bindingNames.insert(INTERFACEKEY_STRING_A217, "STRING_A217");
+ bindingNames.insert(INTERFACEKEY_STRING_A218, "STRING_A218");
+ bindingNames.insert(INTERFACEKEY_STRING_A219, "STRING_A219");
+ bindingNames.insert(INTERFACEKEY_STRING_A220, "STRING_A220");
+ bindingNames.insert(INTERFACEKEY_STRING_A221, "STRING_A221");
+ bindingNames.insert(INTERFACEKEY_STRING_A222, "STRING_A222");
+ bindingNames.insert(INTERFACEKEY_STRING_A223, "STRING_A223");
+ bindingNames.insert(INTERFACEKEY_STRING_A224, "STRING_A224");
+ bindingNames.insert(INTERFACEKEY_STRING_A225, "STRING_A225");
+ bindingNames.insert(INTERFACEKEY_STRING_A226, "STRING_A226");
+ bindingNames.insert(INTERFACEKEY_STRING_A227, "STRING_A227");
+ bindingNames.insert(INTERFACEKEY_STRING_A228, "STRING_A228");
+ bindingNames.insert(INTERFACEKEY_STRING_A229, "STRING_A229");
+ bindingNames.insert(INTERFACEKEY_STRING_A230, "STRING_A230");
+ bindingNames.insert(INTERFACEKEY_STRING_A231, "STRING_A231");
+ bindingNames.insert(INTERFACEKEY_STRING_A232, "STRING_A232");
+ bindingNames.insert(INTERFACEKEY_STRING_A233, "STRING_A233");
+ bindingNames.insert(INTERFACEKEY_STRING_A234, "STRING_A234");
+ bindingNames.insert(INTERFACEKEY_STRING_A235, "STRING_A235");
+ bindingNames.insert(INTERFACEKEY_STRING_A236, "STRING_A236");
+ bindingNames.insert(INTERFACEKEY_STRING_A237, "STRING_A237");
+ bindingNames.insert(INTERFACEKEY_STRING_A238, "STRING_A238");
+ bindingNames.insert(INTERFACEKEY_STRING_A239, "STRING_A239");
+ bindingNames.insert(INTERFACEKEY_STRING_A240, "STRING_A240");
+ bindingNames.insert(INTERFACEKEY_STRING_A241, "STRING_A241");
+ bindingNames.insert(INTERFACEKEY_STRING_A242, "STRING_A242");
+ bindingNames.insert(INTERFACEKEY_STRING_A243, "STRING_A243");
+ bindingNames.insert(INTERFACEKEY_STRING_A244, "STRING_A244");
+ bindingNames.insert(INTERFACEKEY_STRING_A245, "STRING_A245");
+ bindingNames.insert(INTERFACEKEY_STRING_A246, "STRING_A246");
+ bindingNames.insert(INTERFACEKEY_STRING_A247, "STRING_A247");
+ bindingNames.insert(INTERFACEKEY_STRING_A248, "STRING_A248");
+ bindingNames.insert(INTERFACEKEY_STRING_A249, "STRING_A249");
+ bindingNames.insert(INTERFACEKEY_STRING_A250, "STRING_A250");
+ bindingNames.insert(INTERFACEKEY_STRING_A251, "STRING_A251");
+ bindingNames.insert(INTERFACEKEY_STRING_A252, "STRING_A252");
+ bindingNames.insert(INTERFACEKEY_STRING_A253, "STRING_A253");
+ bindingNames.insert(INTERFACEKEY_STRING_A254, "STRING_A254");
+ bindingNames.insert(INTERFACEKEY_STRING_A255, "STRING_A255");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_A, "CUSTOM_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_B, "CUSTOM_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_C, "CUSTOM_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_D, "CUSTOM_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_E, "CUSTOM_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_F, "CUSTOM_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_G, "CUSTOM_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_H, "CUSTOM_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_I, "CUSTOM_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_J, "CUSTOM_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_K, "CUSTOM_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_L, "CUSTOM_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_M, "CUSTOM_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_N, "CUSTOM_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_O, "CUSTOM_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_P, "CUSTOM_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_Q, "CUSTOM_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_R, "CUSTOM_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_S, "CUSTOM_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_T, "CUSTOM_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_U, "CUSTOM_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_V, "CUSTOM_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_W, "CUSTOM_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_X, "CUSTOM_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_Y, "CUSTOM_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_Z, "CUSTOM_Z");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_A, "CUSTOM_SHIFT_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_B, "CUSTOM_SHIFT_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_C, "CUSTOM_SHIFT_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_D, "CUSTOM_SHIFT_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_E, "CUSTOM_SHIFT_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_F, "CUSTOM_SHIFT_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_G, "CUSTOM_SHIFT_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_H, "CUSTOM_SHIFT_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_I, "CUSTOM_SHIFT_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_J, "CUSTOM_SHIFT_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_K, "CUSTOM_SHIFT_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_L, "CUSTOM_SHIFT_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_M, "CUSTOM_SHIFT_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_N, "CUSTOM_SHIFT_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_O, "CUSTOM_SHIFT_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_P, "CUSTOM_SHIFT_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Q, "CUSTOM_SHIFT_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_R, "CUSTOM_SHIFT_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_S, "CUSTOM_SHIFT_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_T, "CUSTOM_SHIFT_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_U, "CUSTOM_SHIFT_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_V, "CUSTOM_SHIFT_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_W, "CUSTOM_SHIFT_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_X, "CUSTOM_SHIFT_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Y, "CUSTOM_SHIFT_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Z, "CUSTOM_SHIFT_Z");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_A, "CUSTOM_CTRL_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_B, "CUSTOM_CTRL_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_C, "CUSTOM_CTRL_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_D, "CUSTOM_CTRL_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_E, "CUSTOM_CTRL_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_F, "CUSTOM_CTRL_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_G, "CUSTOM_CTRL_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_H, "CUSTOM_CTRL_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_I, "CUSTOM_CTRL_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_J, "CUSTOM_CTRL_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_K, "CUSTOM_CTRL_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_L, "CUSTOM_CTRL_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_M, "CUSTOM_CTRL_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_N, "CUSTOM_CTRL_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_O, "CUSTOM_CTRL_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_P, "CUSTOM_CTRL_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_Q, "CUSTOM_CTRL_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_R, "CUSTOM_CTRL_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_S, "CUSTOM_CTRL_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_T, "CUSTOM_CTRL_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_U, "CUSTOM_CTRL_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_V, "CUSTOM_CTRL_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_W, "CUSTOM_CTRL_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_X, "CUSTOM_CTRL_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_Y, "CUSTOM_CTRL_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_CTRL_Z, "CUSTOM_CTRL_Z");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_A, "CUSTOM_ALT_A");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_B, "CUSTOM_ALT_B");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_C, "CUSTOM_ALT_C");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_D, "CUSTOM_ALT_D");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_E, "CUSTOM_ALT_E");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_F, "CUSTOM_ALT_F");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_G, "CUSTOM_ALT_G");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_H, "CUSTOM_ALT_H");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_I, "CUSTOM_ALT_I");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_J, "CUSTOM_ALT_J");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_K, "CUSTOM_ALT_K");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_L, "CUSTOM_ALT_L");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_M, "CUSTOM_ALT_M");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_N, "CUSTOM_ALT_N");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_O, "CUSTOM_ALT_O");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_P, "CUSTOM_ALT_P");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_Q, "CUSTOM_ALT_Q");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_R, "CUSTOM_ALT_R");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_S, "CUSTOM_ALT_S");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_T, "CUSTOM_ALT_T");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_U, "CUSTOM_ALT_U");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_V, "CUSTOM_ALT_V");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_W, "CUSTOM_ALT_W");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_X, "CUSTOM_ALT_X");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_Y, "CUSTOM_ALT_Y");
+ bindingNames.insert(INTERFACEKEY_CUSTOM_ALT_Z, "CUSTOM_ALT_Z");
+ bindingNames.insert(INTERFACEKEY_FPS_UP, "FPS_UP");
+ bindingNames.insert(INTERFACEKEY_FPS_DOWN, "FPS_DOWN");
+ bindingNames.insert(INTERFACEKEY_TOGGLE_TTF, "TOGGLE_TTF");
+ bindingNames.insert(INTERFACEKEY_PREFIX, "PREFIX");
+
+
+ displayNames.insert(INTERFACEKEY_NONE, "None");
+ displayNames.insert(INTERFACEKEY_SELECT, "Select");
+ displayNames.insert(INTERFACEKEY_SEC_SELECT, "Secondary Select");
+ displayNames.insert(INTERFACEKEY_DESELECT, "Deselect");
+ displayNames.insert(INTERFACEKEY_SELECT_ALL, "Select all");
+ displayNames.insert(INTERFACEKEY_DESELECT_ALL, "Deselect All");
+ displayNames.insert(INTERFACEKEY_LEAVESCREEN, "Leave screen");
+ displayNames.insert(INTERFACEKEY_LEAVESCREEN_ALL, "Leave all screens");
+ displayNames.insert(INTERFACEKEY_CLOSE_MEGA_ANNOUNCEMENT, "Close mega announcement");
+ displayNames.insert(INTERFACEKEY_TOGGLE_FULLSCREEN, "Toggle Fullscreen");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_ADD, "World Param: Add");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_COPY, "World Param: Copy");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DELETE, "World Param: Delete");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_TITLE, "World Param: Title");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_RANDOM, "World Param: Name, Random");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_NAME_ENTER, "World Param: Name, Enter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_RANDOM, "World Param: Seed, Random");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SEED_ENTER, "World Param: Seed, Enter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_LOAD, "World Param: Load");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SAVE, "World Param: Save");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_UP, "World Param: Dim X, Up");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_X_DOWN, "World Param: Dim X, Down");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_UP, "World Param: Dim Y, Up");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DIM_Y_DOWN, "World Param: Dim Y, Down");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_SET, "World Param: Enter Advanced Parameters");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_INCREASE, "World Param: Increase Parameter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_DECREASE, "World Param: Decrease Parameter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_ENTER_VALUE, "World Param: Enter Value");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_NULLIFY, "World Param: Nullify Parameter");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_PRESET, "World Param: Set Presets");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_CONTINUE, "World Param: Reject, Continue");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ABORT, "World Param: Reject, Abort");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_THIS, "World Param: Reject, Allow This");
+ displayNames.insert(INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_ALL, "World Param: Reject, Allow All");
+ displayNames.insert(INTERFACEKEY_WORLD_GEN_CONTINUE, "World Generation: Continue");
+ displayNames.insert(INTERFACEKEY_WORLD_GEN_USE, "World Generation: Use");
+ displayNames.insert(INTERFACEKEY_WORLD_GEN_ABORT, "World Generation: Abort");
+ displayNames.insert(INTERFACEKEY_SETUP_EMBARK, "Setup game: Embark");
+ displayNames.insert(INTERFACEKEY_SETUP_NAME_FORT, "Setup game: Name Fort");
+ displayNames.insert(INTERFACEKEY_SETUP_NAME_GROUP, "Setup game: Name Group");
+ displayNames.insert(INTERFACEKEY_SETUP_RECLAIM, "Setup game: Reclaim");
+ displayNames.insert(INTERFACEKEY_SETUP_FIND, "Setup game: Find");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES, "Setup game: Notes");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_TAKE_NOTES, "Setup game: Notes, New Note");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_DELETE_NOTE, "Setup game: Notes, Delete Note");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_CHANGE_SYMBOL_SELECTION, "Setup game: Notes, Change Symbol Selection");
+ displayNames.insert(INTERFACEKEY_SETUP_NOTES_ADOPT_SYMBOL, "Setup game: Notes, Adopt Symbol");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_UP, "Setup game: Resize Local Y Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_DOWN, "Setup game: Resize Local Y Down");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_UP, "Setup game: Resize Local X Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_DOWN, "Setup game: Resize Local X Down");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MUP, "Setup game: Move Local Y Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_Y_MDOWN, "Setup game: Move Local Y Down");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MUP, "Setup game: Move Local X Up");
+ displayNames.insert(INTERFACEKEY_SETUP_LOCAL_X_MDOWN, "Setup game: Move Local X Down");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_1, "Setup game: View Biome 1");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_2, "Setup game: View Biome 2");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_3, "Setup game: View Biome 3");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_4, "Setup game: View Biome 4");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_5, "Setup game: View Biome 5");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_6, "Setup game: View Biome 6");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_7, "Setup game: View Biome 7");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_8, "Setup game: View Biome 8");
+ displayNames.insert(INTERFACEKEY_SETUP_BIOME_9, "Setup game: View Biome 9");
+ displayNames.insert(INTERFACEKEY_CHOOSE_NAME_RANDOM, "Choose name: Random");
+ displayNames.insert(INTERFACEKEY_CHOOSE_NAME_CLEAR, "Choose name: Clear");
+ displayNames.insert(INTERFACEKEY_CHOOSE_NAME_TYPE, "Choose name: Type");
+ displayNames.insert(INTERFACEKEY_ITEM_DESCRIPTION, "View item: Description");
+ displayNames.insert(INTERFACEKEY_ITEM_FORBID, "View item: Forbid");
+ displayNames.insert(INTERFACEKEY_ITEM_MELT, "View item: Melt");
+ displayNames.insert(INTERFACEKEY_ITEM_DUMP, "View item: Dump");
+ displayNames.insert(INTERFACEKEY_ITEM_HIDE, "View item: Hide");
+ displayNames.insert(INTERFACEKEY_OPTIONS, "Main menu");
+ displayNames.insert(INTERFACEKEY_OPTION_EXPORT, "Options, Export Local Image");
+ displayNames.insert(INTERFACEKEY_HELP, "Help");
+ displayNames.insert(INTERFACEKEY_MOVIES, "Movies");
+ displayNames.insert(INTERFACEKEY_CHANGETAB, "Change tab or highlight selection");
+ displayNames.insert(INTERFACEKEY_SEC_CHANGETAB, "Change tab or highlight selection, secondary");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_UP, "Move selector up");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_DOWN, "Move selector down");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_LEFT, "Move selector left");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_RIGHT, "Move selector right");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEUP, "Page selector up");
+ displayNames.insert(INTERFACEKEY_STANDARDSCROLL_PAGEDOWN, "Page selector down");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_UP, "Move secondary selector up");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_DOWN, "Move secondary selector down");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEUP, "Page secondary selector up");
+ displayNames.insert(INTERFACEKEY_SECONDSCROLL_PAGEDOWN, "Page secondary selector down");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP, "Move view/cursor up");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN, "Move view/cursor down");
+ displayNames.insert(INTERFACEKEY_CURSOR_LEFT, "Move view/cursor left");
+ displayNames.insert(INTERFACEKEY_CURSOR_RIGHT, "Move view/cursor right");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPLEFT, "Move view/cursor up and left");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPRIGHT, "Move view/cursor up and right");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT, "Move view/cursor down and left");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT, "Move view/cursor down and right");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP_FAST, "Move view/cursor up, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN_FAST, "Move view/cursor down, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_LEFT_FAST, "Move view/cursor left, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_RIGHT_FAST, "Move view/cursor right, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPLEFT_FAST, "Move view/cursor up and left, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_UPRIGHT_FAST, "Move view/cursor up and right, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNLEFT_FAST, "Move view/cursor down and left, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWNRIGHT_FAST, "Move view/cursor down and right, fast");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP_Z, "Move view/cursor up (z)");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN_Z, "Move view/cursor down (z)");
+ displayNames.insert(INTERFACEKEY_CURSOR_UP_Z_AUX, "Move view/cursor up (z), aux");
+ displayNames.insert(INTERFACEKEY_CURSOR_DOWN_Z_AUX, "Move view/cursor down (z), aux");
+ displayNames.insert(INTERFACEKEY_A_RETURN_TO_ARENA, "Adventure: return to arena");
+ displayNames.insert(INTERFACEKEY_A_MOVE_N, "Adventure: move north");
+ displayNames.insert(INTERFACEKEY_A_MOVE_S, "Adventure: move south");
+ displayNames.insert(INTERFACEKEY_A_MOVE_E, "Adventure: move east");
+ displayNames.insert(INTERFACEKEY_A_MOVE_W, "Adventure: move west");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NW, "Adventure: move northwest");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NE, "Adventure: move northeast");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SW, "Adventure: move southwest");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SE, "Adventure: move southeast");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SAME_SQUARE, "Adventure: move same square");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_N, "Adventure: careful move north up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_S, "Adventure: careful move south up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_E, "Adventure: careful move east up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_W, "Adventure: careful move west up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_NW, "Adventure: careful move northwest up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_NE, "Adventure: careful move northeast up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_SW, "Adventure: careful move southwest up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_SE, "Adventure: careful move southeast up/down");
+ displayNames.insert(INTERFACEKEY_A_CARE_MOVE_UPDOWN, "Adventure: careful move up/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_N_UP, "Adventure: move north/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_S_UP, "Adventure: move south/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_E_UP, "Adventure: move east/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_W_UP, "Adventure: move west/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NW_UP, "Adventure: move northwest/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NE_UP, "Adventure: move northeast/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SW_UP, "Adventure: move southwest/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SE_UP, "Adventure: move southeast/up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_UP, "Adventure: move up");
+ displayNames.insert(INTERFACEKEY_A_MOVE_N_DOWN, "Adventure: move north/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_S_DOWN, "Adventure: move south/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_E_DOWN, "Adventure: move east/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_W_DOWN, "Adventure: move west/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NW_DOWN, "Adventure: move northwest/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_NE_DOWN, "Adventure: move northeast/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SW_DOWN, "Adventure: move southwest/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_SE_DOWN, "Adventure: move southeast/down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_DOWN, "Adventure: move down");
+ displayNames.insert(INTERFACEKEY_A_MOVE_UP_AUX, "Adventure: move up, aux");
+ displayNames.insert(INTERFACEKEY_A_MOVE_DOWN_AUX, "Adventure: move down, aux");
+ displayNames.insert(INTERFACEKEY_WORLDGEN_EXPORT_MAP, "World Gen: Export Map");
+ displayNames.insert(INTERFACEKEY_LEGENDS_EXPORT_MAP, "Legends: Export Map");
+ displayNames.insert(INTERFACEKEY_LEGENDS_EXPORT_XML, "Legends: Export XML");
+ displayNames.insert(INTERFACEKEY_LEGENDS_EXPORT_DETAILED_MAP, "Legends: Export Detailed Map");
+ displayNames.insert(INTERFACEKEY_LEGENDS_TOGGLE_CIVSITE, "Legends: Civ/Site");
+ displayNames.insert(INTERFACEKEY_LEGENDS_STRING_FILTER, "Legends: String filter");
+ displayNames.insert(INTERFACEKEY_A_COMBAT_ATTACK, "Adventure: Combat, Attack Mode");
+ displayNames.insert(INTERFACEKEY_A_COMBAT_DODGE, "Adventure: Combat, Dodge Mode");
+ displayNames.insert(INTERFACEKEY_A_COMBAT_CHARGEDEF, "Adventure: Combat, Charge Defend Mode");
+ displayNames.insert(INTERFACEKEY_A_STATUS, "Adventure: Status");
+ displayNames.insert(INTERFACEKEY_A_STATUS_WRESTLE, "Adventure: Status, Close Combat");
+ displayNames.insert(INTERFACEKEY_A_STATUS_CUSTOMIZE, "Adventure: Status, Customize");
+ displayNames.insert(INTERFACEKEY_A_STATUS_KILLS, "Adventure: Status, Kills");
+ displayNames.insert(INTERFACEKEY_A_STATUS_HEALTH, "Adventure: Status, Health");
+ displayNames.insert(INTERFACEKEY_A_STATUS_ATT_SKILL, "Adventure: Status, Att/Skills");
+ displayNames.insert(INTERFACEKEY_A_STATUS_DESC, "Adventure: Status, Desc");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_CUSTOMIZE, "Unit View, Customize");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_HEALTH, "Unit View, Health");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS, "Unit View, Relationships");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_ZOOM, "Unit View, Relationships, Zoom");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_RELATIONSHIPS_VIEW, "Unit View, Relationships, View");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_KILLS, "Unit View, Kills");
+ displayNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_NICKNAME, "Customize Unit, Nickname");
+ displayNames.insert(INTERFACEKEY_CUSTOMIZE_UNIT_PROFNAME, "Customize Unit, Profession");
+ displayNames.insert(INTERFACEKEY_A_CLEAR_ANNOUNCEMENTS, "Adventure: Clear announcements");
+ displayNames.insert(INTERFACEKEY_A_SLEEP, "Adventure: Sleep");
+ displayNames.insert(INTERFACEKEY_A_SLEEP_SLEEP, "Adventure: Sleep, Sleep");
+ displayNames.insert(INTERFACEKEY_A_SLEEP_WAIT, "Adventure: Sleep, Wait");
+ displayNames.insert(INTERFACEKEY_A_SLEEP_DAWN, "Adventure: Sleep, Dawn");
+ displayNames.insert(INTERFACEKEY_A_WAIT, "Adventure: Wait Ten Instants");
+ displayNames.insert(INTERFACEKEY_A_SHORT_WAIT, "Adventure: Wait One Instant");
+ displayNames.insert(INTERFACEKEY_A_ATTACK, "Adventure: Attack");
+ displayNames.insert(INTERFACEKEY_A_ATTACK_CONFIRM, "Adventure: Attack, Confirm");
+ displayNames.insert(INTERFACEKEY_QUICK_ATTACK, "Adventure: Attack, Quick");
+ displayNames.insert(INTERFACEKEY_HEAVY_ATTACK, "Adventure: Attack, Heavy");
+ displayNames.insert(INTERFACEKEY_WILD_ATTACK, "Adventure: Attack, Wild");
+ displayNames.insert(INTERFACEKEY_PRECISE_ATTACK, "Adventure: Attack, Precise");
+ displayNames.insert(INTERFACEKEY_CHARGE_ATTACK, "Adventure: Attack, Charge");
+ displayNames.insert(INTERFACEKEY_MULTI_ATTACK, "Adventure: Attack, Multi");
+ displayNames.insert(INTERFACEKEY_A_LOOK, "Adventure: Look");
+ displayNames.insert(INTERFACEKEY_A_SEARCH, "Adventure: Search");
+ displayNames.insert(INTERFACEKEY_A_ODOR,"Adventure: Describe Odor");
+ displayNames.insert(INTERFACEKEY_A_DISPLAY_ODOR,"Adventure: Display Strongest Odor");
+ displayNames.insert(INTERFACEKEY_A_YIELD,"Adventure: Yield");
+ displayNames.insert(INTERFACEKEY_A_DISPLAY_TRACKS,"Adventure: Display Tracks");
+ displayNames.insert(INTERFACEKEY_A_FRESHEST_TRACK,"Adventure: Freshest Track");
+ displayNames.insert(INTERFACEKEY_A_INV_DRAW_WEAPON,"Adventure: Inv. Draw Weapon");
+ displayNames.insert(INTERFACEKEY_A_JUMP,"Adventure: Jump");
+ displayNames.insert(INTERFACEKEY_A_HOLD,"Adventure: Hold/Hang (Climb)");
+ displayNames.insert(INTERFACEKEY_A_TALK, "Adventure: Talk");
+ displayNames.insert(INTERFACEKEY_A_INTERACT, "Adventure: Inv. Interact");
+ displayNames.insert(INTERFACEKEY_A_ACTION, "Adventure: Misc. Action");
+ displayNames.insert(INTERFACEKEY_A_ACTION_CREATE, "Adventure: Misc. Action, Create");
+ displayNames.insert(INTERFACEKEY_A_ACTION_BUTCHER, "Adventure: Misc. Action, Butcher");
+ displayNames.insert(INTERFACEKEY_A_ACTION_ABILITY, "Adventure: Misc. Action, Ability");
+ displayNames.insert(INTERFACEKEY_A_ACTION_POWER, "Adventure: Misc. Action, Power");
+ displayNames.insert(INTERFACEKEY_A_INV_LOOK, "Adventure: Inv. Look");
+ displayNames.insert(INTERFACEKEY_A_INV_REMOVE, "Adventure: Inv. Remove");
+ displayNames.insert(INTERFACEKEY_A_INV_WEAR, "Adventure: Inv. Wear");
+ displayNames.insert(INTERFACEKEY_A_INV_EATDRINK, "Adventure: Inv. Eat/Drink");
+ displayNames.insert(INTERFACEKEY_A_INV_PUTIN, "Adventure: Inv. Put In");
+ displayNames.insert(INTERFACEKEY_A_INV_DROP, "Adventure: Inv. Drop");
+ displayNames.insert(INTERFACEKEY_A_GROUND, "Adventure: Get/Ground");
+ displayNames.insert(INTERFACEKEY_A_THROW, "Adventure: Throw");
+ displayNames.insert(INTERFACEKEY_A_SHOOT, "Adventure: Fire");
+ displayNames.insert(INTERFACEKEY_A_ANNOUNCEMENTS, "Adventure: Announcements");
+ displayNames.insert(INTERFACEKEY_A_COMBAT, "Adventure: Combat Options");
+ displayNames.insert(INTERFACEKEY_A_MOVEMENT, "Adventure: Movement Options");
+ displayNames.insert(INTERFACEKEY_A_MOVEMENT_SWIM, "Adventure: Movement Options, Swim");
+ displayNames.insert(INTERFACEKEY_A_SNEAK, "Adventure: Sneak");
+ displayNames.insert(INTERFACEKEY_A_SPEED_SNEAK, "Adventure: Speed and Sneaking Options");
+ displayNames.insert(INTERFACEKEY_A_CENTER, "Adventure: Center");
+ displayNames.insert(INTERFACEKEY_A_COMPANIONS, "Adventure: Companions");
+ displayNames.insert(INTERFACEKEY_A_BUILDING, "Adventure: Building Interact");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL, "Adventure: Travel");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_SLEEP, "Adventure: Travel, Sleep");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_MAP, "Adventure: Travel, Map");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_HIDE_INSTRUCTIONS, "Adventure: Travel, Hide Instructions");
+ displayNames.insert(INTERFACEKEY_A_DATE, "Adventure: Get Date");
+ displayNames.insert(INTERFACEKEY_A_WEATHER, "Adventure: Get Weather");
+ displayNames.insert(INTERFACEKEY_A_TEMPERATURE, "Adventure: Get Temperature");
+ displayNames.insert(INTERFACEKEY_A_STANCE, "Adventure: Change Stance");
+ displayNames.insert(INTERFACEKEY_OPTION1, "Option 1");
+ displayNames.insert(INTERFACEKEY_OPTION2, "Option 2");
+ displayNames.insert(INTERFACEKEY_OPTION3, "Option 3");
+ displayNames.insert(INTERFACEKEY_OPTION4, "Option 4");
+ displayNames.insert(INTERFACEKEY_OPTION5, "Option 5");
+ displayNames.insert(INTERFACEKEY_OPTION6, "Option 6");
+ displayNames.insert(INTERFACEKEY_OPTION7, "Option 7");
+ displayNames.insert(INTERFACEKEY_OPTION8, "Option 8");
+ displayNames.insert(INTERFACEKEY_OPTION9, "Option 9");
+ displayNames.insert(INTERFACEKEY_OPTION10, "Option 10");
+ displayNames.insert(INTERFACEKEY_OPTION11, "Option 11");
+ displayNames.insert(INTERFACEKEY_OPTION12, "Option 12");
+ displayNames.insert(INTERFACEKEY_OPTION13, "Option 13");
+ displayNames.insert(INTERFACEKEY_OPTION14, "Option 14");
+ displayNames.insert(INTERFACEKEY_OPTION15, "Option 15");
+ displayNames.insert(INTERFACEKEY_OPTION16, "Option 16");
+ displayNames.insert(INTERFACEKEY_OPTION17, "Option 17");
+ displayNames.insert(INTERFACEKEY_OPTION18, "Option 18");
+ displayNames.insert(INTERFACEKEY_OPTION19, "Option 19");
+ displayNames.insert(INTERFACEKEY_OPTION20, "Option 20");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION1, "Secondary Option 1");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION2, "Secondary Option 2");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION3, "Secondary Option 3");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION4, "Secondary Option 4");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION5, "Secondary Option 5");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION6, "Secondary Option 6");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION7, "Secondary Option 7");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION8, "Secondary Option 8");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION9, "Secondary Option 9");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION10, "Secondary Option 10");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION11, "Secondary Option 11");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION12, "Secondary Option 12");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION13, "Secondary Option 13");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION14, "Secondary Option 14");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION15, "Secondary Option 15");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION16, "Secondary Option 16");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION17, "Secondary Option 17");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION18, "Secondary Option 18");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION19, "Secondary Option 19");
+ displayNames.insert(INTERFACEKEY_SEC_OPTION20, "Secondary Option 20");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MAKE_ASH, "Hotkey: Make Ash");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MAKE_CHARCOAL, "Hotkey: Make Charcoal");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MELT_OBJECT, "Hotkey: Melt Object");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_GREEN, "Hotkey: Green Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CLEAR, "Hotkey: Clear Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CRYSTAL, "Hotkey: Crystal Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_COLLECT_SAND, "Hotkey: Collect Sand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_COLLECT_CLAY, "Hotkey: Collect Clay");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_ROUGH, "Hotkey: Raw Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_ARMORSTAND, "Hotkey: Glass Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_BOX, "Hotkey: Glass Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CABINET, "Hotkey: Glass Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_COFFIN, "Hotkey: Glass Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLOODGATE, "Hotkey: Glass Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_HATCH_COVER, "Hotkey: Glass Hatch Cover");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_GRATE, "Hotkey: Glass Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_GOBLET, "Hotkey: Glass Goblet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_TOY, "Hotkey: Glass Toy");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_INSTRUMENT, "Hotkey: Glass Instrument");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_DOOR, "Hotkey: Glass Portal");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_STATUE, "Hotkey: Glass Statue");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_TABLE, "Hotkey: Glass Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CAGE, "Hotkey: Glass Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_CHAIR, "Hotkey: Glass Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_BLOCKS, "Hotkey: Glass Blocks");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_FLASK, "Hotkey: Glass Vial");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_WEAPONRACK, "Hotkey: Glass Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_GLASS_WINDOW, "Hotkey: Glass Window");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ASHERY_LYE, "Hotkey: Ashery, Lye");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH, "Hotkey: Ashery, Potash (Lye)");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ASHERY_POTASH_DIRECT, "Hotkey: Ashery, Potash (Ash)");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BARREL, "Hotkey: Carpenter, Barrel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BLOCKS, "Hotkey: Carpenter, Blocks");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BUCKET, "Hotkey: Carpenter, Bucket");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TRAP_ANIMAL, "Hotkey: Carpenter, Animal Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CAGE, "Hotkey: Carpenter, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_ARMORSTAND, "Hotkey: Carpenter, Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BED, "Hotkey: Carpenter, Bed");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CHAIR, "Hotkey: Carpenter, Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_COFFIN, "Hotkey: Carpenter, Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_DOOR, "Hotkey: Carpenter, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_FLOODGATE, "Hotkey: Carpenter, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_HATCH_COVER, "Hotkey: Carpenter, Hatch Cover");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_GRATE, "Hotkey: Carpenter, Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_CABINET, "Hotkey: Carpenter, Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BIN, "Hotkey: Carpenter, Bin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_BOX, "Hotkey: Carpenter, Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_WEAPONRACK, "Hotkey: Carpenter, Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CARPENTER_TABLE, "Hotkey: Carpenter, Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SIEGE_BALLISTA, "Hotkey: Siege Shop, Ballista");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SIEGE_CATAPULT, "Hotkey: Siege Shop, Catapult");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BOX, "Hotkey: Leather, Bag");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_FLASK, "Hotkey: Leather, Flask");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_SHIRT, "Hotkey: Leather, Shirt");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_CLOAK, "Hotkey: Leather, Cloak");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_BACKPACK, "Hotkey: Leather, Backpack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_QUIVER, "Hotkey: Leather, Quiver");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LEATHER_IMAGE, "Hotkey: Leather, Image");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_PLANT, "Hotkey: Clothes, Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_SILK, "Hotkey: Clothes, Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_MAT_YARN, "Hotkey: Clothes, Yarn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_SHIRT, "Hotkey: Clothes, Shirt");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CLOAK, "Hotkey: Clothes, Cloak");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_BOX, "Hotkey: Clothes, Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_CHAIN, "Hotkey: Clothes, Rope");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CLOTHES_IMAGE, "Hotkey: Clothes, Image");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_STONE, "Hotkey: Crafts, Mat Stone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_WOOD, "Hotkey: Crafts, Mat Wood");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_BONE, "Hotkey: Crafts, Dec Bone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_SHELL, "Hotkey: Crafts, Dec Shell");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_TOOTH, "Hotkey: Crafts, Dec Tooth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_HORN, "Hotkey: Crafts, Dec Horn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_DEC_PEARL, "Hotkey: Crafts, Dec Pearl");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOTEM, "Hotkey: Crafts, Totem");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_CLOTH, "Hotkey: Crafts, Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SILK, "Hotkey: Crafts, Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_YARN, "Hotkey: Crafts, Yarn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_WOOD, "Hotkey: Crafts, Wood Material");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_BONE, "Hotkey: Crafts, Bone Material");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SEL_SHELL, "Hotkey: Crafts, Shell Material");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SHELL, "Hotkey: Crafts, Shell");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_TOOTH, "Hotkey: Crafts, Tooth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_HORN, "Hotkey: Crafts, Horn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_PEARL, "Hotkey: Crafts, Pearl");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_BONE, "Hotkey: Crafts, Bone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_LEATHER, "Hotkey: Crafts, Leather");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_SLAB, "Hotkey: Crafts, Slab");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_CRAFTS, "Hotkey: Crafts, Mat Crafts");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_GOBLET, "Hotkey: Crafts, Mat Goblet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_INSTRUMENT, "Hotkey: Crafts, Mat Instrument");
+ displayNames.insert(INTERFACEKEY_HOTKEY_CRAFTS_MAT_TOY, "Hotkey: Crafts, Mat Toy");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_WEAPON, "Hotkey: Forge, Weapon");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_ARMOR, "Hotkey: Forge, Armor");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_FURNITURE, "Hotkey: Forge, Furniture");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_SIEGE, "Hotkey: Forge, Siege");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_TRAP, "Hotkey: Forge, Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_OTHER, "Hotkey: Forge, Other");
+ displayNames.insert(INTERFACEKEY_HOTKEY_SMITH_METAL, "Hotkey: Forge, Metal Clothing");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARMORSTAND, "Hotkey: Building, Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BED, "Hotkey: Building, Bed");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRACTION_BENCH, "Hotkey: Building, Traction Bench");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SLAB, "Hotkey: Building, Slab");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_NEST_BOX, "Hotkey: Building, Nest Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HIVE, "Hotkey: Building, Hive");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIR, "Hotkey: Building, Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_COFFIN, "Hotkey: Building, Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_DOOR, "Hotkey: Building, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FLOODGATE, "Hotkey: Building, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_HATCH, "Hotkey: Building, Hatch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_WALL, "Hotkey: Building, Wall Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_GRATE_FLOOR, "Hotkey: Building, Floor Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_VERTICAL, "Hotkey: Building, Vertical Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BARS_FLOOR, "Hotkey: Building, Floor Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CABINET, "Hotkey: Building, Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BOX, "Hotkey: Building, Chest");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_KENNEL, "Hotkey: Building, Kennel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FARMPLOT, "Hotkey: Building, Farm Plot");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WEAPONRACK, "Hotkey: Building, Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_STATUE, "Hotkey: Building, Statue");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TABLE, "Hotkey: Building, Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_DIRT, "Hotkey: Building, Dirt Road");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ROAD_PAVED, "Hotkey: Building, Paved Road");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_BRIDGE, "Hotkey: Building, Bridge");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WELL, "Hotkey: Building, Well");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE, "Hotkey: Building, Siege");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP, "Hotkey: Building, Workshop");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE, "Hotkey: Building, Furnace");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GLASS, "Hotkey: Building, Glass Window");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GEM, "Hotkey: Building, Gem Window");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SHOP, "Hotkey: Building, Shop");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ANIMALTRAP, "Hotkey: Building, Animal Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CHAIN, "Hotkey: Building, Chain");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CAGE, "Hotkey: Building, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRADEDEPOT, "Hotkey: Building, Trade Depot");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP, "Hotkey: Building, Trap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE, "Hotkey: Building, Machine Component");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SUPPORT, "Hotkey: Building, Support");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_ARCHERYTARGET, "Hotkey: Building, Archery Target");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_SCREW_PUMP, "Hotkey: Building, Machine Component, Screw Pump");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WATER_WHEEL, "Hotkey: Building, Machine Component, Water Wheel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WINDMILL, "Hotkey: Building, Machine Component, Windmill");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY, "Hotkey: Building, Machine Component, Gear Assembly");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL, "Hotkey: Building, Machine Component, Horizontal Axle");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL, "Hotkey: Building, Machine Component, Vertical Axle");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_MACHINE_ROLLERS, "Hotkey: Building, Machine Component, Rollers");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_BALLISTA, "Hotkey: Building, Siege, Ballista");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_CATAPULT, "Hotkey: Building, Siege, Catapult");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_STONE, "Hotkey: Building, Trap, Stone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_WEAPON, "Hotkey: Building, Trap, Weapon");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_LEVER, "Hotkey: Building, Trap, Lever");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_TRIGGER, "Hotkey: Building, Trap, Trigger");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_CAGE, "Hotkey: Building, Trap, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_TRAP_SPIKE, "Hotkey: Building, Trap, Upright Spear/Spike");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION, "Hotkey: Building, Wall/Floor/Stairs");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION, "Hotkey: Building, Construction, Fortification");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_WALL, "Hotkey: Building, Construction, Wall");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FLOOR, "Hotkey: Building, Construction, Floor");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_RAMP, "Hotkey: Building, Construction, Ramp");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP, "Hotkey: Building, Construction, Upward Stair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN, "Hotkey: Building, Construction, Downward Stair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN, "Hotkey: Building, Construction, Up/Down Stair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK, "Hotkey: Building, Construction, Track");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP, "Hotkey: Building, Construction, Track Stop");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LEATHER, "Hotkey: Building, Wksp, Leather");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_QUERN, "Hotkey: Building, Wksp, Quern");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MILLSTONE, "Hotkey: Building, Wksp, Millstone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LOOM, "Hotkey: Building, Wksp, Loom");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CLOTHES, "Hotkey: Building, Wksp, Clothes");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BOWYER, "Hotkey: Building, Wksp, Bowyer");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CARPENTER, "Hotkey: Building, Wksp, Carpenter");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_METALSMITH, "Hotkey: Building, Wksp, Metalsmith");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LAVAMILL, "Hotkey: Building, Wksp, Lavamill");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_JEWELER, "Hotkey: Building, Wksp, Jeweler");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MASON, "Hotkey: Building, Wksp, Mason");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BUTCHER, "Hotkey: Building, Wksp, Butcher");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_TANNER, "Hotkey: Building, Wksp, Tanner");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_DYER, "Hotkey: Building, Wksp, Dyer");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN, "Hotkey: Building, Wksp, Craftsman");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_SIEGE, "Hotkey: Building, Wksp, Siege");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MECHANIC, "Hotkey: Building, Wksp, Mechanic");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_STILL, "Hotkey: Building, Wksp, Still");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FARMER, "Hotkey: Building, Wksp, Farmer");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_KITCHEN, "Hotkey: Building, Wksp, Kitchen");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FISHERY, "Hotkey: Building, Wksp, Fishery");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_ASHERY, "Hotkey: Building, Wksp, Ashery");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_WOOD, "Hotkey: Building, Furn, Wood");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER, "Hotkey: Building, Furn, Smelter");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS, "Hotkey: Building, Furn, Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN, "Hotkey: Building, Furn, Kiln");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER_LAVA, "Hotkey: Building, Furn, Smelter");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS_LAVA, "Hotkey: Building, Furn, Glass");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN_LAVA, "Hotkey: Building, Furn, Kiln");
+ displayNames.insert(INTERFACEKEY_HIVE_INSTALL_COLONY, "Hotkey: Building, Hive, Install Colony");
+ displayNames.insert(INTERFACEKEY_HIVE_GATHER_PRODUCTS, "Hotkey: Building, Hive, Gather Products");
+ displayNames.insert(INTERFACEKEY_D_ONESTEP, "Main: One-Step");
+ displayNames.insert(INTERFACEKEY_D_PAUSE, "Main: Pause/Resume");
+ displayNames.insert(INTERFACEKEY_D_DEPOT, "Depot Access");
+ displayNames.insert(INTERFACEKEY_D_HOT_KEYS, "Main: Hot Keys");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY1, "Main: Hot Key 1");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY2, "Main: Hot Key 2");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY3, "Main: Hot Key 3");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY4, "Main: Hot Key 4");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY5, "Main: Hot Key 5");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY6, "Main: Hot Key 6");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY7, "Main: Hot Key 7");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY8, "Main: Hot Key 8");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY9, "Main: Hot Key 9");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY10, "Main: Hot Key 10");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY11, "Main: Hot Key 11");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY12, "Main: Hot Key 12");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY13, "Main: Hot Key 13");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY14, "Main: Hot Key 14");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY15, "Main: Hot Key 15");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY16, "Main: Hot Key 16");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY_CHANGE_NAME, "Hot Keys: Change Name");
+ displayNames.insert(INTERFACEKEY_D_HOTKEY_ZOOM, "Hot Keys: Zoom");
+ displayNames.insert(INTERFACEKEY_D_ANNOUNCE, "Main: Announcements");
+ displayNames.insert(INTERFACEKEY_D_REPORTS, "Main: Reports");
+ displayNames.insert(INTERFACEKEY_D_BUILDING, "Main: Place Building");
+ displayNames.insert(INTERFACEKEY_D_CIVLIST, "Main: Civilizations");
+ displayNames.insert(INTERFACEKEY_D_DESIGNATE, "Main: Designations");
+ displayNames.insert(INTERFACEKEY_D_ARTLIST, "Main: Artifacts");
+ displayNames.insert(INTERFACEKEY_D_NOBLES, "Main: Nobles");
+ displayNames.insert(INTERFACEKEY_D_ORDERS, "Main: Standing Orders");
+ displayNames.insert(INTERFACEKEY_D_MILITARY, "Main: Military");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SQUAD, "Main: Military, Create Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_DISBAND_SQUAD, "Main: Military, Disband Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_CREATE_SUB_SQUAD, "Main: Military, Create Sub-Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_CANCEL_ORDERS, "Main: Military, Cancel Orders");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_POSITIONS, "Main: Military, Positions");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS, "Main: Military, Alerts");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_ADD, "Main: Military, Alerts, Add");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_DELETE, "Main: Military, Alerts, Delete");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET, "Main: Military, Alerts, Set");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_NAME, "Main: Military, Alerts, Name");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ALERTS_SET_RETAIN, "Main: Military, Alerts, Set/Retain");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP, "Main: Military, Equip");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_CUSTOMIZE, "Main: Military, Equip, Customize");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_UNIFORM, "Main: Military, Equip, Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EQUIP_PRIORITY, "Main: Military, Equip, Priority");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_UNIFORMS, "Main: Military, Uniforms");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES, "Main: Military, Supplies");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_DOWN, "Main: Military, Supplies, Water Down");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_UP, "Main: Military, Supplies, Water Up");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_DOWN, "Main: Military, Supplies, Food Down");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_UP, "Main: Military, Supplies, Food Up");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION, "Main: Military, Ammunition");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_ADD_ITEM, "Main: Military, Ammunition, Add Item");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_REMOVE_ITEM, "Main: Military, Ammunition, Remove Item");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT, "Main: Military, Ammunition, Lower Amount");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT, "Main: Military, Ammunition, Raise Amount");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS, "Main: Military, Ammunition, Lower Amount Lots");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS, "Main: Military, Ammunition, Raise Amount Lots");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_MATERIAL, "Main: Military, Ammunition, Material");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_COMBAT, "Main: Military, Ammunition, Combat");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_AMMUNITION_TRAINING, "Main: Military, Ammunition, Training");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_TRAINING, "Main: Military, Training");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_SCHEDULE, "Main: Military, Schedule");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_UNIFORM, "Main: Military, Add Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_DELETE_UNIFORM, "Main: Military, Delete Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_NAME_UNIFORM, "Main: Military, Name Uniform");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_NAME_SQUAD, "Main: Military, Name Squad");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_ARMOR, "Main: Military, Add Armor");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_PANTS, "Main: Military, Add Pants");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_HELM, "Main: Military, Add Helm");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_GLOVES, "Main: Military, Add Gloves");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_BOOTS, "Main: Military, Add Boots");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_SHIELD, "Main: Military, Add Shield");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_WEAPON, "Main: Military, Add Weapon");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_MATERIAL, "Main: Military, Add Material");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_ADD_COLOR, "Main: Military, Add Color");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_REPLACE_CLOTHING, "Main: Military, Replace Clothing");
+ displayNames.insert(INTERFACEKEY_D_MILITARY_EXACT_MATCH, "Main: Military, Exact Match");
+ displayNames.insert(INTERFACEKEY_D_ROOMS, "Main: Rooms");
+ displayNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_T, "Building List: Zoom T");
+ displayNames.insert(INTERFACEKEY_BUILDINGLIST_ZOOM_Q, "Building List: Zoom Q");
+ displayNames.insert(INTERFACEKEY_RECENTER_ON_LEVER, "Recenter on Lever");
+ displayNames.insert(INTERFACEKEY_D_SQUADS, "Main: Control Squads");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_MOVE, "Main: Control Squads, Move");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_KILL, "Main: Control Squads, Kill");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_KILL_LIST, "Main: Control Squads, Kill List");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_KILL_RECT, "Main: Control Squads, Kill Rect");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_SCHEDULE, "Main: Control Squads, Schedule");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_CANCEL_ORDER, "Main: Control Squads, Cancel Order");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_ALERT, "Main: Control Squads, Alert");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_SELECT_INDIVIDUALS, "Main: Control Squads, Select Individuals");
+ displayNames.insert(INTERFACEKEY_D_SQUADS_CENTER, "Main: Control Squads, Center");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_SLEEP, "Squad Schedule: Sleep");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_CIVILIAN_UNIFORM, "Squad Schedule: Civilian Uniform");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_GIVE_ORDER, "Squad Schedule: Give Order");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_EDIT_ORDER, "Squad Schedule: Edit Order");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_CANCEL_ORDER, "Squad Schedule: Cancel Order");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_COPY_ORDERS, "Squad Schedule: Copy Orders");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_PASTE_ORDERS, "Squad Schedule: Paste Orders");
+ displayNames.insert(INTERFACEKEY_D_SQUAD_SCH_MS_NAME, "Squad Schedule: Name Grid Cell");
+ displayNames.insert(INTERFACEKEY_D_STOCKPILES, "Main: Stockpiles");
+ displayNames.insert(INTERFACEKEY_D_CIVZONE, "Main: Activity Zone");
+ displayNames.insert(INTERFACEKEY_D_VIEWUNIT, "Main: View Units");
+ displayNames.insert(INTERFACEKEY_D_JOBLIST, "Main: Job List");
+ displayNames.insert(INTERFACEKEY_D_UNITLIST, "Main: Unit List");
+ displayNames.insert(INTERFACEKEY_D_LOOK, "Main: Look");
+ displayNames.insert(INTERFACEKEY_D_HAULING, "Main: Hauling");
+ displayNames.insert(INTERFACEKEY_D_HAULING_NEW_ROUTE, "Main: Hauling, New Route");
+ displayNames.insert(INTERFACEKEY_D_HAULING_NEW_STOP, "Main: Hauling, New Stop");
+ displayNames.insert(INTERFACEKEY_D_HAULING_REMOVE, "Main: Hauling, Remove");
+ displayNames.insert(INTERFACEKEY_D_HAULING_PROMOTE, "Main: Hauling, Promote");
+ displayNames.insert(INTERFACEKEY_D_HAULING_VEHICLE, "Main: Hauling, Vehicle");
+ displayNames.insert(INTERFACEKEY_D_HAULING_NICKNAME, "Main: Hauling, Name");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_DEPART, "Main: Hauling, Stop, New Leave Condition");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_NEW_LINK, "Main: Hauling, Stop, New Stockpile Link");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_REMOVE, "Main: Hauling, Stop, Remove");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_SELECT_PILE, "Main: Hauling, Stop, Stockpile, Select");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_SL_TAKE_GIVE, "Main: Hauling, Stop, Stockpile, Take/Give");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DIR, "Main: Hauling, Stop, Leave Condition, Dir");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MODE, "Main: Hauling, Stop, Leave Condition, Mode");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_UP, "Main: Hauling, Stop, Leave Condition, Timer Up");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_TIMER_DOWN, "Main: Hauling, Stop, Leave Condition, Timer Down");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_UP, "Main: Hauling, Stop, Leave Condition, Fullness Up");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_DOWN, "Main: Hauling, Stop, Leave Condition, Fullness Down");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_MORE_LESS, "Main: Hauling, Stop, Leave Condition, More/Less");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_DESIRED_TOTAL, "Main: Hauling, Stop, Leave Condition, Desired/Total");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_CHANGE, "Main: Hauling, Stop, Leave Condition, Change");
+ displayNames.insert(INTERFACEKEY_D_HAULING_STOP_LC_ADVANCED, "Main: Hauling, Stop, Leave Condition, Advanced");
+ displayNames.insert(INTERFACEKEY_D_BURROWS, "Main: Burrows");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_ADD, "Main: Burrows, Add");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_DELETE, "Main: Burrows, Delete");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_DEFINE, "Main: Burrows, Define");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_ADD_UNIT, "Main: Burrows, Add Citizen");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_WORKSHOP_LIMIT, "Main: Burrows, Limit Workshops");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_CENTER, "Main: Burrows, Center");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_NAME, "Main: Burrows, Name");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_CHANGE_SELECTION, "Main: Burrows, Change Selector");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_BRUSH, "Main: Burrows, Brush");
+ displayNames.insert(INTERFACEKEY_D_BURROWS_REMOVE, "Main: Burrows, Paint/Erase");
+ displayNames.insert(INTERFACEKEY_D_NOTE, "Main: Note");
+ displayNames.insert(INTERFACEKEY_D_NOTE_PLACE, "Main: Note, Place");
+ displayNames.insert(INTERFACEKEY_D_NOTE_DELETE, "Main: Note, Delete");
+ displayNames.insert(INTERFACEKEY_D_NOTE_NAME, "Main: Note, Enter Name");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ENTER, "Main: Note, Enter Text");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ADOPT_SYMBOL, "Main: Note, Adopt Symbol");
+ displayNames.insert(INTERFACEKEY_D_NOTE_CHANGE_SELECTION, "Main: Note, Change Selection");
+ displayNames.insert(INTERFACEKEY_D_NOTE_POINTS, "Main: Note, Route, Done");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE, "Main: Note, Routes");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_ADD, "Main: Note, Route, Add");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_EDIT, "Main: Note, Route, Edit");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_DELETE, "Main: Note, Route, Delete");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_CENTER, "Main: Note, Route, Center");
+ displayNames.insert(INTERFACEKEY_D_NOTE_ROUTE_NAME, "Main: Note, Route, Name");
+ displayNames.insert(INTERFACEKEY_D_BUILDJOB, "Main: Building Jobs");
+ displayNames.insert(INTERFACEKEY_D_STATUS, "Main: Overall Status");
+ displayNames.insert(INTERFACEKEY_D_STATUS_OVERALL_HEALTH_RECENTER, "Main: Status, Overall Health, Recenter");
+ displayNames.insert(INTERFACEKEY_D_BUILDITEM, "Main: Building Items");
+ displayNames.insert(INTERFACEKEY_D_BITEM_FORBID, "Building Items: Forbid");
+ displayNames.insert(INTERFACEKEY_D_BITEM_DUMP, "Building Items: Dump");
+ displayNames.insert(INTERFACEKEY_D_BITEM_MELT, "Building Items: Melt");
+ displayNames.insert(INTERFACEKEY_D_BITEM_HIDE, "Building Items: Hide");
+ displayNames.insert(INTERFACEKEY_D_LOOK_FORBID, "Dwf Look: Forbid");
+ displayNames.insert(INTERFACEKEY_D_LOOK_DUMP, "Dwf Look: Dump");
+ displayNames.insert(INTERFACEKEY_D_LOOK_MELT, "Dwf Look: Melt");
+ displayNames.insert(INTERFACEKEY_D_LOOK_HIDE, "Dwf Look: Hide");
+ displayNames.insert(INTERFACEKEY_D_LOOK_FOLLOW, "Dwf Look: Follow");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_CREATURE, "Dwf Look: Arena Creature");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_ADV_MODE, "Dwf Look: Arena Adv Mode");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_WATER, "Dwf Look: Arena Water");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_MAGMA, "Dwf Look: Arena Magma");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_DOWN, "Arena Creature: Side Down");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_SIDE_UP, "Arena Creature: Side Up");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_NEW_ITEM, "Arena Creature: New Item");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_BLANK_LIST, "Arena Creature: Blank List");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_REMOVE_ITEM, "Arena Creature: Remove Item");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_UNDEAD, "Arena Creature: Undead");
+ displayNames.insert(INTERFACEKEY_ARENA_CREATURE_STRING, "Arena Creature: String");
+ displayNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_1, "Arena Conflict State 1");
+ displayNames.insert(INTERFACEKEY_ARENA_CONFLICT_STATE_2, "Arena Conflict State 2");
+ displayNames.insert(INTERFACEKEY_ARENA_MORALE, "Arena Morale");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER, "Arena Weather");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER_SNOW, "Arena Weather: Snow");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER_MUD, "Arena Weather: Mud");
+ displayNames.insert(INTERFACEKEY_ARENA_WEATHER_CLEAR_SPATTER, "Arena Weather: Clear Spatter");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_TREE, "Dwf Look: Arena Tree");
+ displayNames.insert(INTERFACEKEY_ARENA_TREE_FILTER, "Arena Tree: Filter");
+ displayNames.insert(INTERFACEKEY_ARENA_TREE_AGE, "Arena Tree: Age");
+ displayNames.insert(INTERFACEKEY_D_LOOK_ARENA_MOUNT, "Dwf Look: Arena Mount");
+ displayNames.insert(INTERFACEKEY_A_ENTER_NAME, "Adventure: Creation, Name Entry");
+ displayNames.insert(INTERFACEKEY_A_CUST_NAME, "Adventure: Creation, Customize Name");
+ displayNames.insert(INTERFACEKEY_A_RANDOM_NAME, "Adventure: Creation, Random Name");
+ displayNames.insert(INTERFACEKEY_A_CHANGE_GENDER, "Adventure: Creation, Change Gender");
+ displayNames.insert(INTERFACEKEY_A_END_TRAVEL, "Adventure: Travel, Visit Site");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_CLOUDS, "Adventure: Travel, Clouds");
+ displayNames.insert(INTERFACEKEY_A_LOG, "Adventure: Log");
+ displayNames.insert(INTERFACEKEY_A_TRAVEL_LOG, "Adventure: Travel, Log");
+ displayNames.insert(INTERFACEKEY_A_LOG_TASKS, "Adventure: Log, Tasks");
+ displayNames.insert(INTERFACEKEY_A_LOG_ENTITIES, "Adventure: Log, Entities");
+ displayNames.insert(INTERFACEKEY_A_LOG_SITES, "Adventure: Log, Sites");
+ displayNames.insert(INTERFACEKEY_A_LOG_SUBREGIONS, "Adventure: Log, Regions");
+ displayNames.insert(INTERFACEKEY_A_LOG_FEATURE_LAYERS, "Adventure: Log, Feature Layers");
+ displayNames.insert(INTERFACEKEY_A_LOG_PEOPLE, "Adventure: Log, People");
+ displayNames.insert(INTERFACEKEY_A_LOG_AGREEMENTS, "Adventure: Log, Agreements");
+ displayNames.insert(INTERFACEKEY_A_LOG_EVENTS, "Adventure: Log, Events");
+ displayNames.insert(INTERFACEKEY_A_LOG_BESTIARY, "Adventure: Log, Bestiary");
+ displayNames.insert(INTERFACEKEY_A_LOG_FILTER, "Adventure: Log, Filter");
+ displayNames.insert(INTERFACEKEY_A_LOG_ZOOM_CURRENT_LOCATION, "Adventure: Log, Zoom to Current Location");
+ displayNames.insert(INTERFACEKEY_A_LOG_ZOOM_SELECTED, "Adventure: Log, Zoom to Selected");
+ displayNames.insert(INTERFACEKEY_A_LOG_LINE, "Adventure: Log, Toggle Line");
+ displayNames.insert(INTERFACEKEY_A_LOG_MAP, "Adventure: Log, Toggle Map/Info");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTOFORBID, "Orders: Forbid");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_PROJECTILE, "Orders: Forbid Projectiles");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_CORPSE, "Orders: Forbid Your Corpse");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_YOUR_ITEMS, "Orders: Forbid Your Items");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_CORPSE, "Orders: Forbid Other Corpse");
+ displayNames.insert(INTERFACEKEY_ORDERS_FORBID_OTHER_ITEMS, "Orders: Forbid Other Items");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_GATHER, "Orders: Gather Refuse");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE, "Orders: Gather Outside");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_OUTSIDE_VERMIN, "Orders: Gather Outside Vermin");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_CORPSE, "Orders: Dump Corpse");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKULL, "Orders: Dump Skull");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SKIN, "Orders: Dump Skin");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_BONE, "Orders: Dump Bone");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_SHELL, "Orders: Dump Shell");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_OTHER, "Orders: Dump Other");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE_DUMP_STRAND_TISSUE, "Orders: Dump Strand Tissue");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_FURNITURE, "Orders: Gather Furniture");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_ANIMALS, "Orders: Gather Animals");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_FOOD, "Orders: Gather Food");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_BODIES, "Orders: Gather Bodies");
+ displayNames.insert(INTERFACEKEY_ORDERS_REFUSE, "Orders: Refuse");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_STONE, "Orders: Gather Stone");
+ displayNames.insert(INTERFACEKEY_ORDERS_GATHER_WOOD, "Orders: Gather Wood");
+ displayNames.insert(INTERFACEKEY_ORDERS_ALL_HARVEST, "Orders: All Harvest");
+ displayNames.insert(INTERFACEKEY_ORDERS_SAMEPILE, "Orders: Piles Same");
+ displayNames.insert(INTERFACEKEY_ORDERS_MIXFOODS, "Orders: Mix Foods");
+ displayNames.insert(INTERFACEKEY_ORDERS_EXCEPTIONS, "Orders: Exceptions");
+ displayNames.insert(INTERFACEKEY_ORDERS_LOOM, "Orders: Loom");
+ displayNames.insert(INTERFACEKEY_ORDERS_DYED_CLOTH, "Orders: Dyed Cloth");
+ displayNames.insert(INTERFACEKEY_ORDERS_WORKSHOP, "Orders: Workshop");
+ displayNames.insert(INTERFACEKEY_ORDERS_COLLECT_WEB, "Orders: Auto-Collect Web");
+ displayNames.insert(INTERFACEKEY_ORDERS_SLAUGHTER, "Orders: Auto-Slaughter");
+ displayNames.insert(INTERFACEKEY_ORDERS_BUTCHER, "Orders: Auto-Butcher");
+ displayNames.insert(INTERFACEKEY_ORDERS_TAN, "Orders: Auto-Tan");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_FISHERY, "Orders: Auto-Fishery");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_KITCHEN, "Orders: Auto-Kitchen");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_KILN, "Orders: Auto-Kiln");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_SMELTER, "Orders: Auto-Smelter");
+ displayNames.insert(INTERFACEKEY_ORDERS_AUTO_OTHER, "Orders: Auto-Other");
+ displayNames.insert(INTERFACEKEY_ORDERS_ZONE, "Orders: Zone");
+ displayNames.insert(INTERFACEKEY_ORDERS_ZONE_DRINKING, "Orders: Zone, Drinking");
+ displayNames.insert(INTERFACEKEY_ORDERS_ZONE_FISHING, "Orders: Zone, Fishing");
+ displayNames.insert(INTERFACEKEY_DESTROYBUILDING, "Destroy Building");
+ displayNames.insert(INTERFACEKEY_SUSPENDBUILDING, "Suspend Building");
+ displayNames.insert(INTERFACEKEY_MENU_CONFIRM, "Menu Confirm");
+ displayNames.insert(INTERFACEKEY_SAVE_BINDINGS, "Save Bindings");
+ displayNames.insert(INTERFACEKEY_LOAD_BINDINGS, "Load Bindings");
+ displayNames.insert(INTERFACEKEY_KEYBINDING_COMPLETE, "Complete Binding");
+ displayNames.insert(INTERFACEKEY_ZOOM_IN, "Zoom In");
+ displayNames.insert(INTERFACEKEY_ZOOM_OUT, "Zoom Out");
+ displayNames.insert(INTERFACEKEY_ZOOM_TOGGLE, "Toggle Zoom");
+ displayNames.insert(INTERFACEKEY_ZOOM_RESET, "Reset Zoom");
+ displayNames.insert(INTERFACEKEY_MACRO_BREAK, "Macro, Break");
+ displayNames.insert(INTERFACEKEY_RECORD_MACRO, "Macro, Record");
+ displayNames.insert(INTERFACEKEY_PLAY_MACRO, "Macro, Play");
+ displayNames.insert(INTERFACEKEY_SAVE_MACRO, "Macro, Save");
+ displayNames.insert(INTERFACEKEY_LOAD_MACRO, "Macro, Load");
+ displayNames.insert(INTERFACEKEY_HOTKEY_ALCHEMIST_SOAP, "Hotkey: Alchemist, Soap");
+ displayNames.insert(INTERFACEKEY_HOTKEY_STILL_BREW, "Hotkey: Still, Brew");
+ displayNames.insert(INTERFACEKEY_HOTKEY_STILL_EXTRACT, "Hotkey: Still, Extract");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_COLLECT_SILK, "Hotkey: Loom, Collect Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_CLOTH, "Hotkey: Loom, Weave Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_SILK, "Hotkey: Loom, Weave Silk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_YARN, "Hotkey: Loom, Weave Yarn");
+ displayNames.insert(INTERFACEKEY_HOTKEY_LOOM_WEAVE_METAL, "Hotkey: Loom, Metal");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_2, "Hotkey: Kitchen, Meal 1");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_3, "Hotkey: Kitchen, Meal 2");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_COOK_4, "Hotkey: Kitchen, Meal 3");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KITCHEN_RENDER_FAT, "Hotkey: Kitchen, Render Fat");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS, "Hotkey: Farmer, Process");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_VIAL, "Hotkey: Farmer, Vial");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BAG, "Hotkey: Farmer, Bag");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_PROCESS_BARREL, "Hotkey: Farmer, Barrel");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_CHEESE, "Hotkey: Farmer, Cheese");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_MILK, "Hotkey: Farmer, Milk");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_SHEAR_CREATURE, "Hotkey: Farmer, Shear");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FARMER_SPIN_THREAD, "Hotkey: Farmer, Spin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MILL_MILL, "Hotkey: Mill, Mill");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KENNEL_CATCH_VERMIN, "Hotkey: Kennel, Catch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_KENNEL_TAME_VERMIN, "Hotkey: Kennel, Tame Small");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FISHERY_PROCESS, "Hotkey: Fishery, Process");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FISHERY_EXTRACT, "Hotkey: Fishery, Extract");
+ displayNames.insert(INTERFACEKEY_HOTKEY_FISHERY_CATCH, "Hotkey: Fishery, Catch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_BUTCHER, "Hotkey: Butcher, Butcher");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_EXTRACT, "Hotkey: Butcher, Extract");
+ displayNames.insert(INTERFACEKEY_HOTKEY_BUTCHER_CATCH, "Hotkey: Butcher, Catch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TANNER_TAN, "Hotkey: Tanner, Tan");
+ displayNames.insert(INTERFACEKEY_HOTKEY_DYER_THREAD, "Hotkey: Dyer, Thread");
+ displayNames.insert(INTERFACEKEY_HOTKEY_DYER_CLOTH, "Hotkey: Dyer, Cloth");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FURNITURE, "Hotkey: Jeweler, Furniture");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_FINISHED, "Hotkey: Jeweler, Finished");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_AMMO, "Hotkey: Jeweler, Ammo");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_CUT, "Hotkey: Jeweler, Cut");
+ displayNames.insert(INTERFACEKEY_HOTKEY_JEWELER_ENCRUST, "Hotkey: Jeweler, Encrust");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_PARTS, "Hotkey: Mechanic, Mechanisms");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MECHANIC_TRACTION_BENCH, "Hotkey: Mechanic, Traction Bench");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_ARMORSTAND, "Hotkey: Mason, Armorstand");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_BLOCKS, "Hotkey: Mason, Blocks");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_CHAIR, "Hotkey: Mason, Chair");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_COFFIN, "Hotkey: Mason, Coffin");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_DOOR, "Hotkey: Mason, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_FLOODGATE, "Hotkey: Mason, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_HATCH_COVER, "Hotkey: Mason, Hatch Cover");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_GRATE, "Hotkey: Mason, Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_CABINET, "Hotkey: Mason, Cabinet");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_BOX, "Hotkey: Mason, Box");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_STATUE, "Hotkey: Mason, Statue");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_QUERN, "Hotkey: Mason, Quern");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_MILLSTONE, "Hotkey: Mason, Millstone");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_TABLE, "Hotkey: Mason, Table");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_WEAPONRACK, "Hotkey: Mason, Weaponrack");
+ displayNames.insert(INTERFACEKEY_HOTKEY_MASON_SLAB, "Hotkey: Mason, Slab");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_BRIDGE, "Hotkey: Trap, Bridge");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_GEAR_ASSEMBLY, "Hotkey: Trap, Gear Assembly");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_DOOR, "Hotkey: Trap, Door");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_FLOODGATE, "Hotkey: Trap, Floodgate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_SPIKE, "Hotkey: Trap, Spike");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_HATCH, "Hotkey: Trap, Hatch");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_WALL, "Hotkey: Trap, Wall Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_GRATE_FLOOR, "Hotkey: Trap, Floor Grate");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_VERTICAL, "Hotkey: Trap, Vertical Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_BARS_FLOOR, "Hotkey: Trap, Floor Bars");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_SUPPORT, "Hotkey: Trap, Support");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_CHAIN, "Hotkey: Trap, Chain");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_CAGE, "Hotkey: Trap, Cage");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_PULL_LEVER, "Hotkey: Trap, Lever");
+ displayNames.insert(INTERFACEKEY_HOTKEY_TRAP_TRACK_STOP, "Hotkey: Trap, Track Stop");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ADD, "Buildjob: Add");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CANCEL, "Buildjob: Cancel");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_PROMOTE, "Buildjob: Promote");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_NOW, "Buildjob: Now");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_REPEAT, "Buildjob: Repeat");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_SUSPEND, "Buildjob: Suspend");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_WORKSHOP_PROFILE, "Buildjob: Workshop Profile");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_WELL_FREE, "Buildjob: Well, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_WELL_SIZE, "Buildjob: Well, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_FREE, "Buildjob: Target, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_SIZE, "Buildjob: Target, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_DOWN, "Buildjob: Target, Down");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_UP, "Buildjob: Target, Up");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_RIGHT, "Buildjob: Target, Right");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TARGET_LEFT, "Buildjob: Target, Left");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STATUE_ASSIGN, "Buildjob: Statue, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STATUE_FREE, "Buildjob: Statue, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STATUE_SIZE, "Buildjob: Statue, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_JUSTICE, "Buildjob: Cage, Justice");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_FREE, "Buildjob: Cage, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_SIZE, "Buildjob: Cage, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN_OCC, "Buildjob: Cage, Assign Occ");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_WATER, "Buildjob: Cage, Water");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CAGE_ASSIGN, "Buildjob: Cage, Assign Owner");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN_OCC, "Buildjob: Chain, Assign Occ");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_JUSTICE, "Buildjob: Chain, Justice");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN, "Buildjob: Chain, Assign Owner");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_FREE, "Buildjob: Chain, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIN_SIZE, "Buildjob: Chain, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_FIRING, "Buildjob: Siege, Fire");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_SIEGE_ORIENT, "Buildjob: Siege, Orient");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DOOR_INTERNAL, "Buildjob: Door, Internal");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DOOR_LOCK, "Buildjob: Door, Forbid");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DOOR_AJAR, "Buildjob: Door, Pet-passable");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_ASSIGN, "Buildjob: Coffin, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_FREE, "Buildjob: Coffin, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_SIZE, "Buildjob: Coffin, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_BURIAL, "Buildjob: Coffin, Gen. Burial");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_CIV, "Buildjob: Coffin, Allow Citizens");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_COFFIN_PET, "Buildjob: Coffin, Allow Pets");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_ASSIGN, "Buildjob: Chair, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_FREE, "Buildjob: Chair, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_CHAIR_SIZE, "Buildjob: Chair, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_ASSIGN, "Buildjob: Table, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_HALL, "Buildjob: Table, Hall");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_FREE, "Buildjob: Table, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_TABLE_SIZE, "Buildjob: Table, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_ASSIGN, "Buildjob: Bed, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_FREE, "Buildjob: Bed, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_BARRACKS, "Buildjob: Bed, Barracks");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_DORMITORY, "Buildjob: Bed, Dormitory");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_RENT, "Buildjob: Bed, Rent");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_SIZE, "Buildjob: Bed, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_NAME, "Buildjob: Bed, Name");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_SLEEP, "Buildjob: Bed, Sleep");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_TRAIN, "Buildjob: Bed, Train");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_INDIV_EQ, "Buildjob: Bed, Indiv Eq");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_SQUAD_EQ, "Buildjob: Bed, Squad Eq");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_BED_POSITION, "Buildjob: Bed, Position");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BRING, "Buildjob: Depot, Bring");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_TRADE, "Buildjob: Depot, Trade");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_REQUEST_TRADER, "Buildjob: Depot, Request Trader");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_DEPOT_BROKER_ONLY, "Buildjob: Depot, Broker Only");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_NONE, "Buildjob: Animal Trap, No Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_MEAT, "Buildjob: Animal Trap, Meat Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_FISH, "Buildjob: Animal Trap, Fish Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_GEM, "Buildjob: Animal Trap, Gem Bait");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_FALLOW, "Buildjob: Farm, Fallow");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_FERTILIZE, "Buildjob: Farm, Fertilize");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_SEASFERT, "Buildjob: Farm, Seas Fert");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_SPRING, "Buildjob: Farm, Spring");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_SUMMER, "Buildjob: Farm, Summer");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_AUTUMN, "Buildjob: Farm, Autumn");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_FARM_WINTER, "Buildjob: Farm, Winter");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_MASTER, "Buildjob: Stockpile, Master");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_LINK_ANYWHERE, "Buildjob: Stockpile, Link/Anywhere");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_GIVE_TO, "Buildjob: Stockpile, Give To");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_WHEELBARROW, "Buildjob: Stockpile, Wheelbarrow");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_DELETE_CHILD, "Buildjob: Stockpile, Delete Child");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_SETTINGS, "Buildjob: Stockpile, Settings");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_UP, "Buildjob: Stockpile, Barrel Up");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_DOWN, "Buildjob: Stockpile, Barrel Down");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_ZERO, "Buildjob: Stockpile, Barrel Zero");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_MAX, "Buildjob: Stockpile, Barrel Max");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_UP, "Buildjob: Stockpile, Bin Up");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_DOWN, "Buildjob: Stockpile, Bin Down");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_ZERO, "Buildjob: Stockpile, Bin Zero");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_MAX, "Buildjob: Stockpile, Bin Max");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BONE, "Buildjob: Rack, Mat, Bone");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_BRONZE, "Buildjob: Rack, Mat, Bronze");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_COPPER, "Buildjob: Rack, Mat, Copper");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_IRON, "Buildjob: Rack, Mat, Iron");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_STEEL, "Buildjob: Rack, Mat, Steel");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_WOOD, "Buildjob: Rack, Mat, Wood");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACK_MAT_METAL, "Buildjob: Rack, Mat, Special Metal");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BONE, "Buildjob: Stand, Mat, Bone");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_LEATHER, "Buildjob: Stand, Mat, Leather");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_COPPER, "Buildjob: Stand, Mat, Copper");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_BRONZE, "Buildjob: Stand, Mat, Bronze");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_STEEL, "Buildjob: Stand, Mat, Steel");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_IRON, "Buildjob: Stand, Mat, Iron");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_WOOD, "Buildjob: Stand, Mat, Wood");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_STAND_MAT_METAL, "Buildjob: Stand, Mat, Special Metal");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ASSIGN, "Buildjob: Rackstand, Assign");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_FREE, "Buildjob: Rackstand, Free");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_SIZE, "Buildjob: Rackstand, Size");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_ITEM, "Buildjob: Rackstand, Item");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_MAT, "Buildjob: Rackstand, Mat");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS1, "Buildjob: Rackstand, All Items");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL1, "Buildjob: Rackstand, No Items");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS2, "Buildjob: Rackstand, All Mats");
+ displayNames.insert(INTERFACEKEY_BUILDJOB_RACKSTAND_KILL2, "Buildjob: Rackstand, No Mats");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_ENABLE, "Stockpile Settings: Enable");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_DISABLE, "Stockpile Settings: Disable");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_ALL, "Stockpile Settings: Permit All");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_ALL, "Stockpile Settings: Forbid All");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_SUB, "Stockpile Settings: Permit Sub");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_SUB, "Stockpile Settings: Forbit Sub");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC1, "Stockpile Settings: Specific 1");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC2, "Stockpile Settings: Specific 2");
+ displayNames.insert(INTERFACEKEY_MOVIE_RECORD, "Movie: Record");
+ displayNames.insert(INTERFACEKEY_MOVIE_PLAY, "Movie: Play");
+ displayNames.insert(INTERFACEKEY_MOVIE_SAVE, "Movie: Save");
+ displayNames.insert(INTERFACEKEY_MOVIE_LOAD, "Movie: Load");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_VIEW, "Assign Trade: View");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_STRING, "Assign Trade: String");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_EXCLUDE_PROHIBITED, "Assign Trade: Exclude Prohibited");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_PENDING, "Assign Trade: Pending");
+ displayNames.insert(INTERFACEKEY_ASSIGNTRADE_SORT, "Assign Trade: Sort");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_REPLACE, "Noble List: Replace");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_SETTINGS, "Noble List: Settings");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_CAPITAL, "Noble List: Capital");
+ displayNames.insert(INTERFACEKEY_NOBLELIST_VIEW_CANDIDATE, "Noble List: View Candidate");
+ displayNames.insert(INTERFACEKEY_A_BARTER_VIEW, "Adventure: Barter, View");
+ displayNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_1, "Adventure: Barter, Currency 1");
+ displayNames.insert(INTERFACEKEY_A_BARTER_CURRENCY_2, "Adventure: Barter, Currency 2");
+ displayNames.insert(INTERFACEKEY_A_BARTER_TRADE, "Adventure: Barter, Trade");
+ displayNames.insert(INTERFACEKEY_TRADE_VIEW, "Trade, View");
+ displayNames.insert(INTERFACEKEY_TRADE_TRADE, "Trade, Trade");
+ displayNames.insert(INTERFACEKEY_TRADE_OFFER, "Trade, Offer");
+ displayNames.insert(INTERFACEKEY_TRADE_SEIZE, "Trade, Seize");
+ displayNames.insert(INTERFACEKEY_STORES_VIEW, "Stores, View");
+ displayNames.insert(INTERFACEKEY_STORES_FORBID, "Stores, Forbid");
+ displayNames.insert(INTERFACEKEY_STORES_MELT, "Stores, Melt");
+ displayNames.insert(INTERFACEKEY_STORES_DUMP, "Stores, Dump");
+ displayNames.insert(INTERFACEKEY_STORES_ZOOM, "Stores, Zoom");
+ displayNames.insert(INTERFACEKEY_STORES_HIDE, "Stores, Hide");
+ displayNames.insert(INTERFACEKEY_MILITARY_ACTIVATE, "Military, Activate");
+ displayNames.insert(INTERFACEKEY_MILITARY_VIEW, "Military, View");
+ displayNames.insert(INTERFACEKEY_MILITARY_WEAPON, "Military, Weapon");
+ displayNames.insert(INTERFACEKEY_MILITARY_ZOOM, "Military, Zoom");
+ displayNames.insert(INTERFACEKEY_ANNOUNCE_ZOOM, "Announcements, Zoom");
+ displayNames.insert(INTERFACEKEY_UNITJOB_REMOVE_CRE, "Unitjob, Remove Unit");
+ displayNames.insert(INTERFACEKEY_UNITJOB_ZOOM_CRE, "Unitjob, Zoom Unit");
+ displayNames.insert(INTERFACEKEY_UNITJOB_ZOOM_BUILD, "Unitjob, Zoom Building");
+ displayNames.insert(INTERFACEKEY_UNITJOB_VIEW, "Unitjob, View");
+ displayNames.insert(INTERFACEKEY_UNITJOB_MANAGER, "Unitjob, Manager");
+ displayNames.insert(INTERFACEKEY_MANAGER_NEW_ORDER, "Manager, New Order");
+ displayNames.insert(INTERFACEKEY_MANAGER_REMOVE, "Manager, Remove");
+ displayNames.insert(INTERFACEKEY_MANAGER_PROMOTE, "Manager, Promote");
+ displayNames.insert(INTERFACEKEY_MANAGER_MAX, "Manager, Max");
+ displayNames.insert(INTERFACEKEY_MANAGER_WAGES, "Manager, Wages");
+ displayNames.insert(INTERFACEKEY_PET_BUTCHER, "Animals, Slaughter");
+ displayNames.insert(INTERFACEKEY_PET_GELD, "Animals, Geld");
+ displayNames.insert(INTERFACEKEY_ANIMAL_SELECT_TRAINER, "Animals, Trainer");
+ displayNames.insert(INTERFACEKEY_ANIMAL_WAR_TRAINING, "Animals, War Training");
+ displayNames.insert(INTERFACEKEY_ANIMAL_HUNTING_TRAINING, "Animals, Hunting Training");
+ displayNames.insert(INTERFACEKEY_KITCHEN_COOK, "Kitchen, Cook");
+ displayNames.insert(INTERFACEKEY_KITCHEN_BREW, "Kitchen, Brew");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_NEW, "Setup, New");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_VIEW, "Setup, View");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_CUSTOMIZE_UNIT, "Setup, Customize Unit");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE, "Setup, Save Profile");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_ABORT, "Setup, Save Profile, Abort");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_SAVE_PROFILE_GO, "Setup, Save Profile, Go");
+ displayNames.insert(INTERFACEKEY_SETUPGAME_VIEW_PROFILE_PROBLEMS, "Setup, View Profile Problems");
+ displayNames.insert(INTERFACEKEY_CIVZONE_REMOVE, "Main: Activity Zone, Remove");
+ displayNames.insert(INTERFACEKEY_CIVZONE_REMOVE_ZONE, "Main: Activity Zone, Remove Zone");
+ displayNames.insert(INTERFACEKEY_CIVZONE_SHAPE, "Main: Activity Zone, Shape");
+ displayNames.insert(INTERFACEKEY_CIVZONE_NEXT, "Main: Activity Zone, Next");
+ displayNames.insert(INTERFACEKEY_CIVZONE_WATER_SOURCE, "Main: Activity Zone, Water Source");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER, "Main: Activity Zone, Gather");
+ displayNames.insert(INTERFACEKEY_CIVZONE_DUMP, "Main: Activity Zone, Garbage Dump");
+ displayNames.insert(INTERFACEKEY_CIVZONE_POND, "Main: Activity Zone, Pond");
+ displayNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL, "Main: Activity Zone, Hospital");
+ displayNames.insert(INTERFACEKEY_CIVZONE_SAND_COLLECT, "Main: Activity Zone, Sand Collect");
+ displayNames.insert(INTERFACEKEY_CIVZONE_CLAY_COLLECT, "Main: Activity Zone, Clay Collect");
+ displayNames.insert(INTERFACEKEY_CIVZONE_ACTIVE, "Main: Activity Zone, Active");
+ displayNames.insert(INTERFACEKEY_CIVZONE_FISH, "Main: Activity Zone, Fish");
+ displayNames.insert(INTERFACEKEY_CIVZONE_MEETING, "Main: Activity Zone, Meeting");
+ displayNames.insert(INTERFACEKEY_CIVZONE_ANIMAL_TRAINING, "Main: Activity Zone, Animal Training");
+ displayNames.insert(INTERFACEKEY_CIVZONE_POND_OPTIONS, "Main: Activity Zone, Pond Options");
+ displayNames.insert(INTERFACEKEY_CIVZONE_POND_WATER, "Main: Activity Zone: Pond, Water");
+ displayNames.insert(INTERFACEKEY_CIVZONE_HOSPITAL_OPTIONS, "Main: Activity Zone, Hospital Options");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS, "Main: Activity Zone, Gather Options");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_TREES, "Main: Activity Zone, Gather Options, Pick Trees");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_SHRUBS, "Main: Activity Zone, Gather Options, Pick Shrubs");
+ displayNames.insert(INTERFACEKEY_CIVZONE_GATHER_OPTIONS_GATHER_FALLEN, "Main: Activity Zone, Gather Options, Gather Fallen");
+ displayNames.insert(INTERFACEKEY_CIVZONE_PEN, "Main: Activity Zone, Pen");
+ displayNames.insert(INTERFACEKEY_CIVZONE_PEN_OPTIONS, "Main: Activity Zone, Pen Options");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_ANIMAL, "Stockpile, Animal");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_FOOD, "Stockpile, Food");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_WEAPON, "Stockpile, Weapon");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_ARMOR, "Stockpile, Armor");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM, "Stockpile, Custom");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_CUSTOM_SETTINGS, "Stockpile, Custom Settings");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_FURNITURE, "Stockpile, Furniture");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_GRAVEYARD, "Stockpile, Corpse");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_REFUSE, "Stockpile, Refuse");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_WOOD, "Stockpile, Wood");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_STONE, "Stockpile, Stone");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_GEM, "Stockpile, Gem");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_BARBLOCK, "Stockpile, Bar/Block");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_CLOTH, "Stockpile, Cloth");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_LEATHER, "Stockpile, Leather");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_AMMO, "Stockpile, Ammo");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_COINS, "Stockpile, Coins");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_FINISHED, "Stockpile, Finished");
+ displayNames.insert(INTERFACEKEY_STOCKPILE_NONE, "Stockpile, None");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_BITEM, "Designate, Building/Item");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_CLAIM, "Designate, Reclaim");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_UNCLAIM, "Designate, Forbid");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_MELT, "Designate, Melt");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_NO_MELT, "Designate, No Melt");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_DUMP, "Designate, Dump");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_NO_DUMP, "Designate, No Dump");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_HIDE, "Designate, Hide");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_NO_HIDE, "Designate, No Hide");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC, "Designate, Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_HIGH, "Designate, High Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_NORMAL, "Designate, Normal Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_LOW, "Designate, Low Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_RESTRICTED, "Designate, Restricted Traffic");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT, "Designate, Increase Weight");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT, "Designate, Decrease Weight");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE, "Designate, Increase Weight More");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE, "Designate, Decrease Weight More");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_DIG, "Designate, Dig");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_DIG_REMOVE_STAIRS_RAMPS, "Designate, Dig Remove Stairs Ramps");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UP, "Designate, U Stair");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STAIR_DOWN, "Designate, D Stair");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STAIR_UPDOWN, "Designate, UD Stair");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_RAMP, "Designate, Ramp");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_CHANNEL, "Designate, Channel");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_CHOP, "Designate, Chop");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_PLANTS, "Designate, Plants");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_SMOOTH, "Designate, Smooth");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_ENGRAVE, "Designate, Engrave");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_FORTIFY, "Designate, Fortify");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TRACK, "Designate, Carve Track");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_ENGRAVING, "Designate, Toggle Engraving");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_STANDARD_MARKER, "Designate, Standard/Marker");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_MINE_MODE, "Designate, Mine Mode");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_TOGGLE_MARKER, "Designate, Toggle Marker");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_UNDO, "Designate, Undo");
+ displayNames.insert(INTERFACEKEY_DESIGNATE_REMOVE_CONSTRUCTION, "Designate, Remove Construction");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_Y_UP, "Building, Change Height +");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_Y_DOWN, "Building, Change Height -");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_X_UP, "Building, Change Width +");
+ displayNames.insert(INTERFACEKEY_BUILDING_DIM_X_DOWN, "Building, Change Width -");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_UP, "Building, Orient Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_LEFT, "Building, Orient Left");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_RIGHT, "Building, Orient Right");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_DOWN, "Building, Orient Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_ORIENT_NONE, "Building, Orient None");
+ displayNames.insert(INTERFACEKEY_BUILDING_VIEW_ITEM, "Building, View Item");
+ displayNames.insert(INTERFACEKEY_BUILDING_ADVANCE_STAGE, "Building, Done Selecting");
+ displayNames.insert(INTERFACEKEY_BUILDING_EXPAND_CONTRACT, "Building, Expand/Contract");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_WATER, "Building, Trigger, Enable Water");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_UP, "Building, Trigger, Min Water Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_DOWN, "Building, Trigger, Min Water Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_UP, "Building, Trigger, Max Water Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_DOWN, "Building, Trigger, Max Water Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_MAGMA, "Building, Trigger, Enabler Magma");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_UP, "Building, Trigger, Min Magma Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_DOWN, "Building, Trigger, Min Magma Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_UP, "Building, Trigger, Max Magma Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_DOWN, "Building, Trigger, Max Magma Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_TRACK_CART, "Building, Trigger, Enable Cart");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_DOWN, "Building, Trigger, Min Cart Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_UP, "Building, Trigger, Min Cart Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_DOWN, "Building, Trigger, Max Cart Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_UP, "Building, Trigger, Max Cart Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_UP, "Building, Rollers, Speed Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_ROLLERS_SPEED_DOWN, "Building, Rollers, Speed Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_UP, "Building, Track Stop, Friction Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_DOWN, "Building, Track Stop, Friction Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRACK_STOP_DUMP, "Building, Track Stop, Dump");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_CREATURE, "Building, Trigger, Enable Creature");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_ENABLE_LOCALS, "Building, Trigger, Enable Locals");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_RESETS, "Building, Trigger, Resets");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP, "Building, Trigger, Min Size Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN, "Building, Trigger, Min Size Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP, "Building, Trigger, Max Size Up");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN, "Building, Trigger, Max Size Down");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP_PLUS, "Building, Trigger, Min Size Up+");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS, "Building, Trigger, Min Size Down+");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP_PLUS, "Building, Trigger, Max Size Up+");
+ displayNames.insert(INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS, "Building, Trigger, Max Size Down+");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN, "Unitview, General");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_INV, "Unitview, Inventory");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF, "Unitview, Prefs");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_WND, "Unitview, Wounds");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_NEXT, "Unitview, Next Unit");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_FOLLOW, "Unitview, Follow");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_SLAUGHTER, "Unitview, Slaughter");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GELD, "Unitview, Geld");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN_COMBAT, "Unitview, General, Combat");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN_LABOR, "Unitview, General, Labor");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_GEN_MISC, "Unitview, General, Misc");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_PROF, "Unitview, Prefs, Labor");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_PET, "Unitview, Prefs, Pets");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_VIEW, "Unitview, Prefs, Profile");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_NEW_SQUAD, "Unitview, Prefs, New Squad");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_REMOVE_FROM_SQUAD, "Unitview, Prefs, Remove From Squad");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_CURRENT_SQUAD, "Unitview, Prefs, Name Current Squad");
+ displayNames.insert(INTERFACEKEY_UNITVIEW_PRF_NAME_SELECTED_SQUAD, "Unitview, Prefs, Name Selected Squad");
+
+ displayNames.insert(INTERFACEKEY_STRING_A000, "String: Backspace");
+ displayNames.insert(INTERFACEKEY_STRING_A001, "String: Character 001");
+ displayNames.insert(INTERFACEKEY_STRING_A002, "String: Character 002");
+ displayNames.insert(INTERFACEKEY_STRING_A003, "String: Character 003");
+ displayNames.insert(INTERFACEKEY_STRING_A004, "String: Character 004");
+ displayNames.insert(INTERFACEKEY_STRING_A005, "String: Character 005");
+ displayNames.insert(INTERFACEKEY_STRING_A006, "String: Character 006");
+ displayNames.insert(INTERFACEKEY_STRING_A007, "String: Character 007");
+ displayNames.insert(INTERFACEKEY_STRING_A008, "String: Character 008");
+ displayNames.insert(INTERFACEKEY_STRING_A009, "String: Character 009");
+ displayNames.insert(INTERFACEKEY_STRING_A010, "String: Character 010");
+ displayNames.insert(INTERFACEKEY_STRING_A011, "String: Character 011");
+ displayNames.insert(INTERFACEKEY_STRING_A012, "String: Character 012");
+ displayNames.insert(INTERFACEKEY_STRING_A013, "String: Character 013");
+ displayNames.insert(INTERFACEKEY_STRING_A014, "String: Character 014");
+ displayNames.insert(INTERFACEKEY_STRING_A015, "String: Character 015");
+ displayNames.insert(INTERFACEKEY_STRING_A016, "String: Character 016");
+ displayNames.insert(INTERFACEKEY_STRING_A017, "String: Character 017");
+ displayNames.insert(INTERFACEKEY_STRING_A018, "String: Character 018");
+ displayNames.insert(INTERFACEKEY_STRING_A019, "String: Character 019");
+ displayNames.insert(INTERFACEKEY_STRING_A020, "String: Character 020");
+ displayNames.insert(INTERFACEKEY_STRING_A021, "String: Character 021");
+ displayNames.insert(INTERFACEKEY_STRING_A022, "String: Character 022");
+ displayNames.insert(INTERFACEKEY_STRING_A023, "String: Character 023");
+ displayNames.insert(INTERFACEKEY_STRING_A024, "String: Character 024");
+ displayNames.insert(INTERFACEKEY_STRING_A025, "String: Character 025");
+ displayNames.insert(INTERFACEKEY_STRING_A026, "String: Character 026");
+ displayNames.insert(INTERFACEKEY_STRING_A027, "String: Character 027");
+ displayNames.insert(INTERFACEKEY_STRING_A028, "String: Character 028");
+ displayNames.insert(INTERFACEKEY_STRING_A029, "String: Character 029");
+ displayNames.insert(INTERFACEKEY_STRING_A030, "String: Character 030");
+ displayNames.insert(INTERFACEKEY_STRING_A031, "String: Character 031");
+ displayNames.insert(INTERFACEKEY_STRING_A032, "String: Character 032");
+ displayNames.insert(INTERFACEKEY_STRING_A033, "String: Character 033");
+ displayNames.insert(INTERFACEKEY_STRING_A034, "String: Character 034");
+ displayNames.insert(INTERFACEKEY_STRING_A035, "String: Character 035");
+ displayNames.insert(INTERFACEKEY_STRING_A036, "String: Character 036");
+ displayNames.insert(INTERFACEKEY_STRING_A037, "String: Character 037");
+ displayNames.insert(INTERFACEKEY_STRING_A038, "String: Character 038");
+ displayNames.insert(INTERFACEKEY_STRING_A039, "String: Character 039");
+ displayNames.insert(INTERFACEKEY_STRING_A040, "String: Character 040");
+ displayNames.insert(INTERFACEKEY_STRING_A041, "String: Character 041");
+ displayNames.insert(INTERFACEKEY_STRING_A042, "String: Character 042");
+ displayNames.insert(INTERFACEKEY_STRING_A043, "String: Character 043");
+ displayNames.insert(INTERFACEKEY_STRING_A044, "String: Character 044");
+ displayNames.insert(INTERFACEKEY_STRING_A045, "String: Character 045");
+ displayNames.insert(INTERFACEKEY_STRING_A046, "String: Character 046");
+ displayNames.insert(INTERFACEKEY_STRING_A047, "String: Character 047");
+ displayNames.insert(INTERFACEKEY_STRING_A048, "String: Character 048");
+ displayNames.insert(INTERFACEKEY_STRING_A049, "String: Character 049");
+ displayNames.insert(INTERFACEKEY_STRING_A050, "String: Character 050");
+ displayNames.insert(INTERFACEKEY_STRING_A051, "String: Character 051");
+ displayNames.insert(INTERFACEKEY_STRING_A052, "String: Character 052");
+ displayNames.insert(INTERFACEKEY_STRING_A053, "String: Character 053");
+ displayNames.insert(INTERFACEKEY_STRING_A054, "String: Character 054");
+ displayNames.insert(INTERFACEKEY_STRING_A055, "String: Character 055");
+ displayNames.insert(INTERFACEKEY_STRING_A056, "String: Character 056");
+ displayNames.insert(INTERFACEKEY_STRING_A057, "String: Character 057");
+ displayNames.insert(INTERFACEKEY_STRING_A058, "String: Character 058");
+ displayNames.insert(INTERFACEKEY_STRING_A059, "String: Character 059");
+ displayNames.insert(INTERFACEKEY_STRING_A060, "String: Character 060");
+ displayNames.insert(INTERFACEKEY_STRING_A061, "String: Character 061");
+ displayNames.insert(INTERFACEKEY_STRING_A062, "String: Character 062");
+ displayNames.insert(INTERFACEKEY_STRING_A063, "String: Character 063");
+ displayNames.insert(INTERFACEKEY_STRING_A064, "String: Character 064");
+ displayNames.insert(INTERFACEKEY_STRING_A065, "String: Character 065");
+ displayNames.insert(INTERFACEKEY_STRING_A066, "String: Character 066");
+ displayNames.insert(INTERFACEKEY_STRING_A067, "String: Character 067");
+ displayNames.insert(INTERFACEKEY_STRING_A068, "String: Character 068");
+ displayNames.insert(INTERFACEKEY_STRING_A069, "String: Character 069");
+ displayNames.insert(INTERFACEKEY_STRING_A070, "String: Character 070");
+ displayNames.insert(INTERFACEKEY_STRING_A071, "String: Character 071");
+ displayNames.insert(INTERFACEKEY_STRING_A072, "String: Character 072");
+ displayNames.insert(INTERFACEKEY_STRING_A073, "String: Character 073");
+ displayNames.insert(INTERFACEKEY_STRING_A074, "String: Character 074");
+ displayNames.insert(INTERFACEKEY_STRING_A075, "String: Character 075");
+ displayNames.insert(INTERFACEKEY_STRING_A076, "String: Character 076");
+ displayNames.insert(INTERFACEKEY_STRING_A077, "String: Character 077");
+ displayNames.insert(INTERFACEKEY_STRING_A078, "String: Character 078");
+ displayNames.insert(INTERFACEKEY_STRING_A079, "String: Character 079");
+ displayNames.insert(INTERFACEKEY_STRING_A080, "String: Character 080");
+ displayNames.insert(INTERFACEKEY_STRING_A081, "String: Character 081");
+ displayNames.insert(INTERFACEKEY_STRING_A082, "String: Character 082");
+ displayNames.insert(INTERFACEKEY_STRING_A083, "String: Character 083");
+ displayNames.insert(INTERFACEKEY_STRING_A084, "String: Character 084");
+ displayNames.insert(INTERFACEKEY_STRING_A085, "String: Character 085");
+ displayNames.insert(INTERFACEKEY_STRING_A086, "String: Character 086");
+ displayNames.insert(INTERFACEKEY_STRING_A087, "String: Character 087");
+ displayNames.insert(INTERFACEKEY_STRING_A088, "String: Character 088");
+ displayNames.insert(INTERFACEKEY_STRING_A089, "String: Character 089");
+ displayNames.insert(INTERFACEKEY_STRING_A090, "String: Character 090");
+ displayNames.insert(INTERFACEKEY_STRING_A091, "String: Character 091");
+ displayNames.insert(INTERFACEKEY_STRING_A092, "String: Character 092");
+ displayNames.insert(INTERFACEKEY_STRING_A093, "String: Character 093");
+ displayNames.insert(INTERFACEKEY_STRING_A094, "String: Character 094");
+ displayNames.insert(INTERFACEKEY_STRING_A095, "String: Character 095");
+ displayNames.insert(INTERFACEKEY_STRING_A096, "String: Character 096");
+ displayNames.insert(INTERFACEKEY_STRING_A097, "String: Character 097");
+ displayNames.insert(INTERFACEKEY_STRING_A098, "String: Character 098");
+ displayNames.insert(INTERFACEKEY_STRING_A099, "String: Character 099");
+ displayNames.insert(INTERFACEKEY_STRING_A100, "String: Character 100");
+ displayNames.insert(INTERFACEKEY_STRING_A101, "String: Character 101");
+ displayNames.insert(INTERFACEKEY_STRING_A102, "String: Character 102");
+ displayNames.insert(INTERFACEKEY_STRING_A103, "String: Character 103");
+ displayNames.insert(INTERFACEKEY_STRING_A104, "String: Character 104");
+ displayNames.insert(INTERFACEKEY_STRING_A105, "String: Character 105");
+ displayNames.insert(INTERFACEKEY_STRING_A106, "String: Character 106");
+ displayNames.insert(INTERFACEKEY_STRING_A107, "String: Character 107");
+ displayNames.insert(INTERFACEKEY_STRING_A108, "String: Character 108");
+ displayNames.insert(INTERFACEKEY_STRING_A109, "String: Character 109");
+ displayNames.insert(INTERFACEKEY_STRING_A110, "String: Character 110");
+ displayNames.insert(INTERFACEKEY_STRING_A111, "String: Character 111");
+ displayNames.insert(INTERFACEKEY_STRING_A112, "String: Character 112");
+ displayNames.insert(INTERFACEKEY_STRING_A113, "String: Character 113");
+ displayNames.insert(INTERFACEKEY_STRING_A114, "String: Character 114");
+ displayNames.insert(INTERFACEKEY_STRING_A115, "String: Character 115");
+ displayNames.insert(INTERFACEKEY_STRING_A116, "String: Character 116");
+ displayNames.insert(INTERFACEKEY_STRING_A117, "String: Character 117");
+ displayNames.insert(INTERFACEKEY_STRING_A118, "String: Character 118");
+ displayNames.insert(INTERFACEKEY_STRING_A119, "String: Character 119");
+ displayNames.insert(INTERFACEKEY_STRING_A120, "String: Character 120");
+ displayNames.insert(INTERFACEKEY_STRING_A121, "String: Character 121");
+ displayNames.insert(INTERFACEKEY_STRING_A122, "String: Character 122");
+ displayNames.insert(INTERFACEKEY_STRING_A123, "String: Character 123");
+ displayNames.insert(INTERFACEKEY_STRING_A124, "String: Character 124");
+ displayNames.insert(INTERFACEKEY_STRING_A125, "String: Character 125");
+ displayNames.insert(INTERFACEKEY_STRING_A126, "String: Character 126");
+ displayNames.insert(INTERFACEKEY_STRING_A128, "String: Character 128");
+ displayNames.insert(INTERFACEKEY_STRING_A129, "String: Character 129");
+ displayNames.insert(INTERFACEKEY_STRING_A130, "String: Character 130");
+ displayNames.insert(INTERFACEKEY_STRING_A131, "String: Character 131");
+ displayNames.insert(INTERFACEKEY_STRING_A132, "String: Character 132");
+ displayNames.insert(INTERFACEKEY_STRING_A133, "String: Character 133");
+ displayNames.insert(INTERFACEKEY_STRING_A134, "String: Character 134");
+ displayNames.insert(INTERFACEKEY_STRING_A135, "String: Character 135");
+ displayNames.insert(INTERFACEKEY_STRING_A136, "String: Character 136");
+ displayNames.insert(INTERFACEKEY_STRING_A137, "String: Character 137");
+ displayNames.insert(INTERFACEKEY_STRING_A138, "String: Character 138");
+ displayNames.insert(INTERFACEKEY_STRING_A139, "String: Character 139");
+ displayNames.insert(INTERFACEKEY_STRING_A140, "String: Character 140");
+ displayNames.insert(INTERFACEKEY_STRING_A141, "String: Character 141");
+ displayNames.insert(INTERFACEKEY_STRING_A142, "String: Character 142");
+ displayNames.insert(INTERFACEKEY_STRING_A143, "String: Character 143");
+ displayNames.insert(INTERFACEKEY_STRING_A144, "String: Character 144");
+ displayNames.insert(INTERFACEKEY_STRING_A145, "String: Character 145");
+ displayNames.insert(INTERFACEKEY_STRING_A146, "String: Character 146");
+ displayNames.insert(INTERFACEKEY_STRING_A147, "String: Character 147");
+ displayNames.insert(INTERFACEKEY_STRING_A148, "String: Character 148");
+ displayNames.insert(INTERFACEKEY_STRING_A149, "String: Character 149");
+ displayNames.insert(INTERFACEKEY_STRING_A150, "String: Character 150");
+ displayNames.insert(INTERFACEKEY_STRING_A151, "String: Character 151");
+ displayNames.insert(INTERFACEKEY_STRING_A152, "String: Character 152");
+ displayNames.insert(INTERFACEKEY_STRING_A153, "String: Character 153");
+ displayNames.insert(INTERFACEKEY_STRING_A154, "String: Character 154");
+ displayNames.insert(INTERFACEKEY_STRING_A155, "String: Character 155");
+ displayNames.insert(INTERFACEKEY_STRING_A156, "String: Character 156");
+ displayNames.insert(INTERFACEKEY_STRING_A157, "String: Character 157");
+ displayNames.insert(INTERFACEKEY_STRING_A158, "String: Character 158");
+ displayNames.insert(INTERFACEKEY_STRING_A159, "String: Character 159");
+ displayNames.insert(INTERFACEKEY_STRING_A160, "String: Character 160");
+ displayNames.insert(INTERFACEKEY_STRING_A161, "String: Character 161");
+ displayNames.insert(INTERFACEKEY_STRING_A162, "String: Character 162");
+ displayNames.insert(INTERFACEKEY_STRING_A163, "String: Character 163");
+ displayNames.insert(INTERFACEKEY_STRING_A164, "String: Character 164");
+ displayNames.insert(INTERFACEKEY_STRING_A165, "String: Character 165");
+ displayNames.insert(INTERFACEKEY_STRING_A166, "String: Character 166");
+ displayNames.insert(INTERFACEKEY_STRING_A167, "String: Character 167");
+ displayNames.insert(INTERFACEKEY_STRING_A168, "String: Character 168");
+ displayNames.insert(INTERFACEKEY_STRING_A169, "String: Character 169");
+ displayNames.insert(INTERFACEKEY_STRING_A170, "String: Character 170");
+ displayNames.insert(INTERFACEKEY_STRING_A171, "String: Character 171");
+ displayNames.insert(INTERFACEKEY_STRING_A172, "String: Character 172");
+ displayNames.insert(INTERFACEKEY_STRING_A173, "String: Character 173");
+ displayNames.insert(INTERFACEKEY_STRING_A174, "String: Character 174");
+ displayNames.insert(INTERFACEKEY_STRING_A175, "String: Character 175");
+ displayNames.insert(INTERFACEKEY_STRING_A176, "String: Character 176");
+ displayNames.insert(INTERFACEKEY_STRING_A177, "String: Character 177");
+ displayNames.insert(INTERFACEKEY_STRING_A178, "String: Character 178");
+ displayNames.insert(INTERFACEKEY_STRING_A179, "String: Character 179");
+ displayNames.insert(INTERFACEKEY_STRING_A180, "String: Character 180");
+ displayNames.insert(INTERFACEKEY_STRING_A181, "String: Character 181");
+ displayNames.insert(INTERFACEKEY_STRING_A182, "String: Character 182");
+ displayNames.insert(INTERFACEKEY_STRING_A183, "String: Character 183");
+ displayNames.insert(INTERFACEKEY_STRING_A184, "String: Character 184");
+ displayNames.insert(INTERFACEKEY_STRING_A185, "String: Character 185");
+ displayNames.insert(INTERFACEKEY_STRING_A186, "String: Character 186");
+ displayNames.insert(INTERFACEKEY_STRING_A187, "String: Character 187");
+ displayNames.insert(INTERFACEKEY_STRING_A188, "String: Character 188");
+ displayNames.insert(INTERFACEKEY_STRING_A189, "String: Character 189");
+ displayNames.insert(INTERFACEKEY_STRING_A190, "String: Character 190");
+ displayNames.insert(INTERFACEKEY_STRING_A191, "String: Character 191");
+ displayNames.insert(INTERFACEKEY_STRING_A192, "String: Character 192");
+ displayNames.insert(INTERFACEKEY_STRING_A193, "String: Character 193");
+ displayNames.insert(INTERFACEKEY_STRING_A194, "String: Character 194");
+ displayNames.insert(INTERFACEKEY_STRING_A195, "String: Character 195");
+ displayNames.insert(INTERFACEKEY_STRING_A196, "String: Character 196");
+ displayNames.insert(INTERFACEKEY_STRING_A197, "String: Character 197");
+ displayNames.insert(INTERFACEKEY_STRING_A198, "String: Character 198");
+ displayNames.insert(INTERFACEKEY_STRING_A199, "String: Character 199");
+ displayNames.insert(INTERFACEKEY_STRING_A200, "String: Character 200");
+ displayNames.insert(INTERFACEKEY_STRING_A201, "String: Character 201");
+ displayNames.insert(INTERFACEKEY_STRING_A202, "String: Character 202");
+ displayNames.insert(INTERFACEKEY_STRING_A203, "String: Character 203");
+ displayNames.insert(INTERFACEKEY_STRING_A204, "String: Character 204");
+ displayNames.insert(INTERFACEKEY_STRING_A205, "String: Character 205");
+ displayNames.insert(INTERFACEKEY_STRING_A206, "String: Character 206");
+ displayNames.insert(INTERFACEKEY_STRING_A207, "String: Character 207");
+ displayNames.insert(INTERFACEKEY_STRING_A208, "String: Character 208");
+ displayNames.insert(INTERFACEKEY_STRING_A209, "String: Character 209");
+ displayNames.insert(INTERFACEKEY_STRING_A210, "String: Character 210");
+ displayNames.insert(INTERFACEKEY_STRING_A211, "String: Character 211");
+ displayNames.insert(INTERFACEKEY_STRING_A212, "String: Character 212");
+ displayNames.insert(INTERFACEKEY_STRING_A213, "String: Character 213");
+ displayNames.insert(INTERFACEKEY_STRING_A214, "String: Character 214");
+ displayNames.insert(INTERFACEKEY_STRING_A215, "String: Character 215");
+ displayNames.insert(INTERFACEKEY_STRING_A216, "String: Character 216");
+ displayNames.insert(INTERFACEKEY_STRING_A217, "String: Character 217");
+ displayNames.insert(INTERFACEKEY_STRING_A218, "String: Character 218");
+ displayNames.insert(INTERFACEKEY_STRING_A219, "String: Character 219");
+ displayNames.insert(INTERFACEKEY_STRING_A220, "String: Character 220");
+ displayNames.insert(INTERFACEKEY_STRING_A221, "String: Character 221");
+ displayNames.insert(INTERFACEKEY_STRING_A222, "String: Character 222");
+ displayNames.insert(INTERFACEKEY_STRING_A223, "String: Character 223");
+ displayNames.insert(INTERFACEKEY_STRING_A224, "String: Character 224");
+ displayNames.insert(INTERFACEKEY_STRING_A225, "String: Character 225");
+ displayNames.insert(INTERFACEKEY_STRING_A226, "String: Character 226");
+ displayNames.insert(INTERFACEKEY_STRING_A227, "String: Character 227");
+ displayNames.insert(INTERFACEKEY_STRING_A228, "String: Character 228");
+ displayNames.insert(INTERFACEKEY_STRING_A229, "String: Character 229");
+ displayNames.insert(INTERFACEKEY_STRING_A230, "String: Character 230");
+ displayNames.insert(INTERFACEKEY_STRING_A231, "String: Character 231");
+ displayNames.insert(INTERFACEKEY_STRING_A232, "String: Character 232");
+ displayNames.insert(INTERFACEKEY_STRING_A233, "String: Character 233");
+ displayNames.insert(INTERFACEKEY_STRING_A234, "String: Character 234");
+ displayNames.insert(INTERFACEKEY_STRING_A235, "String: Character 235");
+ displayNames.insert(INTERFACEKEY_STRING_A236, "String: Character 236");
+ displayNames.insert(INTERFACEKEY_STRING_A237, "String: Character 237");
+ displayNames.insert(INTERFACEKEY_STRING_A238, "String: Character 238");
+ displayNames.insert(INTERFACEKEY_STRING_A239, "String: Character 239");
+ displayNames.insert(INTERFACEKEY_STRING_A240, "String: Character 240");
+ displayNames.insert(INTERFACEKEY_STRING_A241, "String: Character 241");
+ displayNames.insert(INTERFACEKEY_STRING_A242, "String: Character 242");
+ displayNames.insert(INTERFACEKEY_STRING_A243, "String: Character 243");
+ displayNames.insert(INTERFACEKEY_STRING_A244, "String: Character 244");
+ displayNames.insert(INTERFACEKEY_STRING_A245, "String: Character 245");
+ displayNames.insert(INTERFACEKEY_STRING_A246, "String: Character 246");
+ displayNames.insert(INTERFACEKEY_STRING_A247, "String: Character 247");
+ displayNames.insert(INTERFACEKEY_STRING_A248, "String: Character 248");
+ displayNames.insert(INTERFACEKEY_STRING_A249, "String: Character 249");
+ displayNames.insert(INTERFACEKEY_STRING_A250, "String: Character 250");
+ displayNames.insert(INTERFACEKEY_STRING_A251, "String: Character 251");
+ displayNames.insert(INTERFACEKEY_STRING_A252, "String: Character 252");
+ displayNames.insert(INTERFACEKEY_STRING_A253, "String: Character 253");
+ displayNames.insert(INTERFACEKEY_STRING_A254, "String: Character 254");
+ displayNames.insert(INTERFACEKEY_STRING_A255, "String: Character 255");
+ displayNames.insert(INTERFACEKEY_CUSTOM_A, "Custom: A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_B, "Custom: B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_C, "Custom: C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_D, "Custom: D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_E, "Custom: E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_F, "Custom: F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_G, "Custom: G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_H, "Custom: H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_I, "Custom: I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_J, "Custom: J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_K, "Custom: K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_L, "Custom: L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_M, "Custom: M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_N, "Custom: N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_O, "Custom: O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_P, "Custom: P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_Q, "Custom: Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_R, "Custom: R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_S, "Custom: S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_T, "Custom: T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_U, "Custom: U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_V, "Custom: V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_W, "Custom: W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_X, "Custom: X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_Y, "Custom: Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_Z, "Custom: Z");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_A, "Custom: Shift + A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_B, "Custom: Shift + B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_C, "Custom: Shift + C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_D, "Custom: Shift + D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_E, "Custom: Shift + E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_F, "Custom: Shift + F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_G, "Custom: Shift + G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_H, "Custom: Shift + H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_I, "Custom: Shift + I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_J, "Custom: Shift + J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_K, "Custom: Shift + K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_L, "Custom: Shift + L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_M, "Custom: Shift + M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_N, "Custom: Shift + N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_O, "Custom: Shift + O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_P, "Custom: Shift + P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Q, "Custom: Shift + Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_R, "Custom: Shift + R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_S, "Custom: Shift + S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_T, "Custom: Shift + T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_U, "Custom: Shift + U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_V, "Custom: Shift + V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_W, "Custom: Shift + W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_X, "Custom: Shift + X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Y, "Custom: Shift + Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_SHIFT_Z, "Custom: Shift + Z");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_A, "Custom: Ctrl + A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_B, "Custom: Ctrl + B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_C, "Custom: Ctrl + C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_D, "Custom: Ctrl + D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_E, "Custom: Ctrl + E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_F, "Custom: Ctrl + F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_G, "Custom: Ctrl + G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_H, "Custom: Ctrl + H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_I, "Custom: Ctrl + I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_J, "Custom: Ctrl + J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_K, "Custom: Ctrl + K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_L, "Custom: Ctrl + L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_M, "Custom: Ctrl + M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_N, "Custom: Ctrl + N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_O, "Custom: Ctrl + O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_P, "Custom: Ctrl + P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_Q, "Custom: Ctrl + Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_R, "Custom: Ctrl + R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_S, "Custom: Ctrl + S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_T, "Custom: Ctrl + T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_U, "Custom: Ctrl + U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_V, "Custom: Ctrl + V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_W, "Custom: Ctrl + W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_X, "Custom: Ctrl + X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_Y, "Custom: Ctrl + Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_CTRL_Z, "Custom: Ctrl + Z");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_A, "Custom: Alt + A");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_B, "Custom: Alt + B");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_C, "Custom: Alt + C");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_D, "Custom: Alt + D");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_E, "Custom: Alt + E");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_F, "Custom: Alt + F");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_G, "Custom: Alt + G");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_H, "Custom: Alt + H");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_I, "Custom: Alt + I");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_J, "Custom: Alt + J");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_K, "Custom: Alt + K");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_L, "Custom: Alt + L");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_M, "Custom: Alt + M");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_N, "Custom: Alt + N");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_O, "Custom: Alt + O");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_P, "Custom: Alt + P");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_Q, "Custom: Alt + Q");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_R, "Custom: Alt + R");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_S, "Custom: Alt + S");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_T, "Custom: Alt + T");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_U, "Custom: Alt + U");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_V, "Custom: Alt + V");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_W, "Custom: Alt + W");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_X, "Custom: Alt + X");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_Y, "Custom: Alt + Y");
+ displayNames.insert(INTERFACEKEY_CUSTOM_ALT_Z, "Custom: Alt + Z");
+ displayNames.insert(INTERFACEKEY_FPS_UP, "Increase FPS limit");
+ displayNames.insert(INTERFACEKEY_FPS_DOWN, "Decrease FPS limit");
+ displayNames.insert(INTERFACEKEY_TOGGLE_TTF, "Toggle Truetype rendering");
+ displayNames.insert(INTERFACEKEY_PREFIX, "Command repeat prefix-key");
+
+
+ sdlNames.insert(SDLK_BACKSPACE, "Backspace");
+ sdlNames.insert(SDLK_TAB, "Tab");
+ sdlNames.insert(SDLK_CLEAR, "Clear");
+ sdlNames.insert(SDLK_RETURN, "Enter");
+ sdlNames.insert(SDLK_PAUSE, "Pause");
+ sdlNames.insert(SDLK_ESCAPE, "ESC");
+ sdlNames.insert(SDLK_SPACE, "Space");
+ sdlNames.insert(SDLK_EXCLAIM, "Exclaim");
+ sdlNames.insert(SDLK_QUOTEDBL, "Quotedbl");
+ sdlNames.insert(SDLK_HASH, "Hash");
+ sdlNames.insert(SDLK_DOLLAR, "Dollar");
+ sdlNames.insert(SDLK_AMPERSAND, "Ampersand");
+ sdlNames.insert(SDLK_QUOTE, "Quote");
+ sdlNames.insert(SDLK_LEFTPAREN, "Leftparen");
+ sdlNames.insert(SDLK_RIGHTPAREN, "Rightparen");
+ sdlNames.insert(SDLK_ASTERISK, "Asterisk");
+ sdlNames.insert(SDLK_PLUS, "Plus");
+ sdlNames.insert(SDLK_COMMA, "Comma");
+ sdlNames.insert(SDLK_MINUS, "Minus");
+ sdlNames.insert(SDLK_PERIOD, "Period");
+ sdlNames.insert(SDLK_SLASH, "Slash");
+ sdlNames.insert(SDLK_0, "0");
+ sdlNames.insert(SDLK_1, "1");
+ sdlNames.insert(SDLK_2, "2");
+ sdlNames.insert(SDLK_3, "3");
+ sdlNames.insert(SDLK_4, "4");
+ sdlNames.insert(SDLK_5, "5");
+ sdlNames.insert(SDLK_6, "6");
+ sdlNames.insert(SDLK_7, "7");
+ sdlNames.insert(SDLK_8, "8");
+ sdlNames.insert(SDLK_9, "9");
+ sdlNames.insert(SDLK_COLON, "Colon");
+ sdlNames.insert(SDLK_SEMICOLON, "Semicolon");
+ sdlNames.insert(SDLK_LESS, "Less");
+ sdlNames.insert(SDLK_EQUALS, "Equals");
+ sdlNames.insert(SDLK_GREATER, "Greater");
+ sdlNames.insert(SDLK_QUESTION, "Question");
+ sdlNames.insert(SDLK_AT, "At");
+ sdlNames.insert(SDLK_LEFTBRACKET, "Leftbracket");
+ sdlNames.insert(SDLK_BACKSLASH, "Backslash");
+ sdlNames.insert(SDLK_RIGHTBRACKET, "Rightbracket");
+ sdlNames.insert(SDLK_CARET, "Caret");
+ sdlNames.insert(SDLK_UNDERSCORE, "Underscore");
+ sdlNames.insert(SDLK_BACKQUOTE, "Backquote");
+ sdlNames.insert(SDLK_a, "a");
+ sdlNames.insert(SDLK_b, "b");
+ sdlNames.insert(SDLK_c, "c");
+ sdlNames.insert(SDLK_d, "d");
+ sdlNames.insert(SDLK_e, "e");
+ sdlNames.insert(SDLK_f, "f");
+ sdlNames.insert(SDLK_g, "g");
+ sdlNames.insert(SDLK_h, "h");
+ sdlNames.insert(SDLK_i, "i");
+ sdlNames.insert(SDLK_j, "j");
+ sdlNames.insert(SDLK_k, "k");
+ sdlNames.insert(SDLK_l, "l");
+ sdlNames.insert(SDLK_m, "m");
+ sdlNames.insert(SDLK_n, "n");
+ sdlNames.insert(SDLK_o, "o");
+ sdlNames.insert(SDLK_p, "p");
+ sdlNames.insert(SDLK_q, "q");
+ sdlNames.insert(SDLK_r, "r");
+ sdlNames.insert(SDLK_s, "s");
+ sdlNames.insert(SDLK_t, "t");
+ sdlNames.insert(SDLK_u, "u");
+ sdlNames.insert(SDLK_v, "v");
+ sdlNames.insert(SDLK_w, "w");
+ sdlNames.insert(SDLK_x, "x");
+ sdlNames.insert(SDLK_y, "y");
+ sdlNames.insert(SDLK_z, "z");
+ sdlNames.insert(SDLK_DELETE, "Delete");
+ sdlNames.insert(SDLK_KP0, "Numpad 0");
+ sdlNames.insert(SDLK_KP1, "Numpad 1");
+ sdlNames.insert(SDLK_KP2, "Numpad 2");
+ sdlNames.insert(SDLK_KP3, "Numpad 3");
+ sdlNames.insert(SDLK_KP4, "Numpad 4");
+ sdlNames.insert(SDLK_KP5, "Numpad 5");
+ sdlNames.insert(SDLK_KP6, "Numpad 6");
+ sdlNames.insert(SDLK_KP7, "Numpad 7");
+ sdlNames.insert(SDLK_KP8, "Numpad 8");
+ sdlNames.insert(SDLK_KP9, "Numpad 9");
+ sdlNames.insert(SDLK_KP_PERIOD, "Numpad Period");
+ sdlNames.insert(SDLK_KP_DIVIDE, "Numpad Divide");
+ sdlNames.insert(SDLK_KP_MULTIPLY, "Numpad Multiply");
+ sdlNames.insert(SDLK_KP_PLUS, "Numpad Plus");
+ sdlNames.insert(SDLK_KP_MINUS, "Numpad Minus");
+ sdlNames.insert(SDLK_KP_ENTER, "Numpad Enter");
+ sdlNames.insert(SDLK_KP_EQUALS, "Numpad Equals");
+ sdlNames.insert(SDLK_UP, "Up");
+ sdlNames.insert(SDLK_DOWN, "Down");
+ sdlNames.insert(SDLK_RIGHT, "Right");
+ sdlNames.insert(SDLK_LEFT, "Left");
+ sdlNames.insert(SDLK_INSERT, "Insert");
+ sdlNames.insert(SDLK_HOME, "Home");
+ sdlNames.insert(SDLK_END, "End");
+ sdlNames.insert(SDLK_PAGEUP, "Page Up");
+ sdlNames.insert(SDLK_PAGEDOWN, "Page Down");
+ sdlNames.insert(SDLK_F1, "F1");
+ sdlNames.insert(SDLK_F2, "F2");
+ sdlNames.insert(SDLK_F3, "F3");
+ sdlNames.insert(SDLK_F4, "F4");
+ sdlNames.insert(SDLK_F5, "F5");
+ sdlNames.insert(SDLK_F6, "F6");
+ sdlNames.insert(SDLK_F7, "F7");
+ sdlNames.insert(SDLK_F8, "F8");
+ sdlNames.insert(SDLK_F9, "F9");
+ sdlNames.insert(SDLK_F10, "F10");
+ sdlNames.insert(SDLK_F11, "F11");
+ sdlNames.insert(SDLK_F12, "F12");
+ sdlNames.insert(SDLK_F13, "F13");
+ sdlNames.insert(SDLK_F14, "F14");
+ sdlNames.insert(SDLK_F15, "F15");
+ sdlNames.insert(SDLK_NUMLOCK, "Numlock");
+ sdlNames.insert(SDLK_CAPSLOCK, "Capslock");
+ sdlNames.insert(SDLK_SCROLLOCK, "Scrollock");
+ sdlNames.insert(SDLK_RSHIFT, "Rshift");
+ sdlNames.insert(SDLK_LSHIFT, "Lshift");
+ sdlNames.insert(SDLK_RCTRL, "Rctrl");
+ sdlNames.insert(SDLK_LCTRL, "Lctrl");
+ sdlNames.insert(SDLK_RALT, "Ralt");
+ sdlNames.insert(SDLK_LALT, "Lalt");
+ sdlNames.insert(SDLK_RMETA, "Rmeta");
+ sdlNames.insert(SDLK_LMETA, "Lmeta");
+ sdlNames.insert(SDLK_LSUPER, "Lsuper");
+ sdlNames.insert(SDLK_RSUPER, "Rsuper");
+ sdlNames.insert(SDLK_MODE, "Mode");
+ sdlNames.insert(SDLK_COMPOSE, "Compose");
+ sdlNames.insert(SDLK_HELP, "Help");
+ sdlNames.insert(SDLK_PRINT, "Print");
+ sdlNames.insert(SDLK_SYSREQ, "Sysreq");
+ sdlNames.insert(SDLK_BREAK, "Break");
+ sdlNames.insert(SDLK_MENU, "Menu");
+ sdlNames.insert(SDLK_POWER, "Power");
+ sdlNames.insert(SDLK_EURO, "Euro");
+ sdlNames.insert(SDLK_UNDO, "Undo");
+}
diff --git a/g_src/keybindings.h b/g_src/keybindings.h
new file mode 100755
index 0000000..f1c9a95
--- /dev/null
+++ b/g_src/keybindings.h
@@ -0,0 +1,1524 @@
+#ifndef KEYBINDINGS_H
+#define KEYBINDINGS_H
+
+#include <SDL/SDL.h>
+#include <map>
+#include <string>
+
+#include "bimap.h"
+
+typedef long InterfaceKey;
+
+enum InterfaceKeyType
+{
+ INTERFACEKEY_NONE=0,
+ INTERFACEKEY_SELECT,
+ INTERFACEKEY_SEC_SELECT,
+ INTERFACEKEY_DESELECT,
+ INTERFACEKEY_SELECT_ALL,
+ INTERFACEKEY_DESELECT_ALL,
+ INTERFACEKEY_LEAVESCREEN,
+ INTERFACEKEY_LEAVESCREEN_ALL,
+ INTERFACEKEY_CLOSE_MEGA_ANNOUNCEMENT,
+ INTERFACEKEY_OPTIONS,
+ INTERFACEKEY_OPTION_EXPORT,
+ INTERFACEKEY_HELP,
+ INTERFACEKEY_TOGGLE_FULLSCREEN,
+ INTERFACEKEY_MOVIES,
+ INTERFACEKEY_ZOOM_IN,
+ INTERFACEKEY_ZOOM_OUT,
+ INTERFACEKEY_ZOOM_TOGGLE,
+ INTERFACEKEY_ZOOM_RESET,
+ INTERFACEKEY_MOVIE_RECORD,
+ INTERFACEKEY_MOVIE_PLAY,
+ INTERFACEKEY_MOVIE_SAVE,
+ INTERFACEKEY_MOVIE_LOAD,
+ INTERFACEKEY_TOGGLE_TTF,
+ INTERFACEKEY_FPS_UP,
+ INTERFACEKEY_FPS_DOWN,
+ INTERFACEKEY_CHANGETAB,
+ INTERFACEKEY_SEC_CHANGETAB,
+ INTERFACEKEY_STANDARDSCROLL_UP,
+ INTERFACEKEY_STANDARDSCROLL_DOWN,
+ INTERFACEKEY_STANDARDSCROLL_LEFT,
+ INTERFACEKEY_STANDARDSCROLL_RIGHT,
+ INTERFACEKEY_STANDARDSCROLL_PAGEUP,
+ INTERFACEKEY_STANDARDSCROLL_PAGEDOWN,
+ INTERFACEKEY_SECONDSCROLL_UP,
+ INTERFACEKEY_SECONDSCROLL_DOWN,
+ INTERFACEKEY_SECONDSCROLL_PAGEUP,
+ INTERFACEKEY_SECONDSCROLL_PAGEDOWN,
+ INTERFACEKEY_CURSOR_UP,
+ INTERFACEKEY_CURSOR_DOWN,
+ INTERFACEKEY_CURSOR_LEFT,
+ INTERFACEKEY_CURSOR_RIGHT,
+ INTERFACEKEY_CURSOR_UPLEFT,
+ INTERFACEKEY_CURSOR_UPRIGHT,
+ INTERFACEKEY_CURSOR_DOWNLEFT,
+ INTERFACEKEY_CURSOR_DOWNRIGHT,
+ INTERFACEKEY_CURSOR_UP_FAST,
+ INTERFACEKEY_CURSOR_DOWN_FAST,
+ INTERFACEKEY_CURSOR_LEFT_FAST,
+ INTERFACEKEY_CURSOR_RIGHT_FAST,
+ INTERFACEKEY_CURSOR_UPLEFT_FAST,
+ INTERFACEKEY_CURSOR_UPRIGHT_FAST,
+ INTERFACEKEY_CURSOR_DOWNLEFT_FAST,
+ INTERFACEKEY_CURSOR_DOWNRIGHT_FAST,
+ INTERFACEKEY_CURSOR_UP_Z,
+ INTERFACEKEY_CURSOR_DOWN_Z,
+ INTERFACEKEY_CURSOR_UP_Z_AUX,
+ INTERFACEKEY_CURSOR_DOWN_Z_AUX,
+ INTERFACEKEY_MENU_CONFIRM,
+ INTERFACEKEY_SAVE_BINDINGS,
+ INTERFACEKEY_LOAD_BINDINGS,
+ INTERFACEKEY_MACRO_BREAK,
+ INTERFACEKEY_RECORD_MACRO,
+ INTERFACEKEY_PLAY_MACRO,
+ INTERFACEKEY_SAVE_MACRO,
+ INTERFACEKEY_LOAD_MACRO,
+ INTERFACEKEY_PREFIX,
+ INTERFACEKEY_OPTION1,
+ INTERFACEKEY_OPTION2,
+ INTERFACEKEY_OPTION3,
+ INTERFACEKEY_OPTION4,
+ INTERFACEKEY_OPTION5,
+ INTERFACEKEY_OPTION6,
+ INTERFACEKEY_OPTION7,
+ INTERFACEKEY_OPTION8,
+ INTERFACEKEY_OPTION9,
+ INTERFACEKEY_OPTION10,
+ INTERFACEKEY_OPTION11,
+ INTERFACEKEY_OPTION12,
+ INTERFACEKEY_OPTION13,
+ INTERFACEKEY_OPTION14,
+ INTERFACEKEY_OPTION15,
+ INTERFACEKEY_OPTION16,
+ INTERFACEKEY_OPTION17,
+ INTERFACEKEY_OPTION18,
+ INTERFACEKEY_OPTION19,
+ INTERFACEKEY_OPTION20,
+ INTERFACEKEY_SEC_OPTION1,
+ INTERFACEKEY_SEC_OPTION2,
+ INTERFACEKEY_SEC_OPTION3,
+ INTERFACEKEY_SEC_OPTION4,
+ INTERFACEKEY_SEC_OPTION5,
+ INTERFACEKEY_SEC_OPTION6,
+ INTERFACEKEY_SEC_OPTION7,
+ INTERFACEKEY_SEC_OPTION8,
+ INTERFACEKEY_SEC_OPTION9,
+ INTERFACEKEY_SEC_OPTION10,
+ INTERFACEKEY_SEC_OPTION11,
+ INTERFACEKEY_SEC_OPTION12,
+ INTERFACEKEY_SEC_OPTION13,
+ INTERFACEKEY_SEC_OPTION14,
+ INTERFACEKEY_SEC_OPTION15,
+ INTERFACEKEY_SEC_OPTION16,
+ INTERFACEKEY_SEC_OPTION17,
+ INTERFACEKEY_SEC_OPTION18,
+ INTERFACEKEY_SEC_OPTION19,
+ INTERFACEKEY_SEC_OPTION20,
+ INTERFACEKEY_CUSTOM_A,
+ INTERFACEKEY_CUSTOM_B,
+ INTERFACEKEY_CUSTOM_C,
+ INTERFACEKEY_CUSTOM_D,
+ INTERFACEKEY_CUSTOM_E,
+ INTERFACEKEY_CUSTOM_F,
+ INTERFACEKEY_CUSTOM_G,
+ INTERFACEKEY_CUSTOM_H,
+ INTERFACEKEY_CUSTOM_I,
+ INTERFACEKEY_CUSTOM_J,
+ INTERFACEKEY_CUSTOM_K,
+ INTERFACEKEY_CUSTOM_L,
+ INTERFACEKEY_CUSTOM_M,
+ INTERFACEKEY_CUSTOM_N,
+ INTERFACEKEY_CUSTOM_O,
+ INTERFACEKEY_CUSTOM_P,
+ INTERFACEKEY_CUSTOM_Q,
+ INTERFACEKEY_CUSTOM_R,
+ INTERFACEKEY_CUSTOM_S,
+ INTERFACEKEY_CUSTOM_T,
+ INTERFACEKEY_CUSTOM_U,
+ INTERFACEKEY_CUSTOM_V,
+ INTERFACEKEY_CUSTOM_W,
+ INTERFACEKEY_CUSTOM_X,
+ INTERFACEKEY_CUSTOM_Y,
+ INTERFACEKEY_CUSTOM_Z,
+ INTERFACEKEY_CUSTOM_SHIFT_A,
+ INTERFACEKEY_CUSTOM_SHIFT_B,
+ INTERFACEKEY_CUSTOM_SHIFT_C,
+ INTERFACEKEY_CUSTOM_SHIFT_D,
+ INTERFACEKEY_CUSTOM_SHIFT_E,
+ INTERFACEKEY_CUSTOM_SHIFT_F,
+ INTERFACEKEY_CUSTOM_SHIFT_G,
+ INTERFACEKEY_CUSTOM_SHIFT_H,
+ INTERFACEKEY_CUSTOM_SHIFT_I,
+ INTERFACEKEY_CUSTOM_SHIFT_J,
+ INTERFACEKEY_CUSTOM_SHIFT_K,
+ INTERFACEKEY_CUSTOM_SHIFT_L,
+ INTERFACEKEY_CUSTOM_SHIFT_M,
+ INTERFACEKEY_CUSTOM_SHIFT_N,
+ INTERFACEKEY_CUSTOM_SHIFT_O,
+ INTERFACEKEY_CUSTOM_SHIFT_P,
+ INTERFACEKEY_CUSTOM_SHIFT_Q,
+ INTERFACEKEY_CUSTOM_SHIFT_R,
+ INTERFACEKEY_CUSTOM_SHIFT_S,
+ INTERFACEKEY_CUSTOM_SHIFT_T,
+ INTERFACEKEY_CUSTOM_SHIFT_U,
+ INTERFACEKEY_CUSTOM_SHIFT_V,
+ INTERFACEKEY_CUSTOM_SHIFT_W,
+ INTERFACEKEY_CUSTOM_SHIFT_X,
+ INTERFACEKEY_CUSTOM_SHIFT_Y,
+ INTERFACEKEY_CUSTOM_SHIFT_Z,
+ INTERFACEKEY_CUSTOM_CTRL_A,
+ INTERFACEKEY_CUSTOM_CTRL_B,
+ INTERFACEKEY_CUSTOM_CTRL_C,
+ INTERFACEKEY_CUSTOM_CTRL_D,
+ INTERFACEKEY_CUSTOM_CTRL_E,
+ INTERFACEKEY_CUSTOM_CTRL_F,
+ INTERFACEKEY_CUSTOM_CTRL_G,
+ INTERFACEKEY_CUSTOM_CTRL_H,
+ INTERFACEKEY_CUSTOM_CTRL_I,
+ INTERFACEKEY_CUSTOM_CTRL_J,
+ INTERFACEKEY_CUSTOM_CTRL_K,
+ INTERFACEKEY_CUSTOM_CTRL_L,
+ INTERFACEKEY_CUSTOM_CTRL_M,
+ INTERFACEKEY_CUSTOM_CTRL_N,
+ INTERFACEKEY_CUSTOM_CTRL_O,
+ INTERFACEKEY_CUSTOM_CTRL_P,
+ INTERFACEKEY_CUSTOM_CTRL_Q,
+ INTERFACEKEY_CUSTOM_CTRL_R,
+ INTERFACEKEY_CUSTOM_CTRL_S,
+ INTERFACEKEY_CUSTOM_CTRL_T,
+ INTERFACEKEY_CUSTOM_CTRL_U,
+ INTERFACEKEY_CUSTOM_CTRL_V,
+ INTERFACEKEY_CUSTOM_CTRL_W,
+ INTERFACEKEY_CUSTOM_CTRL_X,
+ INTERFACEKEY_CUSTOM_CTRL_Y,
+ INTERFACEKEY_CUSTOM_CTRL_Z,
+ INTERFACEKEY_CUSTOM_ALT_A,
+ INTERFACEKEY_CUSTOM_ALT_B,
+ INTERFACEKEY_CUSTOM_ALT_C,
+ INTERFACEKEY_CUSTOM_ALT_D,
+ INTERFACEKEY_CUSTOM_ALT_E,
+ INTERFACEKEY_CUSTOM_ALT_F,
+ INTERFACEKEY_CUSTOM_ALT_G,
+ INTERFACEKEY_CUSTOM_ALT_H,
+ INTERFACEKEY_CUSTOM_ALT_I,
+ INTERFACEKEY_CUSTOM_ALT_J,
+ INTERFACEKEY_CUSTOM_ALT_K,
+ INTERFACEKEY_CUSTOM_ALT_L,
+ INTERFACEKEY_CUSTOM_ALT_M,
+ INTERFACEKEY_CUSTOM_ALT_N,
+ INTERFACEKEY_CUSTOM_ALT_O,
+ INTERFACEKEY_CUSTOM_ALT_P,
+ INTERFACEKEY_CUSTOM_ALT_Q,
+ INTERFACEKEY_CUSTOM_ALT_R,
+ INTERFACEKEY_CUSTOM_ALT_S,
+ INTERFACEKEY_CUSTOM_ALT_T,
+ INTERFACEKEY_CUSTOM_ALT_U,
+ INTERFACEKEY_CUSTOM_ALT_V,
+ INTERFACEKEY_CUSTOM_ALT_W,
+ INTERFACEKEY_CUSTOM_ALT_X,
+ INTERFACEKEY_CUSTOM_ALT_Y,
+ INTERFACEKEY_CUSTOM_ALT_Z,
+
+ WORLDKEY_START,
+ INTERFACEKEY_WORLD_PARAM_TITLE=WORLDKEY_START,
+ INTERFACEKEY_WORLD_PARAM_ADD,
+ INTERFACEKEY_WORLD_PARAM_COPY,
+ INTERFACEKEY_WORLD_PARAM_DELETE,
+ INTERFACEKEY_WORLD_PARAM_NAME_RANDOM,
+ INTERFACEKEY_WORLD_PARAM_NAME_ENTER,
+ INTERFACEKEY_WORLD_PARAM_SEED_RANDOM,
+ INTERFACEKEY_WORLD_PARAM_SEED_ENTER,
+ INTERFACEKEY_WORLD_PARAM_LOAD,
+ INTERFACEKEY_WORLD_PARAM_SAVE,
+ INTERFACEKEY_WORLD_PARAM_DIM_X_UP,
+ INTERFACEKEY_WORLD_PARAM_DIM_X_DOWN,
+ INTERFACEKEY_WORLD_PARAM_DIM_Y_UP,
+ INTERFACEKEY_WORLD_PARAM_DIM_Y_DOWN,
+ INTERFACEKEY_WORLD_PARAM_SET,
+ INTERFACEKEY_WORLD_PARAM_INCREASE,
+ INTERFACEKEY_WORLD_PARAM_DECREASE,
+ INTERFACEKEY_WORLD_PARAM_ENTER_VALUE,
+ INTERFACEKEY_WORLD_PARAM_NULLIFY,
+ INTERFACEKEY_WORLD_PARAM_PRESET,
+ INTERFACEKEY_WORLD_PARAM_REJECT_CONTINUE,
+ INTERFACEKEY_WORLD_PARAM_REJECT_ABORT,
+ INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_THIS,
+ INTERFACEKEY_WORLD_PARAM_REJECT_ALLOW_ALL,
+ INTERFACEKEY_WORLD_GEN_CONTINUE,
+ INTERFACEKEY_WORLD_GEN_USE,
+ INTERFACEKEY_WORLD_GEN_ABORT,
+ INTERFACEKEY_WORLDGEN_EXPORT_MAP,
+ INTERFACEKEY_LEGENDS_EXPORT_MAP,
+ INTERFACEKEY_LEGENDS_EXPORT_XML,
+ INTERFACEKEY_LEGENDS_EXPORT_DETAILED_MAP,
+ INTERFACEKEY_LEGENDS_TOGGLE_CIVSITE,
+ INTERFACEKEY_LEGENDS_STRING_FILTER,
+
+ ADVENTURERKEY_START,
+ INTERFACEKEY_A_RETURN_TO_ARENA=ADVENTURERKEY_START,
+ INTERFACEKEY_A_MOVE_N,
+ INTERFACEKEY_A_MOVE_S,
+ INTERFACEKEY_A_MOVE_E,
+ INTERFACEKEY_A_MOVE_W,
+ INTERFACEKEY_A_MOVE_NW,
+ INTERFACEKEY_A_MOVE_NE,
+ INTERFACEKEY_A_MOVE_SW,
+ INTERFACEKEY_A_MOVE_SE,
+ INTERFACEKEY_A_MOVE_SAME_SQUARE,
+ INTERFACEKEY_A_CARE_MOVE_N,
+ INTERFACEKEY_A_CARE_MOVE_S,
+ INTERFACEKEY_A_CARE_MOVE_E,
+ INTERFACEKEY_A_CARE_MOVE_W,
+ INTERFACEKEY_A_CARE_MOVE_NW,
+ INTERFACEKEY_A_CARE_MOVE_NE,
+ INTERFACEKEY_A_CARE_MOVE_SW,
+ INTERFACEKEY_A_CARE_MOVE_SE,
+ INTERFACEKEY_A_CARE_MOVE_UPDOWN,
+ INTERFACEKEY_A_MOVE_N_UP,
+ INTERFACEKEY_A_MOVE_S_UP,
+ INTERFACEKEY_A_MOVE_E_UP,
+ INTERFACEKEY_A_MOVE_W_UP,
+ INTERFACEKEY_A_MOVE_NW_UP,
+ INTERFACEKEY_A_MOVE_NE_UP,
+ INTERFACEKEY_A_MOVE_SW_UP,
+ INTERFACEKEY_A_MOVE_SE_UP,
+ INTERFACEKEY_A_MOVE_UP,
+ INTERFACEKEY_A_MOVE_N_DOWN,
+ INTERFACEKEY_A_MOVE_S_DOWN,
+ INTERFACEKEY_A_MOVE_E_DOWN,
+ INTERFACEKEY_A_MOVE_W_DOWN,
+ INTERFACEKEY_A_MOVE_NW_DOWN,
+ INTERFACEKEY_A_MOVE_NE_DOWN,
+ INTERFACEKEY_A_MOVE_SW_DOWN,
+ INTERFACEKEY_A_MOVE_SE_DOWN,
+ INTERFACEKEY_A_MOVE_DOWN,
+ INTERFACEKEY_A_MOVE_UP_AUX,
+ INTERFACEKEY_A_MOVE_DOWN_AUX,
+ INTERFACEKEY_A_COMBAT_ATTACK,
+ INTERFACEKEY_A_COMBAT_DODGE,
+ INTERFACEKEY_A_COMBAT_CHARGEDEF,
+ INTERFACEKEY_A_STATUS,
+ INTERFACEKEY_A_STATUS_WRESTLE,
+ INTERFACEKEY_A_STATUS_CUSTOMIZE,
+ INTERFACEKEY_A_STATUS_KILLS,
+ INTERFACEKEY_A_STATUS_HEALTH,
+ INTERFACEKEY_A_STATUS_ATT_SKILL,
+ INTERFACEKEY_A_STATUS_DESC,
+ INTERFACEKEY_A_CLEAR_ANNOUNCEMENTS,
+ INTERFACEKEY_A_SLEEP,
+ INTERFACEKEY_A_SLEEP_SLEEP,
+ INTERFACEKEY_A_SLEEP_WAIT,
+ INTERFACEKEY_A_SLEEP_DAWN,
+ INTERFACEKEY_A_WAIT,
+ INTERFACEKEY_A_SHORT_WAIT,
+ INTERFACEKEY_A_ATTACK,
+ INTERFACEKEY_A_ATTACK_CONFIRM,
+ INTERFACEKEY_QUICK_ATTACK,
+ INTERFACEKEY_HEAVY_ATTACK,
+ INTERFACEKEY_WILD_ATTACK,
+ INTERFACEKEY_PRECISE_ATTACK,
+ INTERFACEKEY_CHARGE_ATTACK,
+ INTERFACEKEY_MULTI_ATTACK,
+ INTERFACEKEY_A_LOOK,
+ INTERFACEKEY_A_SEARCH,
+ INTERFACEKEY_A_ODOR,
+ INTERFACEKEY_A_DISPLAY_ODOR,
+ INTERFACEKEY_A_YIELD,
+ INTERFACEKEY_A_DISPLAY_TRACKS,
+ INTERFACEKEY_A_FRESHEST_TRACK,
+ INTERFACEKEY_A_INV_DRAW_WEAPON,
+ INTERFACEKEY_A_JUMP,
+ INTERFACEKEY_A_HOLD,
+ INTERFACEKEY_A_TALK,
+ INTERFACEKEY_A_INTERACT,
+ INTERFACEKEY_A_ACTION,
+ INTERFACEKEY_A_ACTION_CREATE,
+ INTERFACEKEY_A_ACTION_BUTCHER,
+ INTERFACEKEY_A_ACTION_ABILITY,
+ INTERFACEKEY_A_ACTION_POWER,
+ INTERFACEKEY_A_INV_LOOK,
+ INTERFACEKEY_A_INV_REMOVE,
+ INTERFACEKEY_A_INV_WEAR,
+ INTERFACEKEY_A_INV_EATDRINK,
+ INTERFACEKEY_A_INV_PUTIN,
+ INTERFACEKEY_A_INV_DROP,
+ INTERFACEKEY_A_GROUND,
+ INTERFACEKEY_A_THROW,
+ INTERFACEKEY_A_SHOOT,
+ INTERFACEKEY_A_ANNOUNCEMENTS,
+ INTERFACEKEY_A_COMBAT,
+ INTERFACEKEY_A_MOVEMENT,
+ INTERFACEKEY_A_MOVEMENT_SWIM,
+ INTERFACEKEY_A_SNEAK,
+ INTERFACEKEY_A_SPEED_SNEAK,
+ INTERFACEKEY_A_CENTER,
+ INTERFACEKEY_A_COMPANIONS,
+ INTERFACEKEY_A_BUILDING,
+ INTERFACEKEY_A_TRAVEL,
+ INTERFACEKEY_A_TRAVEL_SLEEP,
+ INTERFACEKEY_A_TRAVEL_MAP,
+ INTERFACEKEY_A_TRAVEL_HIDE_INSTRUCTIONS,
+ INTERFACEKEY_A_DATE,
+ INTERFACEKEY_A_WEATHER,
+ INTERFACEKEY_A_TEMPERATURE,
+ INTERFACEKEY_A_STANCE,
+ INTERFACEKEY_A_ENTER_NAME,
+ INTERFACEKEY_A_CUST_NAME,
+ INTERFACEKEY_A_RANDOM_NAME,
+ INTERFACEKEY_A_CHANGE_GENDER,
+ INTERFACEKEY_A_END_TRAVEL,
+ INTERFACEKEY_A_TRAVEL_CLOUDS,
+ INTERFACEKEY_A_LOG,
+ INTERFACEKEY_A_TRAVEL_LOG,
+ INTERFACEKEY_A_LOG_TASKS,
+ INTERFACEKEY_A_LOG_ENTITIES,
+ INTERFACEKEY_A_LOG_SITES,
+ INTERFACEKEY_A_LOG_SUBREGIONS,
+ INTERFACEKEY_A_LOG_FEATURE_LAYERS,
+ INTERFACEKEY_A_LOG_PEOPLE,
+ INTERFACEKEY_A_LOG_AGREEMENTS,
+ INTERFACEKEY_A_LOG_EVENTS,
+ INTERFACEKEY_A_LOG_BESTIARY,
+ INTERFACEKEY_A_LOG_FILTER,
+ INTERFACEKEY_A_LOG_ZOOM_CURRENT_LOCATION,
+ INTERFACEKEY_A_LOG_ZOOM_SELECTED,
+ INTERFACEKEY_A_LOG_LINE,
+ INTERFACEKEY_A_LOG_MAP,
+ INTERFACEKEY_A_BARTER_VIEW,
+ INTERFACEKEY_A_BARTER_CURRENCY_1,
+ INTERFACEKEY_A_BARTER_CURRENCY_2,
+ INTERFACEKEY_A_BARTER_TRADE,
+
+ EMBARKKEY_START,
+ INTERFACEKEY_SETUP_EMBARK=EMBARKKEY_START,
+ INTERFACEKEY_SETUP_NAME_FORT,
+ INTERFACEKEY_SETUP_NAME_GROUP,
+ INTERFACEKEY_SETUP_RECLAIM,
+ INTERFACEKEY_SETUP_FIND,
+ INTERFACEKEY_SETUP_NOTES,
+ INTERFACEKEY_SETUP_NOTES_TAKE_NOTES,
+ INTERFACEKEY_SETUP_NOTES_DELETE_NOTE,
+ INTERFACEKEY_SETUP_NOTES_CHANGE_SYMBOL_SELECTION,
+ INTERFACEKEY_SETUP_NOTES_ADOPT_SYMBOL,
+ INTERFACEKEY_SETUP_LOCAL_Y_UP,
+ INTERFACEKEY_SETUP_LOCAL_Y_DOWN,
+ INTERFACEKEY_SETUP_LOCAL_X_UP,
+ INTERFACEKEY_SETUP_LOCAL_X_DOWN,
+ INTERFACEKEY_SETUP_LOCAL_Y_MUP,
+ INTERFACEKEY_SETUP_LOCAL_Y_MDOWN,
+ INTERFACEKEY_SETUP_LOCAL_X_MUP,
+ INTERFACEKEY_SETUP_LOCAL_X_MDOWN,
+ INTERFACEKEY_SETUP_BIOME_1,
+ INTERFACEKEY_SETUP_BIOME_2,
+ INTERFACEKEY_SETUP_BIOME_3,
+ INTERFACEKEY_SETUP_BIOME_4,
+ INTERFACEKEY_SETUP_BIOME_5,
+ INTERFACEKEY_SETUP_BIOME_6,
+ INTERFACEKEY_SETUP_BIOME_7,
+ INTERFACEKEY_SETUP_BIOME_8,
+ INTERFACEKEY_SETUP_BIOME_9,
+ INTERFACEKEY_CHOOSE_NAME_RANDOM,
+ INTERFACEKEY_CHOOSE_NAME_CLEAR,
+ INTERFACEKEY_CHOOSE_NAME_TYPE,
+ INTERFACEKEY_SETUPGAME_NEW,
+ INTERFACEKEY_SETUPGAME_VIEW,
+ INTERFACEKEY_SETUPGAME_CUSTOMIZE_UNIT,
+ INTERFACEKEY_SETUPGAME_SAVE_PROFILE,
+ INTERFACEKEY_SETUPGAME_SAVE_PROFILE_ABORT,
+ INTERFACEKEY_SETUPGAME_SAVE_PROFILE_GO,
+ INTERFACEKEY_SETUPGAME_VIEW_PROFILE_PROBLEMS,
+
+ BUILDINGKEY_START,
+ INTERFACEKEY_BUILDJOB_ADD=BUILDINGKEY_START,
+ INTERFACEKEY_BUILDJOB_CANCEL,
+ INTERFACEKEY_BUILDJOB_PROMOTE,
+ INTERFACEKEY_BUILDJOB_NOW,
+ INTERFACEKEY_BUILDJOB_REPEAT,
+ INTERFACEKEY_BUILDJOB_SUSPEND,
+ INTERFACEKEY_BUILDJOB_WORKSHOP_PROFILE,
+ INTERFACEKEY_BUILDJOB_WELL_FREE,
+ INTERFACEKEY_BUILDJOB_WELL_SIZE,
+ INTERFACEKEY_BUILDJOB_TARGET_FREE,
+ INTERFACEKEY_BUILDJOB_TARGET_SIZE,
+ INTERFACEKEY_BUILDJOB_TARGET_DOWN,
+ INTERFACEKEY_BUILDJOB_TARGET_UP,
+ INTERFACEKEY_BUILDJOB_TARGET_RIGHT,
+ INTERFACEKEY_BUILDJOB_TARGET_LEFT,
+ INTERFACEKEY_BUILDJOB_STATUE_ASSIGN,
+ INTERFACEKEY_BUILDJOB_STATUE_FREE,
+ INTERFACEKEY_BUILDJOB_STATUE_SIZE,
+ INTERFACEKEY_BUILDJOB_CAGE_JUSTICE,
+ INTERFACEKEY_BUILDJOB_CAGE_FREE,
+ INTERFACEKEY_BUILDJOB_CAGE_SIZE,
+ INTERFACEKEY_BUILDJOB_CAGE_ASSIGN_OCC,
+ INTERFACEKEY_BUILDJOB_CAGE_WATER,
+ INTERFACEKEY_BUILDJOB_CAGE_ASSIGN,
+ INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN_OCC,
+ INTERFACEKEY_BUILDJOB_CHAIN_JUSTICE,
+ INTERFACEKEY_BUILDJOB_CHAIN_ASSIGN,
+ INTERFACEKEY_BUILDJOB_CHAIN_FREE,
+ INTERFACEKEY_BUILDJOB_CHAIN_SIZE,
+ INTERFACEKEY_BUILDJOB_SIEGE_FIRING,
+ INTERFACEKEY_BUILDJOB_SIEGE_ORIENT,
+ INTERFACEKEY_BUILDJOB_DOOR_INTERNAL,
+ INTERFACEKEY_BUILDJOB_DOOR_LOCK,
+ INTERFACEKEY_BUILDJOB_DOOR_AJAR,
+ INTERFACEKEY_BUILDJOB_COFFIN_ASSIGN,
+ INTERFACEKEY_BUILDJOB_COFFIN_FREE,
+ INTERFACEKEY_BUILDJOB_COFFIN_SIZE,
+ INTERFACEKEY_BUILDJOB_COFFIN_BURIAL,
+ INTERFACEKEY_BUILDJOB_COFFIN_CIV,
+ INTERFACEKEY_BUILDJOB_COFFIN_PET,
+ INTERFACEKEY_BUILDJOB_CHAIR_ASSIGN,
+ INTERFACEKEY_BUILDJOB_CHAIR_FREE,
+ INTERFACEKEY_BUILDJOB_CHAIR_SIZE,
+ INTERFACEKEY_BUILDJOB_TABLE_ASSIGN,
+ INTERFACEKEY_BUILDJOB_TABLE_HALL,
+ INTERFACEKEY_BUILDJOB_TABLE_FREE,
+ INTERFACEKEY_BUILDJOB_TABLE_SIZE,
+ INTERFACEKEY_BUILDJOB_BED_ASSIGN,
+ INTERFACEKEY_BUILDJOB_BED_FREE,
+ INTERFACEKEY_BUILDJOB_BED_BARRACKS,
+ INTERFACEKEY_BUILDJOB_BED_DORMITORY,
+ INTERFACEKEY_BUILDJOB_BED_RENT,
+ INTERFACEKEY_BUILDJOB_BED_SIZE,
+ INTERFACEKEY_BUILDJOB_BED_NAME,
+ INTERFACEKEY_BUILDJOB_BED_SLEEP,
+ INTERFACEKEY_BUILDJOB_BED_TRAIN,
+ INTERFACEKEY_BUILDJOB_BED_INDIV_EQ,
+ INTERFACEKEY_BUILDJOB_BED_SQUAD_EQ,
+ INTERFACEKEY_BUILDJOB_BED_POSITION,
+ INTERFACEKEY_BUILDJOB_DEPOT_BRING,
+ INTERFACEKEY_BUILDJOB_DEPOT_TRADE,
+ INTERFACEKEY_BUILDJOB_DEPOT_REQUEST_TRADER,
+ INTERFACEKEY_BUILDJOB_DEPOT_BROKER_ONLY,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_NONE,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_MEAT,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_FISH,
+ INTERFACEKEY_BUILDJOB_ANIMALTRAP_BAIT_GEM,
+ INTERFACEKEY_BUILDJOB_FARM_FALLOW,
+ INTERFACEKEY_BUILDJOB_FARM_FERTILIZE,
+ INTERFACEKEY_BUILDJOB_FARM_SEASFERT,
+ INTERFACEKEY_BUILDJOB_FARM_SPRING,
+ INTERFACEKEY_BUILDJOB_FARM_SUMMER,
+ INTERFACEKEY_BUILDJOB_FARM_AUTUMN,
+ INTERFACEKEY_BUILDJOB_FARM_WINTER,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_BONE,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_BRONZE,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_COPPER,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_IRON,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_STEEL,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_WOOD,
+ INTERFACEKEY_BUILDJOB_RACK_MAT_METAL,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_BONE,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_LEATHER,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_COPPER,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_BRONZE,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_STEEL,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_IRON,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_WOOD,
+ INTERFACEKEY_BUILDJOB_STAND_MAT_METAL,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_ASSIGN,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_FREE,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_SIZE,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_ITEM,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_MAT,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS1,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_KILL1,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_DEFAULTS2,
+ INTERFACEKEY_BUILDJOB_RACKSTAND_KILL2,
+ INTERFACEKEY_HOTKEY_BUILDING_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_BUILDING_BED,
+ INTERFACEKEY_HOTKEY_BUILDING_CHAIR,
+ INTERFACEKEY_HOTKEY_BUILDING_COFFIN,
+ INTERFACEKEY_HOTKEY_BUILDING_DOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_FLOODGATE,
+ INTERFACEKEY_HOTKEY_BUILDING_HATCH,
+ INTERFACEKEY_HOTKEY_BUILDING_GRATE_WALL,
+ INTERFACEKEY_HOTKEY_BUILDING_GRATE_FLOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_BARS_VERTICAL,
+ INTERFACEKEY_HOTKEY_BUILDING_BARS_FLOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_CABINET,
+ INTERFACEKEY_HOTKEY_BUILDING_BOX,
+ INTERFACEKEY_HOTKEY_BUILDING_KENNEL,
+ INTERFACEKEY_HOTKEY_BUILDING_FARMPLOT,
+ INTERFACEKEY_HOTKEY_BUILDING_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_BUILDING_STATUE,
+ INTERFACEKEY_HOTKEY_BUILDING_TABLE,
+ INTERFACEKEY_HOTKEY_BUILDING_ROAD_DIRT,
+ INTERFACEKEY_HOTKEY_BUILDING_ROAD_PAVED,
+ INTERFACEKEY_HOTKEY_BUILDING_BRIDGE,
+ INTERFACEKEY_HOTKEY_BUILDING_WELL,
+ INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE,
+ INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GLASS,
+ INTERFACEKEY_HOTKEY_BUILDING_WINDOW_GEM,
+ INTERFACEKEY_HOTKEY_BUILDING_SHOP,
+ INTERFACEKEY_HOTKEY_BUILDING_ANIMALTRAP,
+ INTERFACEKEY_HOTKEY_BUILDING_CHAIN,
+ INTERFACEKEY_HOTKEY_BUILDING_CAGE,
+ INTERFACEKEY_HOTKEY_BUILDING_TRADEDEPOT,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE,
+ INTERFACEKEY_HOTKEY_BUILDING_SUPPORT,
+ INTERFACEKEY_HOTKEY_BUILDING_ARCHERYTARGET,
+ INTERFACEKEY_HOTKEY_BUILDING_TRACTION_BENCH,
+ INTERFACEKEY_HOTKEY_BUILDING_SLAB,
+ INTERFACEKEY_HOTKEY_BUILDING_NEST_BOX,
+ INTERFACEKEY_HOTKEY_BUILDING_HIVE,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_SCREW_PUMP,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WATER_WHEEL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_WINDMILL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_GEAR_ASSEMBLY,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_VERTICAL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_AXLE_HORIZONTAL,
+ INTERFACEKEY_HOTKEY_BUILDING_MACHINE_ROLLERS,
+ INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_BALLISTA,
+ INTERFACEKEY_HOTKEY_BUILDING_SIEGEENGINE_CATAPULT,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_STONE,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_WEAPON,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_LEVER,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_TRIGGER,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_CAGE,
+ INTERFACEKEY_HOTKEY_BUILDING_TRAP_SPIKE,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_WALL,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FLOOR,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_RAMP,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UP,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_DOWN,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_STAIR_UPDOWN,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_FORTIFICATION,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK,
+ INTERFACEKEY_HOTKEY_BUILDING_CONSTRUCTION_TRACK_STOP,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LEATHER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_QUERN,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MILLSTONE,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LOOM,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CLOTHES,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BOWYER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CARPENTER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_METALSMITH,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_LAVAMILL,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_JEWELER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MASON,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_BUTCHER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_TANNER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_DYER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_CRAFTSMAN,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_SIEGE,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_MECHANIC,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_STILL,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FARMER,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_KITCHEN,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_FISHERY,
+ INTERFACEKEY_HOTKEY_BUILDING_WORKSHOP_ASHERY,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_WOOD,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_SMELTER_LAVA,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_GLASS_LAVA,
+ INTERFACEKEY_HOTKEY_BUILDING_FURNACE_KILN_LAVA,
+ INTERFACEKEY_HIVE_INSTALL_COLONY,
+ INTERFACEKEY_HIVE_GATHER_PRODUCTS,
+ INTERFACEKEY_BUILDING_DIM_Y_UP,
+ INTERFACEKEY_BUILDING_DIM_Y_DOWN,
+ INTERFACEKEY_BUILDING_DIM_X_UP,
+ INTERFACEKEY_BUILDING_DIM_X_DOWN,
+ INTERFACEKEY_BUILDING_ORIENT_UP,
+ INTERFACEKEY_BUILDING_ORIENT_LEFT,
+ INTERFACEKEY_BUILDING_ORIENT_RIGHT,
+ INTERFACEKEY_BUILDING_ORIENT_DOWN,
+ INTERFACEKEY_BUILDING_ORIENT_NONE,
+ INTERFACEKEY_BUILDING_VIEW_ITEM,
+ INTERFACEKEY_BUILDING_ADVANCE_STAGE,
+ INTERFACEKEY_BUILDING_EXPAND_CONTRACT,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_WATER,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_WATER_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_WATER_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_MAGMA,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_MAGMA_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_MAGMA_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_TRACK_CART,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_TRACK_CART_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_TRACK_CART_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_CREATURE,
+ INTERFACEKEY_BUILDING_TRIGGER_ENABLE_LOCALS,
+ INTERFACEKEY_BUILDING_TRIGGER_RESETS,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_UP_PLUS,
+ INTERFACEKEY_BUILDING_TRIGGER_MIN_SIZE_DOWN_PLUS,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_UP_PLUS,
+ INTERFACEKEY_BUILDING_TRIGGER_MAX_SIZE_DOWN_PLUS,
+ INTERFACEKEY_BUILDING_ROLLERS_SPEED_UP,
+ INTERFACEKEY_BUILDING_ROLLERS_SPEED_DOWN,
+ INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_UP,
+ INTERFACEKEY_BUILDING_TRACK_STOP_FRICTION_DOWN,
+ INTERFACEKEY_BUILDING_TRACK_STOP_DUMP,
+ INTERFACEKEY_DESTROYBUILDING,
+ INTERFACEKEY_SUSPENDBUILDING,
+ INTERFACEKEY_BUILDINGLIST_ZOOM_T,
+ INTERFACEKEY_BUILDINGLIST_ZOOM_Q,
+ INTERFACEKEY_RECENTER_ON_LEVER,
+
+ WORKSHOPKEY_START,
+ INTERFACEKEY_HOTKEY_MAKE_ASH=WORKSHOPKEY_START,
+ INTERFACEKEY_HOTKEY_MAKE_CHARCOAL,
+ INTERFACEKEY_HOTKEY_MELT_OBJECT,
+ INTERFACEKEY_HOTKEY_GLASS_GREEN,
+ INTERFACEKEY_HOTKEY_GLASS_CLEAR,
+ INTERFACEKEY_HOTKEY_GLASS_CRYSTAL,
+ INTERFACEKEY_HOTKEY_COLLECT_SAND,
+ INTERFACEKEY_HOTKEY_COLLECT_CLAY,
+ INTERFACEKEY_HOTKEY_GLASS_ROUGH,
+ INTERFACEKEY_HOTKEY_GLASS_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_GLASS_BOX,
+ INTERFACEKEY_HOTKEY_GLASS_CABINET,
+ INTERFACEKEY_HOTKEY_GLASS_COFFIN,
+ INTERFACEKEY_HOTKEY_GLASS_FLOODGATE,
+ INTERFACEKEY_HOTKEY_GLASS_HATCH_COVER,
+ INTERFACEKEY_HOTKEY_GLASS_GRATE,
+ INTERFACEKEY_HOTKEY_GLASS_GOBLET,
+ INTERFACEKEY_HOTKEY_GLASS_TOY,
+ INTERFACEKEY_HOTKEY_GLASS_INSTRUMENT,
+ INTERFACEKEY_HOTKEY_GLASS_DOOR,
+ INTERFACEKEY_HOTKEY_GLASS_STATUE,
+ INTERFACEKEY_HOTKEY_GLASS_TABLE,
+ INTERFACEKEY_HOTKEY_GLASS_CAGE,
+ INTERFACEKEY_HOTKEY_GLASS_CHAIR,
+ INTERFACEKEY_HOTKEY_GLASS_BLOCKS,
+ INTERFACEKEY_HOTKEY_GLASS_FLASK,
+ INTERFACEKEY_HOTKEY_GLASS_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_GLASS_WINDOW,
+ INTERFACEKEY_HOTKEY_ASHERY_LYE,
+ INTERFACEKEY_HOTKEY_ASHERY_POTASH,
+ INTERFACEKEY_HOTKEY_ASHERY_POTASH_DIRECT,
+ INTERFACEKEY_HOTKEY_CARPENTER_BARREL,
+ INTERFACEKEY_HOTKEY_CARPENTER_BLOCKS,
+ INTERFACEKEY_HOTKEY_CARPENTER_BUCKET,
+ INTERFACEKEY_HOTKEY_CARPENTER_TRAP_ANIMAL,
+ INTERFACEKEY_HOTKEY_CARPENTER_CAGE,
+ INTERFACEKEY_HOTKEY_CARPENTER_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_CARPENTER_BED,
+ INTERFACEKEY_HOTKEY_CARPENTER_CHAIR,
+ INTERFACEKEY_HOTKEY_CARPENTER_COFFIN,
+ INTERFACEKEY_HOTKEY_CARPENTER_DOOR,
+ INTERFACEKEY_HOTKEY_CARPENTER_FLOODGATE,
+ INTERFACEKEY_HOTKEY_CARPENTER_HATCH_COVER,
+ INTERFACEKEY_HOTKEY_CARPENTER_GRATE,
+ INTERFACEKEY_HOTKEY_CARPENTER_CABINET,
+ INTERFACEKEY_HOTKEY_CARPENTER_BIN,
+ INTERFACEKEY_HOTKEY_CARPENTER_BOX,
+ INTERFACEKEY_HOTKEY_CARPENTER_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_CARPENTER_TABLE,
+ INTERFACEKEY_HOTKEY_SIEGE_BALLISTA,
+ INTERFACEKEY_HOTKEY_SIEGE_CATAPULT,
+ INTERFACEKEY_HOTKEY_LEATHER_BOX,
+ INTERFACEKEY_HOTKEY_LEATHER_FLASK,
+ INTERFACEKEY_HOTKEY_LEATHER_SHIRT,
+ INTERFACEKEY_HOTKEY_LEATHER_CLOAK,
+ INTERFACEKEY_HOTKEY_LEATHER_BACKPACK,
+ INTERFACEKEY_HOTKEY_LEATHER_QUIVER,
+ INTERFACEKEY_HOTKEY_LEATHER_IMAGE,
+ INTERFACEKEY_HOTKEY_CLOTHES_MAT_PLANT,
+ INTERFACEKEY_HOTKEY_CLOTHES_MAT_SILK,
+ INTERFACEKEY_HOTKEY_CLOTHES_MAT_YARN,
+ INTERFACEKEY_HOTKEY_CLOTHES_SHIRT,
+ INTERFACEKEY_HOTKEY_CLOTHES_CLOAK,
+ INTERFACEKEY_HOTKEY_CLOTHES_BOX,
+ INTERFACEKEY_HOTKEY_CLOTHES_CHAIN,
+ INTERFACEKEY_HOTKEY_CLOTHES_IMAGE,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_STONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_WOOD,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_BONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_SHELL,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_TOOTH,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_HORN,
+ INTERFACEKEY_HOTKEY_CRAFTS_DEC_PEARL,
+ INTERFACEKEY_HOTKEY_CRAFTS_TOTEM,
+ INTERFACEKEY_HOTKEY_CRAFTS_CLOTH,
+ INTERFACEKEY_HOTKEY_CRAFTS_SILK,
+ INTERFACEKEY_HOTKEY_CRAFTS_YARN,
+ INTERFACEKEY_HOTKEY_CRAFTS_SEL_WOOD,
+ INTERFACEKEY_HOTKEY_CRAFTS_SEL_BONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_SEL_SHELL,
+ INTERFACEKEY_HOTKEY_CRAFTS_SHELL,
+ INTERFACEKEY_HOTKEY_CRAFTS_TOOTH,
+ INTERFACEKEY_HOTKEY_CRAFTS_HORN,
+ INTERFACEKEY_HOTKEY_CRAFTS_PEARL,
+ INTERFACEKEY_HOTKEY_CRAFTS_BONE,
+ INTERFACEKEY_HOTKEY_CRAFTS_LEATHER,
+ INTERFACEKEY_HOTKEY_CRAFTS_SLAB,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_CRAFTS,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_GOBLET,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_INSTRUMENT,
+ INTERFACEKEY_HOTKEY_CRAFTS_MAT_TOY,
+ INTERFACEKEY_HOTKEY_SMITH_WEAPON,
+ INTERFACEKEY_HOTKEY_SMITH_ARMOR,
+ INTERFACEKEY_HOTKEY_SMITH_FURNITURE,
+ INTERFACEKEY_HOTKEY_SMITH_SIEGE,
+ INTERFACEKEY_HOTKEY_SMITH_TRAP,
+ INTERFACEKEY_HOTKEY_SMITH_OTHER,
+ INTERFACEKEY_HOTKEY_SMITH_METAL,
+ INTERFACEKEY_HOTKEY_ALCHEMIST_SOAP,
+ INTERFACEKEY_HOTKEY_STILL_BREW,
+ INTERFACEKEY_HOTKEY_STILL_EXTRACT,
+ INTERFACEKEY_HOTKEY_LOOM_COLLECT_SILK,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_CLOTH,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_SILK,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_YARN,
+ INTERFACEKEY_HOTKEY_LOOM_WEAVE_METAL,
+ INTERFACEKEY_HOTKEY_KITCHEN_COOK_2,
+ INTERFACEKEY_HOTKEY_KITCHEN_COOK_3,
+ INTERFACEKEY_HOTKEY_KITCHEN_COOK_4,
+ INTERFACEKEY_HOTKEY_KITCHEN_RENDER_FAT,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS_VIAL,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS_BAG,
+ INTERFACEKEY_HOTKEY_FARMER_PROCESS_BARREL,
+ INTERFACEKEY_HOTKEY_FARMER_CHEESE,
+ INTERFACEKEY_HOTKEY_FARMER_MILK,
+ INTERFACEKEY_HOTKEY_FARMER_SHEAR_CREATURE,
+ INTERFACEKEY_HOTKEY_FARMER_SPIN_THREAD,
+ INTERFACEKEY_HOTKEY_MILL_MILL,
+ INTERFACEKEY_HOTKEY_KENNEL_CATCH_VERMIN,
+ INTERFACEKEY_HOTKEY_KENNEL_TAME_VERMIN,
+ INTERFACEKEY_HOTKEY_FISHERY_PROCESS,
+ INTERFACEKEY_HOTKEY_FISHERY_EXTRACT,
+ INTERFACEKEY_HOTKEY_FISHERY_CATCH,
+ INTERFACEKEY_HOTKEY_BUTCHER_BUTCHER,
+ INTERFACEKEY_HOTKEY_BUTCHER_EXTRACT,
+ INTERFACEKEY_HOTKEY_BUTCHER_CATCH,
+ INTERFACEKEY_HOTKEY_TANNER_TAN,
+ INTERFACEKEY_HOTKEY_DYER_THREAD,
+ INTERFACEKEY_HOTKEY_DYER_CLOTH,
+ INTERFACEKEY_HOTKEY_JEWELER_FURNITURE,
+ INTERFACEKEY_HOTKEY_JEWELER_FINISHED,
+ INTERFACEKEY_HOTKEY_JEWELER_AMMO,
+ INTERFACEKEY_HOTKEY_JEWELER_CUT,
+ INTERFACEKEY_HOTKEY_JEWELER_ENCRUST,
+ INTERFACEKEY_HOTKEY_MECHANIC_PARTS,
+ INTERFACEKEY_HOTKEY_MECHANIC_TRACTION_BENCH,
+ INTERFACEKEY_HOTKEY_MASON_ARMORSTAND,
+ INTERFACEKEY_HOTKEY_MASON_BLOCKS,
+ INTERFACEKEY_HOTKEY_MASON_CHAIR,
+ INTERFACEKEY_HOTKEY_MASON_COFFIN,
+ INTERFACEKEY_HOTKEY_MASON_DOOR,
+ INTERFACEKEY_HOTKEY_MASON_FLOODGATE,
+ INTERFACEKEY_HOTKEY_MASON_HATCH_COVER,
+ INTERFACEKEY_HOTKEY_MASON_GRATE,
+ INTERFACEKEY_HOTKEY_MASON_CABINET,
+ INTERFACEKEY_HOTKEY_MASON_BOX,
+ INTERFACEKEY_HOTKEY_MASON_STATUE,
+ INTERFACEKEY_HOTKEY_MASON_TABLE,
+ INTERFACEKEY_HOTKEY_MASON_WEAPONRACK,
+ INTERFACEKEY_HOTKEY_MASON_QUERN,
+ INTERFACEKEY_HOTKEY_MASON_MILLSTONE,
+ INTERFACEKEY_HOTKEY_MASON_SLAB,
+ INTERFACEKEY_HOTKEY_TRAP_BRIDGE,
+ INTERFACEKEY_HOTKEY_TRAP_DOOR,
+ INTERFACEKEY_HOTKEY_TRAP_FLOODGATE,
+ INTERFACEKEY_HOTKEY_TRAP_SPIKE,
+ INTERFACEKEY_HOTKEY_TRAP_HATCH,
+ INTERFACEKEY_HOTKEY_TRAP_GRATE_WALL,
+ INTERFACEKEY_HOTKEY_TRAP_GRATE_FLOOR,
+ INTERFACEKEY_HOTKEY_TRAP_BARS_VERTICAL,
+ INTERFACEKEY_HOTKEY_TRAP_BARS_FLOOR,
+ INTERFACEKEY_HOTKEY_TRAP_SUPPORT,
+ INTERFACEKEY_HOTKEY_TRAP_CHAIN,
+ INTERFACEKEY_HOTKEY_TRAP_CAGE,
+ INTERFACEKEY_HOTKEY_TRAP_GEAR_ASSEMBLY,
+ INTERFACEKEY_HOTKEY_TRAP_TRACK_STOP,
+ INTERFACEKEY_HOTKEY_TRAP_PULL_LEVER,
+
+ PILEZONEKEY_START,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_MASTER=PILEZONEKEY_START,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_LINK_ANYWHERE,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_GIVE_TO,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_DELETE_CHILD,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_SETTINGS,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_UP,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_DOWN,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_ZERO,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BARREL_MAX,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_UP,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_DOWN,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_ZERO,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_BIN_MAX,
+ INTERFACEKEY_BUILDJOB_STOCKPILE_WHEELBARROW,
+ INTERFACEKEY_STOCKPILE_ANIMAL,
+ INTERFACEKEY_STOCKPILE_FOOD,
+ INTERFACEKEY_STOCKPILE_WEAPON,
+ INTERFACEKEY_STOCKPILE_ARMOR,
+ INTERFACEKEY_STOCKPILE_CUSTOM,
+ INTERFACEKEY_STOCKPILE_CUSTOM_SETTINGS,
+ INTERFACEKEY_STOCKPILE_FURNITURE,
+ INTERFACEKEY_STOCKPILE_GRAVEYARD,
+ INTERFACEKEY_STOCKPILE_REFUSE,
+ INTERFACEKEY_STOCKPILE_WOOD,
+ INTERFACEKEY_STOCKPILE_STONE,
+ INTERFACEKEY_STOCKPILE_GEM,
+ INTERFACEKEY_STOCKPILE_BARBLOCK,
+ INTERFACEKEY_STOCKPILE_CLOTH,
+ INTERFACEKEY_STOCKPILE_LEATHER,
+ INTERFACEKEY_STOCKPILE_AMMO,
+ INTERFACEKEY_STOCKPILE_COINS,
+ INTERFACEKEY_STOCKPILE_FINISHED,
+ INTERFACEKEY_STOCKPILE_NONE,
+ INTERFACEKEY_STOCKPILE_SETTINGS_ENABLE,
+ INTERFACEKEY_STOCKPILE_SETTINGS_DISABLE,
+ INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_ALL,
+ INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_ALL,
+ INTERFACEKEY_STOCKPILE_SETTINGS_PERMIT_SUB,
+ INTERFACEKEY_STOCKPILE_SETTINGS_FORBID_SUB,
+ INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC1,
+ INTERFACEKEY_STOCKPILE_SETTINGS_SPECIFIC2,
+ INTERFACEKEY_CIVZONE_REMOVE,
+ INTERFACEKEY_CIVZONE_REMOVE_ZONE,
+ INTERFACEKEY_CIVZONE_SHAPE,
+ INTERFACEKEY_CIVZONE_NEXT,
+ INTERFACEKEY_CIVZONE_WATER_SOURCE,
+ INTERFACEKEY_CIVZONE_FISH,
+ INTERFACEKEY_CIVZONE_GATHER,
+ INTERFACEKEY_CIVZONE_DUMP,
+ INTERFACEKEY_CIVZONE_POND,
+ INTERFACEKEY_CIVZONE_HOSPITAL,
+ INTERFACEKEY_CIVZONE_SAND_COLLECT,
+ INTERFACEKEY_CIVZONE_CLAY_COLLECT,
+ INTERFACEKEY_CIVZONE_ACTIVE,
+ INTERFACEKEY_CIVZONE_MEETING,
+ INTERFACEKEY_CIVZONE_ANIMAL_TRAINING,
+ INTERFACEKEY_CIVZONE_PEN,
+ INTERFACEKEY_CIVZONE_PEN_OPTIONS,
+ INTERFACEKEY_CIVZONE_POND_OPTIONS,
+ INTERFACEKEY_CIVZONE_POND_WATER,
+ INTERFACEKEY_CIVZONE_HOSPITAL_OPTIONS,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_TREES,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS_PICK_SHRUBS,
+ INTERFACEKEY_CIVZONE_GATHER_OPTIONS_GATHER_FALLEN,
+
+ STOCKORDERKEY_START,
+ INTERFACEKEY_STORES_VIEW=STOCKORDERKEY_START,
+ INTERFACEKEY_STORES_ZOOM,
+ INTERFACEKEY_STORES_FORBID,
+ INTERFACEKEY_STORES_MELT,
+ INTERFACEKEY_STORES_DUMP,
+ INTERFACEKEY_STORES_HIDE,
+ INTERFACEKEY_PET_BUTCHER,
+ INTERFACEKEY_PET_GELD,
+ INTERFACEKEY_ANIMAL_SELECT_TRAINER,
+ INTERFACEKEY_ANIMAL_WAR_TRAINING,
+ INTERFACEKEY_ANIMAL_HUNTING_TRAINING,
+ INTERFACEKEY_KITCHEN_COOK,
+ INTERFACEKEY_KITCHEN_BREW,
+ INTERFACEKEY_ORDERS_AUTOFORBID,
+ INTERFACEKEY_ORDERS_FORBID_PROJECTILE,
+ INTERFACEKEY_ORDERS_FORBID_YOUR_CORPSE,
+ INTERFACEKEY_ORDERS_FORBID_YOUR_ITEMS,
+ INTERFACEKEY_ORDERS_FORBID_OTHER_CORPSE,
+ INTERFACEKEY_ORDERS_FORBID_OTHER_ITEMS,
+ INTERFACEKEY_ORDERS_REFUSE_GATHER,
+ INTERFACEKEY_ORDERS_REFUSE_OUTSIDE,
+ INTERFACEKEY_ORDERS_REFUSE_OUTSIDE_VERMIN,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_CORPSE,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_SKULL,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_BONE,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_SHELL,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_SKIN,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_OTHER,
+ INTERFACEKEY_ORDERS_REFUSE_DUMP_STRAND_TISSUE,
+ INTERFACEKEY_ORDERS_GATHER_FURNITURE,
+ INTERFACEKEY_ORDERS_GATHER_ANIMALS,
+ INTERFACEKEY_ORDERS_GATHER_FOOD,
+ INTERFACEKEY_ORDERS_GATHER_BODIES,
+ INTERFACEKEY_ORDERS_REFUSE,
+ INTERFACEKEY_ORDERS_GATHER_STONE,
+ INTERFACEKEY_ORDERS_GATHER_WOOD,
+ INTERFACEKEY_ORDERS_ALL_HARVEST,
+ INTERFACEKEY_ORDERS_SAMEPILE,
+ INTERFACEKEY_ORDERS_MIXFOODS,
+ INTERFACEKEY_ORDERS_LOOM,
+ INTERFACEKEY_ORDERS_DYED_CLOTH,
+ INTERFACEKEY_ORDERS_EXCEPTIONS,
+ INTERFACEKEY_ORDERS_WORKSHOP,
+ INTERFACEKEY_ORDERS_COLLECT_WEB,
+ INTERFACEKEY_ORDERS_SLAUGHTER,
+ INTERFACEKEY_ORDERS_BUTCHER,
+ INTERFACEKEY_ORDERS_TAN,
+ INTERFACEKEY_ORDERS_AUTO_FISHERY,
+ INTERFACEKEY_ORDERS_AUTO_KITCHEN,
+ INTERFACEKEY_ORDERS_AUTO_KILN,
+ INTERFACEKEY_ORDERS_AUTO_SMELTER,
+ INTERFACEKEY_ORDERS_AUTO_OTHER,
+ INTERFACEKEY_ORDERS_ZONE,
+ INTERFACEKEY_ORDERS_ZONE_DRINKING,
+ INTERFACEKEY_ORDERS_ZONE_FISHING,
+
+ DWARFMAINKEY_START,
+ INTERFACEKEY_D_ONESTEP=DWARFMAINKEY_START,
+ INTERFACEKEY_D_PAUSE,
+ INTERFACEKEY_D_DEPOT,
+ INTERFACEKEY_D_HOT_KEYS,
+ INTERFACEKEY_D_HOTKEY1,
+ INTERFACEKEY_D_HOTKEY2,
+ INTERFACEKEY_D_HOTKEY3,
+ INTERFACEKEY_D_HOTKEY4,
+ INTERFACEKEY_D_HOTKEY5,
+ INTERFACEKEY_D_HOTKEY6,
+ INTERFACEKEY_D_HOTKEY7,
+ INTERFACEKEY_D_HOTKEY8,
+ INTERFACEKEY_D_HOTKEY9,
+ INTERFACEKEY_D_HOTKEY10,
+ INTERFACEKEY_D_HOTKEY11,
+ INTERFACEKEY_D_HOTKEY12,
+ INTERFACEKEY_D_HOTKEY13,
+ INTERFACEKEY_D_HOTKEY14,
+ INTERFACEKEY_D_HOTKEY15,
+ INTERFACEKEY_D_HOTKEY16,
+ INTERFACEKEY_D_HOTKEY_CHANGE_NAME,
+ INTERFACEKEY_D_HOTKEY_ZOOM,
+ INTERFACEKEY_D_ANNOUNCE,
+ INTERFACEKEY_D_REPORTS,
+ INTERFACEKEY_D_BUILDING,
+ INTERFACEKEY_D_CIVLIST,
+ INTERFACEKEY_D_DESIGNATE,
+ INTERFACEKEY_D_ARTLIST,
+ INTERFACEKEY_D_NOBLES,
+ INTERFACEKEY_D_ORDERS,
+ INTERFACEKEY_D_MILITARY,
+ INTERFACEKEY_D_ROOMS,
+ INTERFACEKEY_D_SQUADS,
+ INTERFACEKEY_D_STOCKPILES,
+ INTERFACEKEY_D_CIVZONE,
+ INTERFACEKEY_D_VIEWUNIT,
+ INTERFACEKEY_D_JOBLIST,
+ INTERFACEKEY_D_UNITLIST,
+ INTERFACEKEY_D_LOOK,
+ INTERFACEKEY_D_HAULING,
+ INTERFACEKEY_D_HAULING_NEW_ROUTE,
+ INTERFACEKEY_D_HAULING_NEW_STOP,
+ INTERFACEKEY_D_HAULING_REMOVE,
+ INTERFACEKEY_D_HAULING_PROMOTE,
+ INTERFACEKEY_D_HAULING_VEHICLE,
+ INTERFACEKEY_D_HAULING_NICKNAME,
+ INTERFACEKEY_D_HAULING_STOP_NEW_DEPART,
+ INTERFACEKEY_D_HAULING_STOP_NEW_LINK,
+ INTERFACEKEY_D_HAULING_STOP_REMOVE,
+ INTERFACEKEY_D_HAULING_STOP_SL_SELECT_PILE,
+ INTERFACEKEY_D_HAULING_STOP_SL_TAKE_GIVE,
+ INTERFACEKEY_D_HAULING_STOP_LC_DIR,
+ INTERFACEKEY_D_HAULING_STOP_LC_MODE,
+ INTERFACEKEY_D_HAULING_STOP_LC_TIMER_UP,
+ INTERFACEKEY_D_HAULING_STOP_LC_TIMER_DOWN,
+ INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_UP,
+ INTERFACEKEY_D_HAULING_STOP_LC_FULLNESS_DOWN,
+ INTERFACEKEY_D_HAULING_STOP_LC_MORE_LESS,
+ INTERFACEKEY_D_HAULING_STOP_LC_DESIRED_TOTAL,
+ INTERFACEKEY_D_HAULING_STOP_LC_CHANGE,
+ INTERFACEKEY_D_HAULING_STOP_LC_ADVANCED,
+ INTERFACEKEY_D_BURROWS,
+ INTERFACEKEY_D_BURROWS_ADD,
+ INTERFACEKEY_D_BURROWS_DELETE,
+ INTERFACEKEY_D_BURROWS_DEFINE,
+ INTERFACEKEY_D_BURROWS_ADD_UNIT,
+ INTERFACEKEY_D_BURROWS_WORKSHOP_LIMIT,
+ INTERFACEKEY_D_BURROWS_CENTER,
+ INTERFACEKEY_D_BURROWS_NAME,
+ INTERFACEKEY_D_BURROWS_CHANGE_SELECTION,
+ INTERFACEKEY_D_BURROWS_BRUSH,
+ INTERFACEKEY_D_BURROWS_REMOVE,
+ INTERFACEKEY_D_NOTE,
+ INTERFACEKEY_D_NOTE_PLACE,
+ INTERFACEKEY_D_NOTE_DELETE,
+ INTERFACEKEY_D_NOTE_NAME,
+ INTERFACEKEY_D_NOTE_ENTER,
+ INTERFACEKEY_D_NOTE_ADOPT_SYMBOL,
+ INTERFACEKEY_D_NOTE_CHANGE_SELECTION,
+ INTERFACEKEY_D_NOTE_POINTS,
+ INTERFACEKEY_D_NOTE_ROUTE,
+ INTERFACEKEY_D_NOTE_ROUTE_ADD,
+ INTERFACEKEY_D_NOTE_ROUTE_EDIT,
+ INTERFACEKEY_D_NOTE_ROUTE_DELETE,
+ INTERFACEKEY_D_NOTE_ROUTE_CENTER,
+ INTERFACEKEY_D_NOTE_ROUTE_NAME,
+ INTERFACEKEY_D_BUILDJOB,
+ INTERFACEKEY_D_STATUS,
+ INTERFACEKEY_D_STATUS_OVERALL_HEALTH_RECENTER,
+ INTERFACEKEY_D_BUILDITEM,
+ INTERFACEKEY_D_BITEM_FORBID,
+ INTERFACEKEY_D_BITEM_DUMP,
+ INTERFACEKEY_D_BITEM_MELT,
+ INTERFACEKEY_D_BITEM_HIDE,
+ INTERFACEKEY_D_LOOK_FORBID,
+ INTERFACEKEY_D_LOOK_DUMP,
+ INTERFACEKEY_D_LOOK_MELT,
+ INTERFACEKEY_D_LOOK_HIDE,
+ INTERFACEKEY_D_LOOK_FOLLOW,
+ INTERFACEKEY_D_LOOK_ARENA_CREATURE,
+ INTERFACEKEY_D_LOOK_ARENA_ADV_MODE,
+ INTERFACEKEY_D_LOOK_ARENA_WATER,
+ INTERFACEKEY_D_LOOK_ARENA_MAGMA,
+ INTERFACEKEY_ARENA_CREATURE_SIDE_DOWN,
+ INTERFACEKEY_ARENA_CREATURE_SIDE_UP,
+ INTERFACEKEY_ARENA_CREATURE_NEW_ITEM,
+ INTERFACEKEY_ARENA_CREATURE_BLANK_LIST,
+ INTERFACEKEY_ARENA_CREATURE_REMOVE_ITEM,
+ INTERFACEKEY_ARENA_CREATURE_UNDEAD,
+ INTERFACEKEY_ARENA_CREATURE_STRING,
+ INTERFACEKEY_ARENA_CONFLICT_STATE_1,
+ INTERFACEKEY_ARENA_CONFLICT_STATE_2,
+ INTERFACEKEY_ARENA_MORALE,
+ INTERFACEKEY_ARENA_WEATHER,
+ INTERFACEKEY_ARENA_WEATHER_SNOW,
+ INTERFACEKEY_ARENA_WEATHER_MUD,
+ INTERFACEKEY_ARENA_WEATHER_CLEAR_SPATTER,
+ INTERFACEKEY_D_LOOK_ARENA_TREE,
+ INTERFACEKEY_ARENA_TREE_FILTER,
+ INTERFACEKEY_ARENA_TREE_AGE,
+ INTERFACEKEY_D_LOOK_ARENA_MOUNT,
+ INTERFACEKEY_ASSIGNTRADE_VIEW,
+ INTERFACEKEY_ASSIGNTRADE_STRING,
+ INTERFACEKEY_ASSIGNTRADE_EXCLUDE_PROHIBITED,
+ INTERFACEKEY_ASSIGNTRADE_PENDING,
+ INTERFACEKEY_ASSIGNTRADE_SORT,
+ INTERFACEKEY_NOBLELIST_REPLACE,
+ INTERFACEKEY_NOBLELIST_SETTINGS,
+ INTERFACEKEY_NOBLELIST_CAPITAL,
+ INTERFACEKEY_NOBLELIST_VIEW_CANDIDATE,
+ INTERFACEKEY_TRADE_VIEW,
+ INTERFACEKEY_TRADE_TRADE,
+ INTERFACEKEY_TRADE_OFFER,
+ INTERFACEKEY_TRADE_SEIZE,
+ INTERFACEKEY_MILITARY_ACTIVATE,
+ INTERFACEKEY_MILITARY_VIEW,
+ INTERFACEKEY_MILITARY_WEAPON,
+ INTERFACEKEY_MILITARY_ZOOM,
+ INTERFACEKEY_ANNOUNCE_ZOOM,
+ INTERFACEKEY_UNITJOB_REMOVE_CRE,
+ INTERFACEKEY_UNITJOB_ZOOM_CRE,
+ INTERFACEKEY_UNITJOB_ZOOM_BUILD,
+ INTERFACEKEY_UNITJOB_VIEW,
+ INTERFACEKEY_UNITJOB_MANAGER,
+ INTERFACEKEY_MANAGER_NEW_ORDER,
+ INTERFACEKEY_MANAGER_REMOVE,
+ INTERFACEKEY_MANAGER_PROMOTE,
+ INTERFACEKEY_MANAGER_MAX,
+ INTERFACEKEY_MANAGER_WAGES,
+ INTERFACEKEY_DESIGNATE_BITEM,
+ INTERFACEKEY_DESIGNATE_CLAIM,
+ INTERFACEKEY_DESIGNATE_UNCLAIM,
+ INTERFACEKEY_DESIGNATE_MELT,
+ INTERFACEKEY_DESIGNATE_NO_MELT,
+ INTERFACEKEY_DESIGNATE_DUMP,
+ INTERFACEKEY_DESIGNATE_NO_DUMP,
+ INTERFACEKEY_DESIGNATE_HIDE,
+ INTERFACEKEY_DESIGNATE_NO_HIDE,
+ INTERFACEKEY_DESIGNATE_DIG,
+ INTERFACEKEY_DESIGNATE_DIG_REMOVE_STAIRS_RAMPS,
+ INTERFACEKEY_DESIGNATE_TRAFFIC,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_HIGH,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_NORMAL,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_LOW,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_RESTRICTED,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_INCREASE_WEIGHT_MORE,
+ INTERFACEKEY_DESIGNATE_TRAFFIC_DECREASE_WEIGHT_MORE,
+ INTERFACEKEY_DESIGNATE_STAIR_UP,
+ INTERFACEKEY_DESIGNATE_STAIR_DOWN,
+ INTERFACEKEY_DESIGNATE_STAIR_UPDOWN,
+ INTERFACEKEY_DESIGNATE_RAMP,
+ INTERFACEKEY_DESIGNATE_CHANNEL,
+ INTERFACEKEY_DESIGNATE_CHOP,
+ INTERFACEKEY_DESIGNATE_PLANTS,
+ INTERFACEKEY_DESIGNATE_SMOOTH,
+ INTERFACEKEY_DESIGNATE_ENGRAVE,
+ INTERFACEKEY_DESIGNATE_FORTIFY,
+ INTERFACEKEY_DESIGNATE_TRACK,
+ INTERFACEKEY_DESIGNATE_TOGGLE_ENGRAVING,
+ INTERFACEKEY_DESIGNATE_STANDARD_MARKER,
+ INTERFACEKEY_DESIGNATE_MINE_MODE,
+ INTERFACEKEY_DESIGNATE_TOGGLE_MARKER,
+ INTERFACEKEY_DESIGNATE_UNDO,
+ INTERFACEKEY_DESIGNATE_REMOVE_CONSTRUCTION,
+ INTERFACEKEY_ITEM_DESCRIPTION,
+ INTERFACEKEY_ITEM_FORBID,
+ INTERFACEKEY_ITEM_MELT,
+ INTERFACEKEY_ITEM_DUMP,
+ INTERFACEKEY_ITEM_HIDE,
+ INTERFACEKEY_UNITVIEW_CUSTOMIZE,
+ INTERFACEKEY_UNITVIEW_HEALTH,
+ INTERFACEKEY_UNITVIEW_RELATIONSHIPS,
+ INTERFACEKEY_UNITVIEW_RELATIONSHIPS_ZOOM,
+ INTERFACEKEY_UNITVIEW_RELATIONSHIPS_VIEW,
+ INTERFACEKEY_UNITVIEW_KILLS,
+ INTERFACEKEY_UNITVIEW_GEN,
+ INTERFACEKEY_UNITVIEW_INV,
+ INTERFACEKEY_UNITVIEW_PRF,
+ INTERFACEKEY_UNITVIEW_WND,
+ INTERFACEKEY_UNITVIEW_FOLLOW,
+ INTERFACEKEY_UNITVIEW_NEXT,
+ INTERFACEKEY_UNITVIEW_SLAUGHTER,
+ INTERFACEKEY_UNITVIEW_GELD,
+ INTERFACEKEY_UNITVIEW_GEN_COMBAT,
+ INTERFACEKEY_UNITVIEW_GEN_LABOR,
+ INTERFACEKEY_UNITVIEW_GEN_MISC,
+ INTERFACEKEY_UNITVIEW_PRF_PROF,
+ INTERFACEKEY_UNITVIEW_PRF_PET,
+ INTERFACEKEY_UNITVIEW_PRF_VIEW,
+ INTERFACEKEY_UNITVIEW_PRF_NEW_SQUAD,
+ INTERFACEKEY_UNITVIEW_PRF_REMOVE_FROM_SQUAD,
+ INTERFACEKEY_UNITVIEW_PRF_NAME_CURRENT_SQUAD,
+ INTERFACEKEY_UNITVIEW_PRF_NAME_SELECTED_SQUAD,
+ INTERFACEKEY_CUSTOMIZE_UNIT_NICKNAME,
+ INTERFACEKEY_CUSTOMIZE_UNIT_PROFNAME,
+
+ MILITIAKEY_START,
+ INTERFACEKEY_D_MILITARY_CREATE_SQUAD=MILITIAKEY_START,
+ INTERFACEKEY_D_MILITARY_DISBAND_SQUAD,
+ INTERFACEKEY_D_MILITARY_CREATE_SUB_SQUAD,
+ INTERFACEKEY_D_MILITARY_CANCEL_ORDERS,
+ INTERFACEKEY_D_MILITARY_POSITIONS,
+ INTERFACEKEY_D_MILITARY_ALERTS,
+ INTERFACEKEY_D_MILITARY_ALERTS_ADD,
+ INTERFACEKEY_D_MILITARY_ALERTS_DELETE,
+ INTERFACEKEY_D_MILITARY_ALERTS_SET,
+ INTERFACEKEY_D_MILITARY_ALERTS_NAME,
+ INTERFACEKEY_D_MILITARY_ALERTS_SET_RETAIN,
+ INTERFACEKEY_D_MILITARY_EQUIP,
+ INTERFACEKEY_D_MILITARY_EQUIP_CUSTOMIZE,
+ INTERFACEKEY_D_MILITARY_EQUIP_UNIFORM,
+ INTERFACEKEY_D_MILITARY_EQUIP_PRIORITY,
+ INTERFACEKEY_D_MILITARY_UNIFORMS,
+ INTERFACEKEY_D_MILITARY_SUPPLIES,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_DOWN,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_WATER_UP,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_DOWN,
+ INTERFACEKEY_D_MILITARY_SUPPLIES_FOOD_UP,
+ INTERFACEKEY_D_MILITARY_AMMUNITION,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_ADD_ITEM,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_REMOVE_ITEM,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_LOWER_AMOUNT_LOTS,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_RAISE_AMOUNT_LOTS,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_MATERIAL,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_COMBAT,
+ INTERFACEKEY_D_MILITARY_AMMUNITION_TRAINING,
+ INTERFACEKEY_D_MILITARY_TRAINING,
+ INTERFACEKEY_D_MILITARY_SCHEDULE,
+ INTERFACEKEY_D_MILITARY_ADD_UNIFORM,
+ INTERFACEKEY_D_MILITARY_DELETE_UNIFORM,
+ INTERFACEKEY_D_MILITARY_NAME_UNIFORM,
+ INTERFACEKEY_D_MILITARY_NAME_SQUAD,
+ INTERFACEKEY_D_MILITARY_ADD_ARMOR,
+ INTERFACEKEY_D_MILITARY_ADD_PANTS,
+ INTERFACEKEY_D_MILITARY_ADD_HELM,
+ INTERFACEKEY_D_MILITARY_ADD_GLOVES,
+ INTERFACEKEY_D_MILITARY_ADD_BOOTS,
+ INTERFACEKEY_D_MILITARY_ADD_SHIELD,
+ INTERFACEKEY_D_MILITARY_ADD_WEAPON,
+ INTERFACEKEY_D_MILITARY_ADD_MATERIAL,
+ INTERFACEKEY_D_MILITARY_ADD_COLOR,
+ INTERFACEKEY_D_MILITARY_REPLACE_CLOTHING,
+ INTERFACEKEY_D_MILITARY_EXACT_MATCH,
+ INTERFACEKEY_D_SQUADS_MOVE,
+ INTERFACEKEY_D_SQUADS_KILL,
+ INTERFACEKEY_D_SQUADS_KILL_LIST,
+ INTERFACEKEY_D_SQUADS_KILL_RECT,
+ INTERFACEKEY_D_SQUADS_SCHEDULE,
+ INTERFACEKEY_D_SQUADS_CANCEL_ORDER,
+ INTERFACEKEY_D_SQUADS_ALERT,
+ INTERFACEKEY_D_SQUADS_SELECT_INDIVIDUALS,
+ INTERFACEKEY_D_SQUADS_CENTER,
+ INTERFACEKEY_D_SQUAD_SCH_SLEEP,
+ INTERFACEKEY_D_SQUAD_SCH_CIVILIAN_UNIFORM,
+ INTERFACEKEY_D_SQUAD_SCH_GIVE_ORDER,
+ INTERFACEKEY_D_SQUAD_SCH_EDIT_ORDER,
+ INTERFACEKEY_D_SQUAD_SCH_CANCEL_ORDER,
+ INTERFACEKEY_D_SQUAD_SCH_COPY_ORDERS,
+ INTERFACEKEY_D_SQUAD_SCH_PASTE_ORDERS,
+ INTERFACEKEY_D_SQUAD_SCH_MS_NAME,
+
+ //TEXTENTRY
+ INTERFACEKEY_STRING_A000,
+ INTERFACEKEY_STRING_A001,
+ INTERFACEKEY_STRING_A002,
+ INTERFACEKEY_STRING_A003,
+ INTERFACEKEY_STRING_A004,
+ INTERFACEKEY_STRING_A005,
+ INTERFACEKEY_STRING_A006,
+ INTERFACEKEY_STRING_A007,
+ INTERFACEKEY_STRING_A008,
+ INTERFACEKEY_STRING_A009,
+ INTERFACEKEY_STRING_A010,
+ INTERFACEKEY_STRING_A011,
+ INTERFACEKEY_STRING_A012,
+ INTERFACEKEY_STRING_A013,
+ INTERFACEKEY_STRING_A014,
+ INTERFACEKEY_STRING_A015,
+ INTERFACEKEY_STRING_A016,
+ INTERFACEKEY_STRING_A017,
+ INTERFACEKEY_STRING_A018,
+ INTERFACEKEY_STRING_A019,
+ INTERFACEKEY_STRING_A020,
+ INTERFACEKEY_STRING_A021,
+ INTERFACEKEY_STRING_A022,
+ INTERFACEKEY_STRING_A023,
+ INTERFACEKEY_STRING_A024,
+ INTERFACEKEY_STRING_A025,
+ INTERFACEKEY_STRING_A026,
+ INTERFACEKEY_STRING_A027,
+ INTERFACEKEY_STRING_A028,
+ INTERFACEKEY_STRING_A029,
+ INTERFACEKEY_STRING_A030,
+ INTERFACEKEY_STRING_A031,
+ INTERFACEKEY_STRING_A032,
+ INTERFACEKEY_STRING_A033,
+ INTERFACEKEY_STRING_A034,
+ INTERFACEKEY_STRING_A035,
+ INTERFACEKEY_STRING_A036,
+ INTERFACEKEY_STRING_A037,
+ INTERFACEKEY_STRING_A038,
+ INTERFACEKEY_STRING_A039,
+ INTERFACEKEY_STRING_A040,
+ INTERFACEKEY_STRING_A041,
+ INTERFACEKEY_STRING_A042,
+ INTERFACEKEY_STRING_A043,
+ INTERFACEKEY_STRING_A044,
+ INTERFACEKEY_STRING_A045,
+ INTERFACEKEY_STRING_A046,
+ INTERFACEKEY_STRING_A047,
+ INTERFACEKEY_STRING_A048,
+ INTERFACEKEY_STRING_A049,
+ INTERFACEKEY_STRING_A050,
+ INTERFACEKEY_STRING_A051,
+ INTERFACEKEY_STRING_A052,
+ INTERFACEKEY_STRING_A053,
+ INTERFACEKEY_STRING_A054,
+ INTERFACEKEY_STRING_A055,
+ INTERFACEKEY_STRING_A056,
+ INTERFACEKEY_STRING_A057,
+ INTERFACEKEY_STRING_A058,
+ INTERFACEKEY_STRING_A059,
+ INTERFACEKEY_STRING_A060,
+ INTERFACEKEY_STRING_A061,
+ INTERFACEKEY_STRING_A062,
+ INTERFACEKEY_STRING_A063,
+ INTERFACEKEY_STRING_A064,
+ INTERFACEKEY_STRING_A065,
+ INTERFACEKEY_STRING_A066,
+ INTERFACEKEY_STRING_A067,
+ INTERFACEKEY_STRING_A068,
+ INTERFACEKEY_STRING_A069,
+ INTERFACEKEY_STRING_A070,
+ INTERFACEKEY_STRING_A071,
+ INTERFACEKEY_STRING_A072,
+ INTERFACEKEY_STRING_A073,
+ INTERFACEKEY_STRING_A074,
+ INTERFACEKEY_STRING_A075,
+ INTERFACEKEY_STRING_A076,
+ INTERFACEKEY_STRING_A077,
+ INTERFACEKEY_STRING_A078,
+ INTERFACEKEY_STRING_A079,
+ INTERFACEKEY_STRING_A080,
+ INTERFACEKEY_STRING_A081,
+ INTERFACEKEY_STRING_A082,
+ INTERFACEKEY_STRING_A083,
+ INTERFACEKEY_STRING_A084,
+ INTERFACEKEY_STRING_A085,
+ INTERFACEKEY_STRING_A086,
+ INTERFACEKEY_STRING_A087,
+ INTERFACEKEY_STRING_A088,
+ INTERFACEKEY_STRING_A089,
+ INTERFACEKEY_STRING_A090,
+ INTERFACEKEY_STRING_A091,
+ INTERFACEKEY_STRING_A092,
+ INTERFACEKEY_STRING_A093,
+ INTERFACEKEY_STRING_A094,
+ INTERFACEKEY_STRING_A095,
+ INTERFACEKEY_STRING_A096,
+ INTERFACEKEY_STRING_A097,
+ INTERFACEKEY_STRING_A098,
+ INTERFACEKEY_STRING_A099,
+ INTERFACEKEY_STRING_A100,
+ INTERFACEKEY_STRING_A101,
+ INTERFACEKEY_STRING_A102,
+ INTERFACEKEY_STRING_A103,
+ INTERFACEKEY_STRING_A104,
+ INTERFACEKEY_STRING_A105,
+ INTERFACEKEY_STRING_A106,
+ INTERFACEKEY_STRING_A107,
+ INTERFACEKEY_STRING_A108,
+ INTERFACEKEY_STRING_A109,
+ INTERFACEKEY_STRING_A110,
+ INTERFACEKEY_STRING_A111,
+ INTERFACEKEY_STRING_A112,
+ INTERFACEKEY_STRING_A113,
+ INTERFACEKEY_STRING_A114,
+ INTERFACEKEY_STRING_A115,
+ INTERFACEKEY_STRING_A116,
+ INTERFACEKEY_STRING_A117,
+ INTERFACEKEY_STRING_A118,
+ INTERFACEKEY_STRING_A119,
+ INTERFACEKEY_STRING_A120,
+ INTERFACEKEY_STRING_A121,
+ INTERFACEKEY_STRING_A122,
+ INTERFACEKEY_STRING_A123,
+ INTERFACEKEY_STRING_A124,
+ INTERFACEKEY_STRING_A125,
+ INTERFACEKEY_STRING_A126,
+ INTERFACEKEY_STRING_A128,
+ INTERFACEKEY_STRING_A129,
+ INTERFACEKEY_STRING_A130,
+ INTERFACEKEY_STRING_A131,
+ INTERFACEKEY_STRING_A132,
+ INTERFACEKEY_STRING_A133,
+ INTERFACEKEY_STRING_A134,
+ INTERFACEKEY_STRING_A135,
+ INTERFACEKEY_STRING_A136,
+ INTERFACEKEY_STRING_A137,
+ INTERFACEKEY_STRING_A138,
+ INTERFACEKEY_STRING_A139,
+ INTERFACEKEY_STRING_A140,
+ INTERFACEKEY_STRING_A141,
+ INTERFACEKEY_STRING_A142,
+ INTERFACEKEY_STRING_A143,
+ INTERFACEKEY_STRING_A144,
+ INTERFACEKEY_STRING_A145,
+ INTERFACEKEY_STRING_A146,
+ INTERFACEKEY_STRING_A147,
+ INTERFACEKEY_STRING_A148,
+ INTERFACEKEY_STRING_A149,
+ INTERFACEKEY_STRING_A150,
+ INTERFACEKEY_STRING_A151,
+ INTERFACEKEY_STRING_A152,
+ INTERFACEKEY_STRING_A153,
+ INTERFACEKEY_STRING_A154,
+ INTERFACEKEY_STRING_A155,
+ INTERFACEKEY_STRING_A156,
+ INTERFACEKEY_STRING_A157,
+ INTERFACEKEY_STRING_A158,
+ INTERFACEKEY_STRING_A159,
+ INTERFACEKEY_STRING_A160,
+ INTERFACEKEY_STRING_A161,
+ INTERFACEKEY_STRING_A162,
+ INTERFACEKEY_STRING_A163,
+ INTERFACEKEY_STRING_A164,
+ INTERFACEKEY_STRING_A165,
+ INTERFACEKEY_STRING_A166,
+ INTERFACEKEY_STRING_A167,
+ INTERFACEKEY_STRING_A168,
+ INTERFACEKEY_STRING_A169,
+ INTERFACEKEY_STRING_A170,
+ INTERFACEKEY_STRING_A171,
+ INTERFACEKEY_STRING_A172,
+ INTERFACEKEY_STRING_A173,
+ INTERFACEKEY_STRING_A174,
+ INTERFACEKEY_STRING_A175,
+ INTERFACEKEY_STRING_A176,
+ INTERFACEKEY_STRING_A177,
+ INTERFACEKEY_STRING_A178,
+ INTERFACEKEY_STRING_A179,
+ INTERFACEKEY_STRING_A180,
+ INTERFACEKEY_STRING_A181,
+ INTERFACEKEY_STRING_A182,
+ INTERFACEKEY_STRING_A183,
+ INTERFACEKEY_STRING_A184,
+ INTERFACEKEY_STRING_A185,
+ INTERFACEKEY_STRING_A186,
+ INTERFACEKEY_STRING_A187,
+ INTERFACEKEY_STRING_A188,
+ INTERFACEKEY_STRING_A189,
+ INTERFACEKEY_STRING_A190,
+ INTERFACEKEY_STRING_A191,
+ INTERFACEKEY_STRING_A192,
+ INTERFACEKEY_STRING_A193,
+ INTERFACEKEY_STRING_A194,
+ INTERFACEKEY_STRING_A195,
+ INTERFACEKEY_STRING_A196,
+ INTERFACEKEY_STRING_A197,
+ INTERFACEKEY_STRING_A198,
+ INTERFACEKEY_STRING_A199,
+ INTERFACEKEY_STRING_A200,
+ INTERFACEKEY_STRING_A201,
+ INTERFACEKEY_STRING_A202,
+ INTERFACEKEY_STRING_A203,
+ INTERFACEKEY_STRING_A204,
+ INTERFACEKEY_STRING_A205,
+ INTERFACEKEY_STRING_A206,
+ INTERFACEKEY_STRING_A207,
+ INTERFACEKEY_STRING_A208,
+ INTERFACEKEY_STRING_A209,
+ INTERFACEKEY_STRING_A210,
+ INTERFACEKEY_STRING_A211,
+ INTERFACEKEY_STRING_A212,
+ INTERFACEKEY_STRING_A213,
+ INTERFACEKEY_STRING_A214,
+ INTERFACEKEY_STRING_A215,
+ INTERFACEKEY_STRING_A216,
+ INTERFACEKEY_STRING_A217,
+ INTERFACEKEY_STRING_A218,
+ INTERFACEKEY_STRING_A219,
+ INTERFACEKEY_STRING_A220,
+ INTERFACEKEY_STRING_A221,
+ INTERFACEKEY_STRING_A222,
+ INTERFACEKEY_STRING_A223,
+ INTERFACEKEY_STRING_A224,
+ INTERFACEKEY_STRING_A225,
+ INTERFACEKEY_STRING_A226,
+ INTERFACEKEY_STRING_A227,
+ INTERFACEKEY_STRING_A228,
+ INTERFACEKEY_STRING_A229,
+ INTERFACEKEY_STRING_A230,
+ INTERFACEKEY_STRING_A231,
+ INTERFACEKEY_STRING_A232,
+ INTERFACEKEY_STRING_A233,
+ INTERFACEKEY_STRING_A234,
+ INTERFACEKEY_STRING_A235,
+ INTERFACEKEY_STRING_A236,
+ INTERFACEKEY_STRING_A237,
+ INTERFACEKEY_STRING_A238,
+ INTERFACEKEY_STRING_A239,
+ INTERFACEKEY_STRING_A240,
+ INTERFACEKEY_STRING_A241,
+ INTERFACEKEY_STRING_A242,
+ INTERFACEKEY_STRING_A243,
+ INTERFACEKEY_STRING_A244,
+ INTERFACEKEY_STRING_A245,
+ INTERFACEKEY_STRING_A246,
+ INTERFACEKEY_STRING_A247,
+ INTERFACEKEY_STRING_A248,
+ INTERFACEKEY_STRING_A249,
+ INTERFACEKEY_STRING_A250,
+ INTERFACEKEY_STRING_A251,
+ INTERFACEKEY_STRING_A252,
+ INTERFACEKEY_STRING_A253,
+ INTERFACEKEY_STRING_A254,
+ INTERFACEKEY_STRING_A255,
+ INTERFACEKEY_KEYBINDING_COMPLETE,
+ INTERFACEKEYNUM,
+};
+
+extern bimap<InterfaceKey,std::string> bindingNames;
+extern bimap<InterfaceKey,std::string> displayNames;
+extern bimap<SDLKey,std::string> sdlNames;
+
+void keybinding_init();
+
+#endif
diff --git a/g_src/mail.hpp b/g_src/mail.hpp
new file mode 100755
index 0000000..b158e31
--- /dev/null
+++ b/g_src/mail.hpp
@@ -0,0 +1,155 @@
+#ifndef MAIL_H
+#define MAIL_H
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_thread.h>
+#include <queue>
+
+template <typename T>
+class MBox {
+ T val;
+ SDL_sem *fill, *empty;
+public:
+ bool try_read(T &r) { // Attempt to read the mbox. Returns true if read succeeded.
+ if (SDL_SemTryWait(fill) == 0) {
+ r = val;
+ SDL_SemPost(empty);
+ return true;
+ } else
+ return false;
+ }
+ void read(T &r) {
+ SDL_SemWait(fill);
+ r = val;
+ SDL_SemPost(empty);
+ }
+ void write(const T &v) {
+ SDL_SemWait(empty);
+ val = v;
+ SDL_SemPost(fill);
+ }
+ bool try_write(const T &v) { // Returns true if the write succeeded
+ if (SDL_SemTryWait(empty) == 0) {
+ val = v;
+ SDL_SemPost(fill);
+ return true;
+ } else
+ return false;
+ }
+ MBox(T &v) {
+ MBox();
+ write(v);
+ }
+ MBox() {
+ fill = SDL_CreateSemaphore(0);
+ empty = SDL_CreateSemaphore(1);
+ }
+ ~MBox() {
+ SDL_DestroySemaphore(fill);
+ SDL_DestroySemaphore(empty);
+ }
+};
+
+template <typename T>
+class MVar {
+ SDL_sem *s;
+public:
+ T val;
+ void lock() { SDL_SemWait(s); }
+ void unlock() { SDL_SemPost(s); }
+ MVar() { s = SDL_CreateSemaphore(1); }
+ ~MVar() { SDL_DestroySemaphore(s); }
+ void write(const T &w) { lock(); val = w; unlock(); }
+ void read(T &r) { lock(); r = val; unlock(); }
+ T read() { T r; read(r); return r; }
+};
+
+
+template<bool start_locked = false>
+class Lock {
+ SDL_sem *s;
+public:
+ void lock() { SDL_SemWait(s); }
+ void unlock() { SDL_SemPost(s); }
+ Lock() { s = SDL_CreateSemaphore(start_locked ? 0 : 1); }
+ ~Lock() { SDL_DestroySemaphore(s); }
+};
+
+
+template<typename T>
+class Chan {
+ MVar<std::queue<T> > vals;
+ SDL_sem *fill;
+public:
+ bool try_read(T &r) {
+ if (SDL_SemTryWait(fill) == 0) {
+ vals.lock();
+ r = vals.val.front();
+ vals.val.pop();
+ vals.unlock();
+ return true;
+ } else
+ return false;
+ }
+ void read(T &r) {
+ SDL_SemWait(fill);
+ vals.lock();
+ r = vals.val.front();
+ vals.val.pop();
+ vals.unlock();
+ }
+ void write(const T &w) {
+ vals.lock();
+ vals.val.push(w);
+ vals.unlock();
+ SDL_SemPost(fill);
+ }
+ Chan() {
+ fill = SDL_CreateSemaphore(0);
+ }
+ ~Chan() {
+ SDL_DestroySemaphore(fill);
+ }
+};
+
+template<>
+class Chan<void> {
+ SDL_sem *fill;
+public:
+ bool try_read() {
+ if (SDL_SemTryWait(fill) == 0)
+ return true;
+ return false;
+ }
+ void read() {
+ SDL_SemWait(fill);
+ }
+ void write() {
+ SDL_SemPost(fill);
+ }
+ Chan() {
+ fill = SDL_CreateSemaphore(0);
+ }
+ ~Chan() {
+ SDL_DestroySemaphore(fill);
+ }
+};
+
+template<typename L, typename R>
+struct Either {
+ bool isL;
+ union {
+ L left;
+ R right;
+ };
+ Either(const L &l) {
+ isL = true;
+ left = l;
+ }
+ Either(const R &r) {
+ isL = false;
+ right = r;
+ }
+};
+
+#endif
diff --git a/g_src/music_and_sound_fmodex.cpp b/g_src/music_and_sound_fmodex.cpp
new file mode 100755
index 0000000..7262c94
--- /dev/null
+++ b/g_src/music_and_sound_fmodex.cpp
@@ -0,0 +1,308 @@
+#ifndef NO_FMOD
+
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <map>
+
+#include "svector.h"
+
+#ifdef WIN32
+
+#ifndef INTEGER_TYPES
+ #define INTEGER_TYPES
+ typedef short int16_t;
+ typedef int int32_t;
+ typedef long long int64_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+ typedef unsigned long long uint64_t;
+#endif
+
+typedef int32_t VIndex;
+typedef int32_t Ordinal;
+
+#endif
+
+#include "random.h"
+
+using std::string;
+using std::map;
+using std::pair;
+
+#include "basics.h"
+#include "endian.h"
+#include "files.h"
+#include "enabler.h"
+#include "init.h"
+
+#include "music_and_sound_fmodex.h"
+#include "music_and_sound_v.h"
+
+void musicsoundst::startbackgroundmusic(int new_song)
+{
+ if (!on || new_song < 0 || new_song > MAXSONGNUM || mod[new_song].sound == NULL) {
+ return;
+ }
+
+ if (song != new_song) {
+
+ stopbackgroundmusic(); /* This is safe to call, even if song isn't valid. */
+
+ song = new_song;
+ FMOD_CHANNELINDEX cid = static_cast<FMOD_CHANNELINDEX>(0);
+ system->playSound(cid, mod[song].sound, false, &mod[song].channel);
+ }
+}
+
+void musicsoundst::stopbackgroundmusic()
+{
+ if (!on || song == -1) {
+ return;
+ }
+
+ if (mod[song].channel != NULL) {
+ mod[song].channel->stop();
+ mod[song].channel = NULL;
+ }
+
+ song = -1;
+}
+
+/* Set channel to less than 0 to have FMOD decide the channel for you. */
+void musicsoundst::playsound(int s,int channel)
+{
+ if (!on || s < 0 || s > MAXSOUNDNUM || samp[s].sound == NULL) {
+ return;
+ }
+
+ if (channel >= 0) {
+ FMOD_CHANNELINDEX cid = static_cast<FMOD_CHANNELINDEX>(channel);
+ system->playSound(cid, samp[s].sound, false, &samp[s].channel);
+ } else {
+ system->playSound(FMOD_CHANNEL_FREE, samp[s].sound, false, &samp[s].channel);
+ }
+}
+
+// Toady:
+/* Yeah, I started porting all that other crap, but it wasn't all applicable to ex
+ * and besides which, you never call it anyway.
+ */
+void musicsoundst::playsound(int s, int min_channel, int max_channel, int force_channel)
+{
+ if (!on || s < 0 || s > MAXSOUNDNUM || samp[s].sound == NULL) {
+ return;
+ }
+
+ playsound(s, force_channel);
+}
+
+// Prints a relevent error message to stderr.
+inline void err(FMOD_RESULT r)
+{
+ std::cerr << "sound: failure: " << FMOD_ErrorString(r) << std::endl;
+}
+
+void musicsoundst::initsound()
+{
+ FMOD_RESULT result = FMOD::System_Create(&system);
+ if (result != FMOD_OK) {
+ err(result);
+ on = 0;
+ return;
+ }
+
+#if defined(linux)
+ /* Set up the sound system. Default to ALSA. */
+ switch (this->sound_system) {
+ default:
+ case ALSA:
+ result = system->setOutput(FMOD_OUTPUTTYPE_ALSA);
+ break;
+ case OSS:
+ result = system->setOutput(FMOD_OUTPUTTYPE_OSS);
+ break;
+ case ESD:
+ result = system->setOutput(FMOD_OUTPUTTYPE_ESD);
+ break;
+ }
+ if (result != FMOD_OK) {
+ err(result);
+ on = 0;
+ return;
+ }
+#endif
+
+ SoftChannelNumber = SOUND_CHANNELNUM;
+ result = system->init(SoftChannelNumber, FMOD_INIT_NORMAL, NULL);
+ if (result != FMOD_OK) {
+ err(result);
+ on = 0;
+ return;
+ }
+
+ result = system->getMasterChannelGroup(&masterchannelgroup);
+ if (result != FMOD_OK) {
+ err(result);
+ on = 0;
+ return;
+ }
+
+ set_master_volume(init.media.volume);
+
+ on = 1;
+}
+
+void musicsoundst::deinitsound()
+{
+ if (!on) {
+ return;
+ }
+
+ int s;
+ for (s = 0; s < MAXSONGNUM; s++) {
+ if (mod[s].sound != NULL) {
+ mod[s].sound->release();
+ mod[s].sound = NULL;
+ mod[s].channel = NULL;
+ }
+ }
+
+ for (s = 0; s < MAXSOUNDNUM; s++) {
+ if (samp[s].sound != NULL) {
+ samp[s].sound->release();
+ samp[s].sound = NULL;
+ samp[s].channel = NULL;
+ }
+ }
+
+ system->release();
+ on = 0;
+}
+
+
+
+void musicsoundst::set_song(string &filename, int slot)
+{
+ if (!on || slot < 0 || slot > MAXSONGNUM) {
+ return;
+ }
+
+ if (mod[slot].sound != NULL) {
+ mod[slot].sound->release();
+ mod[slot].sound = NULL;
+ mod[slot].channel = NULL;
+ }
+
+ FMOD_RESULT result = system->createSound(filename.c_str(), FMOD_DEFAULT, 0, &mod[slot].sound);
+ if (result != FMOD_OK) {
+ mod[slot].sound = NULL;
+ mod[slot].channel = NULL;
+ return;
+ }
+
+ mod[slot].sound->setMode(FMOD_LOOP_NORMAL);
+}
+
+void musicsoundst::set_sound(string &filename, int slot, int pan, int priority)
+{
+ if (!on || slot < 0 || slot > MAXSOUNDNUM) {
+ return;
+ }
+
+ if (samp[slot].sound != NULL) {
+ samp[slot].sound->release();
+ samp[slot].sound = NULL;
+ samp[slot].channel = NULL;
+ }
+
+ FMOD_RESULT result = system->createSound(filename.c_str(), FMOD_DEFAULT, 0, &samp[slot].sound);
+ if (result != FMOD_OK) {
+ samp[slot].sound = NULL;
+ samp[slot].channel = NULL;
+ return;
+ }
+}
+
+void musicsoundst::set_sound_params(int slot, int p1, int vol, int pan, int priority)
+{
+ if (slot < 0 || slot > MAXSOUNDNUM) {
+ return;
+ } if (samp[slot].channel == NULL || on == 0) {
+ return;
+ }
+
+ samp[slot].channel->setPan(oldval_to_panfloat(pan));
+ samp[slot].channel->setVolume(oldval_to_volumefloat(vol));
+ samp[slot].channel->setPriority(oldval_to_priority(priority));
+ samp[slot].channel->setFrequency(static_cast<float>(p1));
+}
+
+void musicsoundst::stop_sound(int channel)
+{
+ FMOD::Channel* c;
+
+ FMOD_RESULT result = system->getChannel((int)channel, &c);
+ if (result != FMOD_OK) {
+ return;
+ }
+
+ c->stop();
+}
+
+
+void musicsoundst::set_master_volume(long newvol)
+{
+ masterchannelgroup->setVolume(oldval_to_volumefloat(newvol));
+}
+
+// Converts old FMOD 3 0 - 255 volume values to FMOD Ex 0.0 <-> 1.0 float values.
+float musicsoundst::oldval_to_volumefloat(int val)
+{
+ if (val < 0) {
+ return 0.0;
+ } else if (val > 255) {
+ return 1.0;
+ }
+
+ return static_cast<float>(val) / 255;
+}
+
+// Converts old FMOD 3 0 - 255 pan values to FMOD Ex -1.0 <-> 1.0 float values.
+float musicsoundst::oldval_to_panfloat(int val)
+{
+ if (val < 0) {
+ return -1.0;
+ } else if (val > 255) {
+ return 1.0;
+ }
+
+ float n = static_cast<float>(val) / 255;
+ return (n * 2) - 1.0;
+}
+
+// Converts old FMOD 3 0(lowest) - 255(highest) priority values to
+// FmodEx 0(highest) - 256(lowest) priority values.
+int musicsoundst::oldval_to_priority(int val)
+{
+ if (val < 0) {
+ return 256;
+ } else if (val > 255) {
+ return 0;
+ }
+
+ return 255 - val;
+}
+
+#endif // NO_FMOD
+
diff --git a/g_src/music_and_sound_fmodex.h b/g_src/music_and_sound_fmodex.h
new file mode 100755
index 0000000..444d555
--- /dev/null
+++ b/g_src/music_and_sound_fmodex.h
@@ -0,0 +1,102 @@
+//copyright (c) 2006 by tarn adams
+
+#define SOUND_CHANNELNUM 16
+
+#include <string>
+#include <map>
+
+#ifndef NO_FMOD
+
+#include <fmod.hpp>
+#include <fmod_errors.h>
+
+/* The maximums can be no larger than the largest value
+ * of a signed integer.
+ */
+#define MAXSONGNUM 1000
+#define MAXSOUNDNUM 1000
+#define FSOUND_STEREOPAN 0
+
+struct fmodSound {
+ FMOD::Sound *sound;
+ FMOD::Channel *channel;
+};
+
+
+
+class musicsoundst
+{
+ public:
+ enum linux_sound_system {
+ ALSA,
+ OSS,
+ ESD,
+ };
+
+ int SoftChannelNumber;
+
+ musicsoundst() : song(-1), system(NULL), masterchannelgroup(NULL), sound_system(ALSA)
+ {
+ int s;
+ for (s = 0; s < MAXSONGNUM; s++) {
+ mod[s].sound = NULL;
+ mod[s].channel = NULL;
+ }
+
+ for (s = 0; s < MAXSOUNDNUM; s++) {
+ samp[s].sound = NULL;
+ samp[s].channel = NULL;
+ }
+ }
+ ~musicsoundst()
+ {
+ deinitsound();
+ }
+
+ void startbackgroundmusic(int new_song);
+ void stopbackgroundmusic();
+ void playsound(int s,int channel=-1);
+ void playsound(int s,int min_channel,int max_channel,int force_channel);
+ void initsound();
+ void deinitsound();
+ void set_song(string &filename,int slot);
+ void set_sound(string &filename,int slot,int pan=-1,int priority=0);
+ void set_sound_params(int slot,int p1,int vol,int pan,int priority);
+ void stop_sound(int channel);
+ void stop_sound() {
+ masterchannelgroup->stop();
+ }
+ void set_master_volume(long newvol);
+ void update() {
+ if (!on) {
+ return;
+ }
+
+ system->update();
+ }
+
+ void set_sound_system(musicsoundst::linux_sound_system system) {
+ sound_system = system;
+ }
+
+ private:
+ float oldval_to_volumefloat(int val);
+ float oldval_to_panfloat(int val);
+ int oldval_to_priority(int val);
+
+ int song;
+ char musicactive;
+ char soundpriority;
+ int soundplaying;
+
+ char on;
+
+ FMOD::System *system;
+ FMOD::ChannelGroup *masterchannelgroup;
+ fmodSound mod[MAXSONGNUM];
+ fmodSound samp[MAXSOUNDNUM];
+
+ musicsoundst::linux_sound_system sound_system;
+};
+#endif
+
diff --git a/g_src/music_and_sound_g.h b/g_src/music_and_sound_g.h
new file mode 100755
index 0000000..dc9acb0
--- /dev/null
+++ b/g_src/music_and_sound_g.h
@@ -0,0 +1,13 @@
+#ifndef MUSIC_AND_SOUND_G
+#define MUSIC_AND_SOUND_G
+
+// Fmodex works well enough on windows/os x, but on some linux distributions it fails badly
+#if defined(linux)
+#include "music_and_sound_openal.h"
+#else
+#include "music_and_sound_fmodex.h"
+#endif // unix
+
+extern musicsoundst musicsound;
+
+#endif
diff --git a/g_src/music_and_sound_openal.cpp b/g_src/music_and_sound_openal.cpp
new file mode 100755
index 0000000..1ee0941
--- /dev/null
+++ b/g_src/music_and_sound_openal.cpp
@@ -0,0 +1,688 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "music_and_sound_openal.h"
+#include "music_and_sound_v.h"
+
+#define ABORT(str) do { printf("%s: line %d: %s\n", __FILE__, __LINE__, str); abort(); } while(0);
+static bool init_openal();
+static bool init_sndfile();
+
+using namespace std;
+
+#define alPrintErrors() do { alPrintErrors_(__FILE__,__LINE__); } while(0);
+
+static void alPrintErrors_(const char* file, int line) {
+ ALenum err;
+ while ((err = alGetError()) != AL_NO_ERROR) {
+ printf("At %s: %d: ", file, line);
+ switch (err) {
+ case AL_INVALID_NAME: puts("AL_INVALID_NAME detected"); break;
+ case AL_INVALID_ENUM: puts("AL_INVALID_ENUM detected"); break;
+ case AL_INVALID_VALUE: puts("AL_INVALID_VALUE detected"); break;
+ case AL_INVALID_OPERATION: puts("AL_INVALID_OPERATION detected"); break;
+ case AL_OUT_OF_MEMORY: puts("AL_OUT_OF_MEMORY detected"); break;
+ }
+ }
+}
+
+bool musicsoundst::initsound() {
+ if (functional) return true;
+
+ // Load the libraries
+ if (!init_openal()) {
+ puts("Dynamically loading the OpenAL library failed, disabling sound");
+ MessageBox(NULL, "Dynamically loading the OpenAL library failed, disabling sound", 0, 0);
+ return false;
+ }
+ if (!init_sndfile()) {
+ puts("Dynamically loading the sndfile library failed, disabling sound");
+ MessageBox(NULL, "Dynamically loading the sndfile library failed, disabling sound", 0, 0);
+ return false;
+ }
+
+ // Find out what devices we have available
+ const char *devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+ if (!devices) {
+ puts("No sound devices available. Sound disabled. OpenAL broken?");
+ return false;
+ }
+
+ const char *firstdevice = devices;
+ puts("Sound devices available:");
+ while (*devices) {
+ puts(devices);
+ devices += strlen(devices) + 1;
+ }
+ printf("Picking %s. If your desired device was missing, make sure you have the appropriate 32-bit libraries installed. If you wanted a different device, configure ~/.openalrc appropriately.\n",
+ firstdevice);
+
+ // Create the context
+ device = alcOpenDevice(firstdevice);
+ if (!device)
+ return false;
+
+ const ALCint attrlist[] = { ALC_FREQUENCY, SOUND_FREQUENCY,
+ ALC_MONO_SOURCES, 0,
+ ALC_STEREO_SOURCES, SOUND_CHANNELNUM };
+ context = alcCreateContext(device, attrlist);
+ if (context) {
+ puts("Perfect OpenAL context attributes GET");
+ goto done;
+ }
+ context = alcCreateContext(device, NULL);
+ if (context) {
+ puts("Using OpenAL in compatibility mode");
+ goto done;
+ }
+ alcCloseDevice(device);
+ return false;
+
+ done:
+ if (ALC_FALSE == alcMakeContextCurrent(context)) {
+ puts("alcMakeContextCurrent failed");
+ return false;
+ }
+ functional = true;
+ return true;
+}
+
+// int main() {
+// musicsound.initsound();
+// string str = "data/sound/song_title.ogg";
+// musicsound.set_song(str, 14);
+// musicsound.startbackgroundmusic(14);
+// sleep(9999);
+// exit(1);
+// }
+
+void musicsoundst::set_song(string &filename, slot slot) {
+ if (!functional) return;
+
+ // printf("%s requested in %d-%d\n", filename.c_str(), (int)slot.first, slot.second);
+ if (!buffers.count(filename)) {
+ // Song not already loaded. Load it.
+ SF_INFO sfinfo;
+ sfinfo.format = 0;
+ SNDFILE *sf = sf_open(filename.c_str(), SFM_READ, &sfinfo);
+ if (!sf) {
+ printf("%s not found, sound not loaded\n", filename.c_str());
+ goto end;
+ }
+ short *buffer = new short[sfinfo.channels * sfinfo.frames];
+ sf_count_t frames_read = sf_readf_short(sf, buffer, sfinfo.frames);
+ if (frames_read != sfinfo.frames)
+ printf("%s: %d frames requested, %d frames read. Corrupted file?\n",
+ filename.c_str(), (int)sfinfo.frames, (int)frames_read);
+ sf_close(sf);
+ // Construct openal buffer and load this
+ ALuint albuf;
+ alGenBuffers(1, &albuf);
+ if (!alIsBuffer(albuf)) {
+ puts("Constructing OpenAL buffer mysteriously failed!");
+ goto end;
+ }
+ ALenum format;
+ switch (sfinfo.channels) {
+ case 1: format = AL_FORMAT_MONO16;
+ break;
+ case 2: format = AL_FORMAT_STEREO16;
+ break;
+ default:
+ printf("%s: Unexpected number of channels: %d\n",
+ filename.c_str(), (int)sfinfo.channels);
+ goto end;
+ }
+ alBufferData(albuf, format, (ALvoid*)buffer,
+ sfinfo.channels * sfinfo.frames * 2, sfinfo.samplerate);
+ alPrintErrors();
+ delete[] buffer;
+
+ // Create a source for this song
+ ALuint source;
+ alGenSources(1, &source);
+ if (!alIsSource(source)) {
+ puts("Constructing OpenAL source mysteriously failed!");
+ goto end;
+ }
+ alSourceQueueBuffers(source, 1, &albuf);
+
+ buffers[filename] = albuf;
+ sources[filename] = source;
+ }
+
+ // Store the requested song in the requested slot.
+ // Say, should this alter the playing song if that slot is already playing?
+ slot_buffer[slot] = buffers[filename];
+ slot_source[slot] = sources[filename];
+
+ end:
+ alPrintErrors();
+}
+
+void musicsoundst::set_song(string &filename, int slot) {
+ set_song(filename, make_pair(true, slot));
+}
+
+void musicsoundst::set_master_volume(long newvol) {
+ if (!functional) return;
+ alListenerf(AL_GAIN, newvol / 255.0f);
+}
+
+void musicsoundst::playsound(slot slot) {
+ if (!functional) return;
+ // printf("%d requested\n", slot);
+ if (!slot_source.count(slot)) {
+ // printf("Slot %d-%d requested, but no song loaded\n", (int)slot.first, slot.second);
+ return;
+ }
+ if (background_slot == slot) {
+ puts("playsound called on background song, background song cancelled!?");
+ background_slot = make_pair(false,-1);
+ }
+ alSourcei(slot_source[slot], AL_LOOPING, AL_FALSE);
+ alSourcePlay(slot_source[slot]);
+ alPrintErrors();
+}
+
+void musicsoundst::playsound(int slot) {
+ playsound(make_pair(false,slot));
+}
+
+void musicsoundst::startbackgroundmusic(slot slot) {
+ if (!functional) return;
+
+ if (!slot_source.count(slot)) {
+ // printf("Slot %d-%d requested, but no song loaded\n", (int)slot.first, slot.second);
+ return;
+ }
+
+ if (background_slot == slot)
+ return; // Verily, it is already playing
+ stop_sound(background_slot);
+ background_slot = slot;
+ // printf("%d backgrounded\n", slot);
+
+ alSourcei(slot_source[slot], AL_LOOPING, AL_TRUE);
+ alSourcePlay(slot_source[slot]);
+ alPrintErrors();
+}
+
+void musicsoundst::startbackgroundmusic(int slot) {
+ startbackgroundmusic(make_pair(true,slot));
+}
+
+void musicsoundst::stopbackgroundmusic() {
+ if (!functional) return;
+ if (background_slot == make_pair(false,-1)) return;
+
+ alSourceStop(slot_source[background_slot]);
+}
+
+void musicsoundst::stop_sound() {
+ if (!functional) return;
+ // Stop all playing sounds. Does this include background music?
+ std::map<std::string,ALuint>::iterator it;
+ for (it = sources.begin(); it != sources.end(); ++it)
+ alSourceStop(it->second);
+}
+
+void musicsoundst::stop_sound(slot slot) {
+ if (!functional) return;
+ if (slot_source.count(slot) == 0) return;
+ ALuint source = slot_source[slot];
+ alSourceStop(source);
+}
+
+void musicsoundst::deinitsound() {
+ if (!functional) return;
+
+ std::map<std::string,ALuint>::iterator it;
+ // Free all sources
+ for (it = sources.begin(); it != sources.end(); ++it) {
+ ALuint source = it->second;
+ alDeleteSources(1, &source);
+ }
+ // Free all sample memory
+ for (it = buffers.begin(); it != buffers.end(); ++it) {
+ ALuint buffer = it->second;
+ alDeleteBuffers(1, &buffer);
+ }
+ // Deinit OpenAL
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(context);
+ alcCloseDevice(device);
+
+ functional=false;
+}
+
+void musicsoundst::set_sound(string &filename, int slot, int pan, int priority) {
+ if (!functional) return;
+ set_song(filename, make_pair(false,slot));
+}
+
+// Deprecated stuff below
+
+void musicsoundst::playsound(int s, int channel) {
+ if (!functional) return;
+ playsound(s);
+}
+
+
+//// OpenAL, ALC and sndfile stub ////
+
+static void (*_alEnable)( ALenum capability );
+static void (*_alDisable)( ALenum capability );
+static ALboolean (*_alIsEnabled)( ALenum capability );
+static const ALchar* (*_alGetString)( ALenum param );
+static void (*_alGetBooleanv)( ALenum param, ALboolean* data );
+static void (*_alGetIntegerv)( ALenum param, ALint* data );
+static void (*_alGetFloatv)( ALenum param, ALfloat* data );
+static void (*_alGetDoublev)( ALenum param, ALdouble* data );
+static ALboolean (*_alGetBoolean)( ALenum param );
+static ALint (*_alGetInteger)( ALenum param );
+static ALfloat (*_alGetFloat)( ALenum param );
+static ALdouble (*_alGetDouble)( ALenum param );
+static ALenum (*_alGetError)( void );
+static ALboolean (*_alIsExtensionPresent)( const ALchar* extname );
+static void* (*_alGetProcAddress)( const ALchar* fname );
+static ALenum (*_alGetEnumValue)( const ALchar* ename );
+static void (*_alListenerf)( ALenum param, ALfloat value );
+static void (*_alListener3f)( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
+static void (*_alListenerfv)( ALenum param, const ALfloat* values );
+static void (*_alListeneri)( ALenum param, ALint value );
+static void (*_alListener3i)( ALenum param, ALint value1, ALint value2, ALint value3 );
+static void (*_alListeneriv)( ALenum param, const ALint* values );
+static void (*_alGetListenerf)( ALenum param, ALfloat* value );
+static void (*_alGetListener3f)( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 );
+static void (*_alGetListenerfv)( ALenum param, ALfloat* values );
+static void (*_alGetListeneri)( ALenum param, ALint* value );
+static void (*_alGetListener3i)( ALenum param, ALint *value1, ALint *value2, ALint *value3 );
+static void (*_alGetListeneriv)( ALenum param, ALint* values );
+static void (*_alGenSources)( ALsizei n, ALuint* sources );
+static void (*_alDeleteSources)( ALsizei n, const ALuint* sources );
+static ALboolean (*_alIsSource)( ALuint sid );
+static void (*_alSourcef)( ALuint sid, ALenum param, ALfloat value );
+static void (*_alSource3f)( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
+static void (*_alSourcefv)( ALuint sid, ALenum param, const ALfloat* values );
+static void (*_alSourcei)( ALuint sid, ALenum param, ALint value );
+static void (*_alSource3i)( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 );
+static void (*_alSourceiv)( ALuint sid, ALenum param, const ALint* values );
+static void (*_alGetSourcef)( ALuint sid, ALenum param, ALfloat* value );
+static void (*_alGetSource3f)( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
+static void (*_alGetSourcefv)( ALuint sid, ALenum param, ALfloat* values );
+static void (*_alGetSourcei)( ALuint sid, ALenum param, ALint* value );
+static void (*_alGetSource3i)( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
+static void (*_alGetSourceiv)( ALuint sid, ALenum param, ALint* values );
+static void (*_alSourcePlayv)( ALsizei ns, const ALuint *sids );
+static void (*_alSourceStopv)( ALsizei ns, const ALuint *sids );
+static void (*_alSourceRewindv)( ALsizei ns, const ALuint *sids );
+static void (*_alSourcePausev)( ALsizei ns, const ALuint *sids );
+static void (*_alSourcePlay)( ALuint sid );
+static void (*_alSourceStop)( ALuint sid );
+static void (*_alSourceRewind)( ALuint sid );
+static void (*_alSourcePause)( ALuint sid );
+static void (*_alSourceQueueBuffers)( ALuint sid, ALsizei numEntries, const ALuint *bids );
+static void (*_alSourceUnqueueBuffers)( ALuint sid, ALsizei numEntries, ALuint *bids );
+static void (*_alGenBuffers)( ALsizei n, ALuint* buffers );
+static void (*_alDeleteBuffers)( ALsizei n, const ALuint* buffers );
+static ALboolean (*_alIsBuffer)( ALuint bid );
+static void (*_alBufferData)( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq );
+static void (*_alBufferf)( ALuint bid, ALenum param, ALfloat value );
+static void (*_alBuffer3f)( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 );
+static void (*_alBufferfv)( ALuint bid, ALenum param, const ALfloat* values );
+static void (*_alBufferi)( ALuint bid, ALenum param, ALint value );
+static void (*_alBuffer3i)( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 );
+static void (*_alBufferiv)( ALuint bid, ALenum param, const ALint* values );
+static void (*_alGetBufferf)( ALuint bid, ALenum param, ALfloat* value );
+static void (*_alGetBuffer3f)( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3);
+static void (*_alGetBufferfv)( ALuint bid, ALenum param, ALfloat* values );
+static void (*_alGetBufferi)( ALuint bid, ALenum param, ALint* value );
+static void (*_alGetBuffer3i)( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3);
+static void (*_alGetBufferiv)( ALuint bid, ALenum param, ALint* values );
+static void (*_alDopplerFactor)( ALfloat value );
+static void (*_alDopplerVelocity)( ALfloat value );
+static void (*_alSpeedOfSound)( ALfloat value );
+static void (*_alDistanceModel)( ALenum distanceModel );
+static ALCcontext * (*_alcCreateContext)( ALCdevice *device, const ALCint* attrlist );
+static ALCboolean (*_alcMakeContextCurrent)( ALCcontext *context );
+static void (*_alcProcessContext)( ALCcontext *context );
+static void (*_alcSuspendContext)( ALCcontext *context );
+static void (*_alcDestroyContext)( ALCcontext *context );
+static ALCcontext * (*_alcGetCurrentContext)( void );
+static ALCdevice* (*_alcGetContextsDevice)( ALCcontext *context );
+static ALCdevice * (*_alcOpenDevice)( const ALCchar *devicename );
+static ALCboolean (*_alcCloseDevice)( ALCdevice *device );
+static ALCenum (*_alcGetError)( ALCdevice *device );
+static ALCboolean (*_alcIsExtensionPresent)( ALCdevice *device, const ALCchar *extname );
+static void * (*_alcGetProcAddress)( ALCdevice *device, const ALCchar *funcname );
+static ALCenum (*_alcGetEnumValue)( ALCdevice *device, const ALCchar *enumname );
+static const ALCchar * (*_alcGetString)( ALCdevice *device, ALCenum param );
+static void (*_alcGetIntegerv)( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data );
+static ALCdevice* (*_alcCaptureOpenDevice)( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize );
+static ALCboolean (*_alcCaptureCloseDevice)( ALCdevice *device );
+static void (*_alcCaptureStart)( ALCdevice *device );
+static void (*_alcCaptureStop)( ALCdevice *device );
+static void (*_alcCaptureSamples)( ALCdevice *device, ALCvoid *buffer, ALCsizei samples );
+
+static bool linkit(void **target, const char *symbol, void *handle) {
+ *target = dlsym(handle, symbol);
+ if (!*target) {
+ printf("Failed to link %s\n", symbol);
+ return false;
+ }
+ return true;
+}
+
+static bool init_openal() {
+ void *handle = dlopen("libopenal.so", RTLD_LAZY);
+ if (!handle) handle = dlopen("libopenal.so.1", RTLD_LAZY);
+ if (!handle) return false;
+
+ if (!linkit((void**)&_alEnable, "alEnable", handle)) return false;
+ if (!linkit((void**)&_alDisable, "alDisable", handle)) return false;
+ if (!linkit((void**)&_alIsEnabled, "alIsEnabled", handle)) return false;
+ if (!linkit((void**)&_alGetString, "alGetString", handle)) return false;
+ if (!linkit((void**)&_alGetBooleanv, "alGetBooleanv", handle)) return false;
+ if (!linkit((void**)&_alGetIntegerv, "alGetIntegerv", handle)) return false;
+ if (!linkit((void**)&_alGetFloatv, "alGetFloatv", handle)) return false;
+ if (!linkit((void**)&_alGetDoublev, "alGetDoublev", handle)) return false;
+ if (!linkit((void**)&_alGetBoolean, "alGetBoolean", handle)) return false;
+ if (!linkit((void**)&_alGetInteger, "alGetInteger", handle)) return false;
+ if (!linkit((void**)&_alGetFloat, "alGetFloat", handle)) return false;
+ if (!linkit((void**)&_alGetDouble, "alGetDouble", handle)) return false;
+ if (!linkit((void**)&_alGetError, "alGetError", handle)) return false;
+ if (!linkit((void**)&_alIsExtensionPresent, "alIsExtensionPresent", handle)) return false;
+ if (!linkit((void**)&_alGetProcAddress, "alGetProcAddress", handle)) return false;
+ if (!linkit((void**)&_alGetEnumValue, "alGetEnumValue", handle)) return false;
+ if (!linkit((void**)&_alListenerf, "alListenerf", handle)) return false;
+ if (!linkit((void**)&_alListener3f, "alListener3f", handle)) return false;
+ if (!linkit((void**)&_alListenerfv, "alListenerfv", handle)) return false;
+ if (!linkit((void**)&_alListeneri, "alListeneri", handle)) return false;
+ if (!linkit((void**)&_alListener3i, "alListener3i", handle)) return false;
+ if (!linkit((void**)&_alListeneriv, "alListeneriv", handle)) return false;
+ if (!linkit((void**)&_alGetListenerf, "alGetListenerf", handle)) return false;
+ if (!linkit((void**)&_alGetListener3f, "alGetListener3f", handle)) return false;
+ if (!linkit((void**)&_alGetListenerfv, "alGetListenerfv", handle)) return false;
+ if (!linkit((void**)&_alGetListeneri, "alGetListeneri", handle)) return false;
+ if (!linkit((void**)&_alGetListener3i, "alGetListener3i", handle)) return false;
+ if (!linkit((void**)&_alGetListeneriv, "alGetListeneriv", handle)) return false;
+ if (!linkit((void**)&_alGenSources, "alGenSources", handle)) return false;
+ if (!linkit((void**)&_alDeleteSources, "alDeleteSources", handle)) return false;
+ if (!linkit((void**)&_alIsSource, "alIsSource", handle)) return false;
+ if (!linkit((void**)&_alSourcef, "alSourcef", handle)) return false;
+ if (!linkit((void**)&_alSource3f, "alSource3f", handle)) return false;
+ if (!linkit((void**)&_alSourcefv, "alSourcefv", handle)) return false;
+ if (!linkit((void**)&_alSourcei, "alSourcei", handle)) return false;
+ if (!linkit((void**)&_alSource3i, "alSource3i", handle)) return false;
+ if (!linkit((void**)&_alSourceiv, "alSourceiv", handle)) return false;
+ if (!linkit((void**)&_alGetSourcef, "alGetSourcef", handle)) return false;
+ if (!linkit((void**)&_alGetSource3f, "alGetSource3f", handle)) return false;
+ if (!linkit((void**)&_alGetSourcefv, "alGetSourcefv", handle)) return false;
+ if (!linkit((void**)&_alGetSourcei, "alGetSourcei", handle)) return false;
+ if (!linkit((void**)&_alGetSource3i, "alGetSource3i", handle)) return false;
+ if (!linkit((void**)&_alGetSourceiv, "alGetSourceiv", handle)) return false;
+ if (!linkit((void**)&_alSourcePlayv, "alSourcePlayv", handle)) return false;
+ if (!linkit((void**)&_alSourceStopv, "alSourceStopv", handle)) return false;
+ if (!linkit((void**)&_alSourceRewindv, "alSourceRewindv", handle)) return false;
+ if (!linkit((void**)&_alSourcePausev, "alSourcePausev", handle)) return false;
+ if (!linkit((void**)&_alSourcePlay, "alSourcePlay", handle)) return false;
+ if (!linkit((void**)&_alSourceStop, "alSourceStop", handle)) return false;
+ if (!linkit((void**)&_alSourceRewind, "alSourceRewind", handle)) return false;
+ if (!linkit((void**)&_alSourcePause, "alSourcePause", handle)) return false;
+ if (!linkit((void**)&_alSourceQueueBuffers, "alSourceQueueBuffers", handle)) return false;
+ if (!linkit((void**)&_alSourceUnqueueBuffers, "alSourceUnqueueBuffers", handle)) return false;
+ if (!linkit((void**)&_alGenBuffers, "alGenBuffers", handle)) return false;
+ if (!linkit((void**)&_alDeleteBuffers, "alDeleteBuffers", handle)) return false;
+ if (!linkit((void**)&_alIsBuffer, "alIsBuffer", handle)) return false;
+ if (!linkit((void**)&_alBufferData, "alBufferData", handle)) return false;
+ if (!linkit((void**)&_alBufferf, "alBufferf", handle)) return false;
+ if (!linkit((void**)&_alBuffer3f, "alBuffer3f", handle)) return false;
+ if (!linkit((void**)&_alBufferfv, "alBufferfv", handle)) return false;
+ if (!linkit((void**)&_alBufferi, "alBufferi", handle)) return false;
+ if (!linkit((void**)&_alBuffer3i, "alBuffer3i", handle)) return false;
+ if (!linkit((void**)&_alBufferiv, "alBufferiv", handle)) return false;
+ if (!linkit((void**)&_alGetBufferf, "alGetBufferf", handle)) return false;
+ if (!linkit((void**)&_alGetBuffer3f, "alGetBuffer3f", handle)) return false;
+ if (!linkit((void**)&_alGetBufferfv, "alGetBufferfv", handle)) return false;
+ if (!linkit((void**)&_alGetBufferi, "alGetBufferi", handle)) return false;
+ if (!linkit((void**)&_alGetBuffer3i, "alGetBuffer3i", handle)) return false;
+ if (!linkit((void**)&_alGetBufferiv, "alGetBufferiv", handle)) return false;
+ if (!linkit((void**)&_alDopplerFactor, "alDopplerFactor", handle)) return false;
+ if (!linkit((void**)&_alDopplerVelocity, "alDopplerVelocity", handle)) return false;
+ if (!linkit((void**)&_alSpeedOfSound, "alSpeedOfSound", handle)) return false;
+ if (!linkit((void**)&_alDistanceModel, "alDistanceModel", handle)) return false;
+ if (!linkit((void**)&_alcCreateContext, "alcCreateContext", handle)) return false;
+ if (!linkit((void**)&_alcMakeContextCurrent, "alcMakeContextCurrent", handle)) return false;
+ if (!linkit((void**)&_alcProcessContext, "alcProcessContext", handle)) return false;
+ if (!linkit((void**)&_alcSuspendContext, "alcSuspendContext", handle)) return false;
+ if (!linkit((void**)&_alcDestroyContext, "alcDestroyContext", handle)) return false;
+ if (!linkit((void**)&_alcGetCurrentContext, "alcGetCurrentContext", handle)) return false;
+ if (!linkit((void**)&_alcGetContextsDevice, "alcGetContextsDevice", handle)) return false;
+ if (!linkit((void**)&_alcOpenDevice, "alcOpenDevice", handle)) return false;
+ if (!linkit((void**)&_alcCloseDevice, "alcCloseDevice", handle)) return false;
+ if (!linkit((void**)&_alcGetError, "alcGetError", handle)) return false;
+ if (!linkit((void**)&_alcIsExtensionPresent, "alcIsExtensionPresent", handle)) return false;
+ if (!linkit((void**)&_alcGetProcAddress, "alcGetProcAddress", handle)) return false;
+ if (!linkit((void**)&_alcGetEnumValue, "alcGetEnumValue", handle)) return false;
+ if (!linkit((void**)&_alcGetString, "alcGetString", handle)) return false;
+ if (!linkit((void**)&_alcGetIntegerv, "alcGetIntegerv", handle)) return false;
+ if (!linkit((void**)&_alcCaptureOpenDevice, "alcCaptureOpenDevice", handle)) return false;
+ if (!linkit((void**)&_alcCaptureCloseDevice, "alcCaptureCloseDevice", handle)) return false;
+ if (!linkit((void**)&_alcCaptureStart, "alcCaptureStart", handle)) return false;
+ if (!linkit((void**)&_alcCaptureStop, "alcCaptureStop", handle)) return false;
+ if (!linkit((void**)&_alcCaptureSamples, "alcCaptureSamples", handle)) return false;
+
+ return true;
+}
+
+
+void alEnable( ALenum capability ) { _alEnable(capability); }
+void alDisable( ALenum capability ) { _alDisable(capability); }
+ALboolean alIsEnabled( ALenum capability ) { _alIsEnabled(capability); }
+const ALchar* alGetString( ALenum param ) { return _alGetString(param); }
+void alGetBooleanv( ALenum param, ALboolean* data ) { _alGetBooleanv(param, data); }
+void alGetIntegerv( ALenum param, ALint* data ) { _alGetIntegerv(param, data); }
+void alGetFloatv( ALenum param, ALfloat* data ) { _alGetFloatv(param, data); }
+void alGetDoublev( ALenum param, ALdouble* data ) { _alGetDoublev(param, data); }
+ALboolean alGetBoolean( ALenum param ) { return _alGetBoolean(param); }
+ALint alGetInteger( ALenum param ) { return _alGetInteger(param); }
+ALfloat alGetFloat( ALenum param ) { return _alGetFloat(param); }
+ALdouble alGetDouble( ALenum param ) { return _alGetDouble(param); }
+ALenum alGetError( void ) { _alGetError(); }
+ALboolean alIsExtensionPresent( const ALchar* extname ) { return _alIsExtensionPresent(extname); }
+void* alGetProcAddress( const ALchar* fname ) { return _alGetProcAddress(fname); }
+ALenum alGetEnumValue( const ALchar* ename ) { return _alGetEnumValue(ename); }
+void alListenerf( ALenum param, ALfloat value ) { return _alListenerf(param, value); }
+void alListener3f( ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { return _alListener3f(param, value1, value2, value3); }
+void alListenerfv( ALenum param, const ALfloat* values ) { return _alListenerfv(param, values); }
+void alListeneri( ALenum param, ALint value ) { return _alListeneri(param, value); }
+void alListener3i( ALenum param, ALint value1, ALint value2, ALint value3 ) { return _alListener3i(param, value1, value2, value3); }
+void alListeneriv( ALenum param, const ALint* values ) { return _alListeneriv(param, values); }
+void alGetListenerf( ALenum param, ALfloat* value ) { return _alGetListenerf(param, value); }
+void alGetListener3f( ALenum param, ALfloat *value1, ALfloat *value2, ALfloat *value3 ) { return _alGetListener3f(param, value1, value2, value3); }
+void alGetListenerfv( ALenum param, ALfloat* values ) { return _alGetListenerfv(param, values); }
+void alGetListeneri( ALenum param, ALint* value ) { return _alGetListeneri(param, value); }
+void alGetListener3i( ALenum param, ALint *value1, ALint *value2, ALint *value3 ) { return _alGetListener3i(param, value1, value2, value3); }
+void alGetListeneriv( ALenum param, ALint* values ) { return _alGetListeneriv(param, values); }
+void alGenSources( ALsizei n, ALuint* sources ) { return _alGenSources(n, sources); }
+void alDeleteSources( ALsizei n, const ALuint* sources ) { return _alDeleteSources(n, sources); }
+ALboolean alIsSource( ALuint sid ) { return _alIsSource(sid); }
+void alSourcef( ALuint sid, ALenum param, ALfloat value ) { return _alSourcef(sid, param, value); }
+void alSource3f( ALuint sid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { return _alSource3f(sid, param, value1, value2, value3); }
+void alSourcefv( ALuint sid, ALenum param, const ALfloat* values ) { return _alSourcefv(sid, param, values); }
+void alSourcei( ALuint sid, ALenum param, ALint value ) { return _alSourcei(sid, param, value); }
+void alSource3i( ALuint sid, ALenum param, ALint value1, ALint value2, ALint value3 ) { return _alSource3i(sid, param, value1, value2, value3); }
+void alSourceiv( ALuint sid, ALenum param, const ALint* values ) { return _alSourceiv(sid, param, values); }
+void alGetSourcef( ALuint sid, ALenum param, ALfloat* value ) { return _alGetSourcef(sid, param, value); }
+void alGetSource3f( ALuint sid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) { return _alGetSource3f(sid, param, value1, value2, value3); }
+void alGetSourcefv( ALuint sid, ALenum param, ALfloat* values ) { return _alGetSourcefv(sid, param, values); }
+void alGetSourcei( ALuint sid, ALenum param, ALint* value ) { return _alGetSourcei(sid, param, value); }
+void alGetSource3i( ALuint sid, ALenum param, ALint* value1, ALint* value2, ALint* value3) { return _alGetSource3i(sid, param, value1, value2, value3); }
+void alGetSourceiv( ALuint sid, ALenum param, ALint* values ) { return _alGetSourceiv(sid, param, values); }
+void alSourcePlayv( ALsizei ns, const ALuint *sids ) { return _alSourcePlayv(ns, sids); }
+void alSourceStopv( ALsizei ns, const ALuint *sids ) { return _alSourceStopv(ns, sids); }
+void alSourceRewindv( ALsizei ns, const ALuint *sids ) { return _alSourceRewindv(ns, sids); }
+void alSourcePausev( ALsizei ns, const ALuint *sids ) { return _alSourcePausev(ns, sids); }
+void alSourcePlay( ALuint sid ) { return _alSourcePlay(sid); }
+void alSourceStop( ALuint sid ) { return _alSourceStop(sid); }
+void alSourceRewind( ALuint sid ) { return _alSourceRewind(sid); }
+void alSourcePause( ALuint sid ) { return _alSourcePause(sid); }
+void alSourceQueueBuffers( ALuint sid, ALsizei numEntries, const ALuint *bids ) { return _alSourceQueueBuffers(sid, numEntries, bids); }
+void alSourceUnqueueBuffers( ALuint sid, ALsizei numEntries, ALuint *bids ) { return _alSourceUnqueueBuffers(sid, numEntries, bids); }
+void alGenBuffers( ALsizei n, ALuint* buffers ) { return _alGenBuffers(n, buffers); }
+void alDeleteBuffers( ALsizei n, const ALuint* buffers ) { return _alDeleteBuffers(n, buffers); }
+ALboolean alIsBuffer( ALuint bid ) { return _alIsBuffer(bid); }
+void alBufferData( ALuint bid, ALenum format, const ALvoid* data, ALsizei size, ALsizei freq ) { return _alBufferData(bid, format, data, size, freq); }
+void alBufferf( ALuint bid, ALenum param, ALfloat value ) { return _alBufferf(bid, param, value); }
+void alBuffer3f( ALuint bid, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3 ) { return _alBuffer3f(bid, param, value1, value2, value3); }
+void alBufferfv( ALuint bid, ALenum param, const ALfloat* values ) { return _alBufferfv(bid, param, values); }
+void alBufferi( ALuint bid, ALenum param, ALint value ) { return _alBufferi(bid, param, value); }
+void alBuffer3i( ALuint bid, ALenum param, ALint value1, ALint value2, ALint value3 ) { return _alBuffer3i(bid, param, value1, value2, value3); }
+void alBufferiv( ALuint bid, ALenum param, const ALint* values ) { return _alBufferiv(bid, param, values); }
+void alGetBufferf( ALuint bid, ALenum param, ALfloat* value ) { return _alGetBufferf(bid, param, value); }
+void alGetBuffer3f( ALuint bid, ALenum param, ALfloat* value1, ALfloat* value2, ALfloat* value3) { return _alGetBuffer3f(bid, param, value1, value2, value3); }
+void alGetBufferfv( ALuint bid, ALenum param, ALfloat* values ) { return _alGetBufferfv(bid, param, values); }
+void alGetBufferi( ALuint bid, ALenum param, ALint* value ) { return _alGetBufferi(bid, param, value); }
+void alGetBuffer3i( ALuint bid, ALenum param, ALint* value1, ALint* value2, ALint* value3) { return _alGetBuffer3i(bid, param, value1, value2, value3); }
+void alGetBufferiv( ALuint bid, ALenum param, ALint* values ) { return _alGetBufferiv(bid, param, values); }
+void alDopplerFactor( ALfloat value ) { return _alDopplerFactor(value); }
+void alDopplerVelocity( ALfloat value ) { return _alDopplerVelocity(value); }
+void alSpeedOfSound( ALfloat value ) { return _alSpeedOfSound(value); }
+void alDistanceModel( ALenum distanceModel ) { return _alDistanceModel(distanceModel); }
+ALCcontext * alcCreateContext( ALCdevice *device, const ALCint* attrlist ) { return _alcCreateContext(device, attrlist); }
+ALCboolean alcMakeContextCurrent( ALCcontext *context ) { return _alcMakeContextCurrent(context); }
+void alcProcessContext( ALCcontext *context ) { return _alcProcessContext(context); }
+void alcSuspendContext( ALCcontext *context ) { return _alcSuspendContext(context); }
+void alcDestroyContext( ALCcontext *context ) { return _alcDestroyContext(context); }
+ALCcontext * alcGetCurrentContext( void ) { return _alcGetCurrentContext(); }
+ALCdevice* alcGetContextsDevice( ALCcontext *context ) { return _alcGetContextsDevice(context); }
+ALCdevice * alcOpenDevice( const ALCchar *devicename ) { return _alcOpenDevice(devicename); }
+ALCboolean alcCloseDevice( ALCdevice *device ) { return _alcCloseDevice(device); }
+ALCenum alcGetError( ALCdevice *device ) { return _alcGetError(device); }
+ALCboolean alcIsExtensionPresent( ALCdevice *device, const ALCchar *extname ) { return _alcIsExtensionPresent(device, extname); }
+void * alcGetProcAddress( ALCdevice *device, const ALCchar *funcname ) { return _alcGetProcAddress(device, funcname); }
+ALCenum alcGetEnumValue( ALCdevice *device, const ALCchar *enumname ) { return _alcGetEnumValue(device, enumname); }
+const ALCchar * alcGetString( ALCdevice *device, ALCenum param ) { return _alcGetString(device, param); }
+void alcGetIntegerv( ALCdevice *device, ALCenum param, ALCsizei size, ALCint *data ) { return _alcGetIntegerv(device, param, size, data); }
+ALCdevice* alcCaptureOpenDevice( const ALCchar *devicename, ALCuint frequency, ALCenum format, ALCsizei buffersize ) { return _alcCaptureOpenDevice(devicename, frequency, format, buffersize); }
+ALCboolean alcCaptureCloseDevice( ALCdevice *device ) { return _alcCaptureCloseDevice(device); }
+void alcCaptureStart( ALCdevice *device ) { return _alcCaptureStart(device); }
+void alcCaptureStop( ALCdevice *device ) { return _alcCaptureStop(device); }
+void alcCaptureSamples( ALCdevice *device, ALCvoid *buffer, ALCsizei samples ) { return _alcCaptureSamples(device, buffer, samples); }
+
+
+static SNDFILE* (*_sf_open) (const char *path, int mode, SF_INFO *sfinfo);
+static SNDFILE* (*_sf_open_fd) (int fd, int mode, SF_INFO *sfinfo, int close_desc);
+static SNDFILE* (*_sf_open_virtual) (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data);
+static int (*_sf_error) (SNDFILE *sndfile);
+static const char* (*_sf_strerror) (SNDFILE *sndfile);
+static const char* (*_sf_error_number) (int errnum);
+static int (*_sf_perror) (SNDFILE *sndfile);
+static int (*_sf_error_str) (SNDFILE *sndfile, char* str, size_t len);
+static int (*_sf_command) (SNDFILE *sndfile, int command, void *data, int datasize);
+static int (*_sf_format_check) (const SF_INFO *info);
+static sf_count_t (*_sf_seek) (SNDFILE *sndfile, sf_count_t frames, int whence);
+static int (*_sf_set_string) (SNDFILE *sndfile, int str_type, const char* str);
+static const char* (*_sf_get_string) (SNDFILE *sndfile, int str_type);
+static const char * (*_sf_version_string) (void);
+static sf_count_t (*_sf_read_raw) (SNDFILE *sndfile, void *ptr, sf_count_t bytes);
+static sf_count_t (*_sf_write_raw) (SNDFILE *sndfile, const void *ptr, sf_count_t bytes);
+static sf_count_t (*_sf_readf_short) (SNDFILE *sndfile, short *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_short) (SNDFILE *sndfile, const short *ptr, sf_count_t frames);
+static sf_count_t (*_sf_readf_int) (SNDFILE *sndfile, int *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_int) (SNDFILE *sndfile, const int *ptr, sf_count_t frames);
+static sf_count_t (*_sf_readf_float) (SNDFILE *sndfile, float *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_float) (SNDFILE *sndfile, const float *ptr, sf_count_t frames);
+static sf_count_t (*_sf_readf_double) (SNDFILE *sndfile, double *ptr, sf_count_t frames);
+static sf_count_t (*_sf_writef_double) (SNDFILE *sndfile, const double *ptr, sf_count_t frames);
+static sf_count_t (*_sf_read_short) (SNDFILE *sndfile, short *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_short) (SNDFILE *sndfile, const short *ptr, sf_count_t items);
+static sf_count_t (*_sf_read_int) (SNDFILE *sndfile, int *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_int) (SNDFILE *sndfile, const int *ptr, sf_count_t items);
+static sf_count_t (*_sf_read_float) (SNDFILE *sndfile, float *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_float) (SNDFILE *sndfile, const float *ptr, sf_count_t items);
+static sf_count_t (*_sf_read_double) (SNDFILE *sndfile, double *ptr, sf_count_t items);
+static sf_count_t (*_sf_write_double) (SNDFILE *sndfile, const double *ptr, sf_count_t items);
+static int (*_sf_close) (SNDFILE *sndfile);
+static void (*_sf_write_sync) (SNDFILE *sndfile);
+
+static bool init_sndfile() {
+ void *handle = dlopen("libsndfile.so", RTLD_LAZY);
+ if (!handle) handle = dlopen("libsndfile.so.1", RTLD_LAZY);
+ if (!handle) return false;
+
+ if (!linkit((void**)&_sf_open, "sf_open", handle)) return false;
+ if (!linkit((void**)&_sf_open_fd, "sf_open_fd", handle)) return false;
+ if (!linkit((void**)&_sf_open_virtual, "sf_open_virtual", handle)) return false;
+ if (!linkit((void**)&_sf_error, "sf_error", handle)) return false;
+ if (!linkit((void**)&_sf_strerror, "sf_strerror", handle)) return false;
+ if (!linkit((void**)&_sf_error_number, "sf_error_number", handle)) return false;
+ if (!linkit((void**)&_sf_perror, "sf_perror", handle)) return false;
+ if (!linkit((void**)&_sf_error_str, "sf_error_str", handle)) return false;
+ if (!linkit((void**)&_sf_command, "sf_command", handle)) return false;
+ if (!linkit((void**)&_sf_format_check, "sf_format_check", handle)) return false;
+ if (!linkit((void**)&_sf_seek, "sf_seek", handle)) return false;
+ if (!linkit((void**)&_sf_set_string, "sf_set_string", handle)) return false;
+ if (!linkit((void**)&_sf_get_string, "sf_get_string", handle)) return false;
+ if (!linkit((void**)&_sf_version_string, "sf_version_string", handle)) return false;
+ if (!linkit((void**)&_sf_read_raw, "sf_read_raw", handle)) return false;
+ if (!linkit((void**)&_sf_write_raw, "sf_write_raw", handle)) return false;
+ if (!linkit((void**)&_sf_readf_short, "sf_readf_short", handle)) return false;
+ if (!linkit((void**)&_sf_writef_short, "sf_writef_short", handle)) return false;
+ if (!linkit((void**)&_sf_readf_int, "sf_readf_int", handle)) return false;
+ if (!linkit((void**)&_sf_writef_int, "sf_writef_int", handle)) return false;
+ if (!linkit((void**)&_sf_readf_float, "sf_readf_float", handle)) return false;
+ if (!linkit((void**)&_sf_writef_float, "sf_writef_float", handle)) return false;
+ if (!linkit((void**)&_sf_readf_double, "sf_readf_double", handle)) return false;
+ if (!linkit((void**)&_sf_writef_double, "sf_writef_double", handle)) return false;
+ if (!linkit((void**)&_sf_read_short, "sf_read_short", handle)) return false;
+ if (!linkit((void**)&_sf_write_short, "sf_write_short", handle)) return false;
+ if (!linkit((void**)&_sf_read_int, "sf_read_int", handle)) return false;
+ if (!linkit((void**)&_sf_write_int, "sf_write_int", handle)) return false;
+ if (!linkit((void**)&_sf_read_float, "sf_read_float", handle)) return false;
+ if (!linkit((void**)&_sf_write_float, "sf_write_float", handle)) return false;
+ if (!linkit((void**)&_sf_read_double, "sf_read_double", handle)) return false;
+ if (!linkit((void**)&_sf_write_double, "sf_write_double", handle)) return false;
+ if (!linkit((void**)&_sf_close, "sf_close", handle)) return false;
+ if (!linkit((void**)&_sf_write_sync, "sf_write_sync", handle)) return false;
+
+ return true;
+}
+
+
+SNDFILE* sf_open (const char *path, int mode, SF_INFO *sfinfo) { return _sf_open(path, mode, sfinfo); }
+SNDFILE* sf_open_fd (int fd, int mode, SF_INFO *sfinfo, int close_desc) { return _sf_open_fd(fd, mode, sfinfo, close_desc); }
+SNDFILE* sf_open_virtual (SF_VIRTUAL_IO *sfvirtual, int mode, SF_INFO *sfinfo, void *user_data) { return _sf_open_virtual(sfvirtual, mode, sfinfo, user_data); }
+int sf_error (SNDFILE *sndfile) { return _sf_error(sndfile); }
+const char* sf_strerror (SNDFILE *sndfile) { return _sf_strerror(sndfile); }
+const char* sf_error_number (int errnum) { return _sf_error_number(errnum); }
+int sf_perror (SNDFILE *sndfile) { return _sf_perror(sndfile); }
+int sf_error_str (SNDFILE *sndfile, char* str, size_t len) { return _sf_error_str(sndfile, str, len); }
+int sf_command (SNDFILE *sndfile, int command, void *data, int datasize) { return _sf_command(sndfile, command, data, datasize); }
+int sf_format_check (const SF_INFO *info) { return _sf_format_check(info); }
+sf_count_t sf_seek (SNDFILE *sndfile, sf_count_t frames, int whence) { return _sf_seek(sndfile, frames, whence); }
+int sf_set_string (SNDFILE *sndfile, int str_type, const char* str) { return _sf_set_string(sndfile, str_type, str); }
+const char* sf_get_string (SNDFILE *sndfile, int str_type) { return _sf_get_string(sndfile, str_type); }
+const char * sf_version_string (void) { return _sf_version_string(); }
+sf_count_t sf_read_raw (SNDFILE *sndfile, void *ptr, sf_count_t bytes) { return _sf_read_raw(sndfile, ptr, bytes); }
+sf_count_t sf_write_raw (SNDFILE *sndfile, const void *ptr, sf_count_t bytes) { return _sf_write_raw(sndfile, ptr, bytes); }
+sf_count_t sf_readf_short (SNDFILE *sndfile, short *ptr, sf_count_t frames) { return _sf_readf_short(sndfile, ptr, frames); }
+sf_count_t sf_writef_short (SNDFILE *sndfile, const short *ptr, sf_count_t frames) { return _sf_writef_short(sndfile, ptr, frames); }
+sf_count_t sf_readf_int (SNDFILE *sndfile, int *ptr, sf_count_t frames) { return _sf_readf_int(sndfile, ptr, frames); }
+sf_count_t sf_writef_int (SNDFILE *sndfile, const int *ptr, sf_count_t frames) { return _sf_writef_int(sndfile, ptr, frames); }
+sf_count_t sf_readf_float (SNDFILE *sndfile, float *ptr, sf_count_t frames) { return _sf_readf_float(sndfile, ptr, frames); }
+sf_count_t sf_writef_float (SNDFILE *sndfile, const float *ptr, sf_count_t frames) { return _sf_writef_float(sndfile, ptr, frames); }
+sf_count_t sf_readf_double (SNDFILE *sndfile, double *ptr, sf_count_t frames) { return _sf_readf_double(sndfile, ptr, frames); }
+sf_count_t sf_writef_double (SNDFILE *sndfile, const double *ptr, sf_count_t frames) { return _sf_writef_double(sndfile, ptr, frames); }
+sf_count_t sf_read_short (SNDFILE *sndfile, short *ptr, sf_count_t items) { return _sf_read_short(sndfile, ptr, items); }
+sf_count_t sf_write_short (SNDFILE *sndfile, const short *ptr, sf_count_t items) { return _sf_write_short(sndfile, ptr, items); }
+sf_count_t sf_read_int (SNDFILE *sndfile, int *ptr, sf_count_t items) { return _sf_read_int(sndfile, ptr, items); }
+sf_count_t sf_write_int (SNDFILE *sndfile, const int *ptr, sf_count_t items) { return _sf_write_int(sndfile, ptr, items); }
+sf_count_t sf_read_float (SNDFILE *sndfile, float *ptr, sf_count_t items) { return _sf_read_float(sndfile, ptr, items); }
+sf_count_t sf_write_float (SNDFILE *sndfile, const float *ptr, sf_count_t items) { return _sf_write_float(sndfile, ptr, items); }
+sf_count_t sf_read_double (SNDFILE *sndfile, double *ptr, sf_count_t items) { return _sf_read_double(sndfile, ptr, items); }
+sf_count_t sf_write_double (SNDFILE *sndfile, const double *ptr, sf_count_t items) { return _sf_write_double(sndfile, ptr, items); }
+int sf_close (SNDFILE *sndfile) { return _sf_close(sndfile); }
+void sf_write_sync (SNDFILE *sndfile) { return _sf_write_sync(sndfile); }
diff --git a/g_src/music_and_sound_openal.h b/g_src/music_and_sound_openal.h
new file mode 100755
index 0000000..b4f3de9
--- /dev/null
+++ b/g_src/music_and_sound_openal.h
@@ -0,0 +1,82 @@
+#ifndef MUSIC_AND_SOUND_OPENAL_H
+#define MUSIC_AND_SOUND_OPENAL_H
+
+#include <AL/al.h>
+#include <AL/alc.h>
+
+// HACKY HACKY HACK
+// Fixes sndfile.h, until the bug is properly fixed
+#include <stdio.h>
+#include <sys/types.h>
+#define _MSCVER
+typedef int64_t __int64;
+#include <sndfile.h>
+#undef _MSCVER
+// END HACKY HACKY HACK
+
+#include <string>
+#include <vector>
+#include <list>
+#include <map>
+#include <algorithm>
+#include <utility>
+
+#define SOUND_CHANNELNUM 16
+
+// Preferred mixer frequency. Should be the same as what the ogg files
+// use, to avoid resampling.
+#define SOUND_FREQUENCY 44100
+
+// If the bool is false, a sound; otherwise a song
+typedef std::pair<bool,int> slot;
+
+class musicsoundst
+{
+ public:
+ bool initsound(); // Returns false if it failed
+ void update() {}
+ void set_master_volume(long newvol);
+
+ void set_song(std::string &filename, slot slot);
+ void set_song(std::string &filename, int slot);
+ void playsound(slot slot);
+ void playsound(int slot); // Assumes sound
+
+ void startbackgroundmusic(slot slot);
+ void startbackgroundmusic(int slot); // Assumes song
+ void stopbackgroundmusic();
+ void stop_sound();
+ void stop_sound(slot slot);
+ void playsound(int s,int channel);
+ void set_sound(std::string &filename,int slot,int pan=-1,int priority=0);
+ void deinitsound();
+
+ // Deprecated:
+ void forcebackgroundmusic(int slot, unsigned long time);
+ void playsound(int s,int min_channel,int max_channel,int force_channel);
+ void set_sound_params(int slot,int p1,int vol,int pan,int priority);
+
+ musicsoundst() {
+ functional = false;
+ background_slot = slot(false,-1);
+ }
+
+ ~musicsoundst() {
+ deinitsound();
+ }
+
+ private:
+ bool functional;
+ ALCdevice *device;
+ ALCcontext *context;
+
+ std::map<std::string,ALuint> buffers; // OpenAL buffers
+ std::map<std::string,ALuint> sources; // And sources
+ std::map<slot, ALuint> slot_buffer; // Mappings from DF slots to openal
+ std::map<slot, ALuint> slot_source;
+
+ slot background_slot; // Currently playing background music, or -1
+};
+
+
+#endif
diff --git a/g_src/music_and_sound_v.h b/g_src/music_and_sound_v.h
new file mode 100755
index 0000000..7c76874
--- /dev/null
+++ b/g_src/music_and_sound_v.h
@@ -0,0 +1,11 @@
+//copyright (c) 2006 by tarn adams
+
+#ifndef NO_FMOD
+#include "enabler.h"
+#include "init.h"
+
+extern enablerst enabler;
+extern initst init;
+musicsoundst musicsound;
+
+#endif \ No newline at end of file
diff --git a/g_src/platform.h b/g_src/platform.h
new file mode 100755
index 0000000..64e5c74
--- /dev/null
+++ b/g_src/platform.h
@@ -0,0 +1,102 @@
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+#ifdef WIN32
+#undef WINDOWS_LEAN_AND_MEAN
+#define WINDOWS_LEAN_AND_MEAN
+# include <windows.h>
+#else
+
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+
+enum {
+ // NOTE: These probably don't match Windows values.
+ MB_OK = 0x01,
+ MB_YESNO = 0x02,
+ MB_ICONQUESTION = 0x10,
+ MB_ICONEXCLAMATION = 0x20,
+
+ IDOK = 1,
+ IDNO,
+ IDYES,
+};
+
+
+typedef int HANDLE;
+typedef HANDLE HINSTANCE;
+typedef HANDLE HWND;
+typedef HANDLE HDC;
+typedef HANDLE HGLRC;
+
+#ifndef HWND_DESKTOP
+#define HWND_DESKTOP ((HWND)-1)
+#endif
+
+
+typedef int BOOL;
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+typedef unsigned short WORD;
+typedef unsigned long DWORD;
+
+typedef unsigned int UINT;
+typedef short SHORT;
+typedef long LONG;
+typedef long long LONGLONG;
+
+typedef WORD WPARAM;
+typedef DWORD LPARAM;
+
+
+typedef struct {
+ LONG x;
+ LONG y;
+} POINT;
+
+typedef union {
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ };
+ struct {
+ DWORD LowPart;
+ LONG HighPart;
+ } u;
+ LONGLONG QuadPart;
+} LARGE_INTEGER;
+
+typedef struct {
+ HWND hwnd;
+ UINT message;
+ WPARAM wParam;
+ LPARAM lParam;
+ DWORD time;
+ POINT pt;
+} MSG;
+
+
+DWORD GetTickCount(); // returns ms since system startup
+BOOL CreateDirectory(const char* pathname, void*);
+BOOL DeleteFile(const char* filename);
+void ZeroMemory(void* dest, int len);
+BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount);
+BOOL QueryPerformanceFrequency(LARGE_INTEGER* performanceCount);
+int MessageBox(HWND *dummy, const char* text, const char* caption, UINT type);
+char* itoa(int value, char* result, int base);
+
+#endif // WIN32
+
+/*
+SHORT Enabler_GetKeyState(int virtKey);
+int Enabler_ShowCursor(BOOL show);
+*/
+
+#endif // _PLATFORM_H_
+
diff --git a/g_src/random.cpp b/g_src/random.cpp
new file mode 100755
index 0000000..1059cb9
--- /dev/null
+++ b/g_src/random.cpp
@@ -0,0 +1,206 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "basics.h"
+
+#include "random.h"
+
+extern int32_t basic_seed;
+extern int mt_index[MT_BUFFER_NUM];
+extern short mt_cur_buffer;
+extern short mt_virtual_buffer;
+extern uint32_t mt_buffer[MT_BUFFER_NUM][MT_LEN];
+
+//public domain RNG stuff by Michael Brundage
+ //with some modifications by me to handle more buffers
+
+void mt_init()
+{
+ mt_cur_buffer=0;
+ mt_virtual_buffer=0;
+
+ mt_buffer[0][0]=GetTickCount();
+ int i;
+ for(i=1;i<MT_LEN;i++)
+ {
+ //2010: better init line from wikipedia, ultimate source unknown
+ mt_buffer[0][i]=1812433253UL * (mt_buffer[0][i-1] ^ (mt_buffer[0][i-1]>>30)) + i;
+ }
+ mt_index[0]=MT_LEN*sizeof(uint32_t);
+
+ int32_t j;
+ for(j=0;j<20;j++)trandom_twist();
+}
+
+#define MT_IA 397
+#define MT_IB (MT_LEN - MT_IA)
+#define UPPER_MASK 0x80000000
+#define LOWER_MASK 0x7FFFFFFF
+#define MATRIX_A 0x9908B0DF
+#define TWIST(b,i,j) ((b)[i] & UPPER_MASK) | ((b)[j] & LOWER_MASK)
+#define MAGIC(s) (((s)&1)*MATRIX_A)
+
+uint32_t mt_trandom()
+{
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+ int idx = mt_index[mt_cur_buffer];
+ uint32_t s;
+ int i;
+
+ if (idx == MT_LEN*sizeof(uint32_t))
+ {
+ idx = 0;
+ i = 0;
+ for (; i < MT_IB; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s);
+ }
+ for (; i < MT_LEN-1; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s);
+ }
+
+ s = TWIST(b, MT_LEN-1, 0);
+ b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s);
+ }
+ mt_index[mt_cur_buffer] = idx + sizeof(uint32_t);
+ return *(uint32_t *)((unsigned char *)b + idx);
+}
+
+void trandom_twist()
+{
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+ uint32_t s;
+ int i;
+
+ i = 0;
+ for (; i < MT_IB; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i + MT_IA] ^ (s >> 1) ^ MAGIC(s);
+ }
+ for (; i < MT_LEN-1; i++) {
+ s = TWIST(b, i, i+1);
+ b[i] = b[i - MT_IB] ^ (s >> 1) ^ MAGIC(s);
+ }
+
+ s = TWIST(b, MT_LEN-1, 0);
+ b[MT_LEN-1] = b[MT_IA-1] ^ (s >> 1) ^ MAGIC(s);
+}
+
+//back to my crap - tarn
+void pop_trandom_uniform_seed()
+{
+ if(mt_virtual_buffer>0)mt_virtual_buffer--;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)mt_cur_buffer=MT_BUFFER_NUM-1;
+}
+
+void push_trandom_uniform_seed(uint32_t newseed)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed;
+ for(i=1;i<MT_LEN;i++)
+ {
+ //2010: better init line from wikipedia, ultimate source unknown
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+void push_trandom_double_seed(uint32_t newseed1,uint32_t newseed2)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed1/2+newseed2/2;
+ for(i=1;i<MT_LEN;i++)
+ {
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+void push_trandom_triple_seed(uint32_t newseed1,uint32_t newseed2,uint32_t newseed3)
+{
+ mt_virtual_buffer++;
+ mt_cur_buffer=mt_virtual_buffer;
+ if(mt_cur_buffer>=MT_BUFFER_NUM)
+ {
+ mt_cur_buffer=MT_BUFFER_NUM-1;
+ errorlog_string("Random Buffer Overload");
+ }
+
+ short i;
+
+ uint32_t * b = mt_buffer[mt_cur_buffer];
+
+ b[0]=newseed1/3+newseed2/3+newseed3/3;
+ for(i=1;i<MT_LEN;i++)
+ {
+ b[i]=1812433253UL * (b[i-1] ^ (b[i-1]>>30)) + i;
+ }
+ mt_index[mt_cur_buffer]=MT_LEN*sizeof(uint32_t);
+
+ trandom_twist();
+}
+
+//picks a random number from 0 to max-1
+int32_t basic_random(int32_t max)
+{
+ r_num();
+
+ return (int32_t)((uint32_t)basic_seed/((1073741824UL/(uint32_t)max)+1UL));
+}
+
+//sets seed to a random number from 0 to 1 billion
+void r_num()
+{
+ basic_seed=(int32_t)(((uint32_t)basic_seed*907725UL+99979777UL)%1073741824UL);
+} \ No newline at end of file
diff --git a/g_src/random.h b/g_src/random.h
new file mode 100755
index 0000000..a160db9
--- /dev/null
+++ b/g_src/random.h
@@ -0,0 +1,40 @@
+#ifndef RANDOM_H
+#define RANDOM_H
+
+#ifndef WIN32
+#include <stdint.h>
+#endif //WIN32
+
+#define MT_BUFFER_NUM 10
+#define MT_LEN 624
+
+
+void mt_init();
+uint32_t mt_trandom();
+static int32_t trandom(uint32_t max=2147483647LU)
+ {
+ if(max<=1)return 0;
+ uint32_t seed=mt_trandom();
+ seed=seed%2147483647LU;
+ seed=seed/((2147483647LU/max)+1);
+
+ return((int32_t)seed);
+ }
+static int32_t loadtrandom(uint32_t max=2147483647LU)
+ {
+ uint32_t seed=mt_trandom();
+ seed=seed%max;
+
+ return((int32_t)seed);
+ }
+void push_trandom_uniform_seed(uint32_t newseed);
+void push_trandom_double_seed(uint32_t newseed1,uint32_t newseed2);
+void push_trandom_triple_seed(uint32_t newseed1,uint32_t newseed2,uint32_t newseed3);
+void pop_trandom_uniform_seed();
+void trandom_twist();
+
+void r_num();
+int32_t basic_random(int32_t max=2147483647);
+
+
+#endif
diff --git a/g_src/renderer_2d.hpp b/g_src/renderer_2d.hpp
new file mode 100755
index 0000000..d088162
--- /dev/null
+++ b/g_src/renderer_2d.hpp
@@ -0,0 +1,352 @@
+#include "enabler.h"
+#include "init.h"
+#include "resize++.h"
+#include "ttf_manager.hpp"
+
+#include <iostream>
+using namespace std;
+
+void report_error(const char*, const char*);
+
+class renderer_2d_base : public renderer {
+protected:
+ SDL_Surface *screen;
+ map<texture_fullid, SDL_Surface*> tile_cache;
+ int dispx, dispy, dimx, dimy;
+ // We may shrink or enlarge dispx/dispy in response to zoom requests. dispx/y_z are the
+ // size we actually display tiles at.
+ int dispx_z, dispy_z;
+ // Viewport origin
+ int origin_x, origin_y;
+
+ SDL_Surface *tile_cache_lookup(texture_fullid &id, bool convert=true) {
+ map<texture_fullid, SDL_Surface*>::iterator it = tile_cache.find(id);
+ if (it != tile_cache.end()) {
+ return it->second;
+ } else {
+ // Create the colorized texture
+ SDL_Surface *tex = enabler.textures.get_texture_data(id.texpos);
+ SDL_Surface *color;
+ color = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ tex->w, tex->h,
+ tex->format->BitsPerPixel,
+ tex->format->Rmask,
+ tex->format->Gmask,
+ tex->format->Bmask,
+ 0);
+ if (!color) {
+ MessageBox (NULL, "Unable to create texture!", "Fatal error", MB_OK | MB_ICONEXCLAMATION);
+ abort();
+ }
+
+ // Fill it
+ Uint32 color_fgi = SDL_MapRGB(color->format, id.r*255, id.g*255, id.b*255);
+ Uint8 *color_fg = (Uint8*) &color_fgi;
+ Uint32 color_bgi = SDL_MapRGB(color->format, id.br*255, id.bg*255, id.bb*255);
+ Uint8 *color_bg = (Uint8*) &color_bgi;
+ SDL_LockSurface(tex);
+ SDL_LockSurface(color);
+
+ Uint8 *pixel_src, *pixel_dst;
+ for (int y = 0; y < tex->h; y++) {
+ pixel_src = ((Uint8*)tex->pixels) + (y * tex->pitch);
+ pixel_dst = ((Uint8*)color->pixels) + (y * color->pitch);
+ for (int x = 0; x < tex->w; x++, pixel_src+=4, pixel_dst+=4) {
+ float alpha = pixel_src[3] / 255.0;
+ for (int c = 0; c < 3; c++) {
+ float fg = color_fg[c] / 255.0, bg = color_bg[c] / 255.0, tex = pixel_src[c] / 255.0;
+ pixel_dst[c] = ((alpha * (tex * fg)) + ((1 - alpha) * bg)) * 255;
+ }
+ }
+ }
+
+ SDL_UnlockSurface(color);
+ SDL_UnlockSurface(tex);
+
+ SDL_Surface *disp = convert ?
+ SDL_Resize(color, dispx_z, dispy_z) : // Convert to display format; deletes color
+ color; // color is not deleted, but we don't want it to be.
+ // Insert and return
+ tile_cache[id] = disp;
+ return disp;
+ }
+ }
+
+ virtual bool init_video(int w, int h) {
+ // Get ourselves a 2D SDL window
+ Uint32 flags = init.display.flag.has_flag(INIT_DISPLAY_FLAG_2DHW) ? SDL_HWSURFACE : SDL_SWSURFACE;
+ flags |= init.display.flag.has_flag(INIT_DISPLAY_FLAG_2DASYNC) ? SDL_ASYNCBLIT : 0;
+
+ // Set it up for windowed or fullscreen, depending.
+ if (enabler.is_fullscreen()) {
+ flags |= SDL_FULLSCREEN;
+ } else {
+ if (!init.display.flag.has_flag(INIT_DISPLAY_FLAG_NOT_RESIZABLE))
+ flags |= SDL_RESIZABLE;
+ }
+
+ // (Re)create the window
+ screen = SDL_SetVideoMode(w, h, 32, flags);
+ if (screen == NULL) cout << "INIT FAILED!" << endl;
+
+ return screen != NULL;
+ }
+
+public:
+ list<pair<SDL_Surface*,SDL_Rect> > ttfs_to_render;
+
+ void update_tile(int x, int y) {
+ // Figure out where to blit
+ SDL_Rect dst;
+ dst.x = dispx_z * x + origin_x;
+ dst.y = dispy_z * y + origin_y;
+ // Read tiles from gps, create cached texture
+ Either<texture_fullid,texture_ttfid> id = screen_to_texid(x, y);
+ SDL_Surface *tex;
+ if (id.isL) { // Ordinary tile, cached here
+ tex = tile_cache_lookup(id.left);
+ // And blit.
+ SDL_BlitSurface(tex, NULL, screen, &dst);
+ } else { // TTF, cached in ttf_manager so no point in also caching here
+ tex = ttf_manager.get_texture(id.right);
+ // Blit later
+ ttfs_to_render.push_back(make_pair(tex, dst));
+ }
+ }
+
+ void update_all() {
+ SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
+ for (int x = 0; x < gps.dimx; x++)
+ for (int y = 0; y < gps.dimy; y++)
+ update_tile(x, y);
+ }
+
+ virtual void render() {
+ // Render the TTFs, which we left for last
+ for (auto it = ttfs_to_render.begin(); it != ttfs_to_render.end(); ++it) {
+ SDL_BlitSurface(it->first, NULL, screen, &it->second);
+ }
+ ttfs_to_render.clear();
+ // And flip out.
+ SDL_Flip(screen);
+ }
+
+ virtual ~renderer_2d_base() {
+ for (auto it = tile_cache.cbegin(); it != tile_cache.cend(); ++it)
+ SDL_FreeSurface(it->second);
+ for (auto it = ttfs_to_render.cbegin(); it != ttfs_to_render.cend(); ++it)
+ SDL_FreeSurface(it->first);
+ }
+
+ void grid_resize(int w, int h) {
+ dimx = w; dimy = h;
+ // Only reallocate the grid if it actually changes
+ if (init.display.grid_x != dimx || init.display.grid_y != dimy)
+ gps_allocate(dimx, dimy);
+ // But always force a full display cycle
+ gps.force_full_display_count = 1;
+ enabler.flag |= ENABLERFLAG_RENDER;
+ }
+
+ renderer_2d_base() {
+ zoom_steps = forced_steps = 0;
+ }
+
+ int zoom_steps, forced_steps;
+ int natural_w, natural_h;
+
+ void compute_forced_zoom() {
+ forced_steps = 0;
+ pair<int,int> zoomed = compute_zoom();
+ while (zoomed.first < MIN_GRID_X || zoomed.second < MIN_GRID_Y) {
+ forced_steps++;
+ zoomed = compute_zoom();
+ }
+ while (zoomed.first > MAX_GRID_X || zoomed.second > MAX_GRID_Y) {
+ forced_steps--;
+ zoomed = compute_zoom();
+ }
+ }
+
+ pair<int,int> compute_zoom(bool clamp = false) {
+ const int dispx = enabler.is_fullscreen() ?
+ init.font.large_font_dispx :
+ init.font.small_font_dispx;
+ const int dispy = enabler.is_fullscreen() ?
+ init.font.large_font_dispy :
+ init.font.small_font_dispy;
+ int w, h;
+ if (dispx < dispy) {
+ w = natural_w + zoom_steps + forced_steps;
+ h = double(natural_h) * (double(w) / double(natural_w));
+ } else {
+ h = natural_h + zoom_steps + forced_steps;
+ w = double(natural_w) * (double(h) / double(natural_h));
+ }
+ if (clamp) {
+ w = MIN(MAX(w, MIN_GRID_X), MAX_GRID_X);
+ h = MIN(MAX(h, MIN_GRID_Y), MAX_GRID_Y);
+ }
+ return make_pair(w,h);
+ }
+
+
+ void resize(int w, int h) {
+ // We've gotten resized.. first step is to reinitialize video
+ cout << "New window size: " << w << "x" << h << endl;
+ init_video(w, h);
+ dispx = enabler.is_fullscreen() ?
+ init.font.large_font_dispx :
+ init.font.small_font_dispx;
+ dispy = enabler.is_fullscreen() ?
+ init.font.large_font_dispy :
+ init.font.small_font_dispy;
+ cout << "Font size: " << dispx << "x" << dispy << endl;
+ // If grid size is currently overridden, we don't change it
+ if (enabler.overridden_grid_sizes.size() == 0) {
+ // (Re)calculate grid-size
+ dimx = MIN(MAX(w / dispx, MIN_GRID_X), MAX_GRID_X);
+ dimy = MIN(MAX(h / dispy, MIN_GRID_Y), MAX_GRID_Y);
+ cout << "Resizing grid to " << dimx << "x" << dimy << endl;
+ grid_resize(dimx, dimy);
+ }
+ // Calculate zoomed tile size
+ natural_w = MAX(w / dispx,1);
+ natural_h = MAX(h / dispy,1);
+ compute_forced_zoom();
+ reshape(compute_zoom(true));
+ cout << endl;
+ }
+
+ void reshape(pair<int,int> max_grid) {
+ int w = max_grid.first,
+ h = max_grid.second;
+ // Compute the largest tile size that will fit this grid into the window, roughly maintaining aspect ratio
+ double try_x = dispx, try_y = dispy;
+ try_x = screen->w / w;
+ try_y = MIN(try_x / dispx * dispy, screen->h / h);
+ try_x = MIN(try_x, try_y / dispy * dispx);
+ dispx_z = MAX(1,try_x); dispy_z = MAX(try_y,1);
+ cout << "Resizing font to " << dispx_z << "x" << dispy_z << endl;
+ // Remove now-obsolete tile catalog
+ for (map<texture_fullid, SDL_Surface*>::iterator it = tile_cache.begin();
+ it != tile_cache.end();
+ ++it)
+ SDL_FreeSurface(it->second);
+ tile_cache.clear();
+ // Recompute grid based on the new tile size
+ w = CLAMP(screen->w / dispx_z, MIN_GRID_X, MAX_GRID_X);
+ h = CLAMP(screen->h / dispy_z, MIN_GRID_Y, MAX_GRID_Y);
+ // Reset grid size
+#ifdef DEBUG
+ cout << "Resizing grid to " << w << "x" << h << endl;
+#endif
+ gps_allocate(w,h);
+ // Force redisplay
+ gps.force_full_display_count = 1;
+ // Calculate viewport origin, for centering
+ origin_x = (screen->w - dispx_z * w) / 2;
+ origin_y = (screen->h - dispy_z * h) / 2;
+ // Reset TTF rendering
+ ttf_manager.init(dispy_z, dispx_z);
+ }
+
+private:
+
+ void set_fullscreen() {
+ if (enabler.is_fullscreen()) {
+ init.display.desired_windowed_width = screen->w;
+ init.display.desired_windowed_height = screen->h;
+ resize(init.display.desired_fullscreen_width,
+ init.display.desired_fullscreen_height);
+ } else {
+ resize(init.display.desired_windowed_width, init.display.desired_windowed_height);
+ }
+ }
+
+ bool get_mouse_coords(int &x, int &y) {
+ int mouse_x, mouse_y;
+ SDL_GetMouseState(&mouse_x, &mouse_y);
+ mouse_x -= origin_x; mouse_y -= origin_y;
+ if (mouse_x < 0 || mouse_x >= dispx_z*dimx ||
+ mouse_y < 0 || mouse_y >= dispy_z*dimy)
+ return false;
+ x = mouse_x / dispx_z;
+ y = mouse_y / dispy_z;
+ return true;
+ }
+
+ void zoom(zoom_commands cmd) {
+ pair<int,int> before = compute_zoom(true);
+ int before_steps = zoom_steps;
+ switch (cmd) {
+ case zoom_in: zoom_steps -= init.input.zoom_speed; break;
+ case zoom_out: zoom_steps += init.input.zoom_speed; break;
+ case zoom_reset:
+ zoom_steps = 0;
+ case zoom_resetgrid:
+ compute_forced_zoom();
+ break;
+ }
+ pair<int,int> after = compute_zoom(true);
+ if (after == before && (cmd == zoom_in || cmd == zoom_out))
+ zoom_steps = before_steps;
+ else
+ reshape(after);
+ }
+
+};
+
+class renderer_2d : public renderer_2d_base {
+public:
+ renderer_2d() {
+ // Disable key repeat
+ SDL_EnableKeyRepeat(0, 0);
+ // Set window title/icon.
+ SDL_WM_SetCaption(GAME_TITLE_STRING, NULL);
+ SDL_Surface *icon = IMG_Load("data/art/icon.png");
+ if (icon != NULL) {
+ SDL_WM_SetIcon(icon, NULL);
+ // The icon's surface doesn't get used past this point.
+ SDL_FreeSurface(icon);
+ }
+
+ // Find the current desktop resolution if fullscreen resolution is auto
+ if (init.display.desired_fullscreen_width == 0 ||
+ init.display.desired_fullscreen_height == 0) {
+ const struct SDL_VideoInfo *info = SDL_GetVideoInfo();
+ init.display.desired_fullscreen_width = info->current_w;
+ init.display.desired_fullscreen_height = info->current_h;
+ }
+
+ // Initialize our window
+ bool worked = init_video(enabler.is_fullscreen() ?
+ init.display.desired_fullscreen_width :
+ init.display.desired_windowed_width,
+ enabler.is_fullscreen() ?
+ init.display.desired_fullscreen_height :
+ init.display.desired_windowed_height);
+
+ // Fallback to windowed mode if fullscreen fails
+ if (!worked && enabler.is_fullscreen()) {
+ enabler.fullscreen = false;
+ report_error("SDL initialization failure, trying windowed mode", SDL_GetError());
+ worked = init_video(init.display.desired_windowed_width,
+ init.display.desired_windowed_height);
+ }
+ // Quit if windowed fails
+ if (!worked) {
+ report_error("SDL initialization failure", SDL_GetError());
+ exit(EXIT_FAILURE);
+ }
+ }
+};
+
+class renderer_offscreen : public renderer_2d_base {
+ virtual bool init_video(int, int);
+public:
+ virtual ~renderer_offscreen();
+ renderer_offscreen(int, int);
+ void update_all(int, int);
+ void save_to_file(const string &file);
+};
diff --git a/g_src/renderer_curses.cpp b/g_src/renderer_curses.cpp
new file mode 100755
index 0000000..2d90d9c
--- /dev/null
+++ b/g_src/renderer_curses.cpp
@@ -0,0 +1,369 @@
+static bool curses_initialized = false;
+
+static void endwin_void() {
+ if (curses_initialized) {
+ endwin();
+ curses_initialized = false;
+ }
+}
+
+class renderer_curses : public renderer {
+ std::map<std::pair<int,int>,int> color_pairs;
+
+ // Map from DF color to ncurses color
+ static int ncurses_map_color(int color) {
+ if (color < 0) abort();
+ switch (color) {
+ case 0: return 0;
+ case 1: return 4;
+ case 2: return 2;
+ case 3: return 6;
+ case 4: return 1;
+ case 5: return 5;
+ case 6: return 3;
+ case 7: return 7;
+ default: return ncurses_map_color(color - 7);
+ }
+ }
+
+ // Look up, or create, a curses color pair
+ int lookup_pair(pair<int,int> color) {
+ map<pair<int,int>,int>::iterator it = color_pairs.find(color);
+ if (it != color_pairs.end()) return it->second;
+ // We don't already have it. Make sure it's in range.
+ if (color.first < 0 || color.first > 7 || color.second < 0 || color.second > 7) return 0;
+ // We don't already have it. Generate a new pair if possible.
+ if (color_pairs.size() < COLOR_PAIRS - 1) {
+ const short pair = color_pairs.size() + 1;
+ init_pair(pair, ncurses_map_color(color.first), ncurses_map_color(color.second));
+ color_pairs[color] = pair;
+ return pair;
+ }
+ // We don't have it, and there's no space for more. Find the closest equivalent.
+ int score = 999, pair = 0;
+ int rfg = color.first % 16, rbg = color.second % 16;
+ for (auto it = color_pairs.cbegin(); it != color_pairs.cend(); ++it) {
+ int fg = it->first.first;
+ int bg = it->first.second;
+ int candidate = it->second;
+ int candidate_score = 0; // Lower is better.
+ if (rbg != bg) {
+ if (rbg == 0 || rbg == 15)
+ candidate_score += 3; // We would like to keep the background black/white.
+ if ((rbg == 7 || rbg == 8)) {
+ if (bg == 7 || bg == 8)
+ candidate_score += 1; // Well, it's still grey.
+ else
+ candidate_score += 2;
+ }
+ }
+ if (rfg != fg) {
+ if (rfg == 0 || rfg == 15)
+ candidate_score += 5; // Keep the foreground black/white if at all possible.
+ if (rfg == 7 || rfg == 8) {
+ if (fg == 7 || fg == 8)
+ candidate_score += 1; // Still grey. Meh.
+ else
+ candidate_score += 3;
+ }
+ }
+ if (candidate_score < score) {
+ score = candidate_score;
+ pair = candidate;
+ }
+ }
+ color_pairs[color] = pair;
+ return pair;
+ }
+
+public:
+
+ void update_tile(int x, int y) {
+ const int ch = gps.screen[x*gps.dimy*4 + y*4 + 0];
+ const int fg = gps.screen[x*gps.dimy*4 + y*4 + 1];
+ const int bg = gps.screen[x*gps.dimy*4 + y*4 + 2];
+ const int bold = gps.screen[x*gps.dimy*4 + y*4 + 3];
+
+ const int pair = lookup_pair(make_pair(fg,bg));
+
+ if (ch == 219 && !bold) {
+ // It's â–ˆ, which is used for borders and digging designations.
+ // A_REVERSE space looks better if it isn't completely tall.
+ // Which is most of the time, for me at least.
+ // â–ˆ <-- Do you see gaps?
+ // â–ˆ
+ // The color can't be bold.
+ wattrset(*stdscr_p, COLOR_PAIR(pair) | A_REVERSE);
+ mvwaddstr(*stdscr_p, y, x, " ");
+ } else {
+ wattrset(*stdscr_p, COLOR_PAIR(pair) | (bold ? A_BOLD : 0));
+ wchar_t chs[2] = {charmap[ch],0};
+ mvwaddwstr(*stdscr_p, y, x, chs);
+ }
+ }
+
+ void update_all() {
+ for (int x = 0; x < init.display.grid_x; x++)
+ for (int y = 0; y < init.display.grid_y; y++)
+ update_tile(x, y);
+ }
+
+ void render() {
+ refresh();
+ }
+
+ void resize(int w, int h) {
+ if (enabler.overridden_grid_sizes.size() == 0)
+ gps_allocate(w, h);
+ erase();
+ // Force a full display cycle
+ gps.force_full_display_count = 1;
+ enabler.flag |= ENABLERFLAG_RENDER;
+ }
+
+ void grid_resize(int w, int h) {
+ gps_allocate(w, h);
+ }
+
+ renderer_curses() {
+ init_curses();
+ }
+
+ bool get_mouse_coords(int &x, int &y) {
+ return false;
+ }
+};
+
+// Reads from getch, collapsing utf-8 encoding to the actual unicode
+// character. Ncurses symbols (left arrow, etc.) are returned as
+// positive values, unicode as negative. Error returns 0.
+static int getch_utf8() {
+ int byte = wgetch(*stdscr_p);
+ if (byte == ERR) return 0;
+ if (byte > 0xff) return byte;
+ int len = decode_utf8_predict_length(byte);
+ if (!len) return 0;
+ string input(len,0); input[0] = byte;
+ for (int i = 1; i < len; i++) input[i] = wgetch(*stdscr_p);
+ return -decode_utf8(input);
+}
+
+void enablerst::eventLoop_ncurses() {
+ int x, y, oldx = 0, oldy = 0;
+ renderer_curses *renderer = static_cast<renderer_curses*>(this->renderer);
+
+ while (loopvar) {
+ // Check for terminal resize
+ getmaxyx(*stdscr_p, y, x);
+ if (y != oldy || x != oldx) {
+ pause_async_loop();
+ renderer->resize(x, y);
+ unpause_async_loop();
+ oldx = x; oldy = y;
+ }
+
+ // Deal with input
+ Uint32 now = SDL_GetTicks();
+ // Read keyboard input, if any, and transform to artificial SDL
+ // events for enabler_input.
+ int key;
+ bool paused_loop = false;
+ while ((key = getch_utf8())) {
+ if (!paused_loop) {
+ pause_async_loop();
+ paused_loop = true;
+ }
+ bool esc = false;
+ if (key == KEY_MOUSE) {
+ MEVENT ev;
+ if (getmouse(&ev) == OK) {
+ // TODO: Deal with curses mouse input. And turn it on above.
+ }
+ } else if (key == -27) { // esc
+ int second = getch_utf8();
+ if (second) { // That was an escape sequence
+ esc = true;
+ key = second;
+ }
+ }
+ add_input_ncurses(key, now, esc);
+ }
+
+ if (paused_loop)
+ unpause_async_loop();
+
+ // Run the common logic
+ do_frame();
+ }
+}
+
+
+//// libncursesw stub ////
+
+extern "C" {
+ static void *handle;
+ WINDOW **stdscr_p;
+
+ int COLOR_PAIRS;
+ static int (*_erase)(void);
+ static int (*_wmove)(WINDOW *w, int y, int x);
+ static int (*_waddnstr)(WINDOW *w, const char *s, int n);
+ static int (*_nodelay)(WINDOW *w, bool b);
+ static int (*_refresh)(void);
+ static int (*_wgetch)(WINDOW *w);
+ static int (*_endwin)(void);
+ static WINDOW *(*_initscr)(void);
+ static int (*_raw)(void);
+ static int (*_keypad)(WINDOW *w, bool b);
+ static int (*_noecho)(void);
+ static int (*_set_escdelay)(int delay);
+ static int (*_curs_set)(int s);
+ static int (*_start_color)(void);
+ static int (*_init_pair)(short p, short fg, short bg);
+ static int (*_getmouse)(MEVENT *m);
+ static int (*_waddnwstr)(WINDOW *w, const wchar_t *s, int i);
+
+ static void *dlsym_orexit(const char *symbol, bool actually_exit = true) {
+ void *sym = dlsym(handle, symbol);
+ if (!sym) {
+ printf("Symbol not found: %s\n", symbol);
+ if (actually_exit)
+ exit(EXIT_FAILURE);
+ }
+ return sym;
+ }
+
+ int erase(void) {
+ return _erase();
+ }
+ int wmove(WINDOW *w, int y, int x) {
+ return _wmove(w, y, x);
+ }
+ int waddnstr(WINDOW *w, const char *s, int n) {
+ return _waddnstr(w, s, n);
+ }
+ int nodelay(WINDOW *w, bool b) {
+ return _nodelay(w, b);
+ }
+ int refresh(void) {
+ return _refresh();
+ }
+ int wgetch(WINDOW *w) {
+ return _wgetch(w);
+ }
+ int endwin(void) {
+ return _endwin();
+ }
+ WINDOW *initscr(void) {
+ return _initscr();
+ }
+ int raw(void) {
+ return _raw();
+ }
+ int keypad(WINDOW *w, bool b) {
+ return _keypad(w, b);
+ }
+ int noecho(void) {
+ return _noecho();
+ }
+ int set_escdelay(int delay) {
+ if (_set_escdelay)
+ return _set_escdelay(delay);
+ else
+ return 0;
+ }
+ int curs_set(int s) {
+ return _curs_set(s);
+ }
+ int start_color(void) {
+ return _start_color();
+ }
+ int init_pair(short p, short fg, short bg) {
+ return _init_pair(p, fg, bg);
+ }
+ int getmouse(MEVENT *m) {
+ return _getmouse(m);
+ }
+ int waddnwstr(WINDOW *w, const wchar_t *s, int n) {
+ return _waddnwstr(w, s, n);
+ }
+
+ void init_curses() {
+ static bool stub_initialized = false;
+ // Initialize the stub
+ if (!stub_initialized) {
+ stub_initialized = true;
+ // We prefer libncursesw, but we'll accept libncurses if we have to
+ handle = dlopen("libncursesw.so.5", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncursesw.so", RTLD_LAZY);
+ if (handle) goto opened;
+ puts("Didn't find any flavor of libncursesw, attempting libncurses");
+ sleep(5);
+ handle = dlopen("libncurses.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncurses.so.5", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncurses.so", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("libncurses.5.4.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("/usr/lib/libncurses.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+ handle = dlopen("/usr/lib/libncurses.5.4.dylib", RTLD_LAZY);
+ if (handle) goto opened;
+
+ opened:
+ if (!handle) {
+ puts("Unable to open any flavor of libncurses!");
+ exit(EXIT_FAILURE);
+ }
+ // Okay, look up our symbols
+ int *pairs = (int*)dlsym_orexit("COLOR_PAIRS");
+ COLOR_PAIRS = *pairs;
+ stdscr_p = (WINDOW**)dlsym_orexit("stdscr");
+ _erase = (int (*)(void))dlsym_orexit("erase");
+ _wmove = (int (*)(WINDOW *w, int y, int x))dlsym_orexit("wmove");
+ _waddnstr = (int (*)(WINDOW *w, const char *s, int n))dlsym_orexit("waddnstr");
+ _nodelay = (int (*)(WINDOW *w, bool b))dlsym_orexit("nodelay");
+ _refresh = (int (*)(void))dlsym_orexit("refresh");
+ _wgetch = (int (*)(WINDOW *w))dlsym_orexit("wgetch");
+ _endwin = (int (*)(void))dlsym_orexit("endwin");
+ _initscr = (WINDOW *(*)(void))dlsym_orexit("initscr");
+ _raw = (int (*)(void))dlsym_orexit("raw");
+ _keypad = (int (*)(WINDOW *w, bool b))dlsym_orexit("keypad");
+ _noecho = (int (*)(void))dlsym_orexit("noecho");
+ _set_escdelay = (int (*)(int delay))dlsym_orexit("set_escdelay", false);
+ _curs_set = (int (*)(int s))dlsym_orexit("curs_set");
+ _start_color = (int (*)(void))dlsym_orexit("start_color");
+ _init_pair = (int (*)(short p, short fg, short bg))dlsym_orexit("init_pair");
+ _getmouse = (int (*)(MEVENT *m))dlsym_orexit("getmouse");
+ _waddnwstr = (int (*)(WINDOW *w, const wchar_t *s, int i))dlsym_orexit("waddnwstr");
+ }
+
+ // Initialize curses
+ if (!curses_initialized) {
+ curses_initialized = true;
+ WINDOW *new_window = initscr();
+ if (!new_window) {
+ puts("unable to create ncurses window - initscr failed!");
+ exit(EXIT_FAILURE);
+ }
+ // in some versions of curses, initscr does not update stdscr!
+ if (!*stdscr_p) *stdscr_p = new_window;
+ raw();
+ noecho();
+ keypad(*stdscr_p, true);
+ nodelay(*stdscr_p, true);
+ set_escdelay(25); // Possible bug
+ curs_set(0);
+ mmask_t dummy;
+ // mousemask(ALL_MOUSE_EVENTS, &dummy);
+ start_color();
+ init_pair(1, COLOR_WHITE, COLOR_BLACK);
+
+ atexit(endwin_void);
+ }
+ }
+};
+
diff --git a/g_src/renderer_offscreen.cpp b/g_src/renderer_offscreen.cpp
new file mode 100755
index 0000000..a3a7f16
--- /dev/null
+++ b/g_src/renderer_offscreen.cpp
@@ -0,0 +1,86 @@
+#include "renderer_2d.hpp"
+
+
+bool renderer_offscreen::init_video(int w, int h) {
+ if (screen) SDL_FreeSurface(screen);
+ // Create an offscreen buffer
+ screen = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0, 0, 0, 0);
+ assert(screen);
+ return true;
+}
+
+renderer_offscreen::~renderer_offscreen() {
+ //ASSUMES renderer_offscreen IS NEVER gps_allocate()'d THROUGH reshape()/grid_resize()
+ //to-do: flag for those calls on the renderer to control this behavior?
+ renderer::screen = NULL;
+ renderer::screentexpos = NULL;
+ renderer::screentexpos_addcolor = NULL;
+ renderer::screentexpos_grayscale = NULL;
+ renderer::screentexpos_cf = NULL;
+ renderer::screentexpos_cbr = NULL;
+ renderer::screen_old = NULL;
+ renderer::screentexpos_old = NULL;
+ renderer::screentexpos_addcolor_old = NULL;
+ renderer::screentexpos_grayscale_old = NULL;
+ renderer::screentexpos_cf_old = NULL;
+ renderer::screentexpos_cbr_old = NULL;
+
+ SDL_FreeSurface(screen);
+}
+
+// Create an offscreen renderer of a given grid-size
+renderer_offscreen::renderer_offscreen(int grid_x, int grid_y) {
+ screen = NULL;
+ dispx = enabler.is_fullscreen() ?
+ init.font.large_font_dispx :
+ init.font.small_font_dispx;
+ dispy = enabler.is_fullscreen() ?
+ init.font.large_font_dispy :
+ init.font.small_font_dispy;
+ dispx_z = dispx;
+ dispy_z = dispy;
+ origin_x = origin_y = 0;
+ zoom_steps = forced_steps = 0;
+ natural_w = dispx * grid_x;
+ natural_h = dispy * grid_y;
+ dimx = grid_x;
+ dimy = grid_y;
+ init_video(natural_w, natural_h);
+ // Copy the GPS pointers here
+ renderer::screen = gps.screen;
+ renderer::screentexpos = gps.screentexpos;
+ renderer::screentexpos_addcolor = gps.screentexpos_addcolor;
+ renderer::screentexpos_grayscale = gps.screentexpos_grayscale;
+ renderer::screentexpos_cf = gps.screentexpos_cf;
+ renderer::screentexpos_cbr = gps.screentexpos_cbr;
+}
+
+// Slurp the entire gps content into the renderer at some given offset
+void renderer_offscreen::update_all(int offset_x, int offset_y) {
+ for (int x = 0; x < gps.dimx; x++) {
+ for (int y = 0; y < gps.dimy; y++) {
+ // Read tiles from gps, create cached texture
+ Either<texture_fullid,texture_ttfid> id = screen_to_texid(x, y);
+ SDL_Surface *tex = id.isL ?
+ tile_cache_lookup(id.left, false) :
+ ttf_manager.get_texture(id.right);
+ if (id.isL) {
+ tex = tile_cache_lookup(id.left);
+ } else {
+ tex = enabler.textures.get_texture_data(id.right);
+ }
+ // Figure out where to blit
+ SDL_Rect dst;
+ dst.x = dispx * (x+offset_x);
+ dst.y = dispy * (y+offset_y);
+ // And blit.
+ SDL_BlitSurface(tex, NULL, screen, &dst);
+ }
+ }
+}
+
+// Save the image to some file
+void renderer_offscreen::save_to_file(const string &file) {
+ // TODO: Support png, etc.
+ SDL_SaveBMP(screen, file.c_str());
+}
diff --git a/g_src/renderer_opengl.hpp b/g_src/renderer_opengl.hpp
new file mode 100755
index 0000000..0ea3c6c
--- /dev/null
+++ b/g_src/renderer_opengl.hpp
@@ -0,0 +1,609 @@
+// STANDARD
+class renderer_opengl : public renderer {
+public:
+ virtual bool uses_opengl() { return true; }
+
+protected:
+ SDL_Surface *screen;
+
+ int dispx, dispy; // Cache of the current font size
+
+ bool init_video(int w, int h) {
+ // Get ourselves an opengl-enabled SDL window
+ Uint32 flags = SDL_HWSURFACE | SDL_OPENGL;
+
+ // Set it up for windowed or fullscreen, depending.
+ if (enabler.is_fullscreen()) {
+ flags |= SDL_FULLSCREEN;
+ } else {
+ if (!init.display.flag.has_flag(INIT_DISPLAY_FLAG_NOT_RESIZABLE))
+ flags |= SDL_RESIZABLE;
+ }
+
+ // Setup OpenGL attributes
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, init.window.flag.has_flag(INIT_WINDOW_FLAG_VSYNC_ON));
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,
+ init.display.flag.has_flag(INIT_DISPLAY_FLAG_SINGLE_BUFFER) ? 0 : 1);
+
+ // (Re)create the window
+ screen = SDL_SetVideoMode(w, h, 32, flags);
+
+ if (!screen) return false;
+
+ // Test double-buffering status
+ int test;
+ SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &test);
+ if (test != ((init.display.flag.has_flag(INIT_DISPLAY_FLAG_SINGLE_BUFFER)) ? 0 : 1)) {
+ if (enabler.is_fullscreen());
+ //errorlog << "Requested single-buffering not available\n" << flush;
+ else
+ report_error("OpenGL", "Requested single-buffering not available");
+ }
+
+ // (Re)initialize GLEW. Technically only needs to be done once on
+ // linux, but on windows forgetting will cause crashes.
+ glewInit();
+
+ // Set the viewport and clear
+ glViewport(0, 0, screen->w, screen->h);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ return true;
+ }
+
+ // Vertexes, foreground color, background color, texture coordinates
+ GLfloat *vertexes, *fg, *bg, *tex;
+
+ void write_tile_vertexes(GLfloat x, GLfloat y, GLfloat *vertex) {
+ vertex[0] = x; // Upper left
+ vertex[1] = y;
+ vertex[2] = x+1; // Upper right
+ vertex[3] = y;
+ vertex[4] = x; // Lower left
+ vertex[5] = y+1;
+ vertex[6] = x; // Lower left again (triangle 2)
+ vertex[7] = y+1;
+ vertex[8] = x+1; // Upper right
+ vertex[9] = y;
+ vertex[10] = x+1; // Lower right
+ vertex[11] = y+1;
+ }
+
+ virtual void allocate(int tiles) {
+ vertexes = static_cast<GLfloat*>(realloc(vertexes, sizeof(GLfloat) * tiles * 2 * 6));
+ assert(vertexes);
+ fg = static_cast<GLfloat*>(realloc(fg, sizeof(GLfloat) * tiles * 4 * 6));
+ assert(fg);
+ bg = static_cast<GLfloat*>(realloc(bg, sizeof(GLfloat) * tiles * 4 * 6));
+ assert(bg);
+ tex = static_cast<GLfloat*>(realloc(tex, sizeof(GLfloat) * tiles * 2 * 6));
+ assert(tex);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, vertexes);
+ }
+
+ virtual void init_opengl() {
+ enabler.textures.upload_textures();
+ }
+
+ virtual void uninit_opengl() {
+ enabler.textures.remove_uploaded_textures();
+ }
+
+ virtual void draw(int vertex_count) {
+ // Render the background colors
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+ glColorPointer(4, GL_FLOAT, 0, bg);
+ glDrawArrays(GL_TRIANGLES, 0, vertex_count);
+ // Render the foreground, colors and textures both
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_NOTEQUAL, 0);
+ glEnable(GL_TEXTURE_2D);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+ glColorPointer(4, GL_FLOAT, 0, fg);
+ glDrawArrays(GL_TRIANGLES, 0, vertex_count);
+
+ printGLError();
+ }
+
+ void write_tile_arrays(int x, int y, GLfloat *fg, GLfloat *bg, GLfloat *tex) {
+ Either<texture_fullid,texture_ttfid> id = screen_to_texid(x, y);
+ if (id.isL) { // An ordinary tile
+ const gl_texpos *txt = enabler.textures.gl_texpos;
+ // TODO: Only bother to set the one that's actually read in flat-shading mode
+ // And set flat-shading mode.
+ for (int i = 0; i < 6; i++) {
+ *(fg++) = id.left.r;
+ *(fg++) = id.left.g;
+ *(fg++) = id.left.b;
+ *(fg++) = 1;
+
+ *(bg++) = id.left.br;
+ *(bg++) = id.left.bg;
+ *(bg++) = id.left.bb;
+ *(bg++) = 1;
+ }
+ // Set texture coordinates
+ *(tex++) = txt[id.left.texpos].left; // Upper left
+ *(tex++) = txt[id.left.texpos].bottom;
+ *(tex++) = txt[id.left.texpos].right; // Upper right
+ *(tex++) = txt[id.left.texpos].bottom;
+ *(tex++) = txt[id.left.texpos].left; // Lower left
+ *(tex++) = txt[id.left.texpos].top;
+
+ *(tex++) = txt[id.left.texpos].left; // Lower left
+ *(tex++) = txt[id.left.texpos].top;
+ *(tex++) = txt[id.left.texpos].right; // Upper right
+ *(tex++) = txt[id.left.texpos].bottom;
+ *(tex++) = txt[id.left.texpos].right; // Lower right
+ *(tex++) = txt[id.left.texpos].top;
+ } else {
+ // TODO
+ }
+ }
+
+public:
+ void update_tile(int x, int y) {
+ const int tile = x*gps.dimy + y;
+ // Update the arrays
+ GLfloat *fg = this->fg + tile * 4 * 6;
+ GLfloat *bg = this->bg + tile * 4 * 6;
+ GLfloat *tex = this->tex + tile * 2 * 6;
+ write_tile_arrays(x, y, fg, bg, tex);
+ }
+
+ void update_all() {
+ glClear(GL_COLOR_BUFFER_BIT);
+ for (int x = 0; x < gps.dimx; x++)
+ for (int y = 0; y < gps.dimy; y++)
+ update_tile(x, y);
+ }
+
+ void render() {
+ draw(gps.dimx*gps.dimy*6);
+ if (init.display.flag.has_flag(INIT_DISPLAY_FLAG_ARB_SYNC) && GL_ARB_sync) {
+ assert(enabler.sync == NULL);
+ enabler.sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
+ }
+ SDL_GL_SwapBuffers();
+ }
+
+ renderer_opengl() {
+ // Init member variables so realloc'll work
+ screen = NULL;
+ vertexes = NULL;
+ fg = NULL;
+ bg = NULL;
+ tex = NULL;
+ zoom_steps = forced_steps = 0;
+
+ // Disable key repeat
+ SDL_EnableKeyRepeat(0, 0);
+ // Set window title/icon.
+ SDL_WM_SetCaption(GAME_TITLE_STRING, NULL);
+ SDL_Surface *icon = IMG_Load("data/art/icon.png");
+ if (icon != NULL) {
+ SDL_WM_SetIcon(icon, NULL);
+ // The icon's surface doesn't get used past this point.
+ SDL_FreeSurface(icon);
+ }
+
+ // Find the current desktop resolution if fullscreen resolution is auto
+ if (init.display.desired_fullscreen_width == 0 ||
+ init.display.desired_fullscreen_height == 0) {
+ const struct SDL_VideoInfo *info = SDL_GetVideoInfo();
+ init.display.desired_fullscreen_width = info->current_w;
+ init.display.desired_fullscreen_height = info->current_h;
+ }
+
+ // Initialize our window
+ bool worked = init_video(enabler.is_fullscreen() ?
+ init.display.desired_fullscreen_width :
+ init.display.desired_windowed_width,
+ enabler.is_fullscreen() ?
+ init.display.desired_fullscreen_height :
+ init.display.desired_windowed_height);
+
+ // Fallback to windowed mode if fullscreen fails
+ if (!worked && enabler.is_fullscreen()) {
+ enabler.fullscreen = false;
+ report_error("SDL initialization failure, trying windowed mode", SDL_GetError());
+ worked = init_video(init.display.desired_windowed_width,
+ init.display.desired_windowed_height);
+ }
+ // Quit if windowed fails
+ if (!worked) {
+ report_error("SDL initialization failure", SDL_GetError());
+ exit(EXIT_FAILURE);
+ }
+
+ // Initialize opengl
+ init_opengl();
+ }
+
+ virtual ~renderer_opengl() {
+ free(vertexes);
+ free(fg);
+ free(bg);
+ free(tex);
+ }
+
+ int zoom_steps, forced_steps;
+ int natural_w, natural_h; // How large our view would be if it wasn't zoomed
+
+ void zoom(zoom_commands cmd) {
+ pair<int,int> before = compute_zoom(true);
+ int before_steps = zoom_steps;
+ switch (cmd) {
+ case zoom_in: zoom_steps -= init.input.zoom_speed; break;
+ case zoom_out: zoom_steps += init.input.zoom_speed; break;
+ case zoom_reset:
+ zoom_steps = 0;
+ case zoom_resetgrid:
+ compute_forced_zoom();
+ break;
+ }
+ pair<int,int> after = compute_zoom(true);
+ if (after == before && (cmd == zoom_in || cmd == zoom_out))
+ zoom_steps = before_steps;
+ else
+ reshape(after);
+ }
+
+ void compute_forced_zoom() {
+ forced_steps = 0;
+ pair<int,int> zoomed = compute_zoom();
+ while (zoomed.first < MIN_GRID_X || zoomed.second < MIN_GRID_Y) {
+ forced_steps++;
+ zoomed = compute_zoom();
+ }
+ while (zoomed.first > MAX_GRID_X || zoomed.second > MAX_GRID_Y) {
+ forced_steps--;
+ zoomed = compute_zoom();
+ }
+ }
+
+ pair<int,int> compute_zoom(bool clamp = false) {
+ const int dispx = enabler.is_fullscreen() ?
+ init.font.large_font_dispx :
+ init.font.small_font_dispx;
+ const int dispy = enabler.is_fullscreen() ?
+ init.font.large_font_dispy :
+ init.font.small_font_dispy;
+ int w, h;
+ if (dispx < dispy) {
+ w = natural_w + zoom_steps + forced_steps;
+ h = double(natural_h) * (double(w) / double(natural_w));
+ } else {
+ h = natural_h + zoom_steps + forced_steps;
+ w = double(natural_w) * (double(h) / double(natural_h));
+ }
+ if (clamp) {
+ w = MIN(MAX(w, MIN_GRID_X), MAX_GRID_X);
+ h = MIN(MAX(h, MIN_GRID_Y), MAX_GRID_Y);
+ }
+ return make_pair(w,h);
+ }
+
+ // Parameters: grid units
+ void reshape(pair<int,int> size) {
+ int w = MIN(MAX(size.first, MIN_GRID_X), MAX_GRID_X);
+ int h = MIN(MAX(size.second, MIN_GRID_Y), MAX_GRID_Y);
+#ifdef DEBUG
+ cout << "Resizing grid to " << w << "x" << h << endl;
+#endif
+ gps_allocate(w, h);
+ reshape_gl();
+ }
+
+ int off_x, off_y, size_x, size_y;
+
+ bool get_mouse_coords(int &x, int &y) {
+ int mouse_x, mouse_y;
+ SDL_GetMouseState(&mouse_x, &mouse_y);
+ mouse_x -= off_x; mouse_y -= off_y;
+ if (mouse_x < 0 || mouse_y < 0 ||
+ mouse_x >= size_x || mouse_y >= size_y)
+ return false; // Out of bounds
+ x = double(mouse_x) / double(size_x) * double(gps.dimx);
+ y = double(mouse_y) / double(size_y) * double(gps.dimy);
+ return true;
+ }
+
+ virtual void reshape_gl() {
+ // Allocate array memory
+ allocate(gps.dimx * gps.dimy);
+ // Initialize the vertex array
+ int tile = 0;
+ for (GLfloat x = 0; x < gps.dimx; x++)
+ for (GLfloat y = 0; y < gps.dimy; y++, tile++)
+ write_tile_vertexes(x, y, vertexes + 6*2*tile);
+ // Setup invariant state
+ glEnableClientState(GL_COLOR_ARRAY);
+ /// Set up our coordinate system
+ if (forced_steps + zoom_steps == 0 &&
+ init.display.flag.has_flag(INIT_DISPLAY_FLAG_BLACK_SPACE)) {
+ size_x = gps.dimx * dispx;
+ size_y = gps.dimy * dispy;
+ off_x = (screen->w - size_x) / 2;
+ off_y = (screen->h - size_y) / 2;
+ } else {
+ // If we're zooming (or just not using black space), we use the
+ // entire window.
+ size_x = screen->w;
+ size_y = screen->h;
+ off_x = off_y = 0;
+ }
+ glViewport(off_x, off_y, size_x, size_y);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0, gps.dimx, gps.dimy, 0);
+ }
+
+ // Parameters: window size
+ void resize(int w, int h) {
+ // (Re)calculate grid-size
+ dispx = enabler.is_fullscreen() ?
+ init.font.large_font_dispx :
+ init.font.small_font_dispx;
+ dispy = enabler.is_fullscreen() ?
+ init.font.large_font_dispy :
+ init.font.small_font_dispy;
+ natural_w = MAX(w / dispx,1);
+ natural_h = MAX(h / dispy,1);
+ // Compute forced_steps so we satisfy our grid-size limits
+ compute_forced_zoom();
+ // Force a full display cycle
+ gps.force_full_display_count = 1;
+ enabler.flag |= ENABLERFLAG_RENDER;
+ // Reinitialize the video
+ uninit_opengl();
+ init_video(w, h);
+ init_opengl();
+ // Only reshape if we're free to pick grid size
+ if (enabler.overridden_grid_sizes.size() == 0)
+ reshape(compute_zoom());
+ }
+
+ // Parameters: grid size
+ void grid_resize(int w, int h) {
+ reshape(make_pair(w, h));
+ }
+
+public:
+ void set_fullscreen() {
+ if (enabler.is_fullscreen()) {
+ init.display.desired_windowed_width = screen->w;
+ init.display.desired_windowed_height = screen->h;
+ resize(init.display.desired_fullscreen_width,
+ init.display.desired_fullscreen_height);
+ } else {
+ resize(init.display.desired_windowed_width, init.display.desired_windowed_height);
+ }
+ }
+};
+
+// Specialization for PARTIAL:0
+class renderer_once : public renderer_opengl {
+ int tile_count;
+
+protected:
+ void update_tile(int x, int y) {
+ write_tile_vertexes(x, y, vertexes + tile_count * 6 * 2);
+ write_tile_arrays(x, y,
+ fg + tile_count * 6 * 4,
+ bg + tile_count * 6 * 4,
+ tex + tile_count * 6 * 2);
+ tile_count++;
+ }
+
+ void draw(int dummy) {
+ renderer_opengl::draw(tile_count*6);
+ tile_count = 0;
+ }
+
+public:
+ renderer_once() {
+ tile_count = 0;
+ }
+};
+
+// PARTIAL:N
+class renderer_partial : public renderer_opengl {
+ int buffersz;
+ list<int> erasz; // Previous eras
+ int current_erasz; // And the current one
+ int sum_erasz;
+ int head, tail; // First unused tile, first used tile respectively
+ int redraw_count; // Number of eras to max out at
+
+ void update_tile(int x, int y) {
+ write_tile_vertexes(x, y, vertexes + head * 6 * 2);
+ write_tile_arrays(x, y,
+ fg + head * 6 * 4,
+ bg + head * 6 * 4,
+ tex + head * 6 * 2);
+ head = (head + 1) % buffersz;
+ current_erasz++; sum_erasz++;
+ if (head == tail) {
+ //gamelog << "Expanding partial-printing buffer" << endl;
+ // Buffer is full, expand it.
+ renderer_opengl::allocate(buffersz * 2);
+ // Move the tail to the end of the newly allocated space
+ tail += buffersz;
+ memmove(vertexes + tail * 6 * 2, vertexes + head * 6 * 2, sizeof(GLfloat) * 6 * 2 * (buffersz - head));
+ memmove(fg + tail * 6 * 4, fg + head * 6 * 4, sizeof(GLfloat) * 6 * 4 * (buffersz - head));
+ memmove(bg + tail * 6 * 4, fg + head * 6 * 4, sizeof(GLfloat) * 6 * 4 * (buffersz - head));
+ memmove(tex + tail * 6 * 2, fg + head * 6 * 2, sizeof(GLfloat) * 6 * 2 * (buffersz - head));
+ // And finish.
+ buffersz *= 2;
+ }
+ }
+
+ void allocate(int tile_count) {
+ assert(false);
+ }
+
+ virtual void reshape_gl() {
+ // TODO: This function is duplicate code w/base class reshape_gl
+ // Setup invariant state
+ glEnableClientState(GL_COLOR_ARRAY);
+ /// Set up our coordinate system
+ if (forced_steps + zoom_steps == 0 &&
+ init.display.flag.has_flag(INIT_DISPLAY_FLAG_BLACK_SPACE)) {
+ size_x = gps.dimx * dispx;
+ size_y = gps.dimy * dispy;
+ off_x = (screen->w - size_x) / 2;
+ off_y = (screen->h - size_y) / 2;
+ } else {
+ // If we're zooming (or just not using black space), we use the
+ // entire window.
+ size_x = screen->w;
+ size_y = screen->h;
+ off_x = off_y = 0;
+ }
+ glViewport(off_x, off_y, size_x, size_y);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluOrtho2D(0, gps.dimx, gps.dimy, 0);
+ }
+
+ void draw_arrays(GLfloat *vertexes, GLfloat *fg, GLfloat *bg, GLfloat *tex, int tile_count) {
+ // Set vertex pointer
+ glVertexPointer(2, GL_FLOAT, 0, vertexes);
+ // Render the background colors
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ glDisable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+ glColorPointer(4, GL_FLOAT, 0, bg);
+ glDrawArrays(GL_TRIANGLES, 0, tile_count * 6);
+ // Render the foreground, colors and textures both
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_NOTEQUAL, 0);
+ glEnable(GL_TEXTURE_2D);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glColorPointer(4, GL_FLOAT, 0, fg);
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+ glDrawArrays(GL_TRIANGLES, 0, tile_count * 6);
+ }
+
+ void draw(int dummy) {
+ if (tail > head) {
+ // We're straddling the end of the array, so have to do this in two steps
+ draw_arrays(vertexes + tail * 6 * 2,
+ fg + tail * 6 * 4,
+ bg + tail * 6 * 4,
+ tex + tail * 6 * 2,
+ buffersz - tail);
+ draw_arrays(vertexes, fg, bg, tex, head-1);
+ } else {
+ draw_arrays(vertexes + tail * 6 * 2,
+ fg + tail * 6 * 4,
+ bg + tail * 6 * 4,
+ tex + tail * 6 * 2,
+ sum_erasz);
+ }
+
+ printGLError();
+ erasz.push_back(current_erasz); current_erasz = 0;
+ if (erasz.size() == redraw_count) {
+ // Right, time to retire the oldest era.
+ tail = (tail + erasz.front()) % buffersz;
+ sum_erasz -= erasz.front();
+ erasz.pop_front();
+ }
+ }
+
+public:
+ renderer_partial() {
+ redraw_count = init.display.partial_print_count;
+ buffersz = 2048;
+ renderer_opengl::allocate(buffersz);
+ current_erasz = head = tail = sum_erasz = 0;
+ }
+};
+
+class renderer_accum_buffer : public renderer_once {
+ void draw(int vertex_count) {
+ // Copy the previous frame's buffer back in
+ glAccum(GL_RETURN, 1);
+ renderer_once::draw(vertex_count);
+ // Store the screen contents back to the buffer
+ glAccum(GL_LOAD, 1);
+ }
+};
+
+class renderer_framebuffer : public renderer_once {
+ GLuint framebuffer, fb_texture;
+
+ void init_opengl() {
+ glGenFramebuffersEXT(1, &framebuffer);
+ // Allocate FBO texture memory
+ glGenTextures(1, &fb_texture);
+ glBindTexture(GL_TEXTURE_2D, fb_texture);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ screen->w, screen->h,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+
+ // Bind texture to FBO
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer);
+ glFramebufferTexture2DEXT(GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, fb_texture, 0);
+ renderer_once::init_opengl();
+ }
+
+ void uninit_opengl() {
+ renderer_once::uninit_opengl();
+ glDeleteTextures(1, &fb_texture);
+ glDeleteFramebuffersEXT(1, &framebuffer);
+ }
+
+ void draw(int vertex_count) {
+ // Bind the framebuffer
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, framebuffer);
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, 0);
+ // Draw
+ renderer_once::draw(vertex_count);
+ // Draw the framebuffer to screen
+ glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
+ glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, framebuffer);
+ glBlitFramebufferEXT(0,0, screen->w, screen->h,
+ 0,0, screen->w, screen->h,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ printGLError();
+ }
+};
+
+class renderer_vbo : public renderer_opengl {
+ GLuint vbo; // Vertexes only
+
+ void init_opengl() {
+ renderer_opengl::init_opengl();
+ glGenBuffersARB(1, &vbo);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, gps.dimx*gps.dimy*6*2*sizeof(GLfloat), vertexes, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, 0, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
+ }
+
+ void uninit_opengl() {
+ glDeleteBuffersARB(1, &vbo);
+ renderer_opengl::uninit_opengl();
+ }
+};
diff --git a/g_src/resize++.cpp b/g_src/resize++.cpp
new file mode 100755
index 0000000..fd1b77c
--- /dev/null
+++ b/g_src/resize++.cpp
@@ -0,0 +1,269 @@
+#include <cmath>
+#include <vector>
+
+#include <SDL/SDL.h>
+
+#include "resize++.h"
+
+//code adapted by David Olsen from Lanczos filtering article on wikipedia.org
+
+#ifndef M_PI
+#define M_PI 3.14159265359
+#endif
+
+static inline double Lanczos(double x, int Radius)
+{
+ if (x == 0.0) return 1.0;
+ if (x <= -Radius || x >= Radius) return 0.0;
+ double tmp = x * M_PI;
+ return Radius * std::sin(tmp) * std::sin(tmp / Radius) / (tmp * tmp);
+}
+
+static inline void Resample(SDL_Surface * src, SDL_Surface * dst, int filter)
+{
+ const double blur = 1.0;
+ double factor = dst->w / (double)src->w;
+ double scale = std::min(factor, 1.0) / blur;
+ int FilterRadius = filter;
+ if (filter < 1 )
+ FilterRadius = 1;
+ if (filter > 3) //automatically determine fastest filter setting
+ {
+ FilterRadius = 3;
+ if (scale < 0.67) FilterRadius = 2;
+ if (scale <= 0.5) FilterRadius = 1;
+ }
+ double support = FilterRadius / scale;
+
+ std::vector<double> contribution_x(std::min((size_t)src->w, 5+(size_t)(2*support)));
+ /* 5 = room for rounding up in calculations of start, stop and support */
+
+ Uint32 ** temp = new Uint32 * [src->h]; //array of source->height * dest->width
+ for (int i = 0 ; i < src->h; i++)
+ temp[i] = new Uint32 [dst->w];
+
+ if (support <= 0.5) { support = 0.5 + 1E-12; scale = 1.0; }
+
+ for (int x = 0; x < dst->w; ++x)
+ {
+ double center = (x + 0.5) / factor;
+ size_t start = (size_t)std::max(center - support + 0.5, (double)0);
+ size_t stop = (size_t)std::min(center + support + 0.5, (double)src->w);
+ double density = 0.0;
+ size_t nmax = stop - start;
+ double s = start - center + 0.5;
+ double point[4] = {0,0,0,0};
+ Uint8 v;
+ double diff;
+
+ for (int y = 0; y < src->h; y++)
+ {
+ for (size_t n = 0; n < nmax; ++n)
+ {
+ if (y == 0)
+ { //only come up with the contribution list once per column.
+ contribution_x[n] = Lanczos (s * scale, FilterRadius);
+ density += contribution_x[n];
+ s++;
+ }
+ //it MUST be a 32-bit surface for following code to work correctly
+ Uint8 * p = (Uint8 *)src->pixels + y * src->pitch + (start+n) * 4;
+ for (int c = 0; c < 4; c++)
+ point[c] += p[c] * contribution_x[n];
+ }
+ /* Normalize. Truncate to Uint8 values. Place in temp array*/
+ Uint8 * p = (Uint8 *)&temp[y][x];
+ for (size_t c = 0; c < 4; c++)
+ {
+ if (density != 0.0 && density != 1.0)
+ point[c] /= density;
+ if (point[c] < 0)
+ point[c] = 0;
+ if (point[c] > 255)
+ point[c] = 255;
+ v = (Uint8) point[c];
+ diff = point[c] - (double)v;
+ if (diff < 0)
+ diff = -diff;
+ if (diff >= 0.5)
+ v++;
+ p[c] = v;
+ point[c] = 0; //reset value for next loop
+ }
+ }
+ }
+
+ factor = dst->h / (double)src->h;
+ scale = std::min(factor, 1.0) / blur;
+ if (filter > 3) //automatically determine fastest filter setting
+ {
+ FilterRadius = 3;
+ if (scale < 0.67) FilterRadius = 2;
+ if (scale <= 0.5) FilterRadius = 1;
+ }
+ support = FilterRadius / scale;
+
+ std::vector<double> contribution_y(std::min((size_t)src->h, 5+(size_t)(2*support)));
+
+ if (support <= 0.5) { support = 0.5 + 1E-12; scale = 1.0; }
+
+ for (int y = 0; y<dst->h; ++y)
+ {
+ double center = (y + 0.5) / factor;
+ size_t start = (size_t)std::max(center - support + 0.5, (double)0);
+ size_t stop = (size_t)std::min(center + support + 0.5, (double)src->h);
+ double density = 0.0;
+ size_t nmax = stop-start;
+ double s = start - center+0.5;
+ double point[4] = {0,0,0,0};
+ Uint8 v;
+ double diff;
+
+ for (int x=0; x<dst->w; x++)
+ {
+ for (size_t n=0; n<nmax; ++n)
+ {
+ if (x == 0)
+ {
+ contribution_y[n] = Lanczos(s * scale, FilterRadius);
+ density += contribution_y[n];
+ s++;
+ }
+ Uint8 * p = (Uint8 *)&temp[start+n][x];
+ for (int c = 0; c < 4; c++)
+ point[c] += p[c] * contribution_y[n];
+ }
+ //destination must also be a 32 bit surface for this to work!
+ Uint8 * p = (Uint8 *)dst->pixels + y * dst->pitch + x * 4;
+ for (size_t c = 0; c < 4; c++)
+ {
+ if (density != 0.0 && density != 1.0)
+ point[c] /= density;
+ if (point[c] < 0)
+ point[c] = 0;
+ if (point[c] > 255)
+ point[c] = 255;
+ v = (Uint8) point[c];
+ diff = point[c] - (double)v;
+ if (diff < 0)
+ diff = -diff;
+ if (diff >= 0.5)
+ v++;
+ p[c] = v;
+ point[c] = 0;
+ }
+ }
+ }
+
+ //free the temp array, so we don't leak any memory
+ for (int i = 0 ; i < src->h; i++)
+ delete [] temp[i];
+ delete [] temp;
+}
+
+static inline Uint32 get_pixel(SDL_Surface *surface, int x, int y)
+{
+ int bpp = surface->format->BytesPerPixel;
+ /* Here p is the address to the pixel we want to retrieve */
+ Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
+
+ switch(bpp)
+ {
+ case 1: return *p;
+ case 2: return *(Uint16 *)p;
+ case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
+ return p[0] << 16 | p[1] << 8 | p[2];
+ else
+ return p[0] | p[1] << 8 | p[2] << 16;
+ case 4: return *(Uint32 *)p;
+ default: return 0; /* shouldn't happen, but avoids warnings */
+ }
+}
+
+static inline bool has_alpha(SDL_Surface * src)
+{
+ Uint8 r, g, b, a;
+ bool is_alpha = false;
+
+ if SDL_MUSTLOCK(src) SDL_LockSurface(src);
+
+ for (int x = 0; x < src->w; x++)
+ for (int y = 0; y < src->h; y++)
+ {
+ SDL_GetRGBA(get_pixel(src, x, y), src->format, &r, &g, &b, &a);
+ if (a != SDL_ALPHA_OPAQUE)
+ {
+ is_alpha = true;
+ x = src->w;
+ break;
+ }
+ }
+
+ if SDL_MUSTLOCK(src) SDL_UnlockSurface(src);
+
+ return is_alpha;
+}
+
+SDL_Surface* SDL_Resize(SDL_Surface *src, float factor, bool free, int filter)
+{
+ if (factor > 100.0f) factor = 100.0f; //let's be reasonable...
+ int new_w = (int)(src->w * factor),
+ new_h = (int)(src->h * factor);
+ if (new_w < 1) new_w = 1;
+ if (new_h < 1) new_h = 1;
+
+ return SDL_Resize(src, new_w, new_h, free, filter);
+}
+
+SDL_Surface* SDL_Resize(SDL_Surface *src, int new_w, int new_h, bool free, int filter)
+{
+ SDL_Surface * dst;
+ bool is_alpha = has_alpha(src);
+
+ if (src->w == new_w && src->h == new_h)
+ {
+ //No change in size. Return an optimized image.
+ if (is_alpha)
+ {
+ dst = SDL_DisplayFormatAlpha(src);
+ SDL_SetAlpha(src, SDL_SRCALPHA, 0);
+ }
+ else
+ dst = SDL_DisplayFormat(src);
+
+ if (free)
+ SDL_FreeSurface(src);
+ return dst;
+ }
+
+ Uint32 rmask = 0x000000ff,
+ gmask = 0x0000ff00,
+ bmask = 0x00ff0000,
+ amask = 0xff000000;
+ #if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0xff000000;
+ gmask = 0x00ff0000;
+ bmask = 0x0000ff00;
+ amask = 0x000000ff;
+ #endif
+
+ dst = SDL_CreateRGBSurface(0, new_w, new_h, 32, rmask, gmask, bmask, amask);
+ SDL_Surface * temp = SDL_ConvertSurface(src,dst->format,0);
+ if (free)
+ SDL_FreeSurface(src);
+ src = temp;
+
+ Resample(src,dst,filter);
+
+ SDL_FreeSurface(temp);
+ if (is_alpha)
+ {
+ temp = SDL_DisplayFormatAlpha(dst);
+ SDL_SetAlpha(temp, SDL_SRCALPHA, 0);
+ }
+ else
+ temp = SDL_DisplayFormat(dst);
+
+ SDL_FreeSurface(dst);
+ return temp;
+}
diff --git a/g_src/resize++.h b/g_src/resize++.h
new file mode 100755
index 0000000..8f9b097
--- /dev/null
+++ b/g_src/resize++.h
@@ -0,0 +1,68 @@
+/*resize++.cpp :
+ High quality image scaling with Lanczos interpolation method adapted
+ from the Lanczos filtering code available on wikipedia.org.
+ -by David Olsen.
+
+ There are two methods to use the library, the only difference is in
+ whether the image should be scaled to a specific size in pixels,
+ or be scaled proportionally by a certain percentage(1.0 = 100%).
+
+ If scale_factor > 1.0 image will be enlarged, < 1.0 will shrink the image
+
+ All scaling operations will return an image that has been optimized(using
+ SDL_DisplayFormat or SDL_DisplayFormatAlpha, as appropriate) for the
+ current screen mode (Even images that were not resized will return an
+ optimized surface pointer, i.e. scale_factor = 1.0). The SDL_SRCALPHA flag
+ is also set for the returned image, if appropriate.
+
+ The option to free or not free the source image is given, so that if you
+ desire to make multiple copies of a source image at various sizes,
+ you do not need to reload the image for each operation.
+
+ The filter variable determines the radius of the Lanczos filter.
+ The following settings can be used:
+ 1 = Quickest filtering mode, but when used for enlarging, produces
+ blocky results, similar to the nearest neighbor approach.
+ When used for reductions, it outputs very nice results.
+ 2 = Medium filtering mode - slightly faster than 3, but slower than 1.
+ When enlarging, this mode produces high quality results similar
+ to (but a bit better than) bilinear interpolation.
+ 3 = The highest quality mode, also the slowest, but only about 30%
+ slower than mode 1. This mode will produce the best enlargements.
+ There is no need for a filter radius greater than 3.
+ The default filtering value passed to the function is 4. Any number
+ greater than 3 will tell the library to automatically choose the quickest
+ filtering mode that still maintains highest quality output. Basically,
+ if you are shrinking an image greatly, it will choose radius of 1.
+ If you shrink an image a little bit, it will choose radius of 2.
+ For all other operations, it will choose a radius of 3.
+ You may therefore specify which filter mode to use manually, if speed
+ is a particular issue, or let it be automatically handled,
+ for highest quality results.
+
+ The typical usage pattern can be demonstrated as follows:
+ SDL_Surface *image = SDL_LoadBMP("myimage.bmp");
+ image = SDL_Resize(image,320,240); //scale image to 320x240
+ //the original image is freed, and image points to the new scaled surface.
+
+ or
+
+ SDL_Surface *image = SDL_LoadBMP("myimage.bmp");
+ SDL_Surface *small_image = SDL_Resize(image,0.5f,false); //shrink to 50% size
+ SDL_Surface *big_image = SDL_Resize(image,2.0f,false); //enlarge to 200% size
+ //image still points to the original loaded surface.
+
+ If you have any questions or comments, feel free to contact me(David Olsen) at:
+ jolynsbass@gmail.com
+
+*/
+
+#ifndef __RESIZEpp__
+#define __RESIZEpp__
+
+#include <SDL/SDL.h>
+
+SDL_Surface * SDL_Resize(SDL_Surface *src, float scale_factor, bool free_src = true, int filter = 4);
+SDL_Surface * SDL_Resize(SDL_Surface *src, int new_w, int new_h, bool free_src = true, int filter = 4);
+
+#endif
diff --git a/g_src/svector.h b/g_src/svector.h
new file mode 100755
index 0000000..3d9e81a
--- /dev/null
+++ b/g_src/svector.h
@@ -0,0 +1,28 @@
+//pelican aka sam dennis wrote this
+#ifndef SVECTOR_H
+#define SVECTOR_H
+
+#include <vector>
+#include <memory>
+
+template <class T, class A = std::allocator<T> >
+class svector : public std::vector<T, A> {
+#ifndef WIN32
+ public:
+ using std::vector<T, A>::begin;
+#endif
+
+#ifdef WIN32
+ public:
+#endif
+ void erase(typename std::vector<T, A>::size_type i) {
+ std::vector<T, A> &vec = *this;
+ vec.erase(begin() + i);
+ }
+ void insert(typename std::vector<T, A>::size_type i, const T &v) {
+
+ std::vector<T, A> &vec = *this;
+ vec.insert(begin() + i, v);
+ }
+};
+#endif
diff --git a/g_src/template.h b/g_src/template.h
new file mode 100755
index 0000000..0272675
--- /dev/null
+++ b/g_src/template.h
@@ -0,0 +1,1235 @@
+template <class T> int32_t get_vector_sum(svector<T> &vec)
+{
+ T total=0;
+ auto ii_s=vec.begin(),ii_e=vec.end();
+ for(;ii_s<ii_e;++ii_s)
+ {
+ total+=(*ii_s);
+ }
+ return total;
+}
+
+template <class T> int32_t get_random_biased_index(svector<T> &chance)
+{
+ if(chance.size()==0)
+ {
+ errorlog_string("Empty biased index vector");
+ return -1;
+ }
+
+ T roll=trandom(get_vector_sum(chance));
+
+ auto ii_s=chance.begin(),ii_e=chance.end();
+ auto ii_b=ii_s;
+ for(;ii_s<ii_e;++ii_s)
+ {
+ if(roll<(*ii_s))return (int32_t)(ii_s-ii_b);
+ roll-=(*ii_s);
+ }
+
+ errorlog_string("Biased index vector computation error");
+ return 0;//MORE FUNCTIONS WILL BE HAPPIER WITH 0 THAN -1 HERE
+}
+
+template <class T> void zero_vector(svector<T> &vc)
+{
+ //NOTE: vector MEMORY IS GUARANTEED TO BE CONTIGUOUS, AND THIS IS FASTER THAN GOING THROUGH ONE BY ONE
+ //apparently this gives linux a headache though, so back to the slower way
+ //int32_t sz=vc.size();
+ //if(sz==0)return;
+ //memset(&(vc[0]),0,sizeof(T)*sz);
+ auto ii_s=vc.begin(),ii_e=vc.end();
+ for(;ii_s<ii_e;++ii_s)(*ii_s)=0;
+}
+
+template <class T> bool positive_vector(svector<T> &vc)
+{
+ auto ii_s=vc.begin(),ii_e=vc.end();
+ for(;ii_s<ii_e;++ii_s)
+ {
+ if((*ii_s)>0)return true;
+ }
+ return false;
+}
+
+template <class T> void add_unique_to_vector(T nl,svector<T> &vc)
+{
+ auto ii_s=vc.begin(),ii_e=vc.end();
+ for(;ii_s<ii_e;++ii_s)
+ {
+ if((*ii_s)==nl)return;
+ }
+ vc.push_back(nl);
+}
+
+template <class T,class T2> void add_dual_unique_to_vectors(T nl,T2 nl2,svector<T> &vc,svector<T2> &vc2)
+{
+ auto ii_s=vc.begin(),ii_e=vc.end();
+ auto ii_s2=vc2.begin(),ii_e2=vc2.end();
+ for(;ii_s<ii_e;++ii_s,++ii_s2)
+ {
+ if((*ii_s)==nl&&
+ (*ii_s2)==nl2)return;
+ }
+ vc.push_back(nl);
+ vc2.push_back(nl2);
+}
+
+template <class T,class T2,class T3,class T4> void add_quad_unique_to_vectors(T nl,T2 nl2,T3 nl3,T4 nl4,
+ svector<T> &vc,svector<T2> &vc2,svector<T3> &vc3,svector<T4> &vc4)
+{
+ auto ii_s=vc.begin(),ii_e=vc.end();
+ auto ii_s2=vc2.begin(),ii_e2=vc2.end();
+ auto ii_s3=vc3.begin(),ii_e3=vc3.end();
+ auto ii_s4=vc4.begin(),ii_e4=vc4.end();
+ for(;ii_s<ii_e;++ii_s,++ii_s2,++ii_s3,++ii_s4)
+ {
+ if((*ii_s)==nl&&
+ (*ii_s2)==nl2&&
+ (*ii_s3)==nl3&&
+ (*ii_s4)==nl4)return;
+ }
+ vc.push_back(nl);
+ vc2.push_back(nl2);
+ vc3.push_back(nl3);
+ vc4.push_back(nl4);
+}
+
+template <class T> void remove_all_from_vector(T nl,svector<T> &vc)
+{
+ int32_t i;
+ for(i=(int32_t)vc.size()-1;i>=0;i--)
+ {
+ if(vc[i]==nl)vc.erase(i);
+ }
+}
+
+template <class T,class T2> void remove_all_from_dual_vectors(T nl,T2 nl2,svector<T> &vc,svector<T2> &vc2)
+{
+ int32_t i;
+ for(i=(int32_t)vc.size()-1;i>=0;i--)
+ {
+ if(vc[i]==nl&&
+ vc2[i]==nl2)
+ {
+ vc.erase(i);
+ vc2.erase(i);
+ }
+ }
+}
+
+template <class T> int32_t get_vector_index(T a,svector<T> &v)
+{
+ auto ii_s=v.begin(),ii_e=v.end();
+ auto ii_b=ii_s;
+ for(;ii_s<ii_e;++ii_s)
+ {
+ if((*ii_s)==a)return (int32_t)(ii_s-ii_b);
+ }
+ return -1;
+}
+
+template <class T,class T2> int32_t get_dual_vector_index(T a1,T2 a2,svector<T> &vc,svector<T2> &vc2)
+{
+ auto ii_s=vc.begin(),ii_e=vc.end();
+ auto ii_s2=vc2.begin(),ii_e2=vc2.end();
+ auto ii_b=ii_s;
+ for(;ii_s<ii_e;++ii_s,++ii_s2)
+ {
+ if((*ii_s)==a1&&
+ (*ii_s2)==a2)return (int32_t)(ii_s-ii_b);
+ }
+ return -1;
+}
+
+template <class T,class T2,class T3,class T4> int32_t get_quad_vector_index(T a1,T2 a2,T3 a3,T4 a4,
+ svector<T> &vc,svector<T2> &vc2,
+ svector<T3> &vc3,svector<T4> &vc4)
+{
+ auto ii_s=vc.begin(),ii_e=vc.end();
+ auto ii_s2=vc2.begin(),ii_e2=vc2.end();
+ auto ii_s3=vc3.begin(),ii_e3=vc3.end();
+ auto ii_s4=vc4.begin(),ii_e4=vc4.end();
+ auto ii_b=ii_s;
+ for(;ii_s<ii_e;++ii_s,++ii_s2,++ii_s3,++ii_s4)
+ {
+ if((*ii_s)==a1&&
+ (*ii_s2)==a2&&
+ (*ii_s3)==a3&&
+ (*ii_s4)==a4)return (int32_t)(ii_s-ii_b);
+ }
+ return -1;
+}
+
+template <class T> void merge_vectors(T &master, T &merger)
+{
+ auto ii_s=merger.begin(),ii_e=merger.end();
+ for(;ii_s<ii_e;++ii_s)
+ {
+ auto ii_s2=master.begin(),ii_e2=master.end();
+ for(;ii_s2<ii_e2;++ii_s2)
+ {
+ if((*ii_s)==(*ii_s2))break;
+ }
+ if(ii_s2>=ii_e2)
+ {
+ master.push_back((*ii_s));
+ }
+ }
+}
+
+template <class T> int32_t get_common_element_vector_index(T &master, T &merger)
+{
+ auto ii_s=merger.begin(),ii_e=merger.end();
+ auto ii_s2=master.begin(),ii_e2=master.end();
+ auto ii_b2=ii_s2;
+
+ for(;ii_s<ii_e;++ii_s)
+ {
+ for(;ii_s2<ii_e2;++ii_s2)
+ {
+ if((*ii_s)==(*ii_s2))return (int32_t)(ii_s2-ii_b2);
+ }
+ ii_s2=ii_b2;
+ }
+
+ return -1;
+}
+
+template <class T,class T2> void merge_dual_vectors(T &master, T2 &master2, T &merger, T2 &merger2)
+{
+ auto ii_s=merger.begin(),ii_e=merger.end();
+ auto ii_s2=merger2.begin(),ii_e2=merger2.end();
+ for(;ii_s<ii_e;++ii_s,++ii_s2)
+ {
+ auto ii_s3=master.begin(),ii_e3=master.end();
+ auto ii_s4=master2.begin(),ii_e4=master2.end();
+ for(;ii_s3<ii_e3;++ii_s3,++ii_s4)
+ {
+ if((*ii_s)==(*ii_s3)&&
+ (*ii_s2)==(*ii_s4))break;
+ }
+ if(ii_s3>=ii_e3)
+ {
+ master.push_back((*ii_s));
+ master2.push_back((*ii_s2));
+ }
+ }
+}
+
+template <class T,class T2,class T3,class T4> void merge_quad_vectors(T &master, T2 &master2, T3 &master3, T4 &master4,
+ T &merger, T2 &merger2, T3 &merger3, T4 &merger4)
+{
+ auto ii_s=merger.begin(),ii_e=merger.end();
+ auto ii_s2=merger2.begin(),ii_e2=merger2.end();
+ auto ii_s3=merger3.begin(),ii_e3=merger3.end();
+ auto ii_s4=merger4.begin(),ii_e4=merger4.end();
+ for(;ii_s<ii_e;++ii_s,++ii_s2,++ii_s3,++ii_s4)
+ {
+ auto ii_s5=master.begin(),ii_e5=master.end();
+ auto ii_s6=master2.begin(),ii_e6=master2.end();
+ auto ii_s7=master3.begin(),ii_e7=master3.end();
+ auto ii_s8=master4.begin(),ii_e8=master4.end();
+ for(;ii_s5<ii_e5;++ii_s5,++ii_s6,++ii_s7,++ii_s8)
+ {
+ if((*ii_s)==(*ii_s5)&&
+ (*ii_s2)==(*ii_s6)&&
+ (*ii_s3)==(*ii_s7)&&
+ (*ii_s4)==(*ii_s8))break;
+ }
+ if(ii_s5>=ii_e5)
+ {
+ master.push_back((*ii_s));
+ master2.push_back((*ii_s2));
+ master3.push_back((*ii_s3));
+ master4.push_back((*ii_s4));
+ }
+ }
+}
+
+template <class T> void cull_vectors(T &master,T &cull)
+{
+ int32_t i,i2;
+ for(i=(int32_t)cull.size()-1;i>=0;i--)
+ {
+ for(i2=(int32_t)master.size()-1;i2>=0;i2--)
+ {
+ if(cull[i]==master[i2])
+ {
+ master.erase(i2);
+ break;
+ }
+ }
+ }
+}
+
+template <class T> void push_on_vector(T &master,T &new_stuff)
+{
+ auto ii_s=new_stuff.begin(),ii_e=new_stuff.end();
+ for(;ii_s<ii_e;++ii_s)
+ {
+ master.push_back(*ii_s);
+ }
+}
+
+template<class T> VIndex add_to_global_id_vector(T ptr,svector<T> &vect)
+{
+ int32_t size=vect.size();
+ if(size==0)
+ {
+ vect.push_back(ptr);
+ return 1;
+ }
+ if(vect[size-1]->global_id<ptr->global_id)
+ {
+ vect.push_back(ptr);
+ return size;
+ }
+
+ int32_t start=0;
+ int32_t end=size-1;
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->global_id==ptr->global_id)return -1;
+ if(start==end)
+ {
+ if(cptr->global_id<ptr->global_id)
+ {
+ if(start+1>=size)return -1;//push_back() FOR UNIQUE ALREADY HANDLED
+ else
+ {
+ vect.insert(start+1,ptr);
+ return start+1;
+ }
+ }
+ else if(cptr->global_id>ptr->global_id)
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ return -1;
+ }
+
+ if(cptr->global_id>ptr->global_id)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr->global_id<ptr->global_id)
+ {
+ if(start+1>=size)return -1;//push_back() FOR UNIQUE ALREADY HANDLED
+ else
+ {
+ vect.insert(start+1,ptr);
+ return start+1;
+ }
+ }
+ else if(cptr->global_id>ptr->global_id)
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr->global_id<ptr->global_id)
+ {
+ if(end+1>=size)return -1;//push_back() FOR UNIQUE ALREADY HANDLED
+ else
+ {
+ vect.insert(end+1,ptr);
+ return end+1;
+ }
+ }
+ else if(cptr->global_id>ptr->global_id)
+ {
+ vect.insert(end,ptr);
+ return end;
+ }
+ }
+ return -1;//push_back() FOR UNIQUE ALREADY HANDLED SO NO else
+}
+
+template<class T> void remove_from_global_id_vector(T ptr,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+ cptr=vect[mid];
+ if(cptr==ptr)
+ {
+ vect.erase(mid);
+ return;
+ }
+
+ if(cptr->global_id>ptr->global_id)end=mid-1;
+ else start=mid+1;
+ }
+}
+
+template<class T> void remove_from_global_id_vector_by_id(int32_t id,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+ cptr=vect[mid];
+ if(cptr->global_id==id)
+ {
+ vect.erase(mid);
+ return;
+ }
+
+ if(cptr->global_id>id)end=mid-1;
+ else start=mid+1;
+ }
+}
+
+template<class T> T get_from_global_id_vector(int32_t id,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->global_id==id)return cptr;
+ else if(cptr->global_id>id)end=mid-1;
+ else start=mid+1;
+ }
+
+ return NULL;
+}
+
+template<class T> int32_t get_index_from_global_id_vector(int32_t id,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->global_id==id)return mid;
+ else if(cptr->global_id>id)end=mid-1;
+ else start=mid+1;
+ }
+
+ return -1;
+}
+
+template<class T> VIndex add_to_binary_vector(T ptr,svector<T> &vect)
+{
+ int32_t size=vect.size();
+ if(size==0)
+ {
+ vect.push_back(ptr);
+ return 0;
+ }
+ if(vect[size-1]<ptr)
+ {
+ vect.push_back(ptr);
+ return size;
+ }
+
+ int32_t start=0;
+ int32_t end=size-1;
+ int32_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr)
+ {
+ vect.insert(mid,ptr);//INSERT A COPY HERE SINCE THIS IS A NON-UNIQUE VECTOR
+ return mid;
+ }
+ if(start==end)
+ {
+ if(cptr<ptr)
+ {
+ if(start+1>=size)vect.push_back(ptr);
+ else vect.insert(start+1,ptr);
+ return start+1;
+ }
+ else
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ }
+
+ if(cptr>ptr)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr<ptr)
+ {
+ if(start+1>=size)vect.push_back(ptr);
+ else vect.insert(start+1,ptr);
+ return start+1;
+ }
+ else
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr<ptr)
+ {
+ if(end+1>=size)vect.push_back(ptr);
+ else vect.insert(end+1,ptr);
+ return end+1;
+ }
+ else
+ {
+ vect.insert(end,ptr);
+ return end;
+ }
+ }
+ else vect.push_back(ptr);
+ return end;
+}
+
+//NOTE: RETURNS -1 IF ALREADY PRESENT, NOT THE INDEX
+template<class T> VIndex add_unique_to_binary_vector(T ptr,svector<T> &vect)
+{
+ int32_t size=vect.size();
+ if(size==0)
+ {
+ vect.push_back(ptr);
+ return 0;
+ }
+ if(vect[size-1]<ptr)
+ {
+ vect.push_back(ptr);
+ return size;
+ }
+
+ int32_t start=0;
+ int32_t end=size-1;
+ int32_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr)return -1;//ALREADY IN VECTOR
+ if(start==end)
+ {
+ if(cptr<ptr)
+ {
+ if(start+1>=(int32_t)vect.size())return -1;//push_back() CASE ALREADY HANDLED
+
+ vect.insert(start+1,ptr);
+ return start+1;
+ }
+ else if(cptr>ptr)
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ return -1;
+ }
+
+ if(cptr>ptr)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr<ptr)
+ {
+ if(start+1>=size)return -1;//push_back() CASE ALREADY HANDLED
+
+ vect.insert(start+1,ptr);
+ return start+1;
+ }
+ else if(cptr>ptr)
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr<ptr)
+ {
+ if(end+1>=size)return -1;//push_back() CASE ALREADY HANDLED
+
+ vect.insert(end+1,ptr);
+ return end+1;
+ }
+ else if(cptr>ptr)
+ {
+ vect.insert(end,ptr);
+ return end;
+ }
+ }
+ return -1;//push_back() CASE ALREADY HANDLED SO NO else
+}
+
+//NOTE: RETURNS INDEX IF ALREADY PRESENT
+template<class T> VIndex add_unique_to_binary_vector_always_index(T ptr,svector<T> &vect,bool &was_present)
+{
+ was_present=false;
+
+ int32_t size=vect.size();
+ if(size==0)
+ {
+ vect.push_back(ptr);
+ return 0;
+ }
+ if(vect[size-1]<ptr)
+ {
+ vect.push_back(ptr);
+ return size;
+ }
+
+ int32_t start=0;
+ int32_t end=size-1;
+ int32_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr){was_present=true;return mid;}//ALREADY IN VECTOR
+ if(start==end)
+ {
+ if(cptr<ptr)
+ {
+ if(start+1>=(int32_t)vect.size())return -1;//push_back() CASE ALREADY HANDLED
+
+ vect.insert(start+1,ptr);
+ return start+1;
+ }
+ else if(cptr>ptr)
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ return -1;
+ }
+
+ if(cptr>ptr)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr<ptr)
+ {
+ if(start+1>=size)return -1;//push_back() CASE ALREADY HANDLED
+
+ vect.insert(start+1,ptr);
+ return start+1;
+ }
+ else if(cptr>ptr)
+ {
+ vect.insert(start,ptr);
+ return start;
+ }
+ if(cptr==ptr){was_present=true;return start;}//ALREADY IN VECTOR
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr<ptr)
+ {
+ if(end+1>=size)return -1;//push_back() CASE ALREADY HANDLED
+
+ vect.insert(end+1,ptr);
+ return end+1;
+ }
+ else if(cptr>ptr)
+ {
+ vect.insert(end,ptr);
+ return end;
+ }
+ if(cptr==ptr){was_present=true;return end;}//ALREADY IN VECTOR
+ }
+ return -1;//push_back() CASE ALREADY HANDLED SO NO else
+}
+
+template<class T> void remove_from_binary_vector(T ptr,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+ int32_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr)
+ {
+ vect.erase(mid);
+ return;
+ }
+
+ if(cptr>ptr)end=mid-1;
+ else start=mid+1;
+ }
+}
+
+template<class T> int32_t get_index_from_binary_vector(T id,svector<T> &vect)
+{
+ int32_t size=vect.size();
+ if(size==0||id==-1)return -1;
+
+ int32_t start=0;
+ int32_t end=size-1;
+ int32_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==id)
+ {
+ return mid;
+ }
+
+ if(cptr>id)end=mid-1;
+ else start=mid+1;
+ }
+
+ return -1;
+}
+
+template<class T> int32_t get_floor_index_from_binary_vector(T ptr,svector<T> &vect)
+{
+ int32_t size=vect.size();
+ if(size==0)return -1;
+ if(vect[size-1]<ptr)return size-1;
+
+ int32_t start=0;
+ int32_t end=size-1;
+ int32_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr)
+ {
+ while(mid>0)
+ {
+ if(vect[mid-1]<ptr)return mid;
+ mid--;
+ }
+ return mid;
+ }
+ if(start==end)
+ {
+ if(cptr<ptr)
+ {
+ if(start+1>=size)return start;
+ else return start;
+ }
+ //NOTE: cptr>ptr as == is already handled above
+ else
+ {
+ if(start<=0)return 0;
+ else return start-1;
+ }
+ }
+
+ if(cptr>ptr)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr<ptr)
+ {
+ if(start+1>=size)return start;
+ else return start;
+ }
+ else if(cptr>ptr)
+ {
+ if(start<=0)return 0;
+ else return start-1;
+ }
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr<ptr)
+ {
+ if(end+1>=size)return end;
+ else return end;
+ }
+ else if(cptr>ptr)
+ {
+ if(end<=0)return 0;
+ else return end-1;
+ }
+ }
+ return start;
+}
+
+template<class T> void fixed_array_push_back(T ptr,T *vect,int32_t &size,int32_t max)
+{
+ if(size>=max)return;
+ vect[size]=ptr;
+ size++;
+}
+
+template<class T> void fixed_array_insert(int32_t index,T ptr,T *vect,int32_t &size,int32_t max)
+{
+ if(size>=max)return;
+ if(size>0)
+ {
+ T *ptr1=vect+size;
+ T *ptr2=vect+(size-1);
+ T *stop=vect+index;
+ while(ptr2>=stop)
+ {
+ (*ptr1)=(*ptr2);
+ --ptr1;
+ --ptr2;
+ }
+ (*ptr1)=ptr;
+ return;
+ }
+ else
+ {
+ vect[index]=ptr;
+ ++size;
+ }
+}
+
+template<class T> void add_to_fixed_binary_array(T ptr,T *vect,int32_t &size,int32_t max)
+{
+ if(size==0)
+ {
+ fixed_array_push_back(ptr,vect,size,max);
+ return;
+ }
+ if(vect[size-1]<ptr)
+ {
+ fixed_array_push_back(ptr,vect,size,max);
+ return;
+ }
+
+ int32_t start=0;
+ int32_t end=size-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr)
+ {
+ fixed_array_insert(mid,ptr,vect,size,max);//INSERT A COPY SINCE THIS IS NON-UNIQUE CASE
+ return;
+ }
+ if(start==end)
+ {
+ if(cptr<ptr)
+ {
+ if(start+1>=size)fixed_array_push_back(ptr,vect,size,max);
+ else fixed_array_insert(start+1,ptr,vect,size,max);
+ }
+ else fixed_array_insert(start,ptr,vect,size,max);
+ return;
+ }
+
+ if(cptr>ptr)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr<ptr)
+ {
+ if(start+1>=size)fixed_array_push_back(ptr,vect,size,max);
+ else fixed_array_insert(start+1,ptr,vect,size,max);
+ }
+ else fixed_array_insert(start,ptr,vect,size,max);
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr<ptr)
+ {
+ if(end+1>=size)fixed_array_push_back(ptr,vect,size,max);
+ else fixed_array_insert(end+1,ptr,vect,size,max);
+ }
+ else fixed_array_insert(end,ptr,vect,size,max);
+ }
+ else fixed_array_push_back(ptr,vect,size,max);
+}
+
+template<class T> void add_unique_to_fixed_binary_array(T ptr,T *vect,int32_t &size,int32_t max)
+{
+ if(size==0)
+ {
+ fixed_array_push_back(ptr,vect,size,max);
+ return;
+ }
+ if(vect[size-1]<ptr)
+ {
+ fixed_array_push_back(ptr,vect,size,max);
+ return;
+ }
+
+ int32_t start=0;
+ int32_t end=size-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr)return;
+ if(start==end)
+ {
+ if(cptr<ptr)
+ {
+ if(start+1>=size)return;//WAS push_back()
+ else fixed_array_insert(start+1,ptr,vect,size,max);
+ }
+ else if(cptr>ptr)fixed_array_insert(start,ptr,vect,size,max);
+ return;
+ }
+
+ if(cptr>ptr)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr<ptr)
+ {
+ if(start+1>=size)return;//WAS push_back()
+ else fixed_array_insert(start+1,ptr,vect,size,max);
+ }
+ else if(cptr>ptr)fixed_array_insert(start,ptr,vect,size,max);
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr<ptr)
+ {
+ if(end+1>=size)return;//WAS push_back()
+ else fixed_array_insert(end+1,ptr,vect,size,max);
+ }
+ else if(cptr>ptr)fixed_array_insert(end,ptr,vect,size,max);
+ }
+ //NOTE: NO else CASE HERE BECAUSE IN THE NON-UNIQUE VERSION IT JUST PUSHED BACK
+ //AND PUSHING BACK IS HANDLED IN THE OPENING FUNCTION
+}
+
+template<class T> void add_to_local_id_vector(T ptr,svector<T> &vect)
+{
+ int32_t size=vect.size();
+ if(size==0)
+ {
+ vect.push_back(ptr);
+ return;
+ }
+ if(vect[size-1]->local_id<ptr->local_id)
+ {
+ vect.push_back(ptr);
+ return;
+ }
+
+ int32_t start=0;
+ int32_t end=size-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->local_id==ptr->local_id)return;
+ if(start==end)
+ {
+ if(cptr->local_id<ptr->local_id)
+ {
+ if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED
+ else vect.insert(start+1,ptr);
+ }
+ else if(cptr->local_id>ptr->local_id)vect.insert(start,ptr);
+ return;
+ }
+
+ if(cptr->local_id>ptr->local_id)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr->local_id<ptr->local_id)
+ {
+ if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED
+ else vect.insert(start+1,ptr);
+ }
+ else if(cptr->local_id>ptr->local_id)vect.insert(start,ptr);
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr->local_id<ptr->local_id)
+ {
+ if(end+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED
+ else vect.insert(end+1,ptr);
+ }
+ else if(cptr->local_id>ptr->local_id)vect.insert(end,ptr);
+ }
+}
+
+template<class T> void remove_from_local_id_vector(T ptr,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr==ptr)
+ {
+ vect.erase(mid);
+ return;
+ }
+
+ if(cptr->local_id>ptr->local_id)end=mid-1;
+ else start=mid+1;
+ }
+}
+
+template<class T> T get_from_local_id_vector(int32_t id,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->local_id==id)return cptr;
+ else if(cptr->local_id>id)end=mid-1;
+ else start=mid+1;
+ }
+
+ return NULL;
+}
+
+template<class T> int32_t get_index_from_local_id_vector(int32_t id,svector<T> &vect)
+{
+ int32_t start=0;
+ int32_t end=(int32_t)vect.size()-1;
+
+ T cptr;
+ int32_t mid;
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->local_id==id)return mid;
+ else if(cptr->local_id>id)end=mid-1;
+ else start=mid+1;
+ }
+
+ return -1;
+}
+
+template<class T> void add_to_short_id_vector(T ptr,svector<T> &vect)
+{
+ int16_t size=vect.size();
+ if(size==0)
+ {
+ vect.push_back(ptr);
+ return;
+ }
+ if(vect[size-1]->short_id<ptr->short_id)
+ {
+ vect.push_back(ptr);
+ return;
+ }
+
+ int16_t start=0;
+ int16_t end=size-1;
+ int16_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->short_id==ptr->short_id)return;
+ if(start==end)
+ {
+ if(cptr->short_id<ptr->short_id)
+ {
+ if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED
+ else vect.insert(start+1,ptr);
+ }
+ else if(cptr->short_id>ptr->short_id)vect.insert(start,ptr);
+ return;
+ }
+
+ if(cptr->short_id>ptr->short_id)end=mid-1;
+ else start=mid+1;
+ }
+
+ if(end<0)
+ {
+ T cptr=vect[start];
+ if(cptr->short_id<ptr->short_id)
+ {
+ if(start+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED
+ else vect.insert(start+1,ptr);
+ }
+ else if(cptr->short_id>ptr->short_id)vect.insert(start,ptr);
+ }
+ else if(end<size)
+ {
+ T cptr=vect[end];
+ if(cptr->short_id<ptr->short_id)
+ {
+ if(end+1>=size)return;//push_back() FOR UNIQUE ALREADY HANDLED
+ else vect.insert(end+1,ptr);
+ }
+ else if(cptr->short_id>ptr->short_id)vect.insert(end,ptr);
+ }
+}
+
+template<class T> void remove_from_short_id_vector(T ptr,svector<T> &vect)
+{
+ int16_t start=0;
+ int16_t end=(int16_t)vect.size()-1;
+ T cptr;
+
+ while(start<=end)
+ {
+ int16_t mid=(start+end)>>1;
+
+ T cptr=vect[mid];
+ if(cptr==ptr)
+ {
+ vect.erase(mid);
+ return;
+ }
+
+ if(cptr->short_id>ptr->short_id)end=mid-1;
+ else start=mid+1;
+ }
+}
+
+template<class T> T get_from_short_id_vector(int16_t id,svector<T> &vect)
+{
+ int16_t start=0;
+ int16_t end=(int16_t)vect.size()-1;
+ int16_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->short_id==id)
+ {
+ return cptr;
+ }
+
+ if(cptr->short_id>id)end=mid-1;
+ else start=mid+1;
+ }
+
+ return NULL;
+}
+
+template<class T> int16_t get_index_from_short_id_vector(int16_t id,svector<T> &vect)
+{
+ int16_t start=0;
+ int16_t end=(int16_t)vect.size()-1;
+ int16_t mid;
+ T cptr;
+
+ while(start<=end)
+ {
+ mid=(start+end)>>1;
+
+ cptr=vect[mid];
+ if(cptr->short_id==id)
+ {
+ return mid;
+ }
+
+ if(cptr->short_id>id)end=mid-1;
+ else start=mid+1;
+ }
+
+ return -1;
+} \ No newline at end of file
diff --git a/g_src/textlines.cpp b/g_src/textlines.cpp
new file mode 100755
index 0000000..e56515a
--- /dev/null
+++ b/g_src/textlines.cpp
@@ -0,0 +1,61 @@
+#include "platform.h"
+#include <string.h>
+#include <math.h>
+#include <iosfwd>
+#include <iostream>
+#include <ios>
+#include <streambuf>
+#include <istream>
+#include <ostream>
+#include <iomanip>
+#include <sstream>
+#include <cstdlib>
+#include <fstream>
+#include <zlib.h>
+
+#include "svector.h"
+using std::string;
+
+#include "endian.h"
+
+#include "files.h"
+
+#include "enabler.h"
+
+#include "textlines.h"
+
+#include "basics.h"
+
+extern char filecomp_buffer[20000];
+extern char filecomp_buffer2[80000];
+extern char filecomp_buffer_aux[20000];
+extern char filecomp_buffer2_aux[80000];
+
+
+void textlinesst::load_raw_to_lines(char *filename)
+{
+ clean_lines();
+
+ //LOAD THE FILE
+ std::ifstream fseed(filename);
+ if(fseed.is_open())
+ {
+ string str;
+
+ while(std::getline(fseed,str))
+ {
+ long end=str.length();
+
+ while(end>0)
+ {
+ if(isspace(str[end-1]))end--;
+ else break;
+ }
+
+ str.resize(end);
+
+ if(str.length()>0)text.add_string(str);
+ }
+ }
+ fseed.close();
+} \ No newline at end of file
diff --git a/g_src/textlines.h b/g_src/textlines.h
new file mode 100755
index 0000000..de2dbfe
--- /dev/null
+++ b/g_src/textlines.h
@@ -0,0 +1,22 @@
+#ifndef TEXTLINES_H
+#define TEXTLINES_H
+
+struct textlinesst
+{
+ stringvectst text;
+
+
+
+ void load_raw_to_lines(char *filename);
+
+ void clean_lines()
+ {
+ text.clean();
+ }
+ void copy_from(textlinesst &ot)
+ {
+ text.copy_from(ot.text);
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/g_src/texture_handler.h b/g_src/texture_handler.h
new file mode 100755
index 0000000..50b73d1
--- /dev/null
+++ b/g_src/texture_handler.h
@@ -0,0 +1,60 @@
+#ifndef TEXTURE_HANDLER_H
+#define TEXTURE_HANDLER_H
+
+#include "textlines.h"
+
+struct tile_pagest
+{
+ string token;
+
+ string filename;
+ short tile_dim_x;
+ short tile_dim_y;
+ short page_dim_x;
+ short page_dim_y;
+
+ svector<int32_t> texpos;
+ svector<int32_t> datapos;
+ svector<int32_t> texpos_gs;
+ svector<int32_t> datapos_gs;
+
+ char loaded;
+
+
+
+ tile_pagest()
+ {
+ loaded=0;
+ }
+
+ void load_graphics(string &graphics_dir);
+};
+
+class texture_handlerst
+{
+ public:
+ svector<tile_pagest *> page;
+
+ svector<int32_t> texpos;
+ svector<int32_t> datapos;
+
+ void clean();
+ void adopt_new_lines(textlinesst &lines,string &graphics_dir);
+
+ ~texture_handlerst()
+ {
+ clean();
+ }
+
+ tile_pagest *get_tile_page_by_token(string &tk)
+ {
+ int32_t t;
+ for(t=0;t<page.size();t++)
+ {
+ if(page[t]->token==tk)return page[t];
+ }
+ return NULL;
+ }
+};
+
+#endif
diff --git a/g_src/textures.cpp b/g_src/textures.cpp
new file mode 100755
index 0000000..50334ba
--- /dev/null
+++ b/g_src/textures.cpp
@@ -0,0 +1,398 @@
+#include <cassert>
+
+#include "enabler.h"
+#include "init.h"
+
+// Used to sort textures
+struct vsize_pos {
+ int h, w;
+ SDL_Surface *s;
+ long pos;
+ // Assigned texture-catalog coordinates
+ int x, y;
+
+ bool operator< (struct vsize_pos y) const {
+ // sort produces an ascending order. We want descending. Don't argue.
+ if (h > y.h) return true;
+ return false;
+ }
+};
+
+
+// Check whether a particular texture can be sized to some size,
+// assuming in RGBA 32-bit format
+bool testTextureSize(GLuint texnum, int w, int h) {
+ GLint gpu_width;
+ glBindTexture(GL_TEXTURE_2D, texnum);
+ printGLError();
+ glTexImage2D(GL_PROXY_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ printGLError();
+ glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &gpu_width);
+ printGLError();
+
+ if (gpu_width == w) return true;
+ return false;
+}
+
+// Texture catalog implementation
+void textures::upload_textures() {
+ if (uploaded) return; // Don't bother
+ if (!enabler.uses_opengl()) return; // No uploading
+ glEnable(GL_TEXTURE_2D);
+ printGLError();
+ glGenTextures(1, &gl_catalog);
+ printGLError();
+
+ // First, sort the textures by vertical size. We'll want to place the large
+ // ones first.
+ // Since we mustn't alter the raws array, first thing is to create a new one.
+ // We pretend textures are one pixel larger than they actually are in either
+ // direction, to avoid border scuffles when interpolating.
+ std::vector<vsize_pos> ordered;
+ long pos = 0;
+ for (std::vector<SDL_Surface *>::iterator it = raws.begin();
+ it != raws.end(); ++it) {
+ if (*it) {
+ vsize_pos item;
+ item.h = (*it)->h+2;
+ item.w = (*it)->w+2;
+ item.s = *it;
+ item.pos = pos;
+ ordered.push_back(item);
+ }
+ pos++;
+ }
+ sort(ordered.begin(), ordered.end());
+
+ /* Tiling algorithm:
+ **
+ ** Given a particular texture width, we pack tiles from largest to smallest
+ ** by reserving rows for tiles with a particular height or lower.
+ ** This does lead to space wastage when a row has, say, one 32x32 tile and
+ ** fifteen 16x16 tiles, but generally not very much.
+ **
+ ** Possible improvement: Allow for multiple rows of smaller tiles inside
+ ** a row that's at least twice as high as the smaller tiles are.
+ */
+
+ // Set the initial width to the minimum possible
+ int catalog_width = 0;
+ for (int i=0; i < ordered.size(); i++)
+ if (catalog_width < ordered[i].w) catalog_width = ordered[i].w;
+ const int width_increment = 4; // For speed, not that it matters.
+ int catalog_height;
+ // Figure out what the optimal texture width is
+ // This may not be actually be an approximately square texture, but for the
+ // moment that's what we're aiming for. On GPUs without the NPOT extension,
+ // rectangular textures may actulaly use less video memory.
+ // However, a square one is less likely to run into dimensional limits.
+ for(;;) {
+ int catalog_x = 0;
+ int catalog_y = 0;
+ int row_height = ordered[0].h;
+ catalog_height = row_height;
+ for (int pos = 0; pos < ordered.size(); pos++) {
+ // Check whether we must start a new row
+ if (catalog_x + ordered[pos].w > catalog_width) {
+ catalog_x = 0;
+ catalog_y = catalog_height;
+ row_height = ordered[pos].h;
+ catalog_height += row_height;
+ }
+ // Tentatively install tile at catalog_x, catalog_y
+ ordered[pos].x = catalog_x;
+ ordered[pos].y = catalog_y;
+ // Goto next tile
+ catalog_x += ordered[pos].w;
+ }
+ // If we didn't just cross "square", increment width and try again.
+ if (catalog_height > catalog_width)
+ catalog_width += width_increment;
+ else
+ break; // Otherwise we're done.
+ }
+
+#ifdef DEBUG
+ std::cout << "Ideal catalog size: " << catalog_width << "x" << catalog_height << "\n";
+#endif
+
+ // Check whether the GPU supports non-power-of-two textures
+ bool npot = false;
+ if (GLEW_ARB_texture_rectangle && GLEW_ARB_texture_non_power_of_two)
+ npot=true;
+
+ if (!npot) {
+ // Use a power-of-two texture catalog
+ int newx = 1, newy = 1;
+ while (newx < catalog_width) newx *= 2;
+ while (newy < catalog_height) newy *= 2;
+ catalog_width = newx;
+ catalog_height = newy;
+ std::cout << "GPU does not support non-power-of-two textures, using " << catalog_width << "x" << catalog_height << " catalog.\n";
+ }
+ // Check whether the GPU will allow a texture of that size
+ if (!testTextureSize(gl_catalog, catalog_width, catalog_height)) {
+ MessageBox(NULL,"GPU unable to accommodate texture catalog. Retry without graphical tiles, update your drivers, or better yet update your GPU.", "GL error", MB_OK);
+ exit(EXIT_FAILURE);
+ }
+
+ // Guess it will. Well, then, actually upload it
+ glBindTexture(GL_TEXTURE_2D, gl_catalog);
+ printGLError();
+ char *zeroes = new char[catalog_width*catalog_height*4];
+ memset(zeroes,0,sizeof(char)*catalog_width*catalog_height*4);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, catalog_width, catalog_height, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, zeroes);
+ delete[] zeroes;
+ printGLError();
+ glBindTexture(GL_TEXTURE_2D, gl_catalog);
+ printGLError();
+ GLint param = (init.window.flag.has_flag(INIT_WINDOW_FLAG_TEXTURE_LINEAR) ?
+ GL_LINEAR : GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,param);
+ printGLError();
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,param);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ printGLError();
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ printGLError();
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ printGLError();
+ // Performance isn't important here. Let's make sure there are no alignment issues.
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+ printGLError();
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ printGLError();
+ // While storing the positions to gl_texpos.
+ if (gl_texpos) delete[] gl_texpos;
+ gl_texpos = new struct gl_texpos[raws.size()];
+ for (int pos = 0; pos < ordered.size(); pos++) {
+ long raws_pos = ordered[pos].pos;
+ SDL_Surface *s = ordered[pos].s;
+ SDL_PixelFormat *f = s->format;
+ SDL_LockSurface(s);
+ // Make /real/ sure we get the GL format right.
+ unsigned char *pixels = new unsigned char[ordered[pos].w * ordered[pos].h * 4];
+ // Recall, ordered[pos].w is 2 larger than s->w because of the border.
+ for (int bx=0; bx < ordered[pos].w; bx++) {
+ int x = bx - 1;
+ if (x == -1) x++;
+ if (x == s->w) x--;
+ for (int by=0; by < ordered[pos].h; by++) {
+ int y = by - 1;
+ if (y == -1) y++;
+ if (y == s->h) y--;
+ // GL textures are loaded upside-down, Y=0 at the bottom
+ unsigned char *pixel_dst = &pixels[(ordered[pos].h - by - 1)*ordered[pos].w*4 + bx*4];
+ unsigned char *pixel_src = &((unsigned char*)s->pixels)[y*s->w*4 + x*4];
+ assert (pixel_dst < pixels + ordered[pos].w * ordered[pos].h * 4);
+ assert (pixel_src < (unsigned char*)s->pixels + s->w * s->h * 4);
+ // We convert all textures to RGBA format at load-time, further below
+ for (int i=0; i<4; i++) {
+ pixel_dst[i] = pixel_src[i];
+ }
+ }
+ }
+ // Right. Upload the texture to the catalog.
+ SDL_UnlockSurface(s);
+ glBindTexture(GL_TEXTURE_2D, gl_catalog);
+ printGLError();
+ glTexSubImage2D(GL_TEXTURE_2D, 0, ordered[pos].x, ordered[pos].y, ordered[pos].w, ordered[pos].h,
+ GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ delete[] pixels;
+ printGLError();
+ // Compute texture coordinates and store to gl_texpos for later output.
+ // To make sure the right pixel is chosen when texturing, we must
+ // pick coordinates that place us in the middle of the pixel we want.
+ //
+ // There's no real reason to use double instead of floats here, but
+ // no reason not to either, and it just might help with precision.
+ //
+ // There's a one-pixel border around each tile, so we offset by 1
+ gl_texpos[raws_pos].left = ((double)ordered[pos].x+1) / (double)catalog_width;
+ gl_texpos[raws_pos].right = ((double)ordered[pos].x+1+s->w) / (double)catalog_width;
+ gl_texpos[raws_pos].top = ((double)ordered[pos].y+1) / (double)catalog_height;
+ gl_texpos[raws_pos].bottom = ((double)ordered[pos].y+1+s->h) / (double)catalog_height;
+ }
+ // And that's that. Locked, loaded and ready for texturing.
+ printGLError();
+ uploaded=true;
+}
+
+void textures::remove_uploaded_textures() {
+ if (!uploaded) return; // Nothing to do
+ glDeleteTextures(1, &gl_catalog);
+ uploaded=false;
+}
+
+SDL_Surface *textures::get_texture_data(long pos) {
+ if (raws.size() > pos) {
+ return raws[pos];
+ } else {
+ std::cerr << "Asked for nonexistent texture data\n";
+ SDL_Surface *surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 8, 8, 32, 0, 0, 0, 0);
+ SDL_FillRect(surf, NULL, SDL_MapRGB(surf->format, 255, 0, 255));
+ raws.resize(pos+1);
+ raws[pos] = surf;
+ return raws[pos];
+ }
+}
+
+long textures::clone_texture(long src) {
+ long tx;
+
+ if (raws.size() > src && raws[src]) {
+ SDL_Surface *dst = SDL_ConvertSurface(raws[src], raws[src]->format, SDL_SWSURFACE);
+ tx=add_texture(dst);
+ }
+ else {
+ // Okay, we've been asked to clone a nonexistent texture. Riight...
+ // Fortunately add_texture doesn't look at the pointer it gets at all.
+ std::cerr << "Asked to clone nonexistent texture!\n";
+ tx=add_texture(NULL);
+ }
+
+ enabler.reset_textures();
+
+ return tx;
+}
+
+void textures::grayscale_texture(long pos) {
+ SDL_Surface *s = get_texture_data(pos);
+ if (!s) return;
+ SDL_LockSurface(s);
+ SDL_PixelFormat *f = s->format;
+ Uint32 *pixels = (Uint32*)(s->pixels);
+ if (f->BytesPerPixel != 4) {
+ std::cerr << "grayscale_texture ran into mysteriously uncanonicalized texture\n";
+ goto cleanup;
+ }
+ for (int i=0; i < s->w*s->h; i++) { // For each pixel
+ int r = (pixels[i] & f->Rmask) >> f->Rshift;
+ int g = (pixels[i] & f->Gmask) >> f->Gshift;
+ int b = (pixels[i] & f->Bmask) >> f->Bshift;
+ int alpha = (pixels[i] & f->Amask) >> f->Ashift;
+int luminosity=(int)((float)r*0.30f+(float)g*0.59f+(float)b*0.11f);
+if(luminosity<0)luminosity=0;
+if(luminosity>255)luminosity=255;
+ pixels[i] = (luminosity << f->Rshift) |
+ (luminosity << f->Gshift) |
+ (luminosity << f->Bshift) |
+ (alpha << f->Ashift);
+ }
+
+ cleanup:
+ SDL_UnlockSurface(s);
+
+ enabler.reset_textures();
+}
+
+// Converts an arbitrary Surface to something like the display format
+// (32-bit RGBA), and converts magenta to transparency if convert_magenta is set
+// and the source surface didn't already have an alpha channel.
+// It also deletes the source surface.
+//
+// It uses the same pixel format (RGBA, R at lowest address) regardless of
+// hardware.
+SDL_Surface *canonicalize_format(SDL_Surface *src, bool convert_magenta) {
+ SDL_PixelFormat fmt;
+ fmt.palette = NULL;
+ fmt.BitsPerPixel = 32;
+ fmt.BytesPerPixel = 4;
+ fmt.Rloss = fmt.Gloss = fmt.Bloss = fmt.Aloss = 0;
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ fmt.Rshift = 24; fmt.Gshift = 16; fmt.Bshift = 8; fmt.Ashift = 0;
+#else
+ fmt.Rshift = 0; fmt.Gshift = 8; fmt.Bshift = 16; fmt.Ashift = 24;
+#endif
+ fmt.Rmask = 255 << fmt.Rshift;
+ fmt.Gmask = 255 << fmt.Gshift;
+ fmt.Bmask = 255 << fmt.Bshift;
+ fmt.Amask = 255 << fmt.Ashift;
+ fmt.colorkey = 0;
+ fmt.alpha = 255;
+
+ if (src->format->Amask == 0 && convert_magenta) { // No alpha
+ SDL_SetColorKey(src, SDL_SRCCOLORKEY,
+ SDL_MapRGB(src->format, 255, 0, 255));
+ }
+ SDL_Surface *tgt = SDL_ConvertSurface(src, &fmt, SDL_SWSURFACE);
+ SDL_FreeSurface(src);
+ return tgt;
+}
+
+// Finds or creates a free spot in the texture array, and inserts
+// surface in that spot, then returns the location.
+long textures::add_texture(SDL_Surface *surface) {
+ long sz = raws.size();
+ // Look for a free spot
+ for (long pos=0; pos < sz; pos++) {
+ if (raws[pos] == NULL) {
+ raws[pos] = surface;
+ return pos;
+ }
+ }
+
+ // No free spot, make one
+ raws.push_back(surface);
+ return sz;
+}
+
+void textures::load_multi_pdim(const string &filename, long *tex_pos, long dimx,
+ long dimy, bool convert_magenta,
+ long *disp_x, long *disp_y) {
+ SDL_Surface *raw = IMG_Load(filename.c_str());
+ if (!raw) {
+ MessageBox(NULL, ("Not found: " + filename).c_str(), "Tileset not found", MB_OK);
+ exit(1);
+ }
+ SDL_Surface *src = canonicalize_format(raw, convert_magenta);
+ SDL_SetAlpha(src, 0, 255);
+ *disp_x = src->w / dimx;
+ *disp_y = src->h / dimy;
+ long idx = 0;
+ for (int y=0; y < dimy; y++) {
+ for (int x=0; x < dimx; x++) {
+ SDL_Surface *tile = SDL_CreateRGBSurface(SDL_SWSURFACE, *disp_x, *disp_y,
+ 32, src->format->Rmask,
+ src->format->Gmask,
+ src->format->Bmask,
+ src->format->Amask);
+ SDL_SetAlpha(tile, 0,255);
+ SDL_Rect pos_src;
+ pos_src.x = *disp_x * x;
+ pos_src.y = *disp_y * y;
+ pos_src.w = *disp_x;
+ pos_src.h = *disp_y;
+ SDL_BlitSurface(src, &pos_src, tile, NULL);
+ tex_pos[idx++] = add_texture(tile);
+ }
+ }
+ SDL_FreeSurface(src);
+ // Re-upload textures if necessary
+ enabler.reset_textures();
+}
+
+long textures::load(const string &filename, bool convert_magenta) {
+ SDL_Surface *raw = IMG_Load(filename.c_str());
+ if (!raw) {
+ MessageBox(NULL, ("Not found: " + filename).c_str(), "Image not found", MB_OK);
+ exit(1);
+ }
+ SDL_Surface *tex = canonicalize_format(raw, convert_magenta);
+ long pos = add_texture(tex);
+ // Re-upload if necessary
+ enabler.reset_textures();
+ return pos;
+}
+
+void textures::delete_texture(long pos) {
+ // We can't actually resize the array, as
+ // (a) it'd be slow, and
+ // (b) it'd change all the positions. Bad stuff would happen.
+ if (raws[pos]) {
+ SDL_FreeSurface(raws[pos]);
+ raws[pos] = NULL;
+ }
+}
diff --git a/g_src/ttf_manager.cpp b/g_src/ttf_manager.cpp
new file mode 100755
index 0000000..f873a40
--- /dev/null
+++ b/g_src/ttf_manager.cpp
@@ -0,0 +1,245 @@
+#include "ttf_manager.hpp"
+#include "init.h"
+#include <iostream>
+
+using namespace std;
+
+ttf_managerst ttf_manager;
+
+bool ttf_managerst::init(int ceiling, int tile_width) {
+ // Reset to a known state, clear everything
+ if ((!TTF_WasInit()) && (TTF_Init() == -1)) {
+ MessageBox(NULL, TTF_GetError(), "TTF error", MB_OK);
+ return false;
+ }
+ if (font) TTF_CloseFont(font);
+ handles.clear();
+ for (auto it = textures.cbegin(); it != textures.cend(); ++it)
+ SDL_FreeSurface(it->second);
+ textures.clear();
+ this->tile_width = tile_width;
+ this->ceiling = ceiling;
+ // Try progressively smaller point sizes until we find one that fits
+ for (int sz=20; sz > 0; sz--) {
+ font = TTF_OpenFont("data/art/font.ttf", sz);
+ if (!font) continue;
+ if (TTF_FontHeight(font) <= ceiling) {
+#ifdef DEBUG
+ cout << "Picked font at " << sz << " points for ceiling " << ceiling << endl;
+ // get the glyph metric for the letter 'M' in a loaded font
+ cout << "TTF_FontHeight " << TTF_FontHeight(font) << endl;
+ cout << "TTF_FontAscent " << TTF_FontAscent(font) << endl;
+ cout << "TTF_FontDescent " << TTF_FontDescent(font) << endl;
+ cout << "TTF_FontLineSkip " << TTF_FontLineSkip(font) << endl;
+#endif
+ int minx,maxx,miny,maxy,advance;
+ if (TTF_GlyphMetrics(font, 'M', &minx, &maxx, &miny, &maxy, &advance) == -1)
+ puts(TTF_GetError());
+ else {
+ em_width = maxx;
+#ifdef DEBUG
+ printf("minx : %d\n",minx);
+ printf("maxx : %d\n",maxx);
+ printf("miny : %d\n",miny);
+ printf("maxy : %d\n",maxy);
+ printf("advance : %d\n",advance);
+#endif
+ }
+ return true;
+ }
+ TTF_CloseFont(font);
+ }
+ // ..fine.
+ cout << "No font found!" << endl;
+ font = NULL;
+ return false;
+}
+
+static void cp437_to_unicode(const string &text, vector<Uint16> &unicode) {
+ unicode.resize(text.length() + 1);
+ int i;
+ for (i=0; i < text.size(); i++) {
+ const int cp437 = (unsigned char)text[i];
+ unicode[i] = charmap[cp437];
+ }
+ unicode[i] = 0;
+}
+
+
+int ttf_managerst::size_text(const string &text) {
+ vector<Uint16> text_unicode;
+ cp437_to_unicode(text, text_unicode);
+ int width, height;
+ TTF_SizeUNICODE(font, &text_unicode[0], &width, &height);
+ return (width + tile_width - 1) / tile_width;
+}
+
+
+ttf_details ttf_managerst::get_handle(const list<ttf_id> &text, justification just) {
+ // Check for an existing handle
+ handleid id = {text, just};
+ auto it = handles.find(id);
+ if (it != handles.end()) return it->second;
+ // Right. Make a new one.
+ int handle = ++max_handle;
+ // Split out any tabs
+ list<ttf_id> split_text;
+ for (auto it = text.cbegin(); it != text.cend(); ++it) {
+ int pos = 0;
+ int tabpos;
+ while ((tabpos = it->text.find("\t", pos)) != string::npos) {
+ ttf_id left;
+ left.fg = it->fg; left.bg = it->bg; left.bold = it->bold;
+ left.text = it->text.substr(pos, tabpos - pos);
+ split_text.push_back(left);
+ ttf_id tabber;
+ tabber.fg = tabber.bg = tabber.bold = 255;
+ split_text.push_back(tabber);
+ pos = tabpos + 1;
+ }
+ ttf_id right;
+ right.fg = it->fg; right.bg = it->bg; right.bold = it->bold;
+ right.text = it->text.substr(pos);
+ split_text.push_back(right);
+ }
+ // Find the total width of the text
+ vector<Uint16> text_unicode;
+ int ttf_width = 0, ttf_height = 0, text_width = 0;
+ for (auto it = split_text.cbegin(); it != split_text.cend(); ++it) {
+ if (it->fg == 255 && it->bg == 255 && it->bold == 255) {
+ // Tab stop
+ int tabstop = tab_width * em_width;
+ int tab_width = tabstop - ((ttf_width - 1) % tabstop) + 1;
+ ttf_width += tab_width;
+ text_width += 1;
+ } else {
+ cp437_to_unicode(it->text, text_unicode);
+ int slice_width, slice_height;
+ TTF_SizeUNICODE(font, &text_unicode[0], &slice_width, &slice_height);
+ ttf_width += slice_width;
+ text_width += it->text.size();
+ }
+ }
+ ttf_height = ceiling;
+ // Compute geometry
+ double grid_width = double(ttf_width) / tile_width;
+ double offset = just == justify_right ? text_width - grid_width :
+ just == justify_center ? (text_width - grid_width) / 2 :
+ 0;
+ if (just == justify_center && text_width % 2)
+ offset += 0.5; // Arbitrary fixup for approximate grid centering
+ double fraction, integral;
+ fraction = modf(offset, &integral);
+ // Outputs:
+ const int grid_offset = int(integral + 0.001); // Tiles to move to the right in addst
+ const int pixel_offset = int(fraction * tile_width); // Black columns to add to the left of the image
+ // const int full_grid_width = int(ceil(double(ttf_width) / double(tile_width) + fraction) + 0.1); // Total width of the image in grid units
+ const int full_grid_width = text_width;
+ const int pixel_width = full_grid_width * tile_width; // And pixels
+ assert(pixel_width >= ttf_width);
+ // Store for later
+ ttf_details ret; ret.handle = handle; ret.offset = grid_offset; ret.width = full_grid_width;
+ handles[id] = ret;
+ // We do the actual rendering in the render thread, later on.
+ todo.push_back(todum(handle, split_text, ttf_height, pixel_offset, pixel_width));
+ return ret;
+}
+
+SDL_Surface *ttf_managerst::get_texture(int handle) {
+ // Run any outstanding renders
+ if (!todo.empty()) {
+ vector<Uint16> text_unicode;
+ for (auto it = todo.cbegin(); it != todo.cend(); ++it) {
+ const int height = it->height;
+ SDL_Surface *textimg = SDL_CreateRGBSurface(SDL_SWSURFACE, it->pixel_width, height, 32, 0, 0, 0, 0);
+// #ifdef DEBUG
+// SDL_FillRect(textimg, NULL, SDL_MapRGBA(textimg->format, 255, 0, 0, 255));
+// #endif
+ // Render each of the text segments
+ int idx = 0;
+ int xpos = it->pixel_offset;
+ for (auto seg = it->text.cbegin(); seg != it->text.cend();) {
+ const ttf_id &text = *seg;
+ ++seg;
+ ++idx;
+ if (text.fg == 255 && text.bg == 255 && text.bold == 255) {
+ // Skip to tab stop
+ int tabstop = tab_width * em_width;
+ int tab_width = tabstop - ((xpos - 1) % tabstop) + 1;
+ xpos += tab_width;
+ continue;
+ }
+ if (text.text.size() <= 0)
+ continue;
+ cp437_to_unicode(text.text, text_unicode);
+ const int fg = (text.fg + text.bold * 8) % 16;
+ SDL_Color fgc = {Uint8(enabler.ccolor[fg][0]*255),
+ Uint8(enabler.ccolor[fg][1]*255),
+ Uint8(enabler.ccolor[fg][2]*255)};
+ const int bg = text.bg % 16;
+ Uint32 bgc = SDL_MapRGB(textimg->format,
+ Uint8(enabler.ccolor[bg][0]*255),
+ Uint8(enabler.ccolor[bg][1]*255),
+ Uint8(enabler.ccolor[bg][2]*255));
+#ifdef DEBUG
+ // SDL_Color white = {255,255,255};
+ // Uint32 red = SDL_MapRGB(textimg->format, 255,0,0);
+ // fgc = white;
+ // bgc = red;
+#endif
+ if (idx == 0) {
+ // Fill in the left side
+ SDL_Rect left = {0, 0, Sint16(xpos), Sint16(height)};
+ SDL_FillRect(textimg, &left, bgc);
+ } else if (seg == it->text.cend()) {
+ // Fill in the right side
+ SDL_Rect right = {Sint16(xpos), 0, Sint16(it->pixel_width), Sint16(height)};
+ SDL_FillRect(textimg, &right, bgc);
+ }
+ // Render the TTF segment
+ SDL_Surface *textimg_seg = TTF_RenderUNICODE_Blended(font, &text_unicode[0], fgc);
+ // Fill the background color of this part of the textimg
+ SDL_Rect dest = {Sint16(xpos), 0, Sint16(textimg_seg->w), Sint16(height)};
+ SDL_FillRect(textimg, &dest,
+ SDL_MapRGB(textimg->format,
+ // Uint8(255),
+ // Uint8(255),
+ // Uint8(255)));
+ Uint8(enabler.ccolor[bg][0]*255),
+ Uint8(enabler.ccolor[bg][1]*255),
+ Uint8(enabler.ccolor[bg][2]*255)));
+ // And copy the TTF segment over.
+ SDL_Rect dest2 = {Sint16(xpos), 0, 0, 0};
+ SDL_BlitSurface(textimg_seg, NULL, textimg, &dest2);
+ // Ready for next segment.
+ xpos += textimg_seg->w;
+ SDL_FreeSurface(textimg_seg);
+ }
+ // ..and make the whole thing display format. Phew!
+ SDL_Surface *textimg_2 = SDL_DisplayFormat(textimg);
+#ifdef DEBUG
+ // cout << "Rendering \"" << text.text << "\" at height " << box2->h << endl;
+ // cout << " width " << textimg->w << " in box of " << box->w << endl;
+#endif
+ SDL_FreeSurface(textimg);
+ // Store it for later.
+ textures[it->handle] = textimg_2;
+ }
+ todo.clear();
+ }
+ // Find the li'l texture
+ SDL_Surface *tex = textures[handle];
+ if (!tex) {
+ cout << "Missing/broken TTF handle: " << handle << endl;
+ }
+ return tex;
+}
+
+void ttf_managerst::gc() {
+ // Just delete everything, for now.
+ for (auto it = textures.begin(); it != textures.end(); ++it)
+ SDL_FreeSurface(it->second);
+ textures.clear();
+ handles.clear();
+ todo.clear();
+}
diff --git a/g_src/ttf_manager.hpp b/g_src/ttf_manager.hpp
new file mode 100755
index 0000000..8316c5a
--- /dev/null
+++ b/g_src/ttf_manager.hpp
@@ -0,0 +1,101 @@
+#ifndef TTF_MANAGER_HPP
+#define TTF_MANAGER_HPP
+
+#include "init.h"
+#include "enabler.h"
+#ifdef __APPLE__
+#include <SDL_ttf/SDL_ttf.h>
+#else
+#include <SDL/SDL_ttf.h>
+#endif
+#include <unordered_map>
+#include <list>
+
+using std::unordered_map;
+using std::list;
+
+struct handleid {
+ list<ttf_id> text;
+ justification just;
+
+ bool operator< (const handleid &other) const {
+ if (text != other.text) return text < other.text;
+ return just < other.just;
+ }
+
+ bool operator== (const handleid &other) const {
+ return just == other.just && text == other.text;
+ }
+};
+
+namespace std {
+ template<> struct hash<struct handleid> {
+ size_t operator()(handleid val) const {
+ size_t h = 0;
+ auto end = val.text.cend();
+ for (auto it = val.text.cbegin(); it != end; ++it) {
+ h += hash<ttf_id>()(*it);
+ }
+ return h + val.just;
+ }
+ };
+};
+
+struct ttf_details {
+ int handle;
+ int offset;
+ int width;
+};
+
+class ttf_managerst {
+ TTF_Font *font;
+ int max_handle;
+ int tile_width, ceiling;
+ double tab_width;
+ int em_width;
+ unordered_map<handleid, ttf_details> handles;
+ unordered_map<int, SDL_Surface*> textures;
+ struct todum {
+ int handle;
+ list<ttf_id> text;
+ int height;
+ int pixel_offset, pixel_width;
+ todum(int handle, const list<ttf_id> &t, int h, int po, int pw) :
+ handle(handle), text(t), height(h), pixel_offset(po), pixel_width(pw) {}
+ };
+ list<todum> todo;
+public:
+ ttf_managerst() {
+ font = NULL;
+ max_handle = 1;
+ tab_width = 2;
+ em_width = 8;
+ }
+ ~ttf_managerst() {
+ for (auto it = textures.cbegin(); it != textures.cend(); ++it)
+ SDL_FreeSurface(it->second);
+ if (font) TTF_CloseFont(font);
+ }
+ bool init(int ceiling, int tile_width);
+ bool was_init() const { return font != NULL; }
+ // Return the expected size of a bit of text, in tiles.
+ int size_text(const string &text);
+ ttf_details get_handle(const list<ttf_id> &text, justification just);
+ // Returns rendered text. Renders too, if necessary.
+ // The returned SDL_Surface is owned by the ttf_managerst.
+ SDL_Surface *get_texture(int handle);
+ // Garbage-collect ttf surfaces
+ void gc();
+ // Set tab-stop width (in ems, i.e. tile widths)
+ void set_tab_width(double width) { tab_width = width; }
+ // Check if TTF is currently active
+ bool ttf_active() const {
+ return was_init() &&
+ (::init.font.use_ttf == ttf_on ||
+ (::init.font.use_ttf == ttf_auto && ::init.font.ttf_limit <= ceiling));
+ }
+};
+
+extern ttf_managerst ttf_manager;
+
+#endif
diff --git a/g_src/win32_compat.cpp b/g_src/win32_compat.cpp
new file mode 100755
index 0000000..44d6ace
--- /dev/null
+++ b/g_src/win32_compat.cpp
@@ -0,0 +1,184 @@
+#include <string>
+
+#include "enabler.h"
+#include "platform.h"
+#ifndef WIN32
+# include <sys/types.h>
+# include <sys/stat.h>
+# include <sys/time.h>
+# include <signal.h>
+# include <errno.h>
+# include <stdio.h>
+# include <string.h>
+# ifdef __APPLE__
+# include "osx_messagebox.h"
+# elif defined(unix)
+# include <gtk/gtk.h>
+# endif
+#endif
+
+#ifndef WIN32
+BOOL CreateDirectory(const char* pathname, void*)
+{
+ if (mkdir(pathname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
+ if (errno != EEXIST) {
+ std::string emsg = "mkdir(";
+ emsg.append(pathname);
+ emsg.append(") failed");
+ perror(emsg.c_str());
+ }
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+BOOL DeleteFile(const char* filename)
+{
+ return !unlink(filename);
+}
+
+void ZeroMemory(void* dest, int len)
+{
+ memset(dest, 0, len);
+}
+
+/* Returns milliseconds since 1970
+ * Wraps every 24 days (assuming 32-bit signed dwords)
+ */
+DWORD GetTickCount()
+{
+ struct timeval tp;
+ gettimeofday(&tp, NULL);
+ return (tp.tv_sec * 1000) + (tp.tv_usec / 1000);
+}
+
+char* itoa(int value, char* result, int base)
+{
+ // check that the base is valid
+ if (base < 2 || base > 16) { *result = 0; return result; }
+
+ char* out = result;
+ int quot = value;
+
+ do
+ {
+ *out = "0123456789abcdef"[ /*std::*/abs(quot % base) ];
+ ++out;
+ quot /= base;
+ }
+ while (quot);
+
+ if (value < 0) *out++ = '-';
+
+ std::reverse(result, out);
+ *out = 0;
+ return result;
+}
+
+// Fills performanceCount with microseconds passed since 1970
+// Wraps in twenty-nine thousand years or so
+BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount)
+{
+ struct timeval tp;
+ gettimeofday(&tp, NULL);
+ performanceCount->QuadPart = ((long long)tp.tv_sec * 1000000) + tp.tv_usec;
+ return TRUE;
+}
+
+BOOL QueryPerformanceFrequency(LARGE_INTEGER* performanceCount)
+{
+ /* A constant, 10^6, as we give microseconds since 1970 in
+ * QueryPerformanceCounter. */
+ performanceCount->QuadPart = 1000000;
+
+ return TRUE;
+}
+
+int MessageBox(HWND *dummy, const char *text, const char *caption, UINT type)
+{
+ bool toggle_screen = false;
+ int ret = IDOK;
+ if (enabler.is_fullscreen()) {
+ enabler.toggle_fullscreen();
+ toggle_screen = true;
+ }
+# ifdef __APPLE__ // Cocoa code
+ if (type & MB_YESNO) {
+ ret = CocoaAlertPanel(caption, text, "Yes", "No", NULL);
+ ret = (ret == 0 ? IDNO : IDYES);
+ } else {
+ CocoaAlertPanel(caption, text, "OK", NULL, NULL);
+ }
+# else // GTK code
+ if (getenv("DISPLAY")) {
+ // Have X, will dialog
+ GtkWidget *dialog = gtk_message_dialog_new(NULL,
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ type & MB_YESNO ?
+ GTK_MESSAGE_QUESTION :
+ GTK_MESSAGE_ERROR,
+ type & MB_YESNO ?
+ GTK_BUTTONS_YES_NO :
+ GTK_BUTTONS_OK,
+ "%s", text);
+ gtk_window_set_position((GtkWindow*)dialog, GTK_WIN_POS_CENTER_ALWAYS);
+ gtk_window_set_title((GtkWindow*)dialog, caption);
+ gint dialog_ret = gtk_dialog_run(GTK_DIALOG(dialog));
+ gtk_widget_destroy(dialog);
+ while (gtk_events_pending())
+ gtk_main_iteration();
+
+ if (type & MB_YESNO) {
+ switch (dialog_ret) {
+ default:
+ case GTK_RESPONSE_DELETE_EVENT:
+ case GTK_RESPONSE_NO:
+ ret = IDNO;
+ break;
+ case GTK_RESPONSE_YES:
+ ret = IDYES;
+ break;
+ }
+ }
+ } else {
+ // Use curses
+ init_curses();
+ erase();
+ gps.force_full_display_count = 1;
+ wattrset(*stdscr_p, A_NORMAL | COLOR_PAIR(1));
+
+ mvwaddstr(*stdscr_p, 0, 5, caption);
+ mvwaddstr(*stdscr_p, 2, 2, text);
+ nodelay(*stdscr_p, false);
+ if (type & MB_YESNO) {
+ mvwaddstr(*stdscr_p, 5, 0, "Press 'y' or 'n'.");
+ refresh();
+ while (1) {
+ char i = wgetch(*stdscr_p);
+ if (i == 'y') {
+ ret = IDYES;
+ break;
+ }
+ else if (i == 'n') {
+ ret = IDNO;
+ break;
+ }
+ }
+ }
+ else {
+ mvwaddstr(*stdscr_p, 5, 0, "Press any key to continue.");
+ refresh();
+ wgetch(*stdscr_p);
+ }
+ nodelay(*stdscr_p, -1);
+ }
+# endif
+
+ if (toggle_screen) {
+ enabler.toggle_fullscreen();
+ }
+
+ return ret;
+}
+#endif