! Menu code purloined from DM4 ! + cursor up code ! + fix to ensure Menus expand window -1 to the entire screen instead of just ! the first few lines, to prevent it writing outside the window and annoying ! some interpreters System_file; Global screen_width; Global screen_height; Array ForUseByOptions -> 129; Class Option with select [; self.emblazon(1, 1, 1); @set_window 0; font on; style roman; new_line; new_line; if (self provides description) return self.description(); "[No text written for this option.]^"; ], emblazon [ bar_height page pages temp; screen_width = 0->33; ! Clear screen: @erase_window -1; @split_window bar_height; ! Black out top line in reverse video: @set_window 1; @set_cursor 1 1; style reverse; spaces(screen_width); if (standard_interpreter == 0) @set_cursor 1 1; else { ForUseByOptions-->0 = 128; @output_stream 3 ForUseByOptions; print (name) self; if (pages ~= 1) print " [", page, "/", pages, "]"; @output_stream -3; temp = (screen_width - ForUseByOptions-->0)/2; @set_cursor 1 temp; } print (name) self; if (pages ~= 1) print " [", page, "/", pages, "]"; return ForUseByOptions-->0; ]; Class Menu class Option with select [ count j obj pkey line oldline top_line bottom_line page pages options top_option; screen_width = 0->33; screen_height = 0->32; if (screen_height == 0 or 255) screen_height = 18; screen_height = screen_height - 7; options = 0; objectloop (obj in self && obj ofclass Option) options++; if (options == 0) return 2; pages = options/screen_height; if (options%screen_height ~= 0) pages++; top_line = 6; page = 1; line = top_line; .ReDisplay; top_option = (page - 1) * screen_height; ! self.emblazon(7 + count, page, pages); self.emblazon(screen_height,page,pages); @set_cursor 2 1; spaces(screen_width); @set_cursor 2 2; print "N = next subject"; j = screen_width-12; @set_cursor 2 j; print "P = previous"; @set_cursor 3 1; spaces(screen_width); @set_cursor 3 2; print "RETURN = read subject"; j = screen_width-17; @set_cursor 3 j; if (sender ofclass Option) print "Q = previous menu"; else print " Q = resume game"; style roman; count = top_line; j = 0; objectloop (obj in self && obj ofclass Option) { if (j >= top_option && j < (top_option+screen_height)) { @set_cursor count 6; print (name) obj; count++; } j++; } bottom_line = count - 1; oldline = 0; for (::) { ! Move or create the > cursor: if (line ~= oldline) { if (oldline ~= 0) { @set_cursor oldline 4; print " "; } @set_cursor line 4; print ">"; } oldline = line; @read_char 1 -> pkey; if (pkey == 'N' or 'n' or 130) { ! Cursor down: line++; if (line > bottom_line) { line = top_line; if (pages > 1) { if (page == pages) page = 1; else page++; jump ReDisplay; } } continue; } if (pkey == 'P' or 'p' or 129) { ! Cursor up: line--; if (line < top_line) { line = bottom_line; if (pages > 1) { if (page == 1) page = pages; else page--; jump ReDisplay; } } continue; } if (pkey == 'Q' or 'q' or 27 or 131) break; if (pkey == 10 or 13 or 132) { count = 0; objectloop (obj in self && obj ofclass Option) { if (count == top_option + line - top_line) break; count++; } switch (obj.select()) { 2: jump ReDisplay; 3: jump ExitMenu; } print "[Please press SPACE to continue.]^"; @read_char 1 -> pkey; jump ReDisplay; } } .ExitMenu; if (sender ofclass Option) return 2; font on; @set_cursor 1 1; @erase_window -1; @set_window 0; new_line; new_line; new_line; if (deadflag == 0) <>; return 2; ]; Class SwitchOption class Option with short_name [; print (object) self, " "; if (self has on) print "(on)"; else print "(off)"; rtrue; ], select [; if (self has on) give self ~on; else give self on; return 2; ];