|
|
@ -72,7 +72,7 @@ |
|
|
|
;; movement constraints. -1 = empty cell. Values are indices into g-game-board-pieces. Used to |
|
|
|
;; easily pick from tap/click |
|
|
|
(def-type-alias BoardPieceIndex char) |
|
|
|
(var g-game-board-occupied-state ([] 6 ([] 6 BoardPieceIndex)) (array 0)) |
|
|
|
(var g-game-board-spatial-state ([] 6 ([] 6 BoardPieceIndex)) (array 0)) |
|
|
|
|
|
|
|
;; Max pieces is determined as follows: |
|
|
|
;; 6x6 grid = 36 squares |
|
|
@ -112,7 +112,7 @@ |
|
|
|
(while (< row g-game-board-grid-size) |
|
|
|
(var column int 0) |
|
|
|
(while (< column g-game-board-grid-size) |
|
|
|
(var index BoardPieceIndex (at row column g-game-board-occupied-state)) |
|
|
|
(var index BoardPieceIndex (at row column g-game-board-spatial-state)) |
|
|
|
(if (and (>= index 0) (field (at index g-game-board-pieces) num-cells)) |
|
|
|
(scope |
|
|
|
(var piece-in-cell (* board-piece) (addr (at index g-game-board-pieces))) |
|
|
@ -141,8 +141,8 @@ |
|
|
|
|
|
|
|
(defun-local game-board-sync-occupied-state (&return bool) |
|
|
|
;; Zero out to make overlap validation easy |
|
|
|
(memset g-game-board-occupied-state -1 |
|
|
|
(sizeof g-game-board-occupied-state)) |
|
|
|
(memset g-game-board-spatial-state -1 |
|
|
|
(sizeof g-game-board-spatial-state)) |
|
|
|
(on-each-existing-board-piece |
|
|
|
piece piece-index |
|
|
|
(when debug-log-enabled |
|
|
@ -179,7 +179,7 @@ |
|
|
|
(set (vec-y cell-to-set) (vec-y (path piece > grid-position))))) |
|
|
|
|
|
|
|
(var occupy-space-pointer (* BoardPieceIndex) |
|
|
|
(addr (at (vec-y cell-to-set) (vec-x cell-to-set) g-game-board-occupied-state))) |
|
|
|
(addr (at (vec-y cell-to-set) (vec-x cell-to-set) g-game-board-spatial-state))) |
|
|
|
(when (!= -1 (deref occupy-space-pointer)) |
|
|
|
(printf "error: Piece %d overlapping %d at (%d, %d)! Aborting\n" |
|
|
|
piece-index (deref occupy-space-pointer) |
|
|
@ -284,6 +284,61 @@ |
|
|
|
(printf "%s\n" fogleman-board-string) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
(defun-local game-piece-position-to-screen-position (piece (* (const board-piece)) &return vec2) |
|
|
|
(var piece-position vec2 (array (type-cast (vec-x (path piece > grid-position)) float) |
|
|
|
(type-cast (vec-y (path piece > grid-position)) float))) |
|
|
|
;; Transfer to pixel space |
|
|
|
(set piece-position (vec2-multiply (array (repeat g-game-board-cell-size-px)) piece-position)) |
|
|
|
;; Add in moving position |
|
|
|
(set piece-position (vec2-add piece-position (path piece > moving-position))) |
|
|
|
;; Add board offset |
|
|
|
(set piece-position (vec2-add piece-position g-game-board-inner-top-left-px)) |
|
|
|
(return piece-position)) |
|
|
|
|
|
|
|
(defun-local game-piece-get-screen-size (piece (* (const board-piece)) &return vec2) |
|
|
|
(var piece-grid-size vec2 |
|
|
|
(array |
|
|
|
(? (path piece > is-vertical) 1.f (type-cast (path piece > num-cells) float)) |
|
|
|
(? (path piece > is-vertical) (type-cast (path piece > num-cells) float) 1.f))) |
|
|
|
(var piece-size vec2 (array (repeat g-game-board-cell-size-px))) |
|
|
|
(set piece-size (vec2-multiply piece-size piece-grid-size)) |
|
|
|
(return piece-size)) |
|
|
|
|
|
|
|
(defun-local is-within-game-piece (piece (* (const board-piece)) point-to-test vec2 &return bool) |
|
|
|
(var piece-top-left-px vec2 (game-piece-position-to-screen-position piece)) |
|
|
|
(var piece-bottom-right-px vec2 (game-piece-get-screen-size piece)) |
|
|
|
(set piece-bottom-right-px (vec2-add piece-top-left-px piece-bottom-right-px)) |
|
|
|
(return |
|
|
|
(and |
|
|
|
(>= (vec-x piece-top-left-px) (vec-x point-to-test)) |
|
|
|
(>= (vec-y piece-top-left-px) (vec-y point-to-test)) |
|
|
|
(< (vec-x piece-bottom-right-px) (vec-x point-to-test)) |
|
|
|
(< (vec-y piece-bottom-right-px) (vec-y point-to-test))))) |
|
|
|
|
|
|
|
(defun-local pick-game-piece-from-screen-position (x int y int &return (* board-piece)) |
|
|
|
(var position vec2 (array (type-cast x float) (type-cast y float))) |
|
|
|
(var board-position vec2 (vec2-subtract position g-game-board-inner-top-left-px)) |
|
|
|
(var grid-position grid-vec2 |
|
|
|
(array (/ (type-cast (vec-x board-position) int) g-game-board-cell-size-px) |
|
|
|
(/ (type-cast (vec-y board-position) int) g-game-board-cell-size-px))) |
|
|
|
|
|
|
|
(unless |
|
|
|
(and |
|
|
|
(>= (vec-x grid-position) 0) |
|
|
|
(>= (vec-y grid-position) 0) |
|
|
|
(< (vec-x grid-position) g-game-board-grid-size) |
|
|
|
(< (vec-y grid-position) g-game-board-grid-size)) |
|
|
|
(return null)) |
|
|
|
|
|
|
|
(var piece-index char |
|
|
|
(at (vec-y grid-position) (vec-x grid-position) g-game-board-spatial-state)) |
|
|
|
(unless (!= -1 piece-index) |
|
|
|
(return null)) |
|
|
|
(var piece (* board-piece) (addr (at piece-index g-game-board-pieces))) |
|
|
|
;; (unless (is-within-game-piece piece position) ;; TODO Broken |
|
|
|
;; (return null)) |
|
|
|
(return piece)) |
|
|
|
|
|
|
|
;; |
|
|
|
;; Helpers |
|
|
|
;; |
|
|
@ -320,6 +375,39 @@ |
|
|
|
(return false)) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
(defun-local sdl-texture-from-bmp (filename (* (const char)) renderer (* SDL_Renderer) |
|
|
|
&return (* SDL_Texture)) |
|
|
|
(var surface (* SDL_Surface) (SDL_LoadBMP filename)) |
|
|
|
(unless surface |
|
|
|
(printf "Failed to load surface\n") |
|
|
|
(sdl-print-error) |
|
|
|
(return null)) |
|
|
|
|
|
|
|
(var texture (* SDL_Texture) |
|
|
|
(SDL_CreateTextureFromSurface renderer surface)) |
|
|
|
;; No need to hold on to surface after texture has been created |
|
|
|
(SDL_FreeSurface surface) |
|
|
|
(unless texture (sdl-print-error)) |
|
|
|
(return texture)) |
|
|
|
|
|
|
|
(defun-local sdl-texture-from-bmp-color-to-transparent |
|
|
|
(filename (* (const char)) renderer (* SDL_Renderer) r char g char b char |
|
|
|
&return (* SDL_Texture)) |
|
|
|
(var surface (* SDL_Surface) (SDL_LoadBMP filename)) |
|
|
|
(unless surface |
|
|
|
(printf "Failed to load surface\n") |
|
|
|
(sdl-print-error) |
|
|
|
(return null)) |
|
|
|
|
|
|
|
(SDL_SetColorKey surface SDL_TRUE (SDL_MapRGB (path surface > format) r g b)) |
|
|
|
|
|
|
|
(var texture (* SDL_Texture) |
|
|
|
(SDL_CreateTextureFromSurface renderer surface)) |
|
|
|
;; No need to hold on to surface after texture has been created |
|
|
|
(SDL_FreeSurface surface) |
|
|
|
(unless texture (sdl-print-error)) |
|
|
|
(return texture)) |
|
|
|
|
|
|
|
;; |
|
|
|
;; Main |
|
|
|
;; |
|
|
@ -333,7 +421,7 @@ Licensed under GPL-3.0-or-later.\n |
|
|
|
Rush Hour database from Michael Fogleman.\n\n") |
|
|
|
|
|
|
|
;; Useful reference for creating assets |
|
|
|
(printf "Window and board dimensions:\n |
|
|
|
(debug-log "Window and board dimensions:\n |
|
|
|
\twindow width: %d\n |
|
|
|
\twindow height: %d\n |
|
|
|
\twindow safe area margin px: %d\n |
|
|
@ -364,34 +452,45 @@ Rush Hour database from Michael Fogleman.\n\n") |
|
|
|
(var renderer (* SDL_Renderer) null) |
|
|
|
(unless (sdl-intialize-2d-renderer (addr renderer) window) (return 1)) |
|
|
|
|
|
|
|
(var background-surface (* SDL_Surface) (SDL_LoadBMP |
|
|
|
(in-data-dir "Board.bmp"))) |
|
|
|
(unless background-surface |
|
|
|
(printf "Failed to load surface. Is the data directory in the right location?\n") |
|
|
|
(sdl-print-error) |
|
|
|
(return 1)) |
|
|
|
(var background-texture (* SDL_Texture) |
|
|
|
(SDL_CreateTextureFromSurface renderer background-surface)) |
|
|
|
(unless background-texture (sdl-print-error) (return 1)) |
|
|
|
;; 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)) 1) |
|
|
|
(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-board-load "60 IBBxooIooLDDJAALooJoKEEMFFKooMGGHHHM 2332") |
|
|
|
|
|
|
|
(var background-texture (* SDL_Texture) (sdl-texture-from-bmp (in-data-dir "Board.bmp") |
|
|
|
renderer)) |
|
|
|
(unless background-texture (return 1)) |
|
|
|
(var grid-texture (* SDL_Texture) (sdl-texture-from-bmp (in-data-dir "Grid.bmp") |
|
|
|
renderer)) |
|
|
|
(unless grid-texture (return 1)) |
|
|
|
|
|
|
|
(var pieces-texture (* SDL_Texture) |
|
|
|
(sdl-texture-from-bmp-color-to-transparent |
|
|
|
"assets/FromV/Exports/KittyGridlockInitialCatAssets.bmp" |
|
|
|
renderer |
|
|
|
0xff 0x00 0xd3)) |
|
|
|
(unless pieces-texture (return 1)) |
|
|
|
;; Texture atlas |
|
|
|
(var piece-primary-origin (const vec2) (array 334.f 525.f)) |
|
|
|
(var piece-2-1-origin (const vec2) (array 534.f 686.f)) |
|
|
|
(var piece-3-1-origin (const vec2) (array 516.f 841.f)) |
|
|
|
(var piece-1-2-origin (const vec2) (array 853.f 519.f)) |
|
|
|
(var piece-1-3-origin (const vec2) (array 843.f 9.f)) |
|
|
|
(var wall-a-origin (const vec2) (array 674.f 507.f)) |
|
|
|
(var wall-b-origin (const vec2) (array 342.f 682.f)) |
|
|
|
|
|
|
|
(ignore ;; Example of setting pieces manually |
|
|
|
(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)) 1) |
|
|
|
(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-board-load "60 IBBxooIooLDDJAALooJoKEEMFFKooMGGHHHM 2332") |
|
|
|
(game-board-load "05 oooooEooDooEAADooEoBBCCCoooooooooooo 69") |
|
|
|
;; |
|
|
|
;; Game loop |
|
|
|
;; |
|
|
@ -405,10 +504,67 @@ Rush Hour database from Michael Fogleman.\n\n") |
|
|
|
(when (at SDL_SCANCODE_ESCAPE currentKeyStates) |
|
|
|
(set exit-reason "Escape pressed")) |
|
|
|
|
|
|
|
(var mouse-x int 0) |
|
|
|
(var mouse-y int 0) |
|
|
|
(var mouse-buttons Uint32 (SDL_GetMouseState (addr mouse-x) (addr mouse-y))) |
|
|
|
|
|
|
|
(var hovered-piece (* board-piece) (pick-game-piece-from-screen-position mouse-x mouse-y)) |
|
|
|
|
|
|
|
(SDL_RenderClear renderer) |
|
|
|
(unless (= 0 (SDL_RenderCopy renderer background-texture null null)) |
|
|
|
(sdl-print-error) |
|
|
|
(return 1)) |
|
|
|
(set exit-reason "Render error")) |
|
|
|
|
|
|
|
(scope ;; Draw grid |
|
|
|
(var row int 0) |
|
|
|
(while (< row g-game-board-grid-size) |
|
|
|
(var column int 0) |
|
|
|
(while (< column g-game-board-grid-size) |
|
|
|
(var current-cell vec2 (array (type-cast row float) (type-cast column float))) |
|
|
|
(var cell-position vec2 |
|
|
|
(vec2-add g-game-board-inner-top-left-px |
|
|
|
(vec2-multiply (array (repeat g-game-board-cell-size-px)) |
|
|
|
current-cell))) |
|
|
|
(var dest-grid-rect SDL_Rect (array (type-cast (vec-x cell-position) int) |
|
|
|
(type-cast (vec-y cell-position) int) |
|
|
|
(repeat g-game-board-cell-size-px))) |
|
|
|
(unless (= 0 (SDL_RenderCopy renderer grid-texture null (addr dest-grid-rect))) |
|
|
|
(sdl-print-error) |
|
|
|
(set exit-reason "Render error")) |
|
|
|
(incr column)) |
|
|
|
(incr row))) |
|
|
|
|
|
|
|
(on-each-existing-board-piece ;; Draw pieces |
|
|
|
piece piece-index |
|
|
|
(when (= hovered-piece piece) |
|
|
|
(continue)) |
|
|
|
(var piece-position vec2 (game-piece-position-to-screen-position piece)) |
|
|
|
|
|
|
|
(var piece-size vec2 (game-piece-get-screen-size piece)) |
|
|
|
|
|
|
|
(var selected-piece-origin vec2 piece-2-1-origin) |
|
|
|
(cond ((path piece > is-primary-piece) ;; Pick atlas texture coords for piece |
|
|
|
(set selected-piece-origin piece-primary-origin)) |
|
|
|
((path piece > is-wall) |
|
|
|
(set selected-piece-origin wall-a-origin)) |
|
|
|
((and (path piece > is-vertical) (= 3 (path piece > num-cells))) |
|
|
|
(set selected-piece-origin piece-1-3-origin)) |
|
|
|
((and (path piece > is-vertical) (= 2 (path piece > num-cells))) |
|
|
|
(set selected-piece-origin piece-1-2-origin)) |
|
|
|
((and (not (path piece > is-vertical)) (= 2 (path piece > num-cells))) |
|
|
|
(set selected-piece-origin piece-2-1-origin)) |
|
|
|
((and (not (path piece > is-vertical)) (= 3 (path piece > num-cells))) |
|
|
|
(set selected-piece-origin piece-3-1-origin))) |
|
|
|
|
|
|
|
(var dest-rect SDL_Rect (array (vec-xy-to-int piece-position) |
|
|
|
(vec-xy-to-int piece-size))) |
|
|
|
(var src-rect SDL_Rect (array (vec-xy-to-int selected-piece-origin) |
|
|
|
(vec-xy-to-int piece-size))) |
|
|
|
(unless (= 0 (SDL_RenderCopy renderer pieces-texture |
|
|
|
(addr src-rect) (addr dest-rect))) |
|
|
|
(sdl-print-error) |
|
|
|
(set exit-reason "Render error"))) |
|
|
|
|
|
|
|
(SDL_RenderPresent renderer)) |
|
|
|
|
|
|
|
;; |
|
|
@ -465,6 +621,19 @@ Rush Hour database from Michael Fogleman.\n\n") |
|
|
|
statement (array-size statement) |
|
|
|
output))) |
|
|
|
|
|
|
|
(defmacro repeat (thing any) |
|
|
|
(tokenize-push |
|
|
|
output |
|
|
|
(token-splice thing) (token-splice thing)) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
(defmacro vec-xy-to-int (vec symbol) |
|
|
|
(tokenize-push |
|
|
|
output |
|
|
|
(type-cast (vec-x (token-splice vec)) int) |
|
|
|
(type-cast (vec-y (token-splice vec)) int)) |
|
|
|
(return true)) |
|
|
|
|
|
|
|
;; |
|
|
|
;; Building |
|
|
|
;; |
|
|
|