Files
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
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>
2026-07-04 19:41:15 -05:00

503 lines
12 KiB
Objective-C

;**
;** BRIEF -- Basic Reconfigurable Interactive Editing Facility
;**
;** Written by Dave Nanian and Michael Strickman.
;**
;** help.m:
;**
;** This macro contains the BRIEF help system. Display of menus and the like
;** is handled by the BRIEF dialog manager.
;**
#include "dialog.h"
#define FIRST_MENU_LINE 3
#define FIRST_MENU_COL 20
(extern to_top
add_to_path
)
;**
;** help:
;**
;** This macro is used as the main help command. It's called when
;** the user presses Alt-h.
;**
(macro help
(
(int _user_kbd)
(global _user_kbd)
(= _user_kbd (inq_keyboard))
(process_help_menu "Help Menu" "help.mnu")
)
)
;**
;** _context_help:
;**
;** This macro is used as the "help" registered macro. It is called
;** when a prompt is displayed on the status line and the user presses
;** Alt-h. Write a replacement macro if you want your own help to be
;** be available for your own commands. The macro should check if the
;** last command is one of your macros, and if so call display_help
;** with the name of your help file; if not, just call _context_help
;** (so that all replacement macros are eventually called).
;**
(macro _context_help
(
(= _user_kbd (inq_keyboard))
(display_help (inq_command))
)
)
;**
;** process_help_menu:
;**
;** This macro takes four parameters: the buffer name, file name,
;** height and width of the menu. It sets things up and calls the
;** dialog manager to deal with the actual display and manipulation of
;** the menus. (If height & width are omitted, menu is sized
;** automatically based on the contents of the menu buffer.)
;**
(macro process_help_menu
(
(string buf_name
file_name
)
(int height
width
startline
startcol
)
(get_parm 0 buf_name)
(get_parm 1 file_name)
(get_parm 2 height)
(get_parm 3 width)
;**
;** Successive menus are offset by a constant amount from the
;** first one. The dialog manager automatically keeps track of
;** the current menu level. Note that if height and width are
;** omitted, height == startline and width == startcol.
;**
(+= height (= startline (+ FIRST_MENU_LINE _dialog_level)))
(+= width (= startcol (+ FIRST_MENU_COL (* _dialog_level 2))))
;**
;** Here we call the dialog manager to create the help menu.
;** Whenever an interesting event occurs, the dialog manager will
;** call process_help_event.
;**
;** Note that process_help_event function may call this
;** routine to display an additional menu.
;**
(_process_menu startcol height width startline
buf_name "Select a Category" file_name
NULL "process_help_event" TRUE)
(returns TRUE)
)
)
;**
;** process_help_event:
;**
;** Action macro called by the dialog manager. Used to add buttons
;** to the menu or handle picking from the menu.
;**
(macro process_help_event
(
(int key)
(string action)
(get_parm 0 key)
;** If a menu button was picked, we parse the action off
;** the menu button and execute it.
(if (== key DIALOG_PICK_MENU)
(
(get_parm 2 action)
(execute_macro (substr action (+ (index action ";") 1)))
)
;else
(if (== key DIALOG_CREATE_MENU)
(
(get_parm 2 action)
(_help_add_button action)
)
)
)
(returns TRUE)
)
)
;**
;** display_help:
;**
;** display_help takes a help keyword and displays the appropriate
;** help information in an overlapping window. It uses the global
;** variable _dialog_level to tie the grey - and Esc keystrokes in
;** with the rest of the menu package (grey - will remove the window,
;** and Esc will remove windows until the _dialog_level is 0).
;**
;** The optional second parameter is the name of the help file.
;**
(macro display_help
(
(int orig_buffer
file_buffer
)
(string topic
commands
)
(= commands "help.txt")
(get_parm 1 commands)
(if (= file_buffer (create_buffer "Help File" (add_to_path _dialog_dir commands) 1))
(
(get_parm 0 topic)
(message "Locating help text...")
(= orig_buffer (inq_buffer))
(set_buffer file_buffer)
(tabs 3)
(if (|| (search_fwd (+ (+ "\xc" topic) "\xc")) (search_back (+ (+ "\xc" topic) "\xc")))
(
(int loc)
(message "Help display for %s." topic)
(if (= loc (index (= commands (read)) "\xc\""))
(= commands (substr commands (+ loc 1) (- (strlen commands) (+ loc 2))))
;else
(= commands "")
)
(beginning_of_line)
(down)
(if (== (inq_called) "_context_help")
(create_window 2 21 76 2 "<Alt-h> for assignment, <Esc> or <Keypad-minus> to exit help")
;else
(create_window 2 21 76 2 "<Keypad-minus> for menu, <Alt-h> for assignment, <Esc> to exit help")
)
(attach_buffer file_buffer)
(keyboard_push)
(assign_to_key "<Keypad-minus>" "_exit")
(assign_to_key "<Esc>" "_help_exit")
(assign_to_key "<PgUp>" "_help_up")
(assign_to_key "<PgDn>" "_help_down")
(assign_to_key "<Alt-h>" (+ "_help_assignment " commands))
(refresh)
(process)
(keyboard_pop)
(delete_window)
(search_back (+ (+ "\xc" topic) "\xc"))
(beginning_of_line)
)
;else
(error "No help available for %s." topic)
)
(set_buffer orig_buffer)
)
;else
(error "Help file not found.")
)
)
)
;**
;** _help_down:
;**
;** _help_down is called when the PgDn key is pressed: it ensures that
;** the user does not go past the end of the help file. Since the command
;** name begins with an underscore, the current command is not reassigned.
;**
(macro _help_down
(
(int line
col
old_line
old_col
)
(inq_position old_line old_col)
(search_fwd "\xc")
(inq_position line col)
(move_abs old_line old_col)
(page_down)
(if (<= (- line old_line) 18)
(move_abs old_line old_col)
)
)
)
;**
;** _help_up:
;**
;** Goes up a page in the help file. Since the command name begins
;** with an underscore, the current command is not reassigned.
;**
(macro _help_up
(
(int line
col
old_line
old_col
)
(inq_position old_line old_col)
(search_back "\xc")
(inq_position line col)
(move_abs old_line old_col)
(page_up)
(if (<= (- old_line line) 18)
(move_abs old_line old_col)
)
)
)
;**
;** key_specific_help:
;**
;** Gets help for the user using the keys, not the menus.
;**
(macro key_specific_help
(
(int saved_level
key_value
)
(string sequence
assignment
)
;**
;** The dialog level is saved and restored when we enter and exit
;** key-specific help. During execution, we set the _dialog_level to
;** 0; a press of Esc will then only remove the help screen.
;**
;** If this wasn't done, extra "exit" calls would be done, and
;** the next time a window came up it would be removed immediately.
;**
(= saved_level _dialog_level)
(= _dialog_level 0)
(keyboard_push _user_kbd)
(while (!= key_value (key_to_int "<Esc>"))
(
(message "Press the key you want help on, <Esc> to exit.")
(while (== (= key_value (read_char)) -1))
(sprintf sequence "#%u" key_value)
;**
;** If the key assignment we have obtained is ambiguous, we keep
;** appending additional key assignments to it until we find a
;** command (or fail).
;**
(while (== (= assignment (inq_assignment sequence)) "ambiguous")
(
(message "Press next key in sequence, <Esc> to exit.")
(while (== (= key_value (read_char)) -1))
(if (== key_value (key_to_int "<Esc>"))
(break)
)
(sprintf sequence "%s#%u" sequence key_value)
)
)
(if (== key_value (key_to_int "<Esc>"))
(break)
)
(display_help assignment)
)
)
(= _dialog_level saved_level)
(keyboard_pop 1)
(message "")
)
)
;**
;** _help_assignment:
;**
;** This macro takes a command name as a parameter, creates a window
;** and displays the keys assigned to that command.
;**
(macro _help_assignment
(
(string commands
this_command
keys
)
(int old_buf
key_buf
loc
comma_loc
semi_loc
key_read
have_assignment
)
(get_parm 0 commands)
(keyboard_push _user_kbd)
(= old_buf (inq_buffer))
(set_buffer (= key_buf (create_buffer "Keys" NULL 1)))
(tabs 4)
(while (strlen commands)
(
(if (&& semi_loc (|| (< semi_loc comma_loc) (! comma_loc)))
(insert "\n\nSee also:\n")
)
(= comma_loc (index commands ","))
(= semi_loc (index commands ";"))
(if (&& semi_loc (|| (< semi_loc comma_loc) (! comma_loc)))
(= loc semi_loc)
;else
(= loc comma_loc)
)
(if loc
(
(= this_command (substr commands 1 (- loc 1)))
(= commands (substr commands (+ loc 1)))
)
;else
(
(= this_command commands)
(= commands "")
)
)
(if (!= this_command "")
(
(++ have_assignment)
(if (== (= keys (inq_assignment this_command 1)) "")
(= keys (+ (+ (inq_assignment "execute_macro" 1) "<-and> ") this_command))
)
(insert (+ (+ "\n \"" this_command) "\" is assigned to:\n\t\t"))
(while (= loc (index keys "<-"))
(
(insert (substr keys 1 (- loc 1)))
(= keys (substr keys loc))
(if (= loc (index keys "<-and>"))
(= keys (substr keys (+ loc 6)))
;else
(if (= loc (index keys "<-also>"))
(
(insert "\n\t\t")
(= keys (substr keys (+ loc 7)))
)
;else
(
(= keys "")
(break)
)
)
)
)
)
(insert (+ keys "\n"))
)
)
)
)
;**
;** If any assignments were found, we display them in a window.
;**
(if have_assignment
(
(keyboard_push)
(assign_to_key "<Esc>" "_exit")
(assign_to_key "<Keypad-minus>" "_exit")
(assign_to_key "<PgUp>" "_assign_up")
(assign_to_key "<PgDn>" "_assign_down")
(top_of_buffer)
(create_window 6 15 72 4 "<Esc> or <Keypad-minus> to exit, <PgUp> or <PgDn> to scroll")
(attach_buffer key_buf)
(refresh)
(process)
(keyboard_pop)
(delete_window)
)
)
(if (! have_assignment)
(beep)
)
(delete_buffer key_buf)
(set_buffer old_buf)
(keyboard_pop 1)
)
)
(macro _assign_up
(page_up)
)
(macro _assign_down
(
(page_down)
(move_rel (* (inq_position) -1))
)
)
;**
;** _help_exit:
;**
;** Exits from the help system; calls exit to remove the help
;** window, and pushes back an <Esc> if the dialog manager is active
;** to remove the other (menu) windows.
;**
(macro _help_exit
(
(if _dialog_level
(push_back (key_to_int "<Esc>"))
)
(exit)
)
)
;**
;** _help_add_button:
;**
;** Used to add buttons to existing menus. This macro does nothing,
;** but you can write a replacement macro for it that checks the only
;** parameter (the buffer name) and adds buttons. When your replacement
;** macro is called, the menu buffer will be current and the menu will
;** be unformatted (just as it is on disk).
;** Make sure your replacement calls _help_add_button so that all
;** other replacement macros eventually get called.
;**
(macro _help_add_button
(returns TRUE)
)