(comptime-define-symbol 'Unix) (comptime-define-symbol 'No-Kitty-Main) (define-constant DATA_DIR "data/") ;; Until GameLib is relocatable, we will build from it; All comptime paths in this file are relative ;; to Dependencies/gamelib! ;; (add-cakelisp-search-directory "Dependencies/gamelib/src") ;; (set-cakelisp-option cakelisp-src-dir "Dependencies/gamelib/Dependencies/cakelisp/src") ;; (add-cakelisp-search-directory "Dependencies/gamelib/Dependencies/cakelisp/runtime") (add-cakelisp-search-directory "src" "Dependencies/cakelisp/runtime" ;; kitty-gridlock src "../../src") (import "SDL.cake" ;; GameLib "Main.cake" ;; kitty-gridlock &comptime-only "Macros.cake" "BuildTools.cake") ;; cakelisp/runtime (c-import "" "" "SDL.h" "SDL_rwops.h") (defun-local read-puzzles-text (&return bool) (var puzzles-file (* FILE) (fopen (in-data-dir "puzzles.txt") "r")) (unless puzzles-file (SDL_Log "Failed to load puzzles. Did the pre-build step generate-puzzles-list fail? You can also run Decompression.cake directly (see Build.sh)\n") (return true)) ;; 48 = max length of a single line in puzzles .txt (var line-buffer ([] 48 char) (array 0)) (unless (fgets line-buffer (array-size line-buffer) puzzles-file) (SDL_Log "Puzzle file malformed\n") (return false)) (var num-puzzles int (atoi line-buffer)) (SDL_Log "Reading %d puzzles\n" num-puzzles) (when g-puzzle-list (free (type-cast g-puzzle-list (* void)))) (set g-num-puzzles num-puzzles) (set g-puzzle-list (type-cast (calloc g-num-puzzles (sizeof (type puzzle-data))) (* puzzle-data))) ;; Read puzzles line by line (var current-puzzle (* puzzle-data) g-puzzle-list) (while (and (fgets line-buffer (array-size line-buffer) puzzles-file) (< (- current-puzzle g-puzzle-list) g-num-puzzles)) (var num-moves int 0) (var num-states int 0) (var pieces-read bool false) (var buffer ([] 37 char) (array 0)) (var write-char (* char) buffer) (var current-char (* (const char)) line-buffer) (while (deref current-char) (cond ;; Space field delimiter ((= (deref current-char) (space-hack)) (cond ((not num-moves) (set num-moves (atoi buffer))) (true ;; Copy pieces ;; TODO Magic number (memcpy (path current-puzzle > board) buffer 36) (set pieces-read true))) ;; Reset buffer after space (memset buffer 0 (sizeof buffer)) (set write-char buffer)) ((= (deref current-char) '\n') (break)) (true (set (deref write-char) (deref current-char)) (incr write-char))) (incr current-char)) (set (path current-puzzle > num-moves) num-moves) (set num-states (atoi buffer)) (set (path current-puzzle > num-states) num-states) (incr current-puzzle)) (fclose puzzles-file) (return (> g-num-puzzles 0))) (var g-puzzle-binary-version Uint32 1) (defun-local write-puzzles-binary (filename (* (const char)) &return bool) (unless g-num-puzzles (SDL_Log "No puzzles to write\n") (return false)) (var puzzles-file (* SDL_RWops) (SDL_RWFromFile filename "w")) (unless puzzles-file (SDL_Log "Failed to open puzzles output file\n") (return false)) (SDL_WriteLE32 puzzles-file g-puzzle-binary-version) (SDL_WriteLE32 puzzles-file g-num-puzzles) (unless (SDL_RWwrite puzzles-file g-puzzle-list (sizeof (type puzzle-data)) g-num-puzzles) (SDL_Log "Failed to write puzzles\n") (return false)) (SDL_RWclose puzzles-file) (return true)) (defun read-puzzles-binary (filename (* (const char)) &return bool) (when g-puzzle-list (free (type-cast g-puzzle-list (* void))) (set g-puzzle-list null)) (var puzzles-file (* SDL_RWops) (SDL_RWFromFile filename "r")) (unless puzzles-file (SDL_Log "Failed to open puzzles output file\n") (return false)) (var version Uint32 (SDL_ReadLE32 puzzles-file)) (unless (= g-puzzle-binary-version version) (SDL_Log "Version mismatch: expected %d, got %d\n" g-puzzle-binary-version version) (return false)) (set g-num-puzzles (SDL_ReadLE32 puzzles-file)) (unless g-num-puzzles (SDL_Log "No puzzles to read\n") (return false)) (set g-puzzle-list (type-cast (calloc g-num-puzzles (sizeof (type puzzle-data))) (* puzzle-data))) (unless (SDL_RWread puzzles-file g-puzzle-list (sizeof (type puzzle-data)) g-num-puzzles) (SDL_Log "Failed to read puzzles\n") (return false)) ;; Not even sure if this will work, but I don't care too much about this (var test-num-moves int (field (at 0 g-puzzle-list) num-moves)) (when (or (< test-num-moves 0) (> test-num-moves 60)) (SDL_Log "Possible endianness mismatch. Puzzles will need to be loaded with converted endianness\n") (return false)) (SDL_RWclose puzzles-file) (return true)) (comptime-cond ('Kitty-Main) (true (defun main (&return int) (unless (read-puzzles-text) (return 1)) (unless (write-puzzles-binary (in-data-dir "puzzles.bin")) (return 1)) (unless (read-puzzles-binary (in-data-dir "puzzles.bin")) (return 1)) (return 0)))) ;; ;; Building ;; (module-use-sdl-build-options) (add-library-runtime-search-directory "Dependencies/gamelib/Dependencies/SDL/buildSDLBuild/lib") ;; Note that this executable still pulls .so files from Dependencies (comptime-cond ('Kitty-Main) (true (set-cakelisp-option executable-output "../../generate-puzzles") ;; Need a label so that our special version of Main.cake isn't used (add-build-config-label "GeneratePuzzles")))