@ -117,14 +117,12 @@
&rest body any )
( tokenize-push
output
( var next-piece-index int 0 )
( var ( token-splice piece-index-name ) int 0 )
( while ( < next-piece-index ( array-size g-game-board-pieces ) )
( var ( token-splice piece-pointer-name ) ( * board-piece )
( addr ( at next-piece-index g-game-board-pieces ) ) )
( set ( token-splice piece-index-name ) next-piece-index )
( incr next-piece-index ) ;; In case expansions include (continue), we've already incremented
( token-splice-rest body tokens ) ) )
( each-in-array
g-game-board-pieces ( token-splice piece-index-name )
( var ( token-splice piece-pointer-name ) ( * board-piece )
( addr ( at ( token-splice piece-index-name ) g-game-board-pieces ) ) )
( token-splice-rest body tokens ) ) )
( return true ) )
( defmacro on-each-existing-board-piece ( piece-pointer-name symbol piece-index-name symbol
@ -139,19 +137,18 @@
( defun-local game-board-print ( )
( var row int 0 )
( 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-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 ) ) )
( var label char ( path piece-in-cell > label ) )
( SDL_Log "%c " ( ? label label ' #' ) ) )
( SDL_Log ". " ) )
( incr column ) )
( SDL_Log "\n" )
( incr row ) ) )
( each-in-range
g-game-board-grid-size row
( each-in-range
g-game-board-grid-size column
( 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 ) ) )
( var label char ( path piece-in-cell > label ) )
( fprintf stderr "%c " ( ? label label ' #' ) ) )
( fprintf stderr ". " ) ) )
( fprintf stderr "\n" ) ) )
( defun-local print-board-piece ( piece ( * ( const board-piece ) ) index int )
( SDL_Log " Piece %c ( [%d] %p )
@ -200,26 +197,25 @@
( SDL_Log "error: 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 ( * BoardPieceIndex )
( addr ( at ( vec-y cell-to-set ) ( vec-x cell-to-set ) g-game-board-spatial-state ) ) )
( when ( != g-empty-cell ( deref occupy-space-pointer ) )
( SDL_Log "error: Piece %d overlapping %d at (%d, %d)! Aborting\n"
piece-index ( deref occupy-space-pointer )
( vec-xy cell-to-set ) )
( return false ) )
( set ( deref occupy-space-pointer ) piece-index )
( incr cell-offset ) ) )
( each-in-range
num-cells cell-offset
( 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 ( * BoardPieceIndex )
( addr ( at ( vec-y cell-to-set ) ( vec-x cell-to-set ) g-game-board-spatial-state ) ) )
( when ( != g-empty-cell ( deref occupy-space-pointer ) )
( SDL_Log "error: Piece %d overlapping %d at (%d, %d)! Aborting\n"
piece-index ( deref occupy-space-pointer )
( vec-xy cell-to-set ) )
( return false ) )
( set ( deref occupy-space-pointer ) piece-index ) ) )
( when debug-log-enabled
( game-board-print ) )
@ -525,7 +521,7 @@
;; Don't try too hard when the data set is small
( when ( < g-num-progression-puzzles max-num-attempts )
( set max-num-attempts ( * 2 g-num-progression-puzzles ) ) )
( while ( or ( = g-previous-progression-puzzle g-current-progression-puzzle ) ;; Try to ensure change
( path g-current-progression-puzzle > is-solved ) ) ;; Only pick non-solved
( pick-random-progression-puzzle )
@ -714,22 +710,20 @@
( defun-local draw-string ( renderer ( * SDL_Renderer ) font-texture ( * SDL_Texture )
text ( * ( const char ) ) position vec2 )
( var current-position vec2 position )
( var current-char ( * ( const char ) ) text )
( while ( deref current-char )
( var glyph ( * font-glyph ) ( pick-font-glyph-from-character ( deref current-char ) ) )
( unless glyph ;; Missing character
( incr current-char )
( continue ) )
( var dest-rect SDL_Rect ( path glyph > position ) )
( var src-rect SDL_Rect ( path glyph > position ) )
( set ( field dest-rect x ) ( to-float ( vec-x current-position ) ) )
( set ( field dest-rect y ) ( to-float ( vec-y current-position ) ) )
( unless ( = 0 ( SDL_RenderCopy renderer font-texture
( addr src-rect ) ( addr dest-rect ) ) )
( sdl-print-error ) )
( set ( vec-x current-position ) ( + ( vec-x current-position ) ( field src-rect w ) ) )
( incr current-char ) ) )
( each-char-in-string-const
text current-char
( var glyph ( * font-glyph ) ( pick-font-glyph-from-character ( deref current-char ) ) )
( unless glyph ;; Missing character
( continue ) )
( var dest-rect SDL_Rect ( path glyph > position ) )
( var src-rect SDL_Rect ( path glyph > position ) )
( set ( field dest-rect x ) ( to-float ( vec-x current-position ) ) )
( set ( field dest-rect y ) ( to-float ( vec-y current-position ) ) )
( unless ( = 0 ( SDL_RenderCopy renderer font-texture
( addr src-rect ) ( addr dest-rect ) ) )
( sdl-print-error ) )
( set ( vec-x current-position ) ( + ( vec-x current-position ) ( field src-rect w ) ) ) ) )
;;
;; Helpers
@ -940,9 +934,6 @@ Rush Hour database from Michael Fogleman.\n\n")
( var background-night-texture ( * SDL_Texture ) ( sdl-texture-from-bmp ( in-data-dir "Board_Night.bmp" )
renderer ) )
( unless background-night-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
@ -991,7 +982,6 @@ Rush Hour database from Michael Fogleman.\n\n")
( var textures-to-destroy ( [] ( * SDL_Texture ) )
( array main-menu-texture
background-texture
grid-texture
pieces-texture
win-texture
theme-button-texture
@ -1144,26 +1134,6 @@ Rush Hour database from Michael Fogleman.\n\n")
renderer next-button-texture )
( game-board-load-next-puzzle ) ) )
;; (when (not is-day-mode) ;; Draw grid
( ignore ;; 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 ( to-float row ) ( to-float column ) ) )
( 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
( if ( = selected-piece piece )
@ -1344,6 +1314,21 @@ Rush Hour database from Michael Fogleman.\n\n")
( array KeywordNoSpace "\n" -1 ) ) )
( return ( c-statement-out statement ) ) )
( defgenerator c-for ( initializer any conditional any update any &rest &optional body any )
( var statement ( const ( [] CStatementOperation ) )
( array
( array Keyword "for" -1 )
( array OpenParen null -1 )
( array Statement null 1 )
( array Expression null 2 )
( array Keyword ";" -1 )
( array Expression null 3 )
( array CloseParen null -1 )
( array OpenBlock null -1 )
( array Body null 4 )
( array CloseBlock null -1 ) ) )
( return ( c-statement-out statement ) ) )
( defmacro c-statement-out ( statement-operation symbol )
( tokenize-push
output
@ -1372,26 +1357,41 @@ Rush Hour database from Michael Fogleman.\n\n")
( type-cast ( token-splice expression ) float ) )
( return true ) )
;; This only works for arrays where the size is known at compile-time
( defmacro each-in-array ( array-name symbol iterator-name symbol &rest body any )
( tokenize-push
output
( scope
( var num-elements int ( array-size ( token-splice array-name ) ) )
( each-in-range num-elements ( token-splice iterator-name )
( each-in-range ( array-size ( token-splice array-name ) ) ( token-splice iterator-name )
( token-splice-rest body tokens ) ) ) )
( return true ) )
;; TODO: Needs temp var to prevent double eval if range is an express ion
( defmacro each-in-range ( range symbol iterator-name symbol &rest body any )
;; Note: Will reevaluate the range expression each iterat ion
( defmacro each-in-range ( range any iterator-name symbol &rest body any )
( tokenize-push
output
( scope
( var ( token-splice iterator-name ) int 0 )
( var next-iterator int 0 ) ;; TODO needs unique name
( while ( < next-iterator ( token-splice range ) )
( set ( token-splice iterator-name ) next-iterator )
( incr next-iterator )
( token-splice-rest body tokens ) ) ) )
( c-for ( var ( token-splice iterator-name ) int 0 )
( < ( token-splice iterator-name ) ( token-splice range ) )
( incr ( token-splice iterator-name ) )
( token-splice-rest body tokens ) ) )
( return true ) )
( defmacro each-char-in-string ( start-char any iterator-name symbol &rest body any )
( tokenize-push
output
( c-for ( var ( token-splice iterator-name ) ( * char ) ( token-splice start-char ) )
( deref ( token-splice iterator-name ) )
( incr ( token-splice iterator-name ) )
( token-splice-rest body tokens ) ) )
( return true ) )
( defmacro each-char-in-string-const ( start-char any iterator-name symbol &rest body any )
( tokenize-push
output
( c-for ( var ( token-splice iterator-name ) ( * ( const char ) ) ( token-splice start-char ) )
( deref ( token-splice iterator-name ) )
( incr ( token-splice iterator-name ) )
( token-splice-rest body tokens ) ) )
( return true ) )
( defmacro draw-formatted-string ( position any format-string string &rest arguments any )