Un-ignored: the dev drive is the ground truth the restoration and emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio content). Kept in-repo for the pod-owner community. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
160 lines
4.6 KiB
Objective-C
160 lines
4.6 KiB
Objective-C
;**
|
|
;** BRIEF -- Basic Reconfigurable Interactive Editing Facility
|
|
;**
|
|
;** Written by Dave Nanian and Michael Strickman.
|
|
;**
|
|
|
|
;**
|
|
;** repeat.m:
|
|
;**
|
|
;** This macro prompts for a number which it uses as a "repeat prefix",
|
|
;** repeating the following for that number of times (default = 1). If
|
|
;** the command keystroke is bound to "repeat", the current repeat count
|
|
;** is multiplied by four.
|
|
;**
|
|
;** Since keystroke macros are handled at the "process" level (by the
|
|
;** standard keyboard handling routine), we have to simulate them if the
|
|
;** user chooses playback as the command to be repeated. Note that a
|
|
;** keystroke macro with an "undo" command in it will not repeat properly,
|
|
;** since undo cannot be called within an undoable command.
|
|
;**
|
|
;** This method does not work (except in the case of keystroke macros)
|
|
;** if the command prompts the user for any reason, nor does it work for
|
|
;** inserting numeric characters (they are interpreted as part of the
|
|
;** repeat count). As always, the Esc key will get you out.
|
|
;**
|
|
;** Revision history:
|
|
;** -----------------
|
|
|
|
(macro repeat
|
|
(
|
|
(int repeat_count ;** The number of times to repeat.
|
|
key_value ;** The complete value of the key read.
|
|
ascii_value ;** The ascii value of the key (lower byte).
|
|
_rep_done ;** Exit flag.
|
|
first ;** Is this the first numeric keypress?
|
|
)
|
|
(string sequence ;** The key sequence we're looking up.
|
|
partial ;** Multiple keystroke place holder.
|
|
assignment ;** Command that sequence is assigned to.
|
|
)
|
|
(global _rep_done)
|
|
|
|
;**
|
|
;** Initialize the repeat count and the "first" flag and display
|
|
;** the first prompt.
|
|
;**
|
|
|
|
(= first (= repeat_count 1))
|
|
(message "Repeat count = 1: type count or command.")
|
|
(= _rep_done 0)
|
|
|
|
;**
|
|
;** This loop processes the repeat count keystrokes. While
|
|
;** valid numeric keys are pressed, we increase the repeat count
|
|
;** in a simple fashion. If a non-numeric key is pressed, we
|
|
;** check to see if it is "repeat". If so, the current repeat
|
|
;** count is multiplied by four and "first" is set to TRUE,
|
|
;** allowing the user to reset the count, if necessary.
|
|
;**
|
|
|
|
(while (! _rep_done)
|
|
(
|
|
(while (== (= key_value (read_char)) -1))
|
|
(= ascii_value (& key_value 0xff))
|
|
|
|
(if (== key_value (key_to_int "<Esc>"))
|
|
(= _rep_done 1)
|
|
;else
|
|
(if (&& (>= ascii_value 48) (<= ascii_value 57))
|
|
(
|
|
;**
|
|
;** If this is the first keystroke, start count at 0.
|
|
;**
|
|
|
|
(if first
|
|
(= first (= repeat_count 0))
|
|
)
|
|
(= repeat_count (+ (* repeat_count 10) (- ascii_value 48)))
|
|
(message "Repeat count = %u: type count or command." repeat_count)
|
|
)
|
|
;else
|
|
(
|
|
;**
|
|
;** If we have a possible command string, we've got
|
|
;** to check and see if it's a real command. If
|
|
;** inq_assignment returns "ambiguous", we're only
|
|
;** partially down a complicated keystroke sequence.
|
|
;** If the command is "repeat", ignore it and multiply
|
|
;** the repeat count by 4. Otherwise, we have a command
|
|
;** to repeat, so we exit this loop.
|
|
;**
|
|
|
|
(sprintf partial "#%d" key_value)
|
|
(+= sequence partial)
|
|
|
|
(if (!= (= assignment (inq_assignment sequence)) "ambiguous")
|
|
(if (== assignment "repeat")
|
|
(
|
|
(*= repeat_count 4)
|
|
(message "Repeat count = %u: type count or command." repeat_count)
|
|
(= first 1)
|
|
(= sequence "")
|
|
)
|
|
;else
|
|
(if (== assignment "nothing")
|
|
(
|
|
(beep)
|
|
(= sequence "")
|
|
)
|
|
;else
|
|
(= _rep_done 1)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
;**
|
|
;** This page of code executes the keystroke command. First,
|
|
;** we check to see if the person pressed Esc -- if so, the command
|
|
;** is cancelled. Otherwise, we repeat the number of times
|
|
;** specified by repeat_count.
|
|
;**
|
|
|
|
(if (== key_value (key_to_int "<Esc>"))
|
|
(message "Command cancelled.")
|
|
;else
|
|
(
|
|
(message "")
|
|
(register_macro 7 "_repeat_halt")
|
|
(= _rep_done 0)
|
|
|
|
(while (&& (! _rep_done) (above repeat_count 0))
|
|
(
|
|
(-- repeat_count)
|
|
(execute_macro assignment)
|
|
)
|
|
)
|
|
(unregister_macro 7 "_repeat_halt")
|
|
|
|
(if _rep_done
|
|
(message "Repeat halted.")
|
|
;else
|
|
(message "Repeat completed.")
|
|
)
|
|
)
|
|
)
|
|
)
|
|
)
|
|
|
|
(macro _repeat_halt
|
|
(
|
|
(= _rep_done 1)
|
|
(returns 0)
|
|
)
|
|
)
|