|
|
@ -19,9 +19,9 @@ |
|
|
|
(define-constant DATA_DIR "data/") |
|
|
|
|
|
|
|
(defmacro in-data-dir (path-in-data string) |
|
|
|
(tokenize-push output |
|
|
|
(static-string-combine DATA_DIR (token-splice path-in-data))) |
|
|
|
(return true)) |
|
|
|
(tokenize-push output |
|
|
|
(static-string-combine DATA_DIR (token-splice path-in-data))) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
;; Made for OnePlus 6T screen |
|
|
|
(var g-window-width (const int) 1080) |
|
|
@ -49,18 +49,20 @@ |
|
|
|
;; |
|
|
|
|
|
|
|
(defstruct-local grid-vec2 |
|
|
|
X int |
|
|
|
Y int) |
|
|
|
X int |
|
|
|
Y int) |
|
|
|
|
|
|
|
(defstruct-local board-piece |
|
|
|
grid-position grid-vec2 ;; Always from the top left |
|
|
|
moving-position vec2 ;; Floating point for animation, smooth dragging |
|
|
|
num-cells int |
|
|
|
is-vertical bool |
|
|
|
grid-position grid-vec2 ;; Always from the top left |
|
|
|
moving-position vec2 ;; Floating point for animation, smooth dragging |
|
|
|
|
|
|
|
num-cells int ;; If 0, piece is empty |
|
|
|
is-vertical bool |
|
|
|
|
|
|
|
is-wall bool |
|
|
|
is-primary-piece bool |
|
|
|
|
|
|
|
exists bool ;; Empty slots in the array will have this as false |
|
|
|
is-wall bool |
|
|
|
is-primary-piece bool) |
|
|
|
label char) |
|
|
|
|
|
|
|
;; Pieces are stored separately, then their positions inform occupied state, which is used to check |
|
|
|
;; movement constraints. null = empty cell. Pointers used to easily pick from tap/click |
|
|
@ -80,27 +82,94 @@ |
|
|
|
(var (token-splice piece-pointer-name) (* board-piece) |
|
|
|
(addr (at next-piece-index g-game-board-pieces))) |
|
|
|
(incr next-piece-index) ;; In case expansions include (continue), we've already incremented |
|
|
|
(when (path (token-splice piece-pointer-name) > exists) |
|
|
|
(when (path (token-splice piece-pointer-name) > num-cells) |
|
|
|
(token-splice-rest body tokens)))) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
(defun-local print-board-piece (piece (* (const board-piece)))) |
|
|
|
|
|
|
|
(defun-local game-board-sync-occupied-state () |
|
|
|
(defun-local print-board-piece (piece (* (const board-piece))) |
|
|
|
(printf "Piece %p |
|
|
|
\n\tgrid-position %d %d |
|
|
|
\n\tmoving-position %f %f |
|
|
|
\n\tnum-cells %d |
|
|
|
\n\tis-vertical %d |
|
|
|
\n\tis-wall %d |
|
|
|
\n\tis-primary-piece %d\n\n" piece |
|
|
|
(field (path piece > grid-position) X) (field (path piece > grid-position) Y) |
|
|
|
(field (path piece > moving-position) X) (field (path piece > moving-position) Y) |
|
|
|
(path piece > num-cells) |
|
|
|
(path piece > is-vertical) |
|
|
|
(path piece > is-wall) |
|
|
|
(path piece > is-primary-piece))) |
|
|
|
|
|
|
|
(defun-local game-board-sync-occupied-state (&return bool) |
|
|
|
;; Zero out to make overlap validation easy |
|
|
|
(memset g-game-board-occupied-state 0 (array-size g-game-board-occupied-state)) |
|
|
|
(on-each-existing-board-piece |
|
|
|
piece |
|
|
|
(print-board-piece piece) |
|
|
|
;; TODO: Determine occupied, error if pointer already set |
|
|
|
)) |
|
|
|
|
|
|
|
(var num-cells int (path piece > num-cells)) |
|
|
|
|
|
|
|
(scope ;; Validate that piece does not go off board |
|
|
|
(when (or (>= (vec-x (path piece > grid-position)) g-game-board-grid-size) |
|
|
|
(< (vec-x (path piece > grid-position)) 0) |
|
|
|
(>= (vec-y (path piece > grid-position)) g-game-board-grid-size) |
|
|
|
(< (vec-y (path piece > grid-position)) 0)) |
|
|
|
(printf "Piece %p origin is off board! Must abort occupied state sync\n" piece) |
|
|
|
(return false)) |
|
|
|
(if (path piece > is-vertical) |
|
|
|
(block ;; Vertical |
|
|
|
(when (> (+ num-cells (vec-y (path piece > grid-position))) g-game-board-grid-size) |
|
|
|
(printf "Piece %p vertical is off board! Must abort occupied state sync\n" piece) |
|
|
|
(return false))) |
|
|
|
(block ;; Horizontal |
|
|
|
(when (> (+ num-cells (vec-x (path piece > grid-position))) g-game-board-grid-size) |
|
|
|
(printf "Piece %p horizontal is off board! Must abort occupied state sync\n" piece) |
|
|
|
(return false))))) |
|
|
|
|
|
|
|
(var cell-offset int 0) |
|
|
|
(while (< cell-offset num-cells) |
|
|
|
(var cell-to-set grid-vec2 (array 0)) |
|
|
|
(if (path piece > is-vertical) |
|
|
|
(block ;; Vertical |
|
|
|
(set (vec-x cell-to-set) (vec-x (path piece > grid-position))) |
|
|
|
(set (vec-y cell-to-set) (+ cell-offset (vec-y (path piece > grid-position))))) |
|
|
|
(block ;; Horizontal |
|
|
|
(set (vec-x cell-to-set) (+ cell-offset (vec-x (path piece > grid-position)))) |
|
|
|
(set (vec-y cell-to-set) (vec-y (path piece > grid-position))))) |
|
|
|
|
|
|
|
(var occupy-space-pointer (* (* board-piece)) |
|
|
|
(addr (at (vec-y cell-to-set) (vec-x cell-to-set) g-game-board-occupied-state))) |
|
|
|
(when (deref occupy-space-pointer) |
|
|
|
(printf "Piece %p overlapping %p at (%d, %d)! Aborting\n" |
|
|
|
piece (deref occupy-space-pointer) |
|
|
|
(vec-xy cell-to-set)) |
|
|
|
(return false)) |
|
|
|
(set (deref occupy-space-pointer) piece) |
|
|
|
(incr cell-offset))) |
|
|
|
|
|
|
|
(var row int 0) |
|
|
|
(while (< row g-game-board-grid-size) |
|
|
|
(var column int 0) |
|
|
|
(while (< column g-game-board-grid-size) |
|
|
|
(var piece-in-cell (* board-piece) (at row column g-game-board-occupied-state)) |
|
|
|
(if (and piece-in-cell (path piece-in-cell > num-cells)) |
|
|
|
(scope |
|
|
|
(var label char (path piece-in-cell > label)) |
|
|
|
(printf "%c " (? label label '#'))) |
|
|
|
(printf ". ")) |
|
|
|
(incr column)) |
|
|
|
(printf "\n") |
|
|
|
(incr row)) |
|
|
|
|
|
|
|
(return true)) |
|
|
|
|
|
|
|
;; |
|
|
|
;; Helpers |
|
|
|
;; |
|
|
|
|
|
|
|
(defun-local sdl-intialize-2d-renderer (renderer-out (* (* SDL_Renderer)) window (* SDL_Window) |
|
|
|
&return bool) |
|
|
|
&return bool) |
|
|
|
(var num-render-drivers int (SDL_GetNumRenderDrivers)) |
|
|
|
(unless num-render-drivers |
|
|
|
(return false)) |
|
|
@ -187,6 +256,20 @@ Rush Hour database from Michael Fogleman.\n\n") |
|
|
|
;; No need to hold on to surface after texture has been created |
|
|
|
(SDL_FreeSurface background-surface) |
|
|
|
|
|
|
|
(set (field (at 0 g-game-board-pieces) num-cells) 3) |
|
|
|
(set (vec-x (field (at 0 g-game-board-pieces) grid-position)) 0) |
|
|
|
(set (vec-y (field (at 0 g-game-board-pieces) grid-position)) 3) |
|
|
|
(set (field (at 0 g-game-board-pieces) is-vertical) true) |
|
|
|
(set (field (at 0 g-game-board-pieces) label) 'b') |
|
|
|
|
|
|
|
(set (field (at 1 g-game-board-pieces) num-cells) 3) |
|
|
|
(set (vec-x (field (at 1 g-game-board-pieces) grid-position)) 2) |
|
|
|
(set (vec-y (field (at 1 g-game-board-pieces) grid-position)) 3) |
|
|
|
(set (field (at 1 g-game-board-pieces) is-vertical) false) |
|
|
|
(set (field (at 1 g-game-board-pieces) label) 'c') |
|
|
|
(unless (game-board-sync-occupied-state) |
|
|
|
(return 1)) |
|
|
|
|
|
|
|
;; |
|
|
|
;; Game loop |
|
|
|
;; |
|
|
|