+ if (debug) {
+ counter_text.Render(viewport);
+ position_text.Render(viewport);
+ orientation_text.Render(viewport);
+ if (aim_world) {
+ block_text.Render(viewport);
+ } else if (aim_entity) {
+ entity_text.Render(viewport);
+ }
+ }
+
+ if (msg_timer.Running()) {
+ messages.Render(viewport);
+ }
+
+ hud.Render(viewport);
+}
+
+
+Keymap::Keymap()
+: codemap{ NONE } {
+
+}
+
+void Keymap::Map(SDL_Scancode scancode, Action action) {
+ if (scancode > MAX_SCANCODE) {
+ throw std::runtime_error("refusing to map scancode: too damn high");
+ }
+ codemap[scancode] = action;
+}
+
+Keymap::Action Keymap::Lookup(SDL_Scancode scancode) {
+ if (scancode < NUM_SCANCODES) {
+ return codemap[scancode];
+ } else {
+ return NONE;
+ }
+}
+
+
+void Keymap::LoadDefault() {
+ Map(SDL_SCANCODE_UP, MOVE_FORWARD);
+ Map(SDL_SCANCODE_W, MOVE_FORWARD);
+ Map(SDL_SCANCODE_DOWN, MOVE_BACKWARD);
+ Map(SDL_SCANCODE_S, MOVE_BACKWARD);
+ Map(SDL_SCANCODE_LEFT, MOVE_LEFT);
+ Map(SDL_SCANCODE_A, MOVE_LEFT);
+ Map(SDL_SCANCODE_RIGHT, MOVE_RIGHT);
+ Map(SDL_SCANCODE_D, MOVE_RIGHT);
+ Map(SDL_SCANCODE_SPACE, MOVE_UP);
+ Map(SDL_SCANCODE_RSHIFT, MOVE_UP);
+ Map(SDL_SCANCODE_LSHIFT, MOVE_DOWN);
+ Map(SDL_SCANCODE_LCTRL, MOVE_DOWN);
+ Map(SDL_SCANCODE_RCTRL, MOVE_DOWN);
+
+ Map(SDL_SCANCODE_Q, BLOCK_FACE);
+ Map(SDL_SCANCODE_E, BLOCK_TURN);
+ Map(SDL_SCANCODE_TAB, BLOCK_NEXT);
+ Map(SDL_SCANCODE_RIGHTBRACKET, BLOCK_NEXT);
+ Map(SDL_SCANCODE_LEFTBRACKET, BLOCK_PREV);
+
+ Map(SDL_SCANCODE_INSERT, BLOCK_PLACE);
+ Map(SDL_SCANCODE_RETURN, BLOCK_PLACE);
+ Map(SDL_SCANCODE_MENU, BLOCK_PICK);
+ Map(SDL_SCANCODE_DELETE, BLOCK_REMOVE);
+ Map(SDL_SCANCODE_BACKSPACE, BLOCK_REMOVE);
+
+ Map(SDL_SCANCODE_N, TOGGLE_COLLISION);
+ Map(SDL_SCANCODE_F1, TOGGLE_VISUAL);
+ Map(SDL_SCANCODE_F3, TOGGLE_DEBUG);
+ Map(SDL_SCANCODE_F4, TOGGLE_AUDIO);
+
+ Map(SDL_SCANCODE_ESCAPE, EXIT);
+}
+
+
+void Keymap::Load(std::istream &is) {
+ TokenStreamReader in(is);
+ std::string key_name;
+ std::string action_name;
+ SDL_Scancode key;
+ Action action;
+ while (in.HasMore()) {
+ if (in.Peek().type == Token::STRING) {
+ in.ReadString(key_name);
+ key = SDL_GetScancodeFromName(key_name.c_str());
+ } else {
+ key = SDL_Scancode(in.GetInt());
+ }
+ in.Skip(Token::EQUALS);
+ in.ReadIdentifier(action_name);
+ action = StringToAction(action_name);
+ if (in.HasMore() && in.Peek().type == Token::SEMICOLON) {
+ in.Skip(Token::SEMICOLON);
+ }
+ Map(key, action);
+ }
+}
+
+void Keymap::Save(std::ostream &out) {
+ for (unsigned int i = 0; i < NUM_SCANCODES; ++i) {
+ if (codemap[i] == NONE) continue;
+
+ const char *str = SDL_GetScancodeName(SDL_Scancode(i));
+ if (str && *str) {
+ out << '"';
+ while (*str) {
+ if (*str == '"') {
+ out << "\\\"";
+ } else {
+ out << *str;
+ }
+ ++str;
+ }
+ out << '"';
+ } else {
+ out << i;
+ }
+
+ out << " = " << ActionToString(codemap[i]) << std::endl;;