A Rush Hour game made with Cakelisp
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
5.6 KiB

(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 "<stdio.h>" "<stdlib.h>"
"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")))