summaryrefslogtreecommitdiff
path: root/starling/kernel.scm
diff options
context:
space:
mode:
Diffstat (limited to 'starling/kernel.scm')
-rw-r--r--starling/kernel.scm129
1 files changed, 60 insertions, 69 deletions
diff --git a/starling/kernel.scm b/starling/kernel.scm
index 04fb4cd..e019b5b 100644
--- a/starling/kernel.scm
+++ b/starling/kernel.scm
@@ -39,21 +39,9 @@
#:use-module (starling asset)
#:use-module (starling node)
#:use-module (starling repl)
+ #:use-module (starling scene)
#:use-module (system repl command)
- #:export (on-quit
- on-key-press
- on-key-release
- on-text-input
- on-mouse-press
- on-mouse-release
- on-mouse-move
- on-controller-add
- on-controller-remove
- on-controller-press
- on-controller-release
- on-controller-move
-
- <window-config>
+ #:export (<window-config>
width
height
title
@@ -66,46 +54,13 @@
gl-context
current-kernel
boot-kernel
- elapsed-time)
+ elapsed-time
+ current-scene
+ push-scene
+ pop-scene
+ replace-scene)
#:re-export (abort-game))
-;; Input event handler methods
-(define-method (on-quit (node <node>))
- (abort-game))
-
-(define-method (on-key-press (node <node>) key scancode modifiers repeat?)
- #t)
-
-(define-method (on-key-release (node <node>) key scancode modifiers)
- #t)
-
-(define-method (on-text-input (node <node>) text)
- #t)
-
-(define-method (on-mouse-press (node <node>) button clicks x y)
- #t)
-
-(define-method (on-mouse-release (node <node>) button x y)
- #t)
-
-(define-method (on-mouse-move (node <node>) x y x-rel y-rel buttons)
- #t)
-
-(define-method (on-controller-add (node <node>) controller)
- #t)
-
-(define-method (on-controller-remove (node <node>) controller)
- #t)
-
-(define-method (on-controller-press (node <node>) controller button)
- #t)
-
-(define-method (on-controller-release (node <node>) controller button)
- #t)
-
-(define-method (on-controller-move controller axis value)
- #t)
-
(define-class <window-config> ()
(width #:accessor width #:init-form 640)
(height #:accessor height #:init-form 480)
@@ -120,7 +75,9 @@
(window #:accessor window)
(gl-context #:accessor gl-context)
(controllers #:accessor controllers #:init-thunk make-hash-table)
- (repl #:accessor repl))
+ (repl #:accessor repl)
+ ;; The scene stack.
+ (scenes #:accessor scenes #:init-form '()))
(define current-kernel (make-parameter #f))
@@ -151,7 +108,7 @@
;; Enable live asset reloading.
(watch-assets #t)
;; Start REPL server.
- (attach-to kernel (make <repl> #:name 'repl #:rank 9999))))
+ (attach-to kernel (make <repl> #:name 'repl))))
(define-method (update* (kernel <kernel>) dt)
(define (invert-y y)
@@ -161,37 +118,37 @@
((_ height)
(- height y))))
(define (process-event event)
- (let ((first-child (car (children kernel))))
+ (let ((current-scene (current-scene)))
(cond
((quit-event? event)
- (on-quit first-child))
+ (on-quit current-scene))
((keyboard-down-event? event)
- (on-key-press first-child
+ (on-key-press current-scene
(keyboard-event-key event)
(keyboard-event-scancode event)
(keyboard-event-modifiers event)
(keyboard-event-repeat? event)))
((keyboard-up-event? event)
- (on-key-release first-child
+ (on-key-release current-scene
(keyboard-event-key event)
(keyboard-event-scancode event)
(keyboard-event-modifiers event)))
((text-input-event? event)
- (on-text-input first-child
+ (on-text-input current-scene
(text-input-event-text event)))
((mouse-button-down-event? event)
- (on-mouse-press first-child
+ (on-mouse-press current-scene
(mouse-button-event-button event)
(mouse-button-event-clicks event)
(mouse-button-event-x event)
(invert-y (mouse-button-event-y event))))
((mouse-button-up-event? event)
- (on-mouse-release first-child
+ (on-mouse-release current-scene
(mouse-button-event-button event)
(mouse-button-event-x event)
(invert-y (mouse-button-event-y event))))
((mouse-motion-event? event)
- (on-mouse-move first-child
+ (on-mouse-move current-scene
(mouse-motion-event-x event)
(invert-y (mouse-motion-event-y event))
(mouse-motion-event-x-rel event)
@@ -202,34 +159,34 @@
(let ((controller
(add-controller kernel
(controller-device-event-which event))))
- (on-controller-add first-child controller)))
+ (on-controller-add current-scene controller)))
((and (controller-device-event? event)
(eq? (controller-device-event-action event) 'removed))
(let ((controller
(lookup-controller kernel
(controller-device-event-which event))))
- (on-controller-remove first-child controller)
+ (on-controller-remove current-scene controller)
(remove-controller kernel (controller-device-event-which event))
(close-game-controller controller)))
((controller-button-down-event? event)
(let ((controller
(lookup-controller kernel
(controller-button-event-which event))))
- (on-controller-press first-child
+ (on-controller-press current-scene
controller
(controller-button-event-button event))))
((controller-button-up-event? event)
(let ((controller
(lookup-controller kernel
(controller-button-event-which event))))
- (on-controller-release first-child
+ (on-controller-release current-scene
controller
(controller-button-event-button event))))
((controller-axis-event? event)
(let ((controller
(lookup-controller kernel
(controller-axis-event-which event))))
- (on-controller-move first-child
+ (on-controller-move current-scene
controller
(controller-axis-event-axis event)
(/ (controller-axis-event-value event) 32768.0)))))))
@@ -268,7 +225,7 @@
(define (elapsed-time)
(sdl-ticks))
-(define (boot-kernel kernel first-node)
+(define-method (boot-kernel (kernel <kernel>) (scene <scene>))
(sdl-init)
;; This will throw an error if any audio subsystem is unavailable,
;; but not every audio subsystem is needed so don't crash the
@@ -298,7 +255,7 @@
(const #t)
(lambda ()
(parameterize ((current-kernel kernel))
- (attach-to kernel first-node)
+ (push-scene scene)
(activate kernel)
(run-game #:update (lambda (dt) (update* kernel dt))
#:render (lambda (alpha) (render* kernel alpha))
@@ -310,6 +267,40 @@
(deactivate kernel)
(close-window! (window kernel))))))
+(define-method (current-scene)
+ "Return the currently active scene"
+ (and (not (null? (scenes (current-kernel))))
+ (car (scenes (current-kernel)))))
+
+(define-method (push-scene (scene <scene>))
+ "Make SCENE the currently active scene and remember the previously
+active scene."
+ (let ((old (current-scene)))
+ (set! (scenes (current-kernel)) (cons scene (scenes (current-kernel))))
+ (when old (detach old))
+ (attach-to (current-kernel) scene)))
+
+(define-method (replace-scene (scene <scene>))
+ "Make SCENE the currently active scene and forget about whatever was
+previously active."
+ (let ((old (current-scene)))
+ (unless old
+ (error "no scene to replace!"))
+ (set! (scenes (current-kernel)) (cons scene (cdr (scenes (current-kernel)))))
+ (detach old)
+ (attach-to (current-kernel) scene)))
+
+(define-method (pop-scene)
+ "Replace the current scene with the previously active scene."
+ (let ((old (current-scene)))
+ (set! (scenes (current-kernel)) (cdr (scenes (current-kernel))))
+ (detach old)
+ (let ((new (current-scene)))
+ (if new
+ (attach-to (current-kernel) new)
+ ;; No scenes remain, it's time to shut down!
+ (abort-game)))))
+
(define-meta-command ((debug-game starling) repl)
"debug-game
Enter a debugger for the current game loop error."