]> git.jsancho.org Git - gacela.git/blob - src/gacela_SDL.c
(no commit message)
[gacela.git] / src / gacela_SDL.c
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 #include <libguile.h>
19 #include <SDL/SDL.h>
20 #include <SDL/SDL_events.h>
21 #include <SDL/SDL_image.h>
22 #include <SDL/SDL_mixer.h>
23 #include "gacela_SDL.h"
24
25 struct surface
26 {
27   SCM filename;
28   SDL_Surface *surface_address;
29 };
30
31 static scm_t_bits surface_tag;
32
33 SCM
34 make_surface (SCM file, SDL_Surface *surface_address)
35 {
36   SCM smob;
37   struct surface *surface;
38
39   surface = (struct surface *) scm_gc_malloc (sizeof (struct surface), "surface");
40
41   surface->filename = SCM_BOOL_F;
42   surface->surface_address = NULL;
43
44   SCM_NEWSMOB (smob, surface_tag, surface);
45
46   surface->filename = file;
47   surface->surface_address = surface_address;
48
49   return smob;
50 }
51
52 SDL_Surface *
53 get_surface_address (SCM surface_smob)
54 {
55   struct surface *surface;
56
57   scm_assert_smob_type (surface_tag, surface_smob);
58   surface = (struct surface *) SCM_SMOB_DATA (surface_smob);
59   return surface->surface_address;
60 }
61
62 SCM
63 get_surface_width (SCM surface_smob)
64 {
65   SDL_Surface *surface = get_surface_address (surface_smob);
66
67   return scm_from_int (surface->w);
68 }
69
70 SCM
71 get_surface_height (SCM surface_smob)
72 {
73   SDL_Surface *surface = get_surface_address (surface_smob);
74
75   return scm_from_int (surface->h);
76 }
77
78 SCM
79 get_surface_pixels (SCM surface_smob)
80 {
81   SDL_Surface *surface = get_surface_address (surface_smob);
82
83   return scm_from_int (surface->pixels);
84 }
85
86 SCM
87 get_surface_format_BytesPerPixel (SCM surface_smob)
88 {
89   SDL_Surface *surface = get_surface_address (surface_smob);
90
91   return scm_from_int (surface->format->BytesPerPixel);
92 }
93
94 SCM
95 mark_surface (SCM surface_smob)
96 {
97   struct surface *surface = (struct surface *) SCM_SMOB_DATA (surface_smob);
98
99   scm_gc_mark (surface->filename);
100      
101   return SCM_BOOL_F;
102 }
103
104 size_t
105 free_surface (SCM surface_smob)
106 {
107   struct surface *surface = (struct surface *) SCM_SMOB_DATA (surface_smob);
108
109   SDL_FreeSurface (surface->surface_address);
110   scm_gc_free (surface, sizeof (struct surface), "surface");
111
112   return 0;
113 }
114
115 static int
116 print_surface (SCM surface_smob, SCM port, scm_print_state *pstate)
117 {
118   struct surface *surface = (struct surface *) SCM_SMOB_DATA (surface_smob);
119
120   scm_puts ("#<surface \"", port);
121   scm_display (surface->filename, port);
122   scm_puts ("\">", port);
123
124   /* non-zero means success */
125   return 1;
126 }
127
128
129 SCM
130 gacela_SDL_Init (SCM flags)
131 {
132   return scm_from_int (SDL_Init (scm_to_int (flags)));
133 }
134
135 SCM
136 gacela_SDL_Quit (void)
137 {
138   SDL_Quit ();
139   return SCM_UNSPECIFIED;
140 }
141
142 SCM
143 gacela_SDL_SetVideoMode (SCM width, SCM height, SCM bpp, SCM flags)
144 {
145   SDL_Surface *screen = SDL_SetVideoMode (scm_to_int (width), scm_to_int (height), \
146                                           scm_to_int (bpp), scm_to_int (flags));
147
148   if (screen) {
149     return make_surface (scm_from_locale_string ("screen"), screen);
150   }
151   else {
152     return SCM_BOOL_F;
153   }
154 }
155
156 SCM
157 gacela_SDL_WM_SetCaption (SCM title, SCM icon)
158 {
159   SDL_WM_SetCaption (scm_to_locale_string(title), scm_to_locale_string(icon));
160   return SCM_UNSPECIFIED;
161 }
162
163 SCM
164 gacela_SDL_Flip (SCM screen)
165 {
166   return scm_from_int (SDL_Flip (get_surface_address (screen)));
167 }
168
169 SCM
170 gacela_SDL_Delay (SCM ms)
171 {
172   SDL_Delay ((int)scm_to_double (ms));
173   return SCM_UNSPECIFIED;
174 }
175
176 SCM
177 gacela_SDL_GetTicks (void)
178 {
179   return scm_from_int (SDL_GetTicks ());
180 }
181
182 SCM
183 gacela_SDL_DisplayFormat (SCM surface)
184 {
185   return scm_from_int ((int)SDL_DisplayFormat (get_surface_address (surface)));
186 }
187
188 SCM
189 gacela_SDL_MapRGB (SCM format, SCM r, SCM g, SCM b)
190 {
191   return scm_from_int (SDL_MapRGB ((SDL_PixelFormat *)scm_to_int (format), scm_to_int (r), scm_to_int (g), scm_to_int (b)));
192 }
193
194 SCM
195 gacela_SDL_SetColorKey (SCM surface, SCM flag, SCM key)
196 {
197   return scm_from_int (SDL_SetColorKey (get_surface_address (surface), scm_to_int (flag), scm_to_int (key)));
198 }
199
200 SCM
201 gacela_SDL_LoadBMP (SCM file)
202 {
203   SDL_Surface *image = SDL_LoadBMP (scm_to_locale_string (file));
204
205   if (image) {
206     return make_surface (file, image);
207   }
208   else {
209     return SCM_BOOL_F;
210   }
211 }
212
213 SCM
214 gacela_IMG_Load (SCM filename)
215 {
216   SDL_Surface *image = IMG_Load (scm_to_locale_string (filename));
217
218   if (image) {
219     return make_surface (filename, image);
220   }
221   else {
222     return SCM_BOOL_F;
223   }
224 }
225
226 SCM
227 gacela_SDL_GetVideoInfo (void)
228 {
229   const SDL_VideoInfo *info;
230   SCM vi;
231
232   info = SDL_GetVideoInfo ();
233   vi = scm_list_n (SCM_UNDEFINED);
234
235   vi = scm_cons (scm_cons (scm_from_locale_symbol ("blit_hw"), scm_from_int (info->blit_hw)), vi);
236   vi = scm_cons (scm_cons (scm_from_locale_symbol ("hw_available"), scm_from_int (info->hw_available)), vi);
237
238   return vi;
239 }
240
241 SCM
242 gacela_SDL_GL_SetAttribute (SCM attr, SCM value)
243 {
244   return scm_from_int (SDL_GL_SetAttribute (scm_to_int (attr), scm_to_int (value)));
245 }
246
247 SCM
248 gacela_SDL_PollEvent (void)
249 {
250   SDL_Event sdl_event;
251   SCM event;
252
253   event = scm_list_n (SCM_UNDEFINED);
254
255   if (SDL_PollEvent (&sdl_event)) {
256     switch (sdl_event.type) {
257     case SDL_KEYDOWN:
258     case SDL_KEYUP:
259       event = scm_cons (scm_cons (scm_from_locale_symbol ("key.keysym.sym"), scm_from_int (sdl_event.key.keysym.sym)), event);
260       break;
261     }
262     event = scm_cons (scm_cons (scm_from_locale_symbol ("type"), scm_from_int (sdl_event.type)), event);
263   }
264
265   return event;
266 }
267
268 SCM
269 gacela_SDL_GL_SwapBuffers (void)
270 {
271   SDL_GL_SwapBuffers ();
272   return SCM_UNSPECIFIED;
273 }
274
275 SCM
276 gacela_SDL_EnableKeyRepeat (SCM delay, SCM interval)
277 {
278   return scm_from_int (SDL_EnableKeyRepeat (scm_to_int (delay), scm_to_int (interval)));
279 }
280
281 SCM
282 gacela_Mix_OpenAudio (SCM frequency, SCM format, SCM channels, SCM chunksize)
283 {
284   return scm_from_int (Mix_OpenAudio (scm_to_int (frequency), scm_to_int (format), scm_to_int (channels), scm_to_int (chunksize)));
285 }
286
287 SCM
288 gacela_Mix_LoadMUS (SCM file)
289 {
290   return scm_from_int ((int)Mix_LoadMUS (scm_to_locale_string (file)));
291 }
292
293 SCM
294 gacela_Mix_LoadWAV (SCM file)
295 {
296   return scm_from_int ((int)Mix_LoadWAV (scm_to_locale_string (file)));
297 }
298
299 SCM
300 gacela_Mix_PlayChannel (SCM channel, SCM chunk, SCM loops)
301 {
302   return scm_from_int (Mix_PlayChannel (scm_to_int (channel), (Mix_Chunk *)scm_to_int (chunk), scm_to_int (loops)));
303 }
304
305 SCM
306 gacela_Mix_PlayMusic (SCM music, SCM loops)
307 {
308   return scm_from_int (Mix_PlayMusic ((Mix_Music *)scm_to_int (music), scm_to_int (loops)));
309 }
310
311 SCM
312 gacela_Mix_PlayingMusic (void)
313 {
314   return scm_from_int (Mix_PlayingMusic ());
315 }
316
317 SCM
318 gacela_Mix_PausedMusic (void)
319 {
320   return scm_from_int (Mix_PausedMusic ());
321 }
322
323 SCM
324 gacela_Mix_PauseMusic (void)
325 {
326   Mix_PauseMusic ();
327   return SCM_UNSPECIFIED;
328 }
329
330 SCM
331 gacela_Mix_ResumeMusic (void)
332 {
333   Mix_ResumeMusic ();
334   return SCM_UNSPECIFIED;
335 }
336
337 SCM
338 gacela_Mix_HaltMusic (void)
339 {
340   return scm_from_int (Mix_HaltMusic ());
341 }
342
343 SCM
344 gacela_Mix_FreeMusic (SCM music)
345 {
346   Mix_FreeMusic ((Mix_Music *)scm_to_int (music));
347   return SCM_UNSPECIFIED;
348 }
349
350 SCM
351 gacela_Mix_FreeChunk (SCM chunk)
352 {
353   Mix_FreeChunk ((Mix_Chunk *)scm_to_int (chunk));
354   return SCM_UNSPECIFIED;
355 }
356
357 SCM
358 gacela_Mix_CloseAudio (void)
359 {
360   Mix_CloseAudio ();
361   return SCM_UNSPECIFIED;
362 }
363
364
365 void*
366 SDL_register_functions (void* data)
367 {
368   surface_tag = scm_make_smob_type ("surface", sizeof (struct surface));
369   scm_set_smob_mark (surface_tag, mark_surface);
370   scm_set_smob_free (surface_tag, free_surface);
371   scm_set_smob_print (surface_tag, print_surface);
372   scm_c_define_gsubr ("surface-w", 1, 0, 0, get_surface_width);
373   scm_c_define_gsubr ("surface-h", 1, 0, 0, get_surface_height);
374   scm_c_define_gsubr ("surface-pixels", 1, 0, 0, get_surface_pixels);
375   scm_c_define_gsubr ("surface-format-BytesPerPixel", 1, 0, 0, get_surface_format_BytesPerPixel);
376
377   scm_c_define ("SDL_INIT_TIMER", scm_from_int (SDL_INIT_TIMER));
378   scm_c_define ("SDL_INIT_AUDIO", scm_from_int (SDL_INIT_AUDIO));
379   scm_c_define ("SDL_INIT_VIDEO", scm_from_int (SDL_INIT_VIDEO));
380   scm_c_define ("SDL_INIT_CDROM", scm_from_int (SDL_INIT_CDROM));
381   scm_c_define ("SDL_INIT_JOYSTICK", scm_from_int (SDL_INIT_JOYSTICK));
382   scm_c_define ("SDL_INIT_NOPARACHUTE", scm_from_int (SDL_INIT_NOPARACHUTE));
383   scm_c_define ("SDL_INIT_EVENTTHREAD", scm_from_int (SDL_INIT_EVENTTHREAD));
384   scm_c_define ("SDL_INIT_EVERYTHING", scm_from_int (SDL_INIT_EVERYTHING));
385
386   scm_c_define ("SDL_SWSURFACE", scm_from_int (SDL_SWSURFACE));
387   scm_c_define ("SDL_HWSURFACE", scm_from_int (SDL_HWSURFACE));
388   scm_c_define ("SDL_ASYNCBLIT", scm_from_int (SDL_ASYNCBLIT));
389
390   scm_c_define ("SDL_ANYFORMAT", scm_from_int (SDL_ANYFORMAT));
391   scm_c_define ("SDL_HWPALETTE", scm_from_int (SDL_HWPALETTE));
392   scm_c_define ("SDL_DOUBLEBUF", scm_from_int (SDL_DOUBLEBUF));
393   scm_c_define ("SDL_FULLSCREEN", scm_from_int (SDL_FULLSCREEN));
394   scm_c_define ("SDL_OPENGL", scm_from_int (SDL_OPENGL));
395   scm_c_define ("SDL_OPENGLBLIT", scm_from_int (SDL_OPENGLBLIT));
396   scm_c_define ("SDL_RESIZABLE", scm_from_int (SDL_RESIZABLE));
397   scm_c_define ("SDL_NOFRAME", scm_from_int (SDL_NOFRAME));
398
399   scm_c_define ("SDL_HWACCEL", scm_from_int (SDL_HWACCEL));
400   scm_c_define ("SDL_SRCCOLORKEY", scm_from_int (SDL_SRCCOLORKEY));
401
402   scm_c_define ("SDL_GL_DOUBLEBUFFER", scm_from_int (SDL_GL_DOUBLEBUFFER));
403
404   scm_c_define ("SDL_DEFAULT_REPEAT_DELAY", scm_from_int (SDL_DEFAULT_REPEAT_DELAY));
405   scm_c_define ("SDL_DEFAULT_REPEAT_INTERVAL", scm_from_int (SDL_DEFAULT_REPEAT_INTERVAL));
406
407   scm_c_define ("SDL_LIL_ENDIAN", scm_from_int (SDL_LIL_ENDIAN));
408   scm_c_define ("SDL_BIG_ENDIAN", scm_from_int (SDL_BIG_ENDIAN));
409   scm_c_define ("SDL_BYTEORDER", scm_from_int (SDL_BYTEORDER));
410
411   scm_c_define ("MIX_DEFAULT_FORMAT", scm_from_int (MIX_DEFAULT_FORMAT));
412
413   scm_c_define ("SDL_NOEVENT", scm_from_int (SDL_NOEVENT));
414   scm_c_define ("SDL_ACTIVEEVENT", scm_from_int (SDL_ACTIVEEVENT));
415   scm_c_define ("SDL_KEYDOWN", scm_from_int (SDL_KEYDOWN));
416   scm_c_define ("SDL_KEYUP", scm_from_int (SDL_KEYUP));
417   scm_c_define ("SDL_MOUSEMOTION", scm_from_int (SDL_MOUSEMOTION));
418   scm_c_define ("SDL_MOUSEBUTTONDOWN", scm_from_int (SDL_MOUSEBUTTONDOWN));
419   scm_c_define ("SDL_MOUSEBUTTONUP", scm_from_int (SDL_MOUSEBUTTONUP));
420   scm_c_define ("SDL_JOYAXISMOTION", scm_from_int (SDL_JOYAXISMOTION));
421   scm_c_define ("SDL_JOYBALLMOTION", scm_from_int (SDL_JOYBALLMOTION));
422   scm_c_define ("SDL_JOYHATMOTION", scm_from_int (SDL_JOYHATMOTION));
423   scm_c_define ("SDL_JOYBUTTONDOWN", scm_from_int (SDL_JOYBUTTONDOWN));
424   scm_c_define ("SDL_JOYBUTTONUP", scm_from_int (SDL_JOYBUTTONUP));
425   scm_c_define ("SDL_QUIT", scm_from_int (SDL_QUIT));
426   scm_c_define ("SDL_SYSWMEVENT", scm_from_int (SDL_SYSWMEVENT));
427   scm_c_define ("SDL_EVENT_RESERVEDA", scm_from_int (SDL_EVENT_RESERVEDA));
428   scm_c_define ("SDL_EVENT_RESERVEDB", scm_from_int (SDL_EVENT_RESERVEDB));
429   scm_c_define ("SDL_VIDEORESIZE", scm_from_int (SDL_VIDEORESIZE));
430   scm_c_define ("SDL_VIDEOEXPOSE", scm_from_int (SDL_VIDEOEXPOSE));
431   scm_c_define ("SDL_EVENT_RESERVED2", scm_from_int (SDL_EVENT_RESERVED2));
432   scm_c_define ("SDL_EVENT_RESERVED3", scm_from_int (SDL_EVENT_RESERVED3));
433   scm_c_define ("SDL_EVENT_RESERVED4", scm_from_int (SDL_EVENT_RESERVED4));
434   scm_c_define ("SDL_EVENT_RESERVED5", scm_from_int (SDL_EVENT_RESERVED5));
435   scm_c_define ("SDL_EVENT_RESERVED6", scm_from_int (SDL_EVENT_RESERVED6));
436   scm_c_define ("SDL_EVENT_RESERVED7", scm_from_int (SDL_EVENT_RESERVED7));
437   scm_c_define ("SDL_USEREVENT", scm_from_int (SDL_USEREVENT));
438   scm_c_define ("SDL_NUMEVENTS", scm_from_int (SDL_NUMEVENTS));
439
440   scm_c_define_gsubr ("SDL_Init", 1, 0, 0, gacela_SDL_Init);
441   scm_c_define_gsubr ("SDL_Quit", 0, 0, 0, gacela_SDL_Quit);
442   scm_c_define_gsubr ("SDL_SetVideoMode", 4, 0, 0, gacela_SDL_SetVideoMode);
443   scm_c_define_gsubr ("SDL_WM_SetCaption", 2, 0, 0, gacela_SDL_WM_SetCaption);
444   scm_c_define_gsubr ("SDL_Flip", 1, 0, 0, gacela_SDL_Flip);
445   scm_c_define_gsubr ("SDL_Delay", 1, 0, 0, gacela_SDL_Delay);
446   scm_c_define_gsubr ("SDL_GetTicks", 0, 0, 0, gacela_SDL_GetTicks);
447   scm_c_define_gsubr ("SDL_DisplayFormat", 1, 0, 0, gacela_SDL_DisplayFormat);
448   scm_c_define_gsubr ("SDL_MapRGB", 4, 0, 0, gacela_SDL_MapRGB);
449   scm_c_define_gsubr ("SDL_SetColorKey", 3, 0, 0, gacela_SDL_SetColorKey);
450   scm_c_define_gsubr ("SDL_LoadBMP", 1, 0, 0, gacela_SDL_LoadBMP);
451   scm_c_define_gsubr ("IMG_Load", 1, 0, 0, gacela_IMG_Load);
452   scm_c_define_gsubr ("SDL_GetVideoInfo", 0, 0, 0, gacela_SDL_GetVideoInfo);
453   scm_c_define_gsubr ("SDL_GL_SetAttribute", 2, 0, 0, gacela_SDL_GL_SetAttribute);
454   scm_c_define_gsubr ("SDL_PollEvent", 0, 0, 0, gacela_SDL_PollEvent);
455   scm_c_define_gsubr ("SDL_GL_SwapBuffers", 0, 0, 0, gacela_SDL_GL_SwapBuffers);
456   scm_c_define_gsubr ("SDL_EnableKeyRepeat", 2, 0, 0, gacela_SDL_EnableKeyRepeat);
457   scm_c_define_gsubr ("Mix_OpenAudio", 4, 0, 0, gacela_Mix_OpenAudio);
458   scm_c_define_gsubr ("Mix_LoadMUS", 1, 0, 0, gacela_Mix_LoadMUS);
459   scm_c_define_gsubr ("Mix_LoadWAV", 1, 0, 0, gacela_Mix_LoadWAV);
460   scm_c_define_gsubr ("Mix_PlayChannel", 3, 0, 0, gacela_Mix_PlayChannel);
461   scm_c_define_gsubr ("Mix_PlayMusic", 2, 0, 0, gacela_Mix_PlayMusic);
462   scm_c_define_gsubr ("Mix_PlayingMusic", 0, 0, 0, gacela_Mix_PlayingMusic);
463   scm_c_define_gsubr ("Mix_PausedMusic", 0, 0, 0, gacela_Mix_PausedMusic);
464   scm_c_define_gsubr ("Mix_PauseMusic", 0, 0, 0, gacela_Mix_PauseMusic);
465   scm_c_define_gsubr ("Mix_ResumeMusic", 0, 0, 0, gacela_Mix_ResumeMusic);
466   scm_c_define_gsubr ("Mix_HaltMusic", 0, 0, 0, gacela_Mix_HaltMusic);
467   scm_c_define_gsubr ("Mix_FreeMusic", 1, 0, 0, gacela_Mix_FreeMusic);
468   scm_c_define_gsubr ("Mix_FreeChunk", 1, 0, 0, gacela_Mix_FreeChunk);
469   scm_c_define_gsubr ("Mix_CloseAudio", 0, 0, 0, gacela_Mix_CloseAudio);
470
471   return NULL;
472 }