From 027053b11a3a5d861ed2fa2db245388bd95ac246 Mon Sep 17 00:00:00 2001 From: Gene Pasquet Date: Sun, 5 Apr 2026 19:47:05 +0100 Subject: Progress --- engine.scm | 54 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'engine.scm') diff --git a/engine.scm b/engine.scm index 73e88f0..553dddf 100644 --- a/engine.scm +++ b/engine.scm @@ -6,6 +6,7 @@ (prefix sdl2 "sdl2:") (prefix sdl2-ttf "ttf:") (prefix sdl2-image "img:") + (srfi 69) defstruct downstroke/world downstroke/input @@ -26,7 +27,9 @@ create-hook ;; (lambda (game) ...) update-hook ;; (lambda (game dt) ...) render-hook ;; (lambda (game) ...) — post-render overlay - scene) ;; current scene struct; #f until create: runs + scene ;; current scene struct; #f until create: runs + states ;; hash-table of name → state-plist + active-state) ;; symbol or #f — currently active state name ;; Store the auto-generated constructor as make-game* (define make-game* make-game) @@ -54,7 +57,9 @@ preload-hook: preload create-hook: create update-hook: update - render-hook: render)) + render-hook: render + states: (make-hash-table) + active-state: #f)) ;; ── Convenience accessors ────────────────────────────────────────────────── @@ -70,6 +75,27 @@ (define (game-asset-set! game key value) (asset-set! (game-assets game) key value)) +;; ── Named scene states ──────────────────────────────────────────────────── + +;; Construct a state plist with lifecycle hooks. +(define (make-game-state #!key (create #f) (update #f) (render #f)) + (list #:create create #:update update #:render render)) + +;; Retrieve a value from a state plist. +(define (state-hook state key) + (get-keyword key state (lambda () #f))) + +;; Register a named state. name is a symbol; state is a make-game-state plist. +(define (game-add-state! game name state) + (hash-table-set! (game-states game) name state)) + +;; Transition to a named state. Calls the state's create: hook if present. +(define (game-start-state! game name) + (game-active-state-set! game name) + (let* ((state (hash-table-ref (game-states game) name)) + (create (state-hook state #:create))) + (when create (create game)))) + ;; ── game-run! ────────────────────────────────────────────────────────────── ;; Main event loop and lifecycle orchestration @@ -93,7 +119,7 @@ (sdl2:create-window! (game-title game) 'centered 'centered (game-width game) (game-height game) '())) (game-renderer-set! game - (sdl2:create-renderer! (game-window game) -1 '(accelerated vsync))) + (sdl2:create-renderer! (game-window game) -1 '(accelerated))) ;; 3. preload: hook — user loads assets here (when (game-preload-hook game) @@ -119,15 +145,19 @@ (game-input-config game)))) (game-input-set! game input) (unless (input-held? input 'quit) - ;; update: hook — user game logic - (when (game-update-hook game) - ((game-update-hook game) game dt)) - ;; render: engine draws world, then user overlay - (sdl2:render-clear! (game-renderer game)) - (when (game-scene game) - (render-scene! (game-renderer game) (game-scene game))) - (when (game-render-hook game) - ((game-render-hook game) game)) + ;; Dispatch to active state hooks, or fall back to game's own hooks + (let* ((active (game-active-state game)) + (state (and active + (hash-table-ref/default (game-states game) active #f))) + (update-fn (or (and state (state-hook state #:update)) + (game-update-hook game))) + (render-fn (or (and state (state-hook state #:render)) + (game-render-hook game)))) + (when update-fn (update-fn game dt)) + (sdl2:render-clear! (game-renderer game)) + (when (game-scene game) + (render-scene! (game-renderer game) (game-scene game))) + (when render-fn (render-fn game))) (sdl2:render-present! (game-renderer game)) (sdl2:delay! (game-frame-delay game)) (loop now))))) -- cgit v1.2.3