;;; -*- Mode:LISP; Package:HACKS; Base:8; Readtable:ZL -*- (DEFVAR *WORM-WINDOW* nil) (defun worm-window () (cond (*worm-window*) (t (setq *worm-window* (MAKE-INSTANCE 'HOF-WINDOW :BLINKER-P NIL))))) (DEFVAR *CHAR*) (defvar *bits*) (defvar *order*) (defvar *worm-x*) (defvar *worm-y*) (defvar *x-worm*) (defvar *y-worm*) (defvar *WORM-ALU-FUNCTION*) (defvar *dir*) (defvar *fitp*) ;These are the "character codes" in the worm font ;for the various kinds of spots. (DEFCONST WORM-BIG-CHAR 5) (DEFCONST WORM-STRIPE-CHAR 4) (DEFCONST WORM-GRAY-CHAR 3) (DEFCONST WORM-BLACK-CHAR 2) ;This is a 6-long array of stack groups, ;each of which runs one worm. (DEFVAR *WORMS* (LET ((ARRAY (MAKE-ARRAY 6 :TYPE 'ART-Q-LIST))) (DOTIMES (I 6) (SETF (AREF ARRAY I) (MAKE-STACK-GROUP (FORMAT NIL "WORM-~D" I)))) ARRAY)) (DEFUN PRESET (SG CHAR ALU-FN N) (STACK-GROUP-PRESET SG #'FLOP (SYMBOL-VALUE CHAR) (SYMBOL-VALUE ALU-FN) *ORDER* *WORM-X* *WORM-Y* *BITS* (* N (^ 3 (1- *ORDER*))) *TERMINAL-IO* SYS:%CURRENT-STACK-GROUP)) (DEFUN WORM (&OPTIONAL (*BITS* 0) (*ORDER* 7) (*WORM-X* 222) (*WORM-Y* 777) &AUX LENGTH (*TERMINAL-IO* (worm-window))) (TV:WINDOW-CALL (*WORM-WINDOW* :DEACTIVATE) (CATCH-ERROR-RESTART ((SYS:ABORT ERROR) "Exit WORM.") (SEND *WORM-WINDOW* :SET-LABEL "Worm") (OR (BOUNDP 'FONTS:WORM) (LOAD "SYS: FONTS ;WORM" :PACKAGE 'FONTS)) (SETQ LENGTH (^ 3 (1+ *ORDER*))) (PRESET (AREF *WORMS* 0) 'WORM-BIG-CHAR 'TV:ALU-IOR 0) (SETQ *FITP* NIL) (DO ((I 0 (1+ I))) ((OR *FITP* ( I 2))) ; Paint blackness over whole worm (SETQ *FITP* T) (SEND *TERMINAL-IO* :CLEAR-WINDOW) (DOTIMES (I (1+ LENGTH)) (IF (FUNCALL (AREF *WORMS* 0)) (signal eh:abort-object)))) (SETQ *WORM-X* *X-WORM* *WORM-Y* *Y-WORM*) (MAPC #'PRESET ; Preset wormlets (G-L-P *WORMS*) '(WORM-GRAY-CHAR WORM-BLACK-CHAR WORM-STRIPE-CHAR WORM-BLACK-CHAR WORM-BLACK-CHAR WORM-BLACK-CHAR) '(TV:ALU-XOR TV:ALU-ANDCA TV:ALU-IOR TV:ALU-IOR TV:ALU-ANDCA TV:ALU-IOR) '(0 1 2 3 5 6)) ;4 is intentionally missing! (WORM-COMMAND-LOOP)))) (DEFUN WORM-COMMAND-LOOP (&AUX (YPOS (- (TV:SHEET-INSIDE-HEIGHT *TERMINAL-IO*) (* 3 (TV:SHEET-LINE-HEIGHT *TERMINAL-IO*))))) (DO ((I 0 (1+ I)) RUN (STOP-VAL 0)) (NIL) (COND ((OR RUN (< I STOP-VAL)) (AND (SEND *TERMINAL-IO* :TYI-NO-HANG) (SETQ RUN NIL STOP-VAL 0))) (T (SEND *WORM-WINDOW* :SET-LABEL (LET ((*PRINT-BASE* 9)) (FORMAT NIL "Worm Generation ~S (base 9)" I))) (SEND *TERMINAL-IO* :SET-CURSORPOS 0 YPOS) (FORMAT *TERMINAL-IO* " P: Run nR: Run until n nN: Run n steps nS: Run till nth order Abort: exit~% ") (PROG (CH VAL) (SETQ VAL 0) LOOP (SETQ CH (CHAR-UPCASE (TYI))) (COND ((AND ( CH #/0)( CH #/9)) (SETQ VAL (+ (* VAL 9) (- CH #/0))) (GO LOOP)) ((EQ CH #/N) (SETQ STOP-VAL (+ VAL I))) ((EQ CH #/R) (SETQ STOP-VAL VAL)) ((EQ CH #/S) (SETQ VAL (^ 3 VAL) STOP-VAL (* VAL (1+ (TRUNCATE I VAL))))) ((EQ CH #/P) (SETQ RUN T)))) (IF (OR RUN (< I STOP-VAL)) (SEND *WORM-WINDOW* :SET-LABEL "Worm Type any character to stop")))) (DOTIMES (I 6) (IF (FUNCALL (AREF *WORMS* I)) (SIGNAL EH:ABORT-OBJECT))))) (DEFVAR *WORM-TURNS* (MAKE-ARRAY 12. :TYPE 'ART-Q-LIST :initial-contents '(6 0 3 5 -3 5 -6 0 -3 -5 3 -5))) ;This is the coroutining function for each worm. ;Returns to the calling stack group with NIL normally, ;T if the user typed Abort. (DEFUN FLOP (*CHAR* *WORM-ALU-FUNCTION* *ORDER* *WORM-X* *WORM-Y* *BITS* SNOOZE *TERMINAL-IO* IGNORE) (CATCH-ERROR-RESTART ((SYS:ABORT ERROR) "Return to Worm command level.") (DO ((I 0 (1+ I))) (( I SNOOZE)) (STACK-GROUP-RETURN NIL)) (DO ((I 0 (1+ I)) (*DIR* (BOOLE 4 (- *ORDER*) 1))) (NIL) (TERD *ORDER* *BITS*) (WORM-STEP) (SETQ *X-WORM* *WORM-X* *Y-WORM* *WORM-Y*) (SETQ *DIR* (+ *DIR* 4)))) (DO () (()) (STACK-GROUP-RETURN T))) (DEFUN TERD (N *BITS*) (IF (PLUSP N) (COND ((Bit-Test *BITS* 1) (TERD (1- N) (LSH *BITS* -1)) (SETQ *DIR* (- *DIR* -2)) (WORM-STEP) (SETQ *DIR* (- *DIR* 4)) (TERD (1- N) (LSH *BITS* -1)) (WORM-STEP) (SETQ *DIR* (+ *DIR* 2)) (TERD (1- N) (LSH *BITS* -1))) (T (TERD (1- N) (LSH *BITS* -1)) (WORM-STEP) (SETQ *DIR* (+ *DIR* 4)) (TERD (1- N) (LSH *BITS* -1)) (SETQ *DIR* (- *DIR* 2)) (WORM-STEP) (SETQ *DIR* (- *DIR* 2)) (TERD (1- N) (LSH *BITS* -1)))))) (DEFUN WORM-STEP () (CLIP '*WORM-X* (TV:SHEET-INSIDE-WIDTH *TERMINAL-IO*) (SETQ *DIR* (\ (+ 12. *DIR*) 12.))) (CLIP '*WORM-Y* (- (TV:SHEET-INSIDE-HEIGHT *TERMINAL-IO*) 55) (1+ *DIR*)) (TV:PREPARE-SHEET (*TERMINAL-IO*) (TV:%DRAW-CHAR FONTS:WORM *CHAR* *WORM-X* *WORM-Y* *WORM-ALU-FUNCTION* *TERMINAL-IO*)) (STACK-GROUP-RETURN NIL)) (DEFUN CLIP (Z N D) (CASE (TRUNCATE (+ N (SET Z (+ (SYMBOL-VALUE Z) (AREF *WORM-TURNS* D)))) N) (0 (SET Z 1) (SETQ *FITP* NIL)) (1) (2 (SET Z (1- N)) (SETQ *FITP* NIL)))) (DEFDEMO "Worm" "Pretty fractal patters, by Gosper and Holloway." (WORM))