]> git.jsancho.org Git - gacela.git/blob - src/gacela.scm
(no commit message)
[gacela.git] / src / gacela.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 ;;; Default values for Gacela
19
20 (define *width-screen* 640)
21 (define *height-screen* 480)
22 (define *bpp-screen* 32)
23 (define *frames-per-second* 20)
24
25
26 ;;; SDL Initialization Subsystem
27
28 (define init-sdl #f)
29 (define sdl-on? #f)
30 (define quit-sdl #f)
31
32 (let ((initialized #f))
33   (set! init-sdl
34         (lambda ()
35           (cond ((not initialized) (SDL_Init SDL_INIT_EVERYTHING) (set! initialized #t))
36                 (else initialized))))
37
38   (set! sdl-on?
39         (lambda ()
40           (if initialized #t #f)))
41
42   (set! quit-sdl
43         (lambda ()
44           (SDL_Quit)
45           (set! initialized #f))))
46
47
48 ;;; Video Subsystem
49
50 (define init-video-mode #f)
51 (define video-mode-on? #f)
52 (define resize-screen #f)
53 (define quit-video-mode #f)
54
55 (let ((screen #f) (flags 0))
56   (set! init-video-mode
57         (lambda ()
58           (cond ((not screen)
59                  (init-sdl)
60                  (let* ((props (get-game-properties))
61                         (width (assoc-ref props 'width)) (height (assoc-ref props 'height))
62                         (bpp (assoc-ref props 'bpp)) (title (assoc-ref props 'title))
63                         (mode (assoc-ref props 'mode))
64                         (info (SDL_GetVideoInfo)))
65                    (SDL_GL_SetAttribute SDL_GL_DOUBLEBUFFER 1)
66                    (set! flags (+ SDL_OPENGL SDL_GL_DOUBLEBUFFER SDL_HWPALETTE SDL_RESIZABLE
67                                   (if (= (assoc-ref info 'hw_available) 0) SDL_SWSURFACE SDL_HWSURFACE)
68                                   (if (= (assoc-ref info 'blit_hw) 0) 0 SDL_HWACCEL)))
69                    (set! screen (SDL_SetVideoMode width height bpp flags))
70                    (SDL_WM_SetCaption title "")
71                    (init-gl)
72                    (if (eq? mode '3d) (set-3d-mode) (set-2d-mode))))
73                 (else #t))))
74
75   (set! video-mode-on?
76         (lambda () (if screen #t #f)))
77
78   (set! resize-screen
79         (lambda* (width height #:optional (bpp current-bpp))
80           (cond (screen (set! screen (SDL_SetVideoMode width height bpp flags))
81                         (resize-screen-GL width height)))))
82
83   (set! quit-video-mode
84         (lambda () (set! screen #f))))
85
86 (define (set-2d-mode)
87   (cond ((not (3d-mode?))
88          (init-video-mode)
89          (glDisable GL_DEPTH_TEST)
90          (apply-mode-change))))
91
92 (define (set-3d-mode)
93   (cond ((3d-mode?)
94          (init-video-mode)
95          (glClearDepth 1)
96          (glEnable GL_DEPTH_TEST)
97          (glDepthFunc GL_LEQUAL)
98          (apply-mode-change))))
99
100 (define (apply-mode-change)
101   (let* ((props (get-game-properties))
102          (width (assoc-ref props 'width)) (height (assoc-ref props 'height)))
103     (resize-screen-GL width height)))
104
105 (define (3d-mode?)
106   (eq? (assoc-ref (get-game-properties) 'mode) '3d))
107
108 (define (init-gl)
109   (glShadeModel GL_SMOOTH)
110   (glClearColor 0 0 0 0)
111 ;  (glClearDepth 1)
112 ;  (glDepthFunc GL_LEQUAL)
113 ;  (glEnable GL_BLEND)
114 ;  (glBlendFunc GL_SRC_ALPHA GL_ONE)
115   (glHint GL_PERSPECTIVE_CORRECTION_HINT GL_NICEST)
116   #t)
117
118 (define (init-lighting)
119   (init-video-mode)
120   (glEnable GL_LIGHTING))
121
122 (define (resize-screen-GL width height)
123   (glViewport 0 0 width height)
124   (glMatrixMode GL_PROJECTION)
125   (glLoadIdentity)
126   (cond ((3d-mode?) (let ((ratio (if (= height 0) width (/ width height))))
127                       (gluPerspective 45 ratio 0.1 100))) ;0.1
128         (else (let* ((w (/ width 2)) (h (/ height 2)))
129                 (glOrtho (- w) w (- h) h 0 1))))
130   (glMatrixMode GL_MODELVIEW)
131   (glLoadIdentity)
132   #t)
133
134 (define get-current-color #f)
135 (define set-current-color #f)
136
137 (let ((current-color '(1 1 1 1)))
138   (set! get-current-color
139         (lambda ()
140           current-color))
141
142   (set! set-current-color
143         (lambda* (red green blue #:optional (alpha 1))
144           (set! current-color (list red green blue alpha))
145           (glColor4f red green blue alpha))))
146
147
148 ;;; Audio Subsystem
149
150 (define init-audio #f)
151 (define quit-audio #f)
152
153 (let ((audio #f))
154   (set! init-audio
155         (lambda ()
156           (cond ((not audio) (begin (init-sdl) (set! audio (Mix_OpenAudio 22050 MIX_DEFAULT_FORMAT 2 4096))))
157                 (else audio))))
158
159   (set! quit-audio
160         (lambda ()
161           (Mix_CloseAudio)
162           (set! audio #f))))
163
164
165 ;;; GaCeLa Functions
166
167 (define set-frames-per-second #f)
168 (define init-frame-time #f)
169 (define delay-frame #f)
170
171 (let ((time 0) (time-per-frame (/ 1000.0 *frames-per-second*)))
172   (set! set-frames-per-second
173         (lambda (fps)
174           (set! time-per-frame (/ 1000.0 fps))))
175
176   (set! init-frame-time
177         (lambda ()
178           (set! time (SDL_GetTicks))))
179
180   (set! delay-frame
181         (lambda ()
182           (let ((frame-time (- (SDL_GetTicks) time)))
183             (cond ((< frame-time time-per-frame)
184                    (SDL_Delay (- time-per-frame frame-time))))))))
185
186
187 (define set-game-properties #f)
188 (define get-game-properties #f)
189
190 (let ((ptitle "") (pwidth *width-screen*) (pheight *height-screen*) (pbpp *bpp-screen*) (pfps *frames-per-second*) (pmode '2d))
191   (set! set-game-properties
192         (lambda* (#:key title width height bpp fps mode)
193 ;         (init-video-mode)
194           (if title
195               (begin
196                 (set! ptitle title)
197                 (if (video-mode-on?) (SDL_WM_SetCaption title ""))))
198           (if (or width height bpp)
199               (begin
200                 (if width (set! pwidth width))
201                 (if height (set! pheight height))
202                 (if bpp (set! pbpp bpp))
203                 (if (video-mode-on?) (resize-screen pwidth pheight pbpp))))
204           (if fps
205               (begin
206                 (set! pfps fps)
207                 (set-frames-per-second fps)))
208           (if mode
209               (begin
210                 (set! pmode mode)
211                 (if (video-mode-on?)
212                     (if (eq? mode '3d) (set-3d-mode) (set-2d-mode)))))
213           (get-game-properties)))
214
215   (set! get-game-properties
216         (lambda ()
217           `((title . ,ptitle) (width . ,pwidth) (height . ,pheight) (bpp . ,pbpp) (fps . ,pfps) (mode . ,pmode)))))
218
219
220 (define-macro (run-game . code)
221   `(let ((game-function ,(if (null? code)
222                              `(lambda () #f)
223                              `(lambda () ,@code))))
224      (init-video-mode)
225      (set-game-code game-function)
226      (cond ((not (game-running?))
227             (game-loop)))))
228
229 (define game-loop #f)
230 (define game-running? #f)
231 (define set-game-code #f)
232
233 (let ((running #f) (game-code #f) (mobs '()))
234   (set! game-loop
235         (lambda ()
236           (set! mobs (get-active-mobs))
237           (set! running #t)
238           (quit! #f)
239           (do () ((quit?))
240             (init-frame-time)
241             (check-connections)
242             (eval-from-clients)
243             (process-events)
244             (cond ((not (quit?))
245                    (cond ((video-mode-on?)
246                           (glClear (+ GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT))
247                           (to-origin)))
248                    (cond ((mobs-changed?) (set! mobs (get-active-mobs))))
249                    (if (procedure? game-code) (game-code))
250                    (run-mob-actions mobs)
251                    (cond ((video-mode-on?)
252                           (render-mobs mobs)
253                           (SDL_GL_SwapBuffers)))
254                    (delay-frame))))
255           (set! running #f)))
256
257   (set! game-running?
258         (lambda ()
259           running))
260
261   (set! set-game-code
262         (lambda (game-function)
263           (set! game-code game-function))))
264
265 (define (quit-game)
266    (quit-audio)
267    (quit-video-mode)
268 ;  (quit-all-mobs)
269 ;   (kill-all-objects)
270 ;   (clear-events)
271    (quit-events)
272    (quit-sdl))