summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chickadee.scm3
-rw-r--r--chickadee/game-loop.scm82
2 files changed, 45 insertions, 40 deletions
diff --git a/chickadee.scm b/chickadee.scm
index aec8eef..c8ad719 100644
--- a/chickadee.scm
+++ b/chickadee.scm
@@ -77,7 +77,8 @@
warp-mouse
set-show-cursor!
run-game)
- #:re-export (abort-game))
+ #:re-export (abort-game
+ current-timestep))
(define %time-freq (exact->inexact (sdl-performance-frequency)))
diff --git a/chickadee/game-loop.scm b/chickadee/game-loop.scm
index 027d7af..76e649a 100644
--- a/chickadee/game-loop.scm
+++ b/chickadee/game-loop.scm
@@ -17,7 +17,8 @@
(define-module (chickadee game-loop)
#:export (run-game*
- abort-game))
+ abort-game
+ current-timestep))
;;;
@@ -56,44 +57,47 @@
(define (abort-game)
(abort-to-prompt game-loop-prompt-tag #f))
-(define* (run-game* #:key update render time error
+(define current-timestep (make-parameter 0.0))
+
+(define* (run-game* #:key init update render time error
(update-hz 60))
(let ((timestep (/ 1.0 update-hz)))
- (call-with-prompt game-loop-prompt-tag
- (lambda ()
- ;; Catch SIGINT and kill the loop.
- (sigaction SIGINT
- (lambda (signum)
- (abort-game)))
- (init)
- ;; A simple analogy is that we are filling up a bucket
- ;; with water. When the bucket fills up to a marked
- ;; line, we dump it out. Our water is time, and each
- ;; time we dump the bucket we update the game. Updating
- ;; the game on a fixed timestep like this yields a
- ;; stable simulation.
- (let loop ((previous-time (time))
- (buffer 0.0))
- (let* ((current-time (time))
- (delta (- current-time previous-time)))
- (let update-loop ((buffer (+ buffer delta)))
- (if (>= buffer timestep)
- ;; Short-circuit the update loop if an error
- ;; occurred, and reset the current time to now in
- ;; order to discard the undefined amount of time
- ;; that was spent handling the error.
- (if (with-error-handling error (update timestep))
- (loop (time) 0.0)
- (update-loop (- buffer timestep)))
- (begin
- ;; We render upon every iteration of the loop, and
- ;; thus rendering is decoupled from updating.
- ;; It's possible to render multiple times before
- ;; an update is performed.
- (if (with-error-handling error
- (render (/ buffer timestep))
- (usleep 1))
+ (parameterize ((current-timestep timestep))
+ (call-with-prompt game-loop-prompt-tag
+ (lambda ()
+ ;; Catch SIGINT and kill the loop.
+ (sigaction SIGINT
+ (lambda (signum)
+ (abort-game)))
+ (init)
+ ;; A simple analogy is that we are filling up a bucket
+ ;; with water. When the bucket fills up to a marked
+ ;; line, we dump it out. Our water is time, and each
+ ;; time we dump the bucket we update the game. Updating
+ ;; the game on a fixed timestep like this yields a
+ ;; stable simulation.
+ (let loop ((previous-time (time))
+ (buffer 0.0))
+ (let* ((current-time (time))
+ (delta (- current-time previous-time)))
+ (let update-loop ((buffer (+ buffer delta)))
+ (if (>= buffer timestep)
+ ;; Short-circuit the update loop if an error
+ ;; occurred, and reset the current time to now in
+ ;; order to discard the undefined amount of time
+ ;; that was spent handling the error.
+ (if (with-error-handling error (update timestep))
(loop (time) 0.0)
- (loop current-time buffer))))))))
- (lambda (cont callback)
- #f))))
+ (update-loop (- buffer timestep)))
+ (begin
+ ;; We render upon every iteration of the loop, and
+ ;; thus rendering is decoupled from updating.
+ ;; It's possible to render multiple times before
+ ;; an update is performed.
+ (if (with-error-handling error
+ (render (/ buffer timestep))
+ (usleep 1))
+ (loop (time) 0.0)
+ (loop current-time buffer))))))))
+ (lambda (cont callback)
+ #f)))))