Menu

[r760]: / trunk / lispbuilder-sdl / documentation / header.html  Maximize  Restore  History

Download this file

868 lines (778 with data), 39.5 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">
<html>
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">
<title>~A - ~A</title>
<style type=\"text/css\">
pre { padding:5px; background-color:#e0e0e0 }
h3, h4 { text-decoration: underline; }
a { text-decoration: none; padding: 1px 2px 1px 2px; }
a:visited { text-decoration: none; padding: 1px 2px 1px 2px; }
a:hover { text-decoration: none; padding: 1px 1px 1px 1px; border: 1px solid #000000; }
a:focus { text-decoration: none; padding: 1px 2px 1px 2px; border: none; }
a.none { text-decoration: none; padding: 0; }
a.none:visited { text-decoration: none; padding: 0; }
a.none:hover { text-decoration: none; border: none; padding: 0; }
a.none:focus { text-decoration: none; border: none; padding: 0; }
a.noborder { text-decoration: none; padding: 0; }
a.noborder:visited { text-decoration: none; padding: 0; }
a.noborder:hover { text-decoration: none; border: none; padding: 0; }
a.noborder:focus { text-decoration: none; border: none; padding: 0; }
pre.none { padding:5px; background-color:#ffffff }
/* code for examples, code and pathnames*/
div.code, div.path {
color: black;
}
div.repl {
color: Green;
}
</style>
</head>
<body bgcolor=white>
<h3> ~2:*~A - ~A</h3>
<blockquote>
<br>&nbsp;</br><h3><a name=abstract class=none>Abstract</a></h3>
<p>
LISPBUILDER-SDL comprises several of packages that allow game development using Common Lisp.
LISPBUILDER-SDL provides a set of bindings and Lispy abstractions for
<a href="http://www.libsdl.org">SDL</a> and other graphics, sound, physics, character animation
and 3D libraries. LISPBUILDER-SDL core functionality includes
window and event management, 2D graphics, 3D graphics using OpenGL and sound support.
The goal for the LISPBUILDER-SDL project is to become a useful resource for the development of games in Lisp.
</p>
<p>
<a href="http://www.libsdl.org">SDL</a> provides the low-level 2D rendering support.
LISPBUILDER-SDL adds 2D graphical effects such as rotation,
rendering circles, polygons, squares, Bezier and Cuttmull-Rom curves as well as bitmap font support.
Additional packages provide native C drawing functions, True Type font rendering,
loading of multiple image formats, a sound mixer and networking support.
The lispbuilder packages are meant to work together with each package providing a specific core set of
functionality. For example, an image that is loaded by lispbuilder-sdl-image may be rotated using
lispbuilder-sdl-gfx. Text may be rendered to a surface using lispbuilder-sdl-ttf and finally blitted to
the display using lispbuilder-sdl.
</p>
<ul>
<li><a href="lispbuilder-sdl-gfx.html" title="lispbuilder-sdl-gfx">lispbuilder-sdl-gfx</a>:
2D graphical effects such as zooming, rotation, circles, polygons and squares, using
<a href="http://www.ferzkopp.net/Software/SDL_gfx-2.0/" title="http://www.ferzkopp.net/Software/SDL_gfx-2.0/" rel="nofollow">SDL_gfx</a></li>
<li> <a href="lispbuilder-sdl-image.html" title="lispbuilder-sdl-image">lispbuilder-sdl-image</a>:
Support for multople image formats such as <acronym title="Portable Network Graphics">PNG</acronym> and
<acronym title="Joint Photographics Experts Group">JPG</acronym>,
using <a href="http://www.libsdl.org/projects/SDL_image/" title="http://www.libsdl.org/projects/SDL_image/" rel="nofollow">SDL_image</a></li>
<li>lispbuilder-sdl-mixer: Sound mixing, using
<a href="http://www.libsdl.org/projects/SDL_mixer/" title="http://www.libsdl.org/projects/SDL_mixer/" rel="nofollow">SDL_mixer</a>
a multi-channel audio mixer library</li>
<li><a href="lispbuilder-sdl-ttf.html" title="lispbuilder-sdl-ttf">lispbuilder-sdl-ttf</a>:
True-type font rendering, using
<a href="http://www.libsdl.org/projects/SDL_ttf/" title="http://www.libsdl.org/projects/SDL_ttf/" rel="nofollow">SDL_ttf</a></li>
<li>lispbuilder-sdl-net: Networking, using
<a href="http://www.libsdl.org" title="http://www.libsdl.org" rel="nofollow">SDL_net</a>
a cross-platform, blocking network library</li>
</ul>
<p>
The code comes with
a <a href="http://en.wikipedia.org/wiki/MIT_License">MIT-style license</a> so you can basically
do with it whatever you want.
</p>
<p>
<font color=red>Download shortcut:</font> <a href="http://www.balooga.com/lispbuilder/~A.tgz">http://www.balooga.com/lispbuilder/~:*~A.tgz</a>.
</p>
</blockquote>
<br>&nbsp;</br><h3><a class=none name="examplesimple">Simple Example</a></h3>
<div class="example">
<pre>
<img src="sdl-alien.png" width="200" height="167" title="Alien Technology" alt="Alien Technology" align=right border=0 vspace=10 hspace=10/>
(sdl:with-init ()
(sdl:window 320 240)
(sdl:draw-surface (load-image "lisp.bmp"))
(sdl:update-display)
(sdl:with-events ()
(:quit-event () t)
(:video-expose-event (sdl:update-display))))
</pre>
</div>
<br>&nbsp;</br><h3><a class=none name="contents">Contents</a></h3>
<ol>
<li><a href="#top">LISPBUILDER-SDL</a></li>
<ol>
<li><a href="#abstract">Abstract</a></li>
<li><a href="#compatibility">Compatibility</a></li>
<li><a href="#dependencies">Dependencies</a></li>
<li><a href="#download">Download</a></li>
<li><a href="#installation">Installation</a></li>
<li><a href="#usage">Usage</a></li>
<li><a href="#examples">Included Examples</a></li>
<li><a href="#support">Support</a></li>
<li><a href="#license">License</a></li>
<li><a href="#packageoverview">Package Overview</a></li>
<ol>
<li><a href="#packageexports">Package Exports</a></li>
<li><a href="#packagestruct">Package Structure</a></li>
</ol>
<li><a href="#devintro">Introduction</a></li>
<ol>
<li><a href="#devinit">Initialisation</a></li>
<li><a href="#devwin">Creation of the SDL Window</a></li>
<li><a href="#devloop">Events and the Game Loop</a></li>
<li><a href="#devprim">Primitives</a></li>
<ol>
<li><a href="#devprimrect">Rectangle</a></li>
<li><a href="#devprimcol">Color</a></li>
</ol>
<li><a href="#devdraw">Drawing</a></li>
<li><a href="#font">Fonts</a></li>
<ol>
<li><a href="#fontinit">Initialisation</a></li>
<li><a href="#fontrend">Rendering Text</a></li>
</ol>
<li><a href="#devsurf">Surfaces</a></li>
<ol>
<li><a href="#devsurfover">Overview</a></li>
<li><a href="#devsurfcreat">Creation</a></li>
<li><a href="#devsurfload">Loading Images</a></li>
<li><a href="#devsurfpos">Positioning</a></li>
<li><a href="#devsurfblit">Drawing & Blitting</a></li>
</ol>
<li><a href="#devdisp">The SDL Display</a></li>
<li><a href="#devcursor">The Cursor</a></li>
<li><a href="#devex">Simple Example</a></li>
<li><a href="#devgarbage">Garbage Collection</a></li>
</ol>
<li><a href="#dictionary">The ~A dictionary</a></li>
<ul>
~{ <li><a href="#~A"><code>~:*~A</code></a></li>
~} </ul>
<li><a href="#ack">Acknowledgements</a></li>
</ol>
</div>
<br>&nbsp;</br><h3><a class=none name="compatibility">Compatibility</h3>
<p>
The following table describes the status of LISPBUILDER-SDL on the major Common Lisp
implementations:
</p>
<table id="mytable" cellspacing="0" summary="Compatibility">
<tr>
<th><b>Lisp Implementation</b></th>
<th colspan="3"><b>LISPBUILDER-SDL Status</b></th>
<th><b>Comments</b></th>
</tr>
<tr>
<th colspan="1"></th>
<th><b>Win32</b></th>
<th><b>Linux</b></th>
<th><b>MacOS</b></th>
<th></th>
</tr>
<tr>
<th class="spec" scope="row">
<a href="http://clisp.cons.org/">CLISP v2.38</a>
</th>
<td bgcolor="#60c060">Working</td>
<td bgcolor="#60c060">Working</td>
<td bgcolor="#60c060">Working</td>
<td></td>
</tr>
<tr>
<th class="specalt" scope="row">
<a href="http://www.lispworks.com/">Lispworks v4.4.6 Personal</a>
</th>
<td class="alt" bgcolor="#60c060">Working</td>
<td class="alt" bgcolor="#60c060">Working</td>
<td class="alt" bgcolor="#60c060">Working</td>
<td></td>
</tr>
<tr>
<th class="spec" scope="row">
<a href="http://www.franz.com/">Allegro Express 8.0</a>
</th>
<td bgcolor="#ff6060">Unknown</td>
<td bgcolor="#60c060">Working</td>
<td bgcolor="#ff6060">Unknown</td>
<td></td>
</tr>
<tr>
<th class="specalt" scope="row">
<a href="http://openmcl.clozure.com/">OpenMCL</a>
</th>
<td class="alt" bgcolor=blue><font color="#FFFFFF">NA</font></td>
<td class="alt" bgcolor=blue><font color="#FFFFFF">NA</font></td>
<td class="alt" bgcolor="#ff6060">Unknown</td>
<td></td>
</tr>
<tr>
<th class="spec" scope="row">
<a href="http://www.sbcl.org/">SBCL</a>
</th>
<td bgcolor="#60c060">Working</td>
<td bgcolor="#60c060">Working</td>
<td bgcolor="#ff6060">Unknown</td>
<td></td>
</tr>
<tr>
<th class="spec" scope="row">
<a href="http://www.cons.org/cmucl">CMUCL</a>
</th>
<td bgcolor="#60c060">Not Working</td>
<td bgcolor="#60c060">Not Working</td>
<td bgcolor="#ff6060">Not Working</td>
<td></td>
</tr>
</table>
<br>&nbsp;</br><h3><a class=none name="dependencies">Dependencies</a></h3>
<ul>
<li><a href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/cclan/asdf/asdf.lisp?rev=1.92" title="http://cvs.sourceforge.net/viewcvs.py/*checkout*/cclan/asdf/asdf.lisp?rev=1.92">ASDF:</a>
ASDF is already installed for users of SBCL, OpenMCL, ECL or ACL, or Lispworks and Edi Weitz's Lisp Starter Pack.
Otherwise, please refer to the official <a href="http://cvs.sourceforge.net/viewcvs.py/*checkout*/cclan/asdf/README?rev=HEAD&content-type=text/plain">ASDF README</a> for installation instructions.</li>
<li><a href="http://common-lisp.net/project/cffi" title="http://common-lisp.net/project/cffi">CFFI</a>:
Automatically installed if using <a href="http://www.cliki.net/ASDF-Install">ASDF-INSTALL</a>, or Edi Weitz's Starter Pack. Otherwise,
please refer to the official <a href="http://common-lisp.net/project/cffi" title="http://common-lisp.net/project/cffi">installation instructions</a>.</li>
<li><a href="http://www.libsdl.org" title="http://www.libsdl.org">SDL</a>:
Automatically installed by Edi Weitz's Lisp Starter Pack. Otherwise, Windows/Mac users should download the binaries from <a href="http://www.libsdl.org" title="http://www.libsdl.org">www.libsdl.org</a>, while
Linux users should use their package managers to install the RPM's or DEBs.</li>
</ul>
<br>&nbsp;</br><h3><a class=none name="download">Download</a></h3>
<p>
<font color=red>Current Version:</font> The latest stable version of ~2:*~A, together with this documentation can be downloaded from
<a href="http://www.balooga.com.com/lispbuilder/~2:*~A.tgz">http://www.balooga.com/lispbuilder/~:*~A.tgz</a>. The
current version is 0.9.5.
</p>
<br>&nbsp;</br><h3><a class=none name="installation">Installation</a></h3>
See <a href="http://lispbuilder.sourceforge.net/index.html">the LISPBUILDER documentation</a>
for installation instructions for <a href="http://lispbuilder.sourceforge.net/index.html#windows">Windows</a>,
<a href="http://lispbuilder.sourceforge.net/index.html#mac">Mac OS-X</a> and
<a href="http://lispbuilder.sourceforge.net/index.html#linux">Linux</a>.
<br>&nbsp;</br><h3><a class=none name="usage">Using LISPBUILDER-SDL</a></h3>
<p>
Enter the following at the REPL to compile and load the LISPBUILDER-SDL package:
<div class="repl">
<pre>(asdf:operate 'asdf:load-op :lispbuilder-sdl)</pre>
</div>
ASDF will take care of loading the CFFI and :LISPBUILDER-SDL dependencies.
The SDL.dll library will also be loaded into the Lisp image at this time.
</p>
<br>&nbsp;</br><h3><a class=none name="examples">Running the Included Examples</a></h3>
<p>Enter the following at the REPL to compile and load the examples included in the
LISPBUILDER-SDL-EXAMPLES package:</p>
<div class="repl">
<pre>
(asdf:operate 'asdf:load-op :lispbuilder-sdl-examples)
</pre>
</div>
<p>Run the examples by entering any of the following at the REPL:
</p>
<div class="repl">
<pre>
(SDL-EXAMPLES:BEZIER)
(SDL-EXAMPLES:BMP-SAMPLE)
(SDL-EXAMPLES:CIRCLE-1)
(SDL-EXAMPLES:CIRCLE-2)
(SDL-EXAMPLES:CIRCLE-3)
(SDL-EXAMPLES:CIRCLE-4)
(SDL-EXAMPLES:CIRCLE-5)
(SDL-EXAMPLES:DISTANCE-2D)
(SDL-EXAMPLES:FLOOD-FILL)
(SDL-EXAMPLES:INBUILT-FONTS)
(SDL-EXAMPLES:LINE-DRAWING)
(SDL-EXAMPLES:MANDELBROT)
(SDL-EXAMPLES:METABALLS)
(SDL-EXAMPLES:MOUSE-2D)
(SDL-EXAMPLES:MOUSE-PAINTER)
(SDL-EXAMPLES:PIXELS-1)
(SDL-EXAMPLES:PIXELS-2)
(SDL-EXAMPLES:PIXELS-3)
(SDL-EXAMPLES:PIXELS-4)
(SDL-EXAMPLES:POINTS-AND-LINES)
(SDL-EXAMPLES:RANDOM-RECTS)
(SDL-EXAMPLES:RANDOM-BOX-1)
(SDL-EXAMPLES:RANDOM-BOX-2)
(SDL-EXAMPLES:RANDOM-BOX-3)
(SDL-EXAMPLES:RANDOM-BOX-4)
(SDL-EXAMPLES:RECURSIVE-RECTS)
(SDL-EXAMPLES:SETUP-AND-DRAW)
(SDL-EXAMPLES:SIMPLE-FONT-DEMO)
(SDL-EXAMPLES:STROKE)
(SDL-EXAMPLES:VERTICES)
(SDL-EXAMPLES:WIDTH-HEIGHT)
</pre>
</div>
<br>&nbsp;</br><h3><a class=none name="support">Documentation, Support & Mailing Lists</a></h3>
Questions answered and help given on the <a href="http://www.lispniks.com/mailman/listinfo/application-builder">lispbuilder discussion list</a>.
Documentation for LISPBUILDER-SDL and related packages is available on the <a href="http://lispbuilder.sourceforge.net">LISPBUILDER project page on Sourceforge</a>.
For additional information, look at the <a href="http://wiki.alu.org/Gardeners_Projects">Lisp Gardeners page</a>, and
<a href="http://wiki.alu.org/Application_Builder">Application Builder page</a>
on the ALU's (Association of Lisp Users) wiki.
<br>&nbsp;</br><h3><a class=none name="license">License</a></h3>
<p>
LISPBUILDER-SDL is distributed under the
<a href="http://en.wikipedia.org/wiki/MIT_License">MIT-style license</a>.
</p>
<br>&nbsp;</br><h3><a class=none name="packageoverview">Package Overview</a></h3>
<h3><a class=none name="packageexports">Package Exports</a></h3>
<p>
Functions and symbols exported from the LISPBUILDER-SDL package are
accessible from the <code>LISPBUILDER-SDL:</code> prefix or the
shorter form <code>SDL:</code> nickname.
</p>
<h3><a class=none name="packagestruct">Package Structure</a></h3>
<p>
The <code>cffi/</code> directory contains the raw CFFI bindings.
These bindings may be automatically generated by <a href="http://www.swig.org">SWIG</a> or created by hand.
CFFI translation functions perform simple low-level conversions for example,
converting Lisp strings to C strings and back (see <code>cffi-translate.lisp</code>).
All functions in <code>cffi/</code> accept and return foreign objects only.
</p>
<p>
The <code>base/</code> directory defines wrappers over the functions in <code>cffi/</code> .
The functions in <code>base/</code> accept keyword arguments and accept NIL instead
of CFFI:NULL-POINTER where appropriate. Generally functions in <code>base/</code> accept and return foreign
objects. <code>base/</code> may perform some type checks (IS-VALID-PTR SURFACE) but
this layer is meant to be lean. Someone who implements a graphics engine
might use this layer instead of <code>sdl/</code> if speed is a concern.
There are no fancy drawing primitives in this layer.
</p>
<p>
The <code>sdl/</code> directory defines the abstractions over <code>cffi/</code> and <code>base/</code>.
Foreign objects are passed around <code>sdl/</code> neatly wrapped in CLOS objects, using TRIVIAL-GARBAGE for
automatic garbage collection (minimize foreign objects being left on the
heap). There are no functions in <code>sdl/</code> that accept or return foreign
objects (with the exception of the functions that create the CLOS
wrapper objects) Functions in <code>sdl/</code> call down into
<code>cffi/</code> and <code>base/</code> as appropriate. All LISPBUILDER-SDL symbols available in
<code>SDL:</code> are exported from <code>sdl/</code>, with symbols imported into <code>sdl/</code> from
<code>cffi/</code> and <code>base/</code> as appropriate (e.g. WITH-EVENTS). All drawing primitives are
defined in this layer; circles, rectangles, lines, triangles, with-bezier etc.
Functions in <code>sdl/</code> implement a lot of type checking.
</p>
<p>
An example of the difference between <code>base/</code> and <code>sdl/</code> is
WITH-RECTANGLE. The WITH-RECTANGLE macro in <code>base/</code> creates and destroys a foreign
SDL_Rect. The WITH-RECTANGLE macro in <code>sdl/</code> will create and destroy
a RECTANGLE object.
</p>
<br>&nbsp;</br><h3><a class=none name="devintro">Introduction</a></h3>
<h3><a class=none name="devinit">Initialisation of SDL</a></h3>
<p>
The SDL library and SDL subsystems must be initialized prior to use.
This is handled automatically when using the macro <a href="#with-init">WITH-INIT</a>.
<a href="#with-init">WITH-INIT</a> also uninitialises the SDL library upon exit.
More detailed information on the LISPBUILDER-SDL initialisation process can be found in the
documentation for <a href="#with-init">WITH-INIT</a>.
</p>
<pre>
(WITH-INIT (SDL-INIT-VIDEO)
...)
</pre>
<h3><a class=none name="devwin">Creation of the SDL Window</a></h3>
<p>
A window must be created to display any kind of output. A window of a specific pixel width and height
is created using the function <a href="#window">WINDOW</a>. <a href="#window">WINDOW</a> takes
additional keyword parameters to set the requested video mode, color bit depth, the window title and
the icon title.
More detailed information can be found in in the documentation for <a href="#window">WINDOW</a>.
</p>
<pre>
(WITH-INIT (SDL-INIT-VIDEO)
(WINDOW 320 240))
</pre>
<h3><a class=none name="devloop">Handling Events and the Game Loop</a></h3>
<p>
LISPBUILDER-SDL provides the <a href="#with-events">WITH-EVENTS</a> macro that simplifies
the game loop and handling SDL events. Event handlers are defined by specifying the event type a well as an
optional list of fields specific to that event.
</p>
<p>
More detailed information on all SDL events (Keyboard events, Joystick events, User events etc.) can be
found in in the documentation for <a href="#with-events">WITH-EVENTS</a>.
</p>
<p>
For example, to process the current x and y mouse position
when the mouse is moved:
</p>
<pre>
(:MOUSE-MOTION-EVENT (:X X-POS :Y Y-POS)
...)
</pre>
<p>
Or to process the x and y relative mouse positions when the mouse is moved:
</p>
<pre>
(:MOUSE-MOTION-EVENT (:X-REL relative-x :Y-REL relative-y)
...)
</pre>
<p>
The only event that must be handled with <a href="#with-events">WITH-EVENTS</a>
is the :QUIT-EVENT. If :QUIT-EVENT is ignored then it is impossible for the user to close the SDL Window
or exit the game loop.
</p>
<pre>
(WITH-EVENTS ()
(:QUIT-EVENT () T)
(:MOUSE-MOTION-EVENT (:X mouse-x :Y mouse-y)
...))
</pre>
<p>
In addition to handling events, <a href="#with-events">WITH-EVENTS</a> also manages the game loop.
Introducing the :IDLE event. :IDLE, although not technically an actual event, is executed once per game
loop after all events have been processed in the SDL event queue. :IDLE is where the user can place code
that needs to be executed once per game loop and that is not 'event' driven. This code may involve
updating world physics, updating the state of game objects and rendering sprites to the display.
</p>
<pre>
(WITH-EVENTS ()
(:QUIT-EVENT () T)
(:MOUSE-MOTION-EVENT (:X mouse-x :Y mouse-y)
...)
(:IDLE ()
(UPDATE-DISPLAY)))
</pre>
<p>
<a href="#with-events">WITH-EVENTS</a> can also limit execution of the the game loop to a specific number
of iterations a second using <a href="#frame-rate">FRAME-RATE</a>. This effectively limits the number of
frames displayed per second. To set the frame rate to 60 frames per second,
<code>(SETF (SDL:FRAME-RATE) 60)</code>. To unlock the frame rate effectively running the game loop as fast
as the CPU will allow set the FRAME-RATE to NIL, <code>(SETF (SDL:FRAME-RATE) NIL)</code>
</p>
<p>The SDL display surface needs to be updated once per game loop, as described in the section
<a href="#devdisp">SDL Display</a>.
</p>
<pre>
(SETF (FRAME-RATE) 30)
(WITH-EVENTS ()
...)
</pre>
<h3><a class=none name="devprim">Primitives</a></h3>
<p>
LISPBUILDER-SDL supports the SDL <a href="#rectangle">RECTANGLE</a> and <a href="#color">COLOR</a> primitives.
These are described below.
</p>
<h4><a class=none name="devprimrect">Rectangle</a></h4>
<p>
A new rectangle is created by the function <a href="#rectangle">RECTANGLE</a>.
The function <a href="#rectangle-from-edges">RECTANGLE-FROM-EDGES</a> will create a new rectangle
from the specified top left and bottom right coordinates. The function
<a href="#rectangle-from-midpoint-*">RECTANGLE-FROM-MIDPOINT-*</a> will create a new rectangle from midpoint.
</p>
<p>
The macros <a href="#with-rectangle">WITH-RECTANGLE</a> and <a href="#with-rectangle">WITH-RECTANGLEs</a>
will create a new rectangle and free this rectangle when it goes out of scope.
</p>
<p>
The rectangle position and width and height can be inspected and modified using the following functions:
<a href="#x">X</a>, <a href="#y">Y</a>, <a href="#width">WIDTH</a> and <a href="#height">HEIGHT</a>.
<a href="#x2">X2</a> and <a href="#y2">Y2</a> will return the (+ x width) and (+ y height) of the rectangle respectively.
</p>
<p>
Additional functions that operate on rectangles are as follows:
<ul>
<li><a href="#point-*">POINT-*</a></li>
<li><a href="#get-point">GET-POINT</a></li>
<li><a href="#set-point">SET-POINT</a></li>
<li><a href="#position">POSITION</a></li>
<li><a href="#get-position">GET-POSITION</a></li>
<li><a href="#rectangle-*">RECTANGLE-*</a></li>
<li><a href="#get-rectangle">GET-RECTANGLE</a></li>
<li><a href="#set-rectangle">SET-RECTANGLE</a></li>
<li><a href="#draw-box">DRAW-BOX</a>, <a href="#draw-rectangle">DRAW-RECTANGLE</a></li>
</ul>
The section <a href="#devdraw">Drawing</a> describes how to render a rectangle to a surface.
</p>
<h4><a class=none name="devprimcol">Color</a></h4>
<p>
A new SDL color is created by <a href="#color">COLOR</a>, returning either a new RGB or RGBA color.
</p>
<p>
RGB/A color componets can be manipulated using the functions <a href="#r">R</a>, <a href="#g">G</a>,
<a href="#b">B</a>, <a href="#a">A</a>, <a href="#set-color">SET-COLOR</a> and
<a href="#set-color-*">SET-COLOR-*</a>. Two colors may be compared using <a href="#color=">COLOR=</a>.
</p>
<p>
Functions that accept a color parameter will most likely bind color to
<a href="#*default-color*">*DEFAULT-COLOR*</a> when unspecified. The macro
<a href="#with-font">WITH-COLOR</a> will bind a color to <a href="#*default-color*">*DEFAULT-COLOR*</a>
within the scope of this macro. When <a href="#*default-color*">*DEFAULT-COLOR*</a> is bound to a color,
all subsequent drawing functions will use this implied color while it remains in scope.
</p>
<p>
Additional functions that operate on colors are as follows:
<ul>
<li><a href="#color-*">COLOR-*</a></li>
<li><a href="#any-color-but-this">ANY-COLOR-BUT-THIS</a></li>
<li><a href="#map-color">MAP-COLOR</a></li>
<li><a href="#pack-color">PACK-COLOR</a></li>
</ul>
</p>
<p>
LISPBULDER-SDL contains several predefined colors; <a href="#*black*">*BLACK*</a>,
<a href="#*white*">*WHITE*</a>, <a href="#*red*">*RED*</a>, <a href="#*green*">*GREEN*</a>,
<a href="#*blue*">*BLUE*</a>, <a href="#*yellow*">*YELLOW*</a>, <a href="#*cyan*">*CYAN*</a>,
<a href="#*magenta*">*MAGENTA*</a>.
</p>
<h3><a class=none name="devdraw">Drawing</a></h3>
<p>
LISPBUILDER-SDL provides low-level drawing support for several primitives. Most primitives can be drawn
with or without alpha transparency. In addition, the filled primitives can be drawn with a single pixel
outline (or stroke) that is a different color to the fill color.
<ul>
<li>Blitting Surfaces: <a href="#draw-surface">DRAW-SURFACE</a> and
<a href="#blit-surface">BLIT-SURFACE</a></li>
<li>Bezier and Cutmull-Rom Curves: <a href="#draw-bezier">DRAW-BEZIER</a>,
<a href="#draw-shape">DRAW-SHAPE</a>, <a href="#with-bezier">WITH-BEZIER</a>,
<a href="#with-curve">WITH-CURVE</a> and <a href="#draw-curve">DRAW-CURVE</a>.</li>
<li>Boxes and Rectangles: <a href="#draw-box">DRAW-BOX</a>,
<a href="#draw-rectangle">DRAW-RECTANGLE</a></li>
<li>Circles: <a href="#draw-circle">DRAW-CIRCLE</a> and
<a href="#draw-filled-circle">DRAW-FILLED-CIRCLE</a></li>
<li>Lines: <a href="#draw-hline">DRAW-HLINE</a>, <a href="#draw-vline">DRAW-VLINE</a> and
<a href="#draw-line">DRAW-LINE</a></li>
<li>Points: <a href="#draw-point">DRAW-POINT</a></li>
<li>Polygons and Triangles: <a href="#draw-polygon">DRAW-POLYGON</a>,
<a href="#draw-trigon">DRAW-TRIGON</a> and <a href="#with-shape">WITH-SHAPE</a></li>
<li>Filling Surfaces with Color: <a href="#fill-surface">FILL-SURFACE</a></li>
<li>Filling Arbitrary Shapes with Color: <a href="#flood-fill">FLOOD-FILL</a></li>
</ul>
</p>
<p>
Drawing functions require a target surface and color. LISPBUILDER-SDL uses defaults for both
target surface (<a href="#*default-surface*">*DEFAULT-SURFACE*</a>) and color
(<a href="#*default-color*">*DEFAULT-COLOR*</a>) unless these are otherwise specified by the user.
The macros <a href="#with-surface">with-surface</a>, and
<a href="#with-surfaces">with-surfaces</a> will bind a surface to <A HREF="#*DEFAULT-SURFACE*">*DEFAULT-SURFACE*</A> within the scope these
macros. For example, instead of specifying a target surface for each draw-* function a user may bind
<A HREF="#*DEFAULT-SURFACE*">*DEFAULT-SURFACE*</A> to a surface once and subsequent draw-* functions will use this implied surface
while it remains in scope.
</p>
<pre>
(DRAW-POINT (sdl:point :x x1 :y y1) :surface a-surface :color *white*)
(DRAW-POINT (sdl:point :x x2 :y y2) :surface a-surface :color *white*)
(DRAW-POINT (sdl:point :x x3 :y y3) :surface a-surface :color *white*)
(DRAW-POINT (sdl:point :x x4 :y y4) :surface a-surface :color *white*)
</pre>
<p>Now, we use <a href="#with-surface">WITH-SURFACE</a> to bind a surface to <A HREF="#*DEFAULT-SURFACE*">*DEFAULT-SURFACE*</A>.</p>
<pre>
(WITH-SURFACE (a-surface)
(DRAW-POINT (sdl:point :x x1 :y y1) :color *white*)
(DRAW-POINT (sdl:point :x x2 :y y2) :color *white*)
(DRAW-POINT (sdl:point :x x3 :y y3) :color *white*)
(DRAW-POINT (sdl:point :x x4 :y y4) :color *white*))
</pre>
<p>
We can use <a href="#with-color">WITH-COLOR</a> to bind <A HREF="#*DEFAULT-COLOR*">*DEFAULT-COLOR*</A> to
<a href="#*white*">*WHITE*</a>:
</p>
<pre>
(WITH-SURFACE (a-surface)
(WITH-COLOR (*white*)
(DRAW-POINT (sdl:point :x x1 :y y1))
(DRAW-POINT (sdl:point :x x2 :y y2))
(DRAW-POINT (sdl:point :x x3 :y y3))
(DRAW-POINT (sdl:point :x x4 :y y4)))
</pre>
<p>
Finally, if the target surface is the display then <A HREF="#WITH-SURFACE">*WITH-SURFACE*</A> is not required as :SURFACE when NIL
will be bound to <A HREF="#*DEFAULT-DISPLAY*">*DEFAULT-DISPLAY*</A> as a default. So the above code can be shortened as follows:
</p>
<pre>
(WITH-COLOR (*white*)
(DRAW-POINT (sdl:point :x x1 :y y1))
(DRAW-POINT (sdl:point :x x2 :y y2))
(DRAW-POINT (sdl:point :x x3 :y y3))
(DRAW-POINT (sdl:point :x x4 :y y4)))
</pre>
<h3><a class=none name="font">Fonts</a></h3>
<p>
LISPBUILDER-SDL contains several bitmap fonts of different sizes and faces (italics/bolded). See
<a href="#initialise-font">INITIALISE-FONT</a> for the complete list of built-in fonts.
</p>
<h4><a class=none name="fontinit">Initialisation</a></h3>
<p>
Fonts are initialised using <a href="#initialise-default-font">INITIALISE-DEFAULT-FONT</a>, or
<a href="#initialise-font">INITIALISE-FONT</a>. The resouces allocated to a font are freed by
<a href="#free-font">FREE-FONT</a>. A font must be initialised prior to use.
</p>
<p>
LISPBUILDER-SDL provides the macros <a href="#with-default-font">WITH-DEFAULT-FONT</a> and
<a href="#with-font">WITH-FONT</a> for the above functions that bind
<a href="#*default-font*">*DEFAULT-FONT*</a> to font within the scope of the macro.
<p>
<h4><a class=none name="fontrend">Rendering Text</a></h3>
<p>
LISPBUILDER-SDL supports the rendering of colored text over a transparent background (Solid rendering),
and the rendering of colored text over a solid colored background (Shaded rendering). Text may be left, right or
center justified. Text can be drawn directly to a target surface using
<a href="#draw-string-solid">DRAW-STRING-SOLID</a> and <a href="#draw-string-shaded">DRAW-STRING-SHADED</a>.
Text can be rendered to a new surface of character height and string width using
<a href="#render-string-solid">RENDER-STRING-SOLID</a> and
<a href="#render-string-shaded">RENDER-STRING-SHADED</a>. This new surface may be optionally cached in the
font object. A cached surface font can be accessed using <a href="#cached-surface">CACHED-SURFACE</a>) and can
be blitted to a target surface using <a href="#draw-font">DRAW-FONT</a>.
</p>
<p>
The font rendering functions accept a font object. This font parameter is bound to
<a href="#*default-font*">*DEFAULT-FONT*</a> when unspecified. The function
<a href="#initialise-default-font">INITIALISE-DEFAULT-FONT</a> and the macros
<a href="#with-font">WITH-FONT</a> and <a href="#with-default-font">WITH-DEFAULT-FONT</a> will bind a
font to <a href="#*default-font*">*DEFAULT-FONT*</a> within the scope of these macros. When
<a href="#*default-font*">*DEFAULT-FONT*</a> is bound to a font, all subsequent font drawing
or font rendering functions will use this implied font while it remains in scope.
</p>
<p>The following methods also apply to fonts; <a href="#x">X</a>, <a href="#y">Y</a>,
<a href="#width">WIDTH</a>, <a href="#height">HEIGHT</a>, Returns the width of the cached [SURFACE](#surface) when `OBJ` is a [FONT](#font).
<pre>
(WITH-COLOR (*WHITE*)
(WITH-FONT (*FONT-8x8*)
(DRAW-STRING-SOLID-* "Font is 8x8." 10 10)
(WITH-FONT (*FONT-10x20*)
(DRAW-STRING-SOLID-* "Font is 10x20." 10 20))
(DRAW-STRING-SOLID-* "Font is 8x8 again." 10 40)))
</pre>
<h3><a class=none name="devsurf">Surfaces</a></h3>
<p>
</p>
<h4><a class=none name="devsurfover">Overview of Surfaces</a></h4>
<p>
An SDL surface, <a href="#surface">SURFACE</a>, represents an area of <em>graphical</em> memory
that can be drawn or rendered to, for example the video framebuffer or an image that is loaded from disk.
</p>
<h4><a class=none name="devsurfcreat">Creating Surfaces</a></h4>
<p>
A surface is created:
<ul>
<li>Automatically by the SDL library to represent a framebuffer by
calling <a href="#window">WINDOW</a>.</li>
<li>When loading an image from disk using <a href="#load-image">LOAD-IMAGE</a>.</li>
<li>Explicitely using <a href="#create-surface">CREATE-SURFACE</a>, or
<a href="#copy-surface">COPY-SURFACE</a>.</li>
<li>Implicitely using <a href="#convert-surface">CONVERT-SURFACE</a>.</li>
</ul>
</p>
<p>
Functions that accept a surface parameter will most likely bind surface to
<a href="#*default-surface*">*DEFAULT-SURFACE*</a> when unspecified.
The macros <a href="#with-surface">WITH-SURFACE</a> and <a href="#with-surfaces">WITH-SURFACES</a> will bind a
surface to <a href="#*default-surface*">*DEFAULT-SURFACE*</a> within the scope of these macro.
When <a href="#*default-surface*">*DEFAULT-SURFACE*</a> is bound to a surface,
all subsequent drawing functions will use this implied surface while it remains in scope.
</p>
<p>
A surface can be explicitely freed by calling <a href="#free-surface">FREE-SURFACE</a>.
</p>
<h4><a class=none name="devsurfload">Images</a></h4>
<p>
BMP images are loaded from disk using <a href="#load-image">LOAD-IMAGE</a>. Support for additional
image formats is provided in the <a href="lispbuilder-sdl-image.html">LISPBUILDER-SDL-IMAGE</a> package.
A surface is saved to disk as a BMP image using <a href="#save-image">SAVE-IMAGE</a>.
</p>
<pre>
(DRAW-SURFACE (LOAD-IMAGE "sdl.bmp")
:surface *default-display*)
</pre>
<h4><a class=none name="devsurfpos">Positioning Surfaces</a></h4>
<p>
A <a href="#surface">SURFACE</a> stores its own position X/Y coordinates. These coordinates
can be inspected and modified using the following functions:
<a href="#x">X</a>, <a href="#y">Y</a>, <a href="#width">WIDTH</a> and <a href="#height">HEIGHT</a>.
</p>
<p>
Additional functions and macros that manage surface coordinates are as follows:
<ul>
<li><a href="#point-*">POINT-*</a></li>
<li><a href="#get-point">GET-POINT</a></li>
<li><a href="#set-point">SET-POINT</a></li>
<li><a href="#set-point-*">SET-POINT-*</a></li>
<li><a href="#position-*">POSITION-*</a></li>
<li><a href="#get-position">GET-POSITION</a></li>
<li><a href="#set-position-*">GET-POSITION</a></li>
<li><a href="#set-surface">SET-SURFACE</a></li>
<li><a href="#set-surface-*">SET-SURFACE-*</a></li>
<li><a href="#rectangle-*">RECTANGLE-*</a></li>
<li><a href="#get-rectangle-*">GET-RECTANGLE-*</a></li>
<li><a href="#get-surface-rect">GET-SURFACE-RECT</a></li>
<li><a href="#draw-surface-at">DRAW-SURFACE-AT</a></li>
</ul>
</p>
<h4><a class=none name="devsurfblit">Drawing & Blitting Surfaces</a></h4>
<p>The functions <a href="#blit-surface">BLIT-SURFACE</a> and <a href="#draw-surface">DRAW-SURFACE</a> will
blit or draw a source surface onto a destination surface using the position coordinates stored in the source surface.
<a href="#draw-surface-at">DRAW-SURFACE-AT</a> will draw the source surface at a specified position.
</p>
<p>
The composition rules that determine how the source surface is composed over the destination surface are
described in the description of <a href="#blit-surface">BLIT-SURFACE</a>.
<a href="#fill-surface">FILL-SURFACE</a> fill will the target surface with a single color.
<a href="#devprim">Drawing Primitives</a> describes how <a href="#*default-surface*">*DEFAULT-SURFACE*</a>
is used when calling blitting operations.
</p>
<p>
Use <a href="#set-color-key">SET-COLOR-KEY</a>, <a href="#clear-color-key">CLEAR-COLOR-KEY</a> and
<a href="#set-alpha">SET-ALPHA</a> to modify the key color and alpha transparency properties of a surface after the
surface has been created.
</p>
<p>
Set a <em>clipping</em> rectangle to limit the draw area on a destination surface.
The clipping rectangle for a surface is manipulated using <a href="#get-clip-rect">GET-CLIP-RECT</a> and
<a href="#set-clip-rect">SET-CLIP-RECT</a>. When this surface is the destination of a blit,
only the area within the <em>clip</em> rectangle will be drawn into.
</p>
<p>
Set a <em>cell</em> rectangle to limit the surface area on the source surface.
The cell rectangle for a surface is manipulated using <a href="#clear-cell">CLEAR-CELL</a> and
<a href="#set-cell">SET-CELL</a>. When this surface is the source of a blit,
only the areas within the <em>cell</em> rectangle will be used.
The cell is useful when only a small area of the source surface needs to be blitted to the destination surface.
For example a sequence of images composed into a single sprite sheet and only the current frame of animation
is to be drawn to the display at any one time.
</p>
<p>
<img src="waddle.png" width="285" height="51" title="Sprite Sheet" alt="Sprite Sheet"/>
</p>
<h4><a class=none name="devupdate">Updating SDL Surfaces and the SDL Display</a></h4>
<p>
The functions <a href="#update-display">UPDATE-DISPLAY</a> and <a href="#update-surface">UPDATE-SURFACE</a>
update the SDL display surface (or OpenGL context) and general SDL surfaces respectively.
</p>
<h3><a class=none name="devdisp">The SDL Display</a></h3>
<p>
The SDL display surface must be updated at least once each game loop using the function
<a href="#update-display">UPDATE-DISPLAY</a>. This function will call
<a href="#sdl-gl-swap-buffers">SDL-GL-SWAP-BUFFERS</a> to update the OpenGL display,
or <a href="#sdl-flip">SDL-FLIP</a> to update the SDL surface depending on the current
<a href="#*opengl-context*">*OPENGL-CONTEXT*</a>. The display can be filled with a background
color using <a href="#clear-display">CLEAR-DISPLAY</a>.
</p>
<p>
The properties of an SDL surface can be queried using <a href="#surface-info">SURFACE-INFO</a>.
The properties of the SDL display and video hardware can be queried using <a href="#video-info">VIDEO-INFO</a>.
The screen resolutions supported by a particular set of video flags can be retrieved using
<a href="#list-modes">LIST-MODES</a>. A pointer to the native SDL window can be retrieved using
<a href="#get-native-window">GET-NATIVE-WINDOW</a>. The name of the video driver can be retrieved as a STRING
using <a href="#video-driver-name">VIDEO-DRIVER-NAME</a>.
<h3><a class=none name="devcursor">The Cursor</a></h3>
<p>
The the current state of the cursor is returned using <a href="#query-cursor">QUERY-CURSOR</a>, and is set using
<a href="#query-cursor">SHOW-CURSOR</a>.
</p>
<h3><a class=none name="devex">Simple Example</a></h3>
<p>
Putting this all together, we can write short example showing a white rectangle that follows the users mouse
movements within an SDL Window. Exit the example by closing the window or pressing the Esc key on the keyboard.
</p>
<pre>
;; Initialise SDL and the Video subsystem
(WITH-INIT (SDL-INIT-VIDEO)
(WINDOW 320 240) ; Open a window, 320 x 240
(SETF (FRAME-RATE) 30) ; Lock the frame rate to 30 fps
(WITH-EVENTS ()
(:QUIT-EVENT () T) ; Absolutely have to handle the :QUIT-EVENT
(:KEY-DOWN-EVENT (:KEY key) (WHEN (KEY= key :SDL-KEY-ESCAPE) (PUSH-QUIT-EVENT)))
(:MOUSE-MOTION-EVENT (:X mouse-x :Y mouse-y)
(CLEAR-DISPLAY *black*)
;; Draw the box with center at the mouse x/y coordinates.
(DRAW-BOX-* (- mouse-x (/ 50 2)) (- mouse-y (/ 50 2)) 50 50 :color *white*))
(:IDLE ()
(UPDATE-DISPLAY))))
</pre>
<h3><a class=none name="devgarbage">Object Lifecycles and Garbage Collection</a></h3>
<p>
...
</p>
<br>&nbsp;</br><h3><a class=none name="dictionary">The ~A dictionary</a></h3>
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.