diff --git a/flora-search-aurora.lisp b/flora-search-aurora.lisp index c398e51..235f0e0 100644 --- a/flora-search-aurora.lisp +++ b/flora-search-aurora.lisp @@ -33,53 +33,83 @@ (in-package :flora-search-aurora) -(defun state-loop (loops &optional (last-matrix (make-screen-matrix)) (matrix (make-screen-matrix))) - (when loops - (let ((loop-result - (apply (car loops) (list matrix)))) - (print-screen-matrix (matrix-delta last-matrix matrix)) +(defun state-loop + (states &key (last-matrix (make-screen-matrix)) (matrix (make-screen-matrix)) (state-params nil)) + "Begin the game’s loop, which executes (henceforthly called) state-functions over and over again +until Hell freezes over and a new king reigns supreme. +Given a list of state-functions, states, it will execute the first function. +Each state-function must take at least a single parameter, a matrix of characters. A state-function +should edit this matrix in-place, replacing its elements with characters that will later be printed +to the terminal. +If this function returns NIL, then it will be removed from state-function list and the next +function in the list will be run in the next iteration. If no more functions remain, the loop +terminates. +If this function returns a list, then the given list will be used as additional parameters to the +state-function in the next iteration, in addition to the aforementioned matrix. +If this function returns a function, then the returned function will go to the front of the +state-function list, and will be ran in the next iteration onward. +If this function returns anything else, then it’ll simply be run again in the next iteration. +Make note to add a delay to your state functions, or… well, y’know. Your computer will overheat, +or something ¯\_(ツ)_/¯" + + (when states + (let ((state-result + (apply (car states) (cons matrix state-params)))) ;; Run the latest-added update/draw loop + (print-screen-matrix (matrix-delta last-matrix matrix)) ;; Print its results. (force-output) (state-loop - (cond ((functionp loop-result) - (cons loop-result loops)) - ((not loop-result) - (cdr loops)) - ('t loops)) - matrix)))) + (cond ((functionp state-result) + (cons state-result states)) + ((not state-result) + (cdr states)) + ('t states)) + :last-matrix matrix + :state-params (when (listp state-result) + state-result))))) -(defun make-main-menu-loop () +(defun make-main-menu-state () + "Return a state-function for the game’s main menu, for use with #'state-loop." (let ((main-menu - `(((LABEL . "CRY OUT") (SELECTED . T) (FUNCTION . ,(lambda () (print "AAAAAA")))) - ((LABEL . "RUN AWAY") (FUNCTION . ,(lambda () nil))) + `(((LABEL . "PLAY") + (SELECTION . 100) (SELECTED . T) + (FUNCTION . ,(lambda () (make-main-overworld-state)))) ((LABEL . "SUBMENU") - (SELECTION . -100) - (FUNCTION . ,(make-options-menu-loop)))))) + (FUNCTION . ,(lambda () (make-options-menu-state)))) + ((LABEL . "QUIT") (FUNCTION . ,(lambda () nil)))))) (lambda (matrix) - (menu-loop matrix main-menu)))) + (menu-state matrix main-menu)))) -(defun make-options-menu-loop () +(defun make-options-menu-state () + "Return a state-function for the options menu, for use with #'state-loop." (let ((options-menu - `(((LABEL . "IDK") (SELECTION . 100) (SELECTED . T) - (FUNCTION . ,(lambda () (print "¯\_(ツ)_/¯")))) - ((LABEL . "GO BACK") (FUNCTION . ,(lambda () nil)))))) + `(((LABEL . "IDK") + (SELECTION . 100) (SELECTED . T) + (FUNCTION . ,(lambda () (print "¯\_(ツ)_/¯")))) + ((LABEL . "GO BACK") + (FUNCTION . ,(lambda () nil)))))) (lambda (matrix) - (menu-loop matrix options-menu)))) + (menu-state matrix options-menu)))) -(defun make-main-overworld-loop () +(defun make-main-overworld-state () + "Return a state-function for the game’s overworld (the majority of the game), for use with +#'state-loop." (lambda (matrix) - (overworld-loop matrix "/home/jaidyn/.local/src/games/flora search aurora/res/map.tmx"))) + (overworld-state matrix "/home/jaidyn/.local/src/games/flora search aurora/res/map.tmx"))) (defun main () - "A pathetic fascimile of a main loop. Look, I'm still tinkering!" + "A pathetic fascimile of a main loop. What does it do? WHAST DOES TI DODOO?" (cl-charms:with-curses () (cl-charms:enable-raw-input :interpret-control-characters 't) (clear-screen) - (state-loop (list (make-main-menu-loop) - (make-main-overworld-loop))))) + (state-loop (list (make-main-menu-state))))) -(main) +(main) ;; — Knock-knock +;; — Who’s there? +;; — Yo momma! +;; — “Yo momma” who? +;; — Yo momma’s a sweet lady, and I think she’s swell! diff --git a/overworld.lisp b/overworld.lisp index 7d52e69..7db4586 100644 --- a/overworld.lisp +++ b/overworld.lisp @@ -21,7 +21,7 @@ (:use :cl :flora-search-aurora.input :flora-search-aurora.display :flora-search-aurora.ui) - (:export #:overworld-loop)) + (:export #:overworld-state)) (in-package :flora-search-aurora.overworld) @@ -30,30 +30,29 @@ ;;; ——————————————————————————————————— ;;; Overworld loop ;;; ——————————————————————————————————— -(defun overworld-loop (matrix map) - "The state loop to be used for displaying/processing/input-managing -with menus." +(defun overworld-state (matrix map) + "Render the given map to the matrix and take user-input — for one frame. +A state-function for use with #'state-loop." (let ((map (if (or (stringp map) (pathnamep map)) (cl-tiled:load-map map) map))) (sleep .02) - (overworld-loop-draw matrix map) - (overworld-loop-update map))) + (overworld-state-draw matrix map) + (overworld-state-update map))) -(defun overworld-loop-draw (matrix map) - "Drawing for." +(defun overworld-state-draw (matrix map) + "Draw the overworld map to the given matrix. +A core part of #'overworld-state." (matrix-write-tiled-map matrix map)) - -(defun overworld-loop-update (map) - "The update loop for menus. It processes all input, state, etc, and -returns the new state of the menu." +(defun overworld-state-update (map) + "Do nothing, lol. +Core part of #'overworld-state." 't) - ;;; ——————————————————————————————————— ;;; Mapping & map-rendering diff --git a/ui.lisp b/ui.lisp index 26faaf0..dfaec9f 100644 --- a/ui.lisp +++ b/ui.lisp @@ -19,7 +19,7 @@ (defpackage :flora-search-aurora.ui (:use :cl :flora-search-aurora.display :flora-search-aurora.input :assoc-utils) - (:export #:menu-loop #:render-menu-strip :label :selection :selected)) + (:export #:menu-state #:render-menu-strip :label :selection :selected)) (in-package :flora-search-aurora.ui) @@ -27,22 +27,23 @@ ;;; ——————————————————————————————————— ;;; Menu loops ;;; ——————————————————————————————————— -(defun menu-loop (matrix menu-alist) - "The state loop to be used for displaying/processing/input-managing -with menus." +(defun menu-state (matrix menu-alist) + "Render a menu in menu-alist format to the given matrix, and process user-input. +A state-function for use with the #'state-loop." (sleep .02) - (menu-loop-draw matrix menu-alist) - (menu-loop-update menu-alist)) + (menu-state-draw matrix menu-alist) + (menu-state-update menu-alist)) -(defun menu-loop-draw (matrix menu-alist) - "Drawing for." +(defun menu-state-draw (matrix menu-alist) + "Render a menu in menu-alist format to the given matrix. +A core part of #'menu-state." (render-menu-strip matrix menu-alist 0 0)) -(defun menu-loop-update (menu-alist) - "The update loop for menus. It processes all input, state, etc, and -returns the new state of the menu." +(defun menu-state-update (menu-alist) + "Update a menu — that is, take user input and modify the menu’s alist appropriately. +A core part of #'menu-state." (progress-menu-items menu-alist) (process-menu-input menu-alist))