Browse Source

Add action buffer for undo

Also fixed buttons counting as being pressed if you drag the pressed
pointer onto them and release.
master
Macoy Madson 3 years ago
parent
commit
469aa56851
  1. 167
      src/Main.cake

167
src/Main.cake

@ -33,6 +33,7 @@
;; (var debug-log-enabled bool true)
(var debug-log-enabled bool false)
;; (var g-show-fps bool true)
(var g-show-fps bool false)
;; TODO: Actually look at frame rate and adjust accordingly
@ -442,23 +443,94 @@
(return (path piece > is-primary-piece)))
(return false))
(defstruct-local move-action
piece (* board-piece)
delta-position grid-vec2)
;; Circular buffer
(var g-action-buffer ([] 128 move-action) (array 0))
(var g-action-buffer-write-head (* move-action) g-action-buffer)
(defun-local reset-action-buffer ()
(memset g-action-buffer 0 (sizeof g-action-buffer)))
(var g-current-move-count int 0)
(defun-local make-action (piece (* board-piece) delta-position grid-vec2)
(set (path g-action-buffer-write-head > piece) piece)
(set (path g-action-buffer-write-head > delta-position) delta-position)
(incr g-action-buffer-write-head)
(when (>= (- g-action-buffer-write-head g-action-buffer) (array-size g-action-buffer))
(set g-action-buffer-write-head g-action-buffer))
(incr g-current-move-count))
(defun-local undo-action ()
(var action-buffer-read-head (* move-action) (- g-action-buffer-write-head 1))
(when (< action-buffer-read-head g-action-buffer)
(set action-buffer-read-head (+ g-action-buffer
(- (array-size g-action-buffer) 1))))
;; Nothing to do, the undo buffer is empty
(var piece (* board-piece) (path action-buffer-read-head > piece))
(when (= piece null)
(return))
;; Undo the action
(scope
(var invert-movement (const grid-vec2) (array -1 -1))
(var undo-movement grid-vec2 (path action-buffer-read-head > delta-position))
(set (vec-x undo-movement) (* (vec-x undo-movement) (vec-x invert-movement)))
(set (vec-y undo-movement) (* (vec-y undo-movement) (vec-y invert-movement)))
(set (path piece > grid-position) (grid-vec2-add (path piece > grid-position) undo-movement))
;; Because pieces tween back to their positions, we will add back in the undid position to the
;; move position for a nice transition
(var relative-movement vec2
(array
(* g-game-board-cell-size-px
(to-float (vec-x (path action-buffer-read-head > delta-position))))
(* g-game-board-cell-size-px
(to-float (vec-y (path action-buffer-read-head > delta-position))))))
(set (path piece > moving-position) (vec2-add (path piece > moving-position) relative-movement))
(decr g-current-move-count)
(game-board-sync-occupied-state))
(set (path action-buffer-read-head > piece) null)
(set (path action-buffer-read-head > delta-position) (array 0 0))
(set g-action-buffer-write-head action-buffer-read-head))
(defun game-board-load-next-puzzle ()
(when g-num-puzzles
(set g-current-puzzle (addr (at (mod (rand) g-num-puzzles) g-puzzle-list)))
(game-board-load (path g-current-puzzle > board))))
(game-board-load (path g-current-puzzle > board)))
(set g-current-move-count 0)
(reset-action-buffer))
;;
;; UI (immediate-mode)
;;
(defstruct-local input-state
pointer-position vec2
is-pointer-pressed bool
start-pressed-position vec2
was-clicked bool) ;; Click on pointer release
(defun-local update-input-state (in-state (* input-state) mouse-position vec2 is-pressed bool)
(set (path in-state > pointer-position) mouse-position)
(set (path in-state > was-clicked) (and (path in-state > is-pointer-pressed)
(not is-pressed)))
(var is-entering-press bool (and (not (path in-state > is-pointer-pressed))
is-pressed))
(var is-exiting-press bool (and (path in-state > is-pointer-pressed)
(not is-pressed)))
;; Clicks only count on release so you can move off a button mid-press to not do action
(set (path in-state > was-clicked) is-exiting-press)
(when is-entering-press
(set (path in-state > start-pressed-position) mouse-position))
(set (path in-state > is-pointer-pressed) is-pressed))
(defun-local is-within-aabb (point-to-test vec2 upper-left vec2 size vec2 &return bool)
@ -484,7 +556,9 @@
(sdl-print-error)))
(return (and (path in-state > was-clicked)
(is-within-aabb (path in-state > pointer-position) position size))))
(is-within-aabb (path in-state > pointer-position) position size)
;; So releasing on a button you didn't start pressing won't do action
(is-within-aabb (path in-state > start-pressed-position) position size))))
(defstruct-local font-glyph
symbol char
@ -777,7 +851,6 @@ Rush Hour database from Michael Fogleman.\n\n")
(var is-day-mode bool false)
(var selected-piece (* board-piece) null)
(var selection-start-position vec2 (array 0))
(var current-move-count int 0)
(var in-state input-state (array 0))
@ -848,40 +921,39 @@ Rush Hour database from Michael Fogleman.\n\n")
(unless selected-piece ;; If holding, allow dragging even when not exactly on piece
(set selection-start-position mouse-position)
(set selected-piece (pick-game-piece-from-screen-position mouse-position))))
(block
(when selected-piece
;; Selection released; let block finish move and update grid
(var delta-grid-movement grid-vec2
(array
(type-cast
(round
(/ (vec-x (path selected-piece > moving-position))
g-game-board-cell-size-px)) int)
(type-cast
(round
(/ (vec-y (path selected-piece > moving-position))
g-game-board-cell-size-px)) int)))
(debug-log "%f %f becomes %d %d\n"
(vec-x (path selected-piece > moving-position))
(vec-y (path selected-piece > moving-position))
(vec-xy delta-grid-movement))
(var new-position grid-vec2
(grid-vec2-add (path selected-piece > grid-position) delta-grid-movement))
(unless (is-within-grid new-position)
(set exit-reason "Piece movement constraints failed to keep piece on board")
(break))
(when (or (!= 0 (vec-x delta-grid-movement))
(!= 0 (vec-y delta-grid-movement)))
(incr current-move-count))
(set (path selected-piece > grid-position) new-position)
;; Remove the moving position difference from changing grid position, b/c moving is relative
(set (vec-x (path selected-piece > moving-position))
(- (vec-x (path selected-piece > moving-position))
(* g-game-board-cell-size-px (vec-x delta-grid-movement))))
(set (vec-y (path selected-piece > moving-position))
(- (vec-y (path selected-piece > moving-position))
(* g-game-board-cell-size-px (vec-y delta-grid-movement))))
(game-board-sync-occupied-state))
(when selected-piece
;; Selection released; let block finish move and update grid
(var delta-grid-movement grid-vec2
(array
(type-cast
(round
(/ (vec-x (path selected-piece > moving-position))
g-game-board-cell-size-px)) int)
(type-cast
(round
(/ (vec-y (path selected-piece > moving-position))
g-game-board-cell-size-px)) int)))
(debug-log "%f %f becomes %d %d\n"
(vec-x (path selected-piece > moving-position))
(vec-y (path selected-piece > moving-position))
(vec-xy delta-grid-movement))
(var new-position grid-vec2
(grid-vec2-add (path selected-piece > grid-position) delta-grid-movement))
(unless (is-within-grid new-position)
(set exit-reason "Piece movement constraints failed to keep piece on board")
(break))
(when (or (!= 0 (vec-x delta-grid-movement))
(!= 0 (vec-y delta-grid-movement)))
(make-action selected-piece delta-grid-movement)
(set (path selected-piece > grid-position) new-position)
;; Remove the moving position difference from changing grid position, b/c moving is relative
(set (vec-x (path selected-piece > moving-position))
(- (vec-x (path selected-piece > moving-position))
(* g-game-board-cell-size-px (vec-x delta-grid-movement))))
(set (vec-y (path selected-piece > moving-position))
(- (vec-y (path selected-piece > moving-position))
(* g-game-board-cell-size-px (vec-y delta-grid-movement))))
(game-board-sync-occupied-state))
(set selected-piece nullptr)))
(SDL_RenderClear renderer)
@ -895,20 +967,11 @@ Rush Hour database from Michael Fogleman.\n\n")
(when (do-button (addr in-state) (array 10.f 10.f) (array 166.f 166.f) renderer theme-button-texture)
(set is-day-mode (not is-day-mode)))
(when (do-button (addr in-state) (array 190.f 1900.f) (array 166.f 166.f) renderer undo-button-texture)
(set current-move-count 0)
(game-board-load-next-puzzle))
(unless selected-piece ;; Don't allow undo while also moving another piece
(undo-action)))
(when (do-button (addr in-state) (array 724.f 1900.f) (array 166.f 166.f) renderer next-button-texture)
(set current-move-count 0)
(game-board-load-next-puzzle)))
;; Pointer position
;; (scope ;; TODO REMOVE
;; (var src-rect SDL_Rect (array (vec-xy-to-int piece-primary-origin)
;; 166 166))
;; (var dest-rect SDL_Rect (array (vec-xy-to-int mouse-position)
;; 166 166))
;; (SDL_RenderCopy renderer pieces-texture (addr src-rect) (addr dest-rect)))
;; (when (not is-day-mode) ;; Draw grid
(ignore ;; Draw grid
(var row int 0)
@ -979,7 +1042,7 @@ Rush Hour database from Michael Fogleman.\n\n")
(var turns-buffer ([] 8 char) (array 0))
(var num-printed int
(snprintf turns-buffer (array-size turns-buffer)
"%d/%d" current-move-count (? g-current-puzzle (path g-current-puzzle > num-moves) 0)))
"%d/%d" g-current-move-count (? g-current-puzzle (path g-current-puzzle > num-moves) 0)))
(set (at num-printed turns-buffer) 0)
(draw-string renderer font-texture turns-buffer (array 600.f 10.f)))
@ -989,7 +1052,7 @@ Rush Hour database from Michael Fogleman.\n\n")
(snprintf fps-buffer (array-size fps-buffer)
"%d" (type-cast (/ 1.f delta-time) int)))
(set (at num-printed fps-buffer) 0)
(draw-string renderer font-texture fps-buffer (array 700.f 2000.f)))
(draw-string renderer font-texture fps-buffer (array 700.f 2100.f)))
(when (is-in-win-state)
(var dest-rect SDL_Rect (array 60 140 960 500))

Loading…
Cancel
Save