ps-grid.scm 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. ;;; ps-grid --- An ASCII grid for Pre-Scheme
  2. (define-record-type grid :grid
  3. (%make-grid width height size front-buffer back-buffer)
  4. (width integer grid-width)
  5. (height integer grid-height)
  6. (size integer grid-size)
  7. (front-buffer (^ char) grid-front-buffer %set-grid-front-buffer!)
  8. (back-buffer (^ char) grid-back-buffer %set-grid-back-buffer!))
  9. (define (create-grid width height)
  10. (let* ((size (* width height))
  11. (front (make-vector size #\nul))
  12. (back (make-vector size #\nul)))
  13. (%make-grid width height size front back)))
  14. (define (destroy-grid grid)
  15. (deallocate (grid-front-buffer grid))
  16. (deallocate (grid-back-buffer grid))
  17. (deallocate grid))
  18. (define (grid-buffer-ref grid ix)
  19. (char->ascii (vector-ref (grid-front-buffer grid) ix)))
  20. (define (grid-buffer-set! grid ix value)
  21. (vector-set! (grid-back-buffer grid) ix (ascii->char value)))
  22. (define (grid-buffer-swap! grid)
  23. (let ((tmp (grid-front-buffer grid)))
  24. (%set-grid-front-buffer! grid (grid-back-buffer grid))
  25. (%set-grid-back-buffer! grid tmp)))
  26. (define (wrap n m)
  27. (let ((rem (remainder n m)))
  28. (if (< rem 0)
  29. (+ rem m)
  30. rem)))
  31. (define (grid-index grid x y)
  32. (let ((x (wrap x (grid-width grid)))
  33. (y (wrap y (grid-height grid))))
  34. (+ x (* y (grid-width grid)))))
  35. (define (grid-ref grid x y)
  36. (grid-buffer-ref grid (grid-index grid x y)))
  37. (define (grid-fold proc grid init)
  38. (let ((width (grid-width grid))
  39. (height (grid-height grid)))
  40. (let loop ((ix 0) (x 0) (y 0) (result init))
  41. (cond ((= y height)
  42. result)
  43. ((= x width)
  44. (goto loop ix 0 (+ y 1) result))
  45. (else
  46. (let* ((value (grid-buffer-ref grid ix))
  47. (result (proc ix x y value result)))
  48. (goto loop (+ ix 1) (+ x 1) y result)))))))
  49. (define (grid-for-each proc grid)
  50. (grid-fold (lambda (ix x y value result)
  51. (proc ix x y value)
  52. result)
  53. grid (unspecific)))
  54. (define (grid-update! proc grid)
  55. (grid-for-each (lambda (ix x y value)
  56. (let ((value (proc ix x y value)))
  57. (grid-buffer-set! grid ix value)))
  58. grid)
  59. (grid-buffer-swap! grid))
  60. (define (grid-unfold proc width height)
  61. (let ((grid (create-grid width height)))
  62. (grid-update! (lambda (ix x y value)
  63. (proc ix x y))
  64. grid)
  65. grid))