]> git.jsancho.org Git - gacela.git/blob - src/views.scm
Extensions for main loop (meshes, controllers, etc)
[gacela.git] / src / views.scm
1 ;;; Gacela, a GNU Guile extension for fast games development
2 ;;; Copyright (C) 2009 by Javier Sancho Fernandez <jsf at jsancho dot org>
3 ;;;
4 ;;; This program is free software: you can redistribute it and/or modify
5 ;;; it under the terms of the GNU General Public License as published by
6 ;;; the Free Software Foundation, either version 3 of the License, or
7 ;;; (at your option) any later version.
8 ;;;
9 ;;; This program is distributed in the hope that it will be useful,
10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 ;;; GNU General Public License for more details.
13 ;;;
14 ;;; You should have received a copy of the GNU General Public License
15 ;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17
18 (define-module (gacela views)
19   #:use-module (gacela gacela)
20   #:use-module ((gacela video) #:renamer (symbol-prefix-proc 'video:))
21   #:use-module ((gacela gl) #:select (glPushMatrix glPopMatrix))
22   #:use-module (ice-9 optargs))
23
24
25 (define default-view (make-hash-table))
26
27 (define* (draw-meshes #:optional (meshes (hash-map->list (lambda (k v) v) default-view)))
28   (cond ((not (null? meshes))
29          (catch #t
30                   (lambda () (mesh-draw (car meshes)))
31                   (lambda (key . args) #f))
32          (draw-meshes (cdr meshes)))))
33
34 (add-extension! draw-meshes 50)
35
36 (define-macro (define-view name content)
37   `(begin
38      (hash-set! active-views ',name (lambda () (video:glmatrix-block ,content)))
39      ',name))
40
41 (define mesh-type
42   (make-record-type "mesh" 
43                     '(draw translate turn rotate inner-properties inner-property properties properties-set! property property-set!)))
44
45 (define mesh-constructor (record-constructor mesh-type))
46 (define mesh? (record-predicate mesh-type))
47
48 (define (mesh proc)
49   (apply
50    mesh-constructor
51    (let ((px 0) (py 0) (pz 0)
52          (ax 0) (ay 0) (az 0)
53          (rx 0) (ry 0) (rz 0)
54          (id (gensym))
55          (properties '()))
56      (let ((inner-properties
57             (lambda ()
58               `((id . ,id) (x . ,px) (y . ,py) (z . ,pz) (ax . ,ax) (ay . ,ay) (az . ,az) (rx . ,rx) (ry . ,ry) (rz . ,rz)))))
59        (list
60         (lambda ()
61           "draw"
62           (video:glmatrix-block
63            (video:rotate ax ay az)
64            (video:translate px py pz)
65            (video:rotate rx ry rz)
66            (proc properties)))
67         (lambda (x y z)
68           "translate"
69           (set! px (+ px x))
70           (set! py (+ py y))
71           (set! pz (+ pz z)))
72         (lambda (x y z)
73           "turn"
74           (set! ax (+ ax x))
75           (set! ay (+ ay y))
76           (set! az (+ az z)))
77         (lambda (x y z)
78           "rotate"
79           (set! rx (+ rx x))
80           (set! ry (+ ry y))
81           (set! rz (+ rz z)))
82         (lambda ()
83           "inner-properties"
84           (inner-properties))
85         (lambda (prop-name)
86           "inner-property"
87           (assoc-ref (inner-properties) prop-name))
88         (lambda ()
89           "properties"
90           properties)
91         (lambda (new-properties)
92           "properties-set!"
93           (set! properties new-properties))
94         (lambda (prop-name)
95           "property"
96           (assoc-ref properties prop-name))
97         (lambda (prop-name value)
98           "property-set!"
99           (set! properties (assoc-set! properties prop-name value))))))))
100
101 (define (mesh-draw mesh)
102   (((record-accessor mesh-type 'draw) mesh)))
103
104 (define (mesh-inner-property mesh prop-name)
105   (((record-accessor mesh-type 'inner-property) mesh) prop-name))
106
107 (define (mesh-properties mesh)
108   (((record-accessor mesh-type 'properties) mesh)))
109
110 (define (mesh-properties-set! mesh new-properties)
111   (((record-accessor mesh-type 'properties-set!) mesh) new-properties))
112
113 (define* (show mesh #:optional (view default-view))
114   (let ((id (mesh-inner-property mesh 'id)))
115     (if (not (hash-ref view id))
116         (hash-set! view id mesh))))
117
118 (define* (hide mesh #:optional (view default-view))
119   (hash-remove! view (mesh 'inner-property 'id)))
120
121 (define* (translate mesh x y #:optional (z 0))
122   (mesh 'translate x y z)
123   mesh)
124
125 (define (turn mesh . params)
126   (if (>= (length params) 3)
127       (apply mesh (cons 'turn params))
128       (mesh 'turn 0 0 (car params)))
129   mesh)
130
131 (define (rotate mesh . params)
132   (if (>= (length params) 3)
133       (apply mesh (cons 'rotate params))
134       (mesh 'rotate 0 0 (car params)))
135   mesh)
136
137
138 ;;; Primitives
139
140 (define-macro (primitive proc)
141   `(lambda (. params)
142      (let ((m (mesh (lambda (props) (apply ,proc ((@ (gacela utils) arguments-apply) ,proc props))))))
143        (mesh-properties-set! m ((@ (gacela utils) arguments-calling) ,proc params))
144        m)))
145
146 (define-macro (define-primitives . symbols)
147   (cond ((null? symbols)
148          `#t)
149         (else
150          (let ((origin (caar symbols))
151                (dest (cadar symbols)))
152            `(begin
153               (define ,origin (primitive ,dest))
154               (define-primitives ,@(cdr symbols)))))))
155
156 (define-primitives
157   (rectangle video:draw-rectangle)
158   (square video:draw-square))
159
160
161 (module-map (lambda (sym var)
162               (if (not (eq? sym '%module-public-interface))
163                   (module-export! (current-module) (list sym))))
164             (current-module))