luvcraft/clim/commands.lisp
The window layer. Fullscreen belongs to the window rather than to anything inside it, and Shift-Tab is the gesture that gets the keyboard back from whatever has taken it -- including a shell reading raw keys, which is exactly the surface that must not be able to swallow it.
Commands run on the canvas thread. start-tracy initially calls whichever
thread invokes it "main", which is right during process startup but would
give this live-started lane the wrong ownership name.
Export session's direct-display Vulkan timing data, when it has any.
Control-Q quits from anywhere, including modal focus. On a KMSDRM console there is no window manager to deliver a close request, so without a quit key the game owns the machine until someone kills it over SSH. It lives in the window layer for the same reason Shift-Tab does: no surface may be able to swallow it. Q is the layout's letter q, wherever that key sits -- gestures match the unshifted character, so a Dvorak console quits from its own Q.
Keyboard equivalents of the pointer buttons, for consoles and laptops without a working click.
Bind place to QWERTY E's physical key, independently of its layout text.
Clear the older character bindings too when this definition is loaded into a live image. On Wayland a Dvorak physical D carries both key name :D and character #\e; a #\e place binding would outrank walking right.
TrackPoint look without a button: M captures and releases the pointer by keyboard alone.
Named but unbound: escape now shows the keymap, which releases the pointer on its way. This stays reachable by name, from a listener or a script.
The quickbar is how many slots the number row reaches, while the block a slot names is looked up in the whole inventory: a slot past the end of the bar selects nothing rather than something further down the list.
The number row selects a quickbar slot. Ten commands would say the same
thing ten times; a keystroke item of type :function instead builds the
command object for the digit that was pressed, which is the ordinary CLIM
way to bind a family of keys to one verb with an argument. The 0 key ends
the row where it sits on the keyboard, as the tenth slot.
Movement.
A direction key is a start and a stop rather than a state someone reads out of a key table later, so what the game holds is the urge itself: a rider on an animal and a player on their own feet run the same commands and set the same intent, and a gamepad or a recorded demo could run them too.
Which key urges which direction. The arrows are deliberately absent:
they belong to looking (see *LOOK-KEYS*), a mouse for a console whose
pointer has no working buttons.
Bound with :ANY because a movement key means the same thing however it is modified: Shift-W is a player sprinting forward, not a player pressing some other key.
Bind every walking key to its start on the way down and its stop on the up.
Definition reloads change the live tables too, so clear both layouts before installing the currently configured one.
Looking.
The arrow keys turn the camera the way holding a mouse-look would: a
start and a stop urging a look intent that advance-luvcraft-keyboard-look
integrates every frame. They live in the world layer rather than the
movement table so that a ridden animal, whose focus offers exactly the
movement vocabulary, is steered with WASD and never has its camera
wrenched by a stray arrow.
Bind every arrow to its look on the way down and its stop on the up.
A rider's focus offers exactly the movement table, so steering an animal and walking are the same commands reaching the same intent. Everything else a rider presses still falls to the ride itself, which wants none of it.
At a terminal.
A wall in shell mode gives every key to the PTY, which is what makes it a
shell and not a menu; so the keys that change what the wall *is* have to be
ones no shell wants. The command modifier is that: a terminal never sees
it, and on this platform it is already how one switches between things.
The keystroke that chooses mode, by its place in the wall's own mode list.
Bind each wall mode to the command modifier and its slot number.
The wall's own chooser asks what key reaches a mode rather than printing a number and hoping. Specializing on SYMBOL beats the core's T default.
(name (&rest lambda-list) documentation &body body)(session)Toggle SESSION's inventory view, returning true when one is available. LUVCRAFT/CORE has no UI dependency. LUVCRAFT/MCCLIM supplies the session method.
(session)(session)(session)Slide SESSION's metabar of knobs in or out, returning true when one is available. LUVCRAFT/MCCLIM supplies the session method.
(session)(session)(&key (application-name "luv"))Load the Tracy client, start the profiler, and answer whether it is running. The client collects on demand, so starting it does not begin a capture: it makes this image discoverable, and zones start recording when a viewer connects. Leaving it started is the intended state for a durable image.
(name)Name the calling thread in Tracy's timeline, if the profiler is running. Worker threads are worth naming as they start: an unnamed thread still gets a lane, but the lane is a thread id rather than a job. A thread that starts before START-TRACY keeps the anonymous lane, so start Tracy before the session whose threads…
(&optional pathname)(&optional pathname)A native destination with a lifetime and frame clock.
(canvas enabled)Give CANVAS its whole display, or hand it back to the window manager.
Logical negation of one test or raw truth value.
(session)Where the in-game timing command writes its latest KMS presentation run.
(session &optional (pathname *presentation-timing-pathname*))A MuPDF context: its allocator, its store, and its error stack.
Logical conjunction of tests and raw truth values.
(context pathname)(session)Request SESSION's one orderly teardown beside its native canvas thread. Native close and commands may call this without waiting. Exactly one worker runs the PLAY-level quit callback when present, or the session teardown itself otherwise; repeated requests still defer native close to that same owner.
(session action)Logical disjunction of tests and raw truth values.
(session)(canvas enabled)Capture or release relative pointer motion for CANVAS.
Test whether one compatible scalar is at most another.
(inventory)(session number)The non-negative remainder of integer division.
(body &optional (detail "superseded"))(intent urge)(layout)How the children of a list are arranged.
Which key urges which direction. The arrows are deliberately absent: they belong to looking (see *LOOK-KEYS*), a mouse for a console whose pointer has no working buttons. Bound with :ANY because a movement key means the same thing however it is modified: Shift-W is a player sprinting forward, not a player pressing…
A simple Org table without formulas.
(session seconds)Which arrow urges the camera which way.
(focus event)Return the command table focused FOCUS offers for EVENT, or NIL for none. A focus with no table takes every key that the window layer did not claim, which is what a shell in raw mode wants: its letters are text, not verbs. A focus which does want verbs answers with a table, and inheritance -- rather than the order…
A player mounted on an animal, going where it goes. The rider steers with the session's own movement intent. Going forward is going forward whether the player's legs or an animal's are doing it, so a mount reads the same urges the player controller would have read rather than keeping a second copy of them.
(display session mode)Select DISPLAY's focused wall MODE. The built-in modes are the EQL-specialized symbols :SHELL and :FILM. LUVCRAFT/MCCLIM adds an :AFTER method which supplies the film browser, while the display continues to own focus and movie lifetime.
The wall modes the hotbar offers, in slot order. A presentation layer which teaches CHANGE-TERMINAL-DISPLAY-MODE a new mode appends it here and gets a numbered slot; nothing else has to change.
Test whether one compatible scalar is less than another.
(thing)Return a short string naming the keystroke that reaches THING, or NIL. A control which draws its own key hint would be inventing one: the keys are decided in the command layer above, so the drawing asks rather than guesses, and a rebound key changes the label on the button.
(gesture)
The verbs. Each one is the body that
handle-canvas-eventused to run inline behind an EQ test on a key name, now carrying its own name, its own human label, and its own keystroke as data in a table.