|
|
@ -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)) |
|
|
|