(module tilemap * (import scheme (chicken io) (chicken base) (chicken pretty-print) (srfi 1) expat defstruct) (defstruct tileset tilewidth tileheight spacing tilecount columns image) (defstruct layer name width height map) (defstruct object name type x y width height properties) (defstruct tilemap width height tilewidth tileheight tileset layers objects) (define (string-alist->alist string-alist) (map (lambda (pair) (cons (string->symbol (car pair)) (cdr pair))) string-alist)) (define (maybe-do action) (lambda (value) (if (eq? value #f) #f (action value)))) (define maybe-string->number (maybe-do string->number)) (define (alist-ref-number key alist) (maybe-string->number (alist-ref key alist))) (define (parse-tilemap string-tilemap) (let ((parser (expat:make-parser)) (tags '()) (tilemap (make-tilemap 0 0 0 0 '() '() '()))) (expat:set-start-handler! parser (lambda (tag attrs) (let ((symbol-attrs (string-alist->alist attrs))) (cond ((string=? tag "map") (pp symbol-attrs) (tilemap-width-set! tilemap (alist-ref-number 'width symbol-attrs)) (tilemap-height-set! tilemap (alist-ref-number 'height symbol-attrs)) (tilemap-tilewidth-set! tilemap (alist-ref-number 'tilewidth symbol-attrs)) (tilemap-tileheight-set! tilemap (alist-ref-number 'tileheight symbol-attrs))) ((string=? tag "tileset") (tilemap-tileset-set! tilemap (alist->tileset symbol-attrs))) ((string=? tag "layer") (tilemap-layers-set! tilemap (cons (alist->layer symbol-attrs) (tilemap-layers tilemap)))) ((string=? tag "object") (tilemap-objects-set! tilemap (cons (alist->object symbol-attrs) (tilemap-objects tilemap)))))))) (expat:set-end-handler! parser (lambda (tag) #f)) (expat:set-character-data-handler! parser (lambda (text) #f)) (expat:parse parser string-tilemap) tilemap)) (define (load-tilemap file-name) (call-with-input-file file-name (lambda (port) (parse-tilemap (read-string port))))) (when #f ;; Demo block (let ((the-map (parse-tilemap " foobar "))) (layer-name (car (tilemap-layers the-map))) ) ;; End demo block ) ) ;; End tilemap module