wiki:InputRework

Version 2 (modified by takkaria, 9 years ago) (diff)

--

One day, takkaria got bored of Angband's hacky input layer and started thinking about something better. A few years later...

Current situation

There are keymaps and macros.

  • Macros are mostly used by the game to port platform-specific keycodes to keycodes the game can understand. They are always active.
  • Keymaps are used to map keys to other key sequences, and are active only when the game expects a command.

So, generally, input goes something like this: keycode (-> macro)? (-> keymap)? -> string of characters -> C command.

Macros end up looking like:

'2' => { ";2" }
'^E' => { "\e\e\er1q4" }

This is a bit horrible.

Proposed situation

Keys are mapped (in pref files) to a set of function calls, such as:

(simple)
'z' => { zap() }
'm' => { cast() }
';' => { walk() }

(more macro-like)
'2' => { walk(DOWN) }
'M' => { cast("Magic Missile") }

(chained commands)
'^E' => { read("Phase Door"), quaff("Healing") }

The functions thus called then check what paramaters they have:

  • pointer to an object_type: (internal use) just use that object
  • strings: search to find the relevant item, in inventory or on floor
  • nothing: prompt for the right item

To map some across, we might need macros like NEAREST_MONSTER or DEFAULT_AMMO, e.g.

'f' => { fire() }
'\'' => { fire(DEFAULT_AMMO, NEAREST_MONSTER) }

The relevant frontend UI code should be dealing with the platform keycode -> angband keycode mapping, so the game will just get a key, find the relevant command chain, and run it.

Other uses

Apart from being a lot nicer conceptually, it would make writing testing scripts pretty easy.

There could be a macro wizard which records the actions you take and then sets them to happen on a given keypress. (The game would record quaff("Cure Light Wounds") rather than 'q0'). That would be a lot nicer. (We'd need to keep a distinction between user-defined key mappings and game-defined ones, though.)