doc: Document collision grid API.
[chickadee.git] / doc / api.texi
1 @menu
2 * Kernel:: The fundamental components.
3 * Math:: Linear algebra and more.
4 * Graphics:: Eye candy.
5 * Scripting:: Bringing the game world to life.
6 @end menu
7
8 @node Kernel
9 @section Kernel
10
11 At the very core of Chickadee, in the @code{(chickadee)} module, lies
12 an event loop. This loop, or ``kernel'', is responsible for ensuring
13 that the game is updated at the desired interval, rendering the
14 current state of the game world, and handling errors if they occur.
15 The kernel implements what is known as a ``fixed timestep'' game loop,
16 meaning that the game simulation will be advanced by a fixed interval
17 of time and will never vary from frame to frame, unlike some other
18 styles of game loops. The appropriately named @code{run-game} and
19 @code{abort-game} procedures are the entry and exit points to the
20 Chickadee game loop kernel.
21
22 On its own, the kernel does not do very much at all. In order to
23 actually respond to input events, update game state, or render output,
24 the programmer must provide an engine. But don’t worry, you don’t
25 have to start from scratch! Chickadee comes with a simple engine that
26 uses SDL to create a graphical window and handle input devices, and
27 OpenGL to handle rendering. This default engine is enough for most
28 users to get started writing games quickly. More advanced users may
29 want to write a custom engine that uses a different I/O system.
30 Perhaps you are writing a text adventure or roguelike that reads from
31 and writes to a terminal instead of a graphical window. The game loop
32 kernel makes no assumptions.
33
34 @deffn {Procedure} run-game [#:update] [#:render] [#:time] [#:error] @
35 [#:update-hz 60]
36
37 Start the game loop. This procedure will not return until
38 @code{abort-game} is called.
39
40 The core game loop is generic and requires four additional procedures
41 to operate:
42
43 @itemize
44 @item
45 @var{update}: Called @var{update-hz} times per second to advance the
46 game simulation. This procedure is called with a single argument: The
47 amount of time that has passed since the last update, in milliseconds.
48 @item
49 @var{render}: Called each iteration of the loop to render the game to
50 the desired output device. This procedure is called with a single
51 argument: A value in the range [0, 1] which represents how much time
52 has past since the last game state update relative to the upcoming
53 game state update, as a percentage. Because the game state is updated
54 independent of rendering, it is often the case that rendering is
55 occuring between two updates. If the game is rendered as it was
56 during the last update, a strange side-effect will occur that makes
57 animation appear rough or ``choppy''. To counter this, the
58 @var{alpha} value can be used to perfrom a linear interpolation of a
59 moving object between its current position and its previous position.
60 This odd trick has the pleasing result of making the animation look
61 smooth again, but requires keeping track of previous state.
62 @item
63 @var{time}: Called to get the current time in milliseconds. This
64 procedure is called with no arguments.
65 @item
66 @var{error}: Called when an error from the @var{update} or
67 @var{render} procedures reaches the game loop. This procedure is
68 called with three arguments: The call stack, the error key, and the
69 error arguments. If no error handler is provided, the default
70 behavior is to simply re-throw the error.
71 @end itemize
72
73 @end deffn
74
75 @deffn {Procedure} abort-game
76 Stop the currently running Chickadee game loop.
77 @end deffn
78
79 Since most users will want to write 2D/3D games with hardware
80 accelerated graphics rendering, controlled via keyboard, mouse, or
81 game controller, Chickadee comes with an easy to use engine just for
82 this purpose in the @code{(chickadee sdl)} module:
83 @code{run-game/sdl}.
84
85 @deffn {Procedure} run-game/sdl [#:window-title "Chickadee!"] @
86 [#:window-width 640] [#:window-height 480] @
87 [#:window-fullscreen? @code{#f}] [#:update-hz 60] @
88 [#:load] [#:update] [#:draw] [#:quit] @
89 [#:key-press] [#:key-release] [#:text-input] @
90 [#:mouse-press] [#:mouse-release] [#:mouse-move] @
91 [#:controller-add] [#:controller-remove] [#:controller-press] @
92 [#:controller-release] [#:controller-move] [#:error]
93
94 Run the Chickadee game loop using the SDL engine.
95
96 A new graphical window will be opened with @var{window-width} x
97 @var{window-height} as its dimensions, @var{window-title} as its
98 title, and in fullscreen mode if @var{window-fullscreen?} is
99 @code{#t}.
100
101 @itemize
102 @item
103 @var{load}: Called with zero arguments when the game window has opened
104 but before the game loop has started. Can be used to perform
105 initialization that requires an open window and OpenGL context such as
106 loading textures.
107
108 @item
109 @var{update}: Called @var{update-hz} times per second with one
110 argument: The amount of time to advance the game simulation.
111
112 @item
113 @var{draw}: Called each time a frame should be rendered with a single
114 argument known as the @code{alpha} value. See the documentation for
115 @code{run-game} for an explanation of this value.
116
117 @item
118 @var{quit}: Called with zero arguments when the user tries to close
119 the game window. The default behavior is to exit the game.
120
121 @item
122 @var{key-press}: Called with four arguments when a key is pressed on
123 the keyboard:
124
125 @enumerate
126 @item
127 @var{key}: The symbolic name of the ``virtual'' key that was pressed.
128 For example: @code{backspace}. It's called a virtual key because the
129 operating system may map a physical keyboard key to another key
130 entirely, such as how the author likes to bind the ``caps lock'' key
131 to mean ``control''.
132
133 @item
134 @var{scancode}: The symbolic name of the physical key that was
135 pressed.
136
137 @item
138 @var{modifiers}: A list of the symbolic names of modifier keys that
139 were being held down when the key was pressed. Possible values
140 include @code{ctrl}, @code{alt}, and @code{shift}.
141
142 @item
143 @var{repeat?}: @code{#t} if this is a repeated press of the same key.
144
145 @end enumerate
146
147 @item
148 @var{key-release}: Called with three arguments when a key is released
149 on the keyboard:
150
151 @enumerate
152 @item
153 @var{key}: The symbolic name of the ``virtual'' key that was released.
154
155 @item
156 @var{scancode}: The symbolic name of the physical key that was
157 released.
158
159 @item
160 @var{modifiers}: A list of the symbolic names of modifier keys that
161 were being held down when the key was released.
162
163 @end enumerate
164
165 @item
166 @var{text-input}: Called with a single argument, a string of text,
167 when printable text is typed on the keyboard.
168
169 @item
170 @var{mouse-press}: Called with four arguments when a mouse button is
171 pressed:
172 @enumerate
173
174 @item
175 @var{button}: The symbolic name of the button that was pressed, such
176 as @code{left}, @code{middle}, or @code{right}.
177
178 @item
179 @var{clicks}: The number of times the button has been clicked in a row.
180
181 @item
182 @var{x}: The x coordinate of the mouse cursor.
183
184 @item
185 @var{y}: The y coordinate of the mouse cursor.
186
187 @end enumerate
188
189 @item
190 @var{mouse-release}: Called with three arguments when a mouse button
191 is released:
192
193 @enumerate
194
195 @item
196 @var{button}: The symbolic name of the button that was released.
197
198 @item
199 @var{x}: The x coordinate of the mouse cursor.
200
201 @item
202 @var{y}: The y coordinate of the mouse cursor.
203
204 @end enumerate
205
206 @item
207 @var{mouse-move}: Called with five arguments when the mouse is moved:
208
209 @enumerate
210
211 @item
212 @var{x}: The x coordinate of the mouse cursor.
213
214 @item
215 @var{y}: The y coordinate of the mouse cursor.
216
217 @item
218 @var{dx}: The amount the mouse has moved along the x axis since the
219 last mouse move event.
220
221 @item
222 @var{dy}: The amount the mouse has moved along the y axis since the
223 last mouse move event.
224
225 @item
226 @var{buttons}: A list of the buttons that were pressed down when the
227 mouse was moved.
228
229 @end enumerate
230
231 @item
232 @var{controller-add}: Called with a single argument, an SDL game
233 controller object, when a game controller is connected.
234
235 @item
236 @var{controller-remove}: Called with a single argument, an SDL game
237 controller object, when a game controller is disconnected.
238
239 @item
240 @var{controller-press}: Called with two arguments when a button on a
241 game controller is pressed:
242
243 @enumerate
244
245 @item
246 @var{controller}: The controller that triggered the event.
247
248 @item
249 @var{button}: The symbolic name of the button that was pressed.
250 Possible buttons are:
251
252 @itemize
253 @item
254 @code{a}
255 @item
256 @code{b}
257 @item
258 @code{x}
259 @item
260 @code{y}
261 @item
262 @code{back}
263 @item
264 @code{guide}
265 @item
266 @code{start}
267 @item
268 @code{left-stick}
269 @item
270 @code{right-stick}
271 @item
272 @code{left-shoulder}
273 @item
274 @code{right-shoulder}
275 @item
276 @code{dpad-up}
277 @item
278 @code{dpad-down}
279 @item
280 @code{dpad-left}
281 @item
282 @code{dpad-right}
283
284 @end itemize
285
286 @end enumerate
287
288 @item
289 @var{controller-release}: Called with two arguments when a button on a
290 game controller is released:
291
292 @enumerate
293
294 @item
295 @var{controller}: The controller that triggered the event.
296
297 @item
298 @var{button}: The symbolic name of the button that was released.
299
300 @end enumerate
301
302 @item
303 @var{controller-move}: Called with three arguments when an analog
304 stick or trigger on a game controller is moved:
305
306 @enumerate
307
308 @item
309 @var{controller}: The controller that triggered the event.
310
311 @item
312 @var{axis}: The symbolic name of the axis that was moved. Possible
313 values are:
314
315 @itemize
316 @item
317 @code{left-x}
318 @item
319 @code{left-y}
320 @item
321 @code{right-x}
322 @item
323 @code{right-y}
324 @item
325 @code{trigger-left}
326 @item
327 @code{trigger-right}
328 @end itemize
329
330 @end enumerate
331
332 @item
333 @var{error}: Called with three arguments when an error occurs:
334
335 @enumerate
336
337 @item
338 @var{stack}: The call stack at the point of error.
339
340 @item
341 @var{key}: The exception key.
342
343 @item
344 @var{args}: The arguments thrown with the exception.
345
346 @end enumerate
347
348 The default behavior is to re-throw the error.
349
350 @end itemize
351
352 @end deffn
353
354 @node Math
355 @section Math
356
357 Chickadee contains data types and procedures for performing the most
358 common computations in video game simulations such as linear algebra
359 with vectors and matrices and axis-aligned bounding box collision
360 detection.
361
362 @menu
363 * Basics:: Commonly used, miscellaneous things.
364 * Vectors:: Euclidean vectors.
365 * Rectangles:: Axis-aligned bounding boxes.
366 * Grid:: Spatial partitioning for bounding boxes.
367 * Matrices:: Transformation matrices.
368 * Quaternions:: Rotations about an arbitrary axis.
369 * Easings:: Easing functions for interesting animations.
370 * Bezier Curves:: Cubic Bezier curves and paths in 2D space.
371 @end menu
372
373 @node Basics
374 @subsection Basics
375
376 @defvar pi
377 An essential constant for all trigonometry. @code{@U{03C0}} is the ratio
378 of a circle's circumferences to its diameter. Since @code{@U{03C0}} is an
379 irrational number, the @var{pi} in Chickadee is a mere floating point
380 approximation that is ``good enough.''
381 @end defvar
382
383 @defvar pi/2
384 Half of @var{pi}.
385 @end defvar
386
387 @deffn {Procedure} cotan @var{z}
388 Return the cotangent of @var{z}.
389 @end deffn
390
391 @node Vectors
392 @subsection Vectors
393
394 Unlike Scheme's vector data type, which is a sequence of arbitrary
395 Scheme objects, Chickadee's @code{(chickadee math vector)} module
396 provides vectors in the linear algebra sense: Sequences of numbers
397 specialized for particular coordinate spaces. As of now, Chickadee
398 provides 2D and 3D vectors, with 4D vector support coming in a future
399 release.
400
401 Here's a quick example of adding two vectors:
402
403 @example
404 (define v (vec2+ (vec2 1 2) (vec2 3 4)))
405 @end example
406
407 Since vectors are used so frequently, the reader macro @code{#v} is
408 used to cut down on typing:
409
410 @example
411 (define v (vec2+ #v(1 2) #v(3 4)))
412 @end example
413
414 @subsubsection A Note About Performance
415
416 A lot of time has been spent making Chickadee's vector operations
417 perform relatively efficiently in critical code paths where excessive
418 garbage generation will cause major performance issues. The general
419 rule is that procedures ending with @code{!} perform an in-place
420 modification of one of the arguments in order to avoid allocating a
421 new vector. These procedures are also inlined by Guile's compiler in
422 order to take advantage of optimizations relating to floating point
423 math operations. The downside is that since these are not pure
424 functions, they do not compose well and create more verbose code.
425
426 @subsubsection 2D Vectors
427
428 @deffn {Procedure} vec2 @var{x} @var{y}
429 Return a new 2D vector with coordinates (@var{x}, @var{y}).
430 @end deffn
431
432 @deffn {Procedure} vec2/polar @var{r} @var{theta}
433 Return a new 2D vector containing the Cartesian representation of the
434 polar coordinate (@var{r}, @var{theta}). The angle @var{theta} is
435 measured in radians.
436 @end deffn
437
438 @deffn {Procedure} vec2? @var{obj}
439 Return @code{#t} if @var{obj} is a 2D vector.
440 @end deffn
441
442 @deffn {Procedure} vec2-x @var{v}
443 Return the X coordinate of the 2D vector @var{v}.
444 @end deffn
445
446 @deffn {Procedure} vec2-y @var{v}
447 Return the Y coordinate of the 2D vector @var{v}.
448 @end deffn
449
450 @deffn {Procedure} vec2-copy @var{v}
451 Return a fresh copy of the 2D vector @var{v}.
452 @end deffn
453
454 @deffn {Procedure} vec2-magnitude @var{v}
455 Return the magnitude of the 2D vector @var{v}.
456 @end deffn
457
458 @deffn {Procedure} vec2-dot-product @var{v1} @var{v2}
459 Return the dot product of the 2D vectors @var{v1} and @var{v2}.
460 @end deffn
461
462 @deffn {Procedure} vec2-normalize @var{v}
463 Return the normalized form of the 2D vector @var{v}.
464 @end deffn
465
466 @deffn {Procedure} vec2+ @var{v} @var{x}
467 Add @var{x}, either a 2D vector or a scalar (i.e. a real number), to
468 the 2D vector @var{v} and return a new vector containing the sum.
469 @end deffn
470
471 @deffn {Procedure} vec2- @var{v} @var{x}
472 Subtract @var{x}, either a 2D vector or a scalar, from the 2D vector
473 @var{v} and return a new vector containing the difference.
474 @end deffn
475
476 @deffn {Procedure} vec2* @var{v} @var{x}
477 Multiply the 2D vector @var{v} by @var{x}, a 2D vector or a scalar,
478 and return a new vector containing the product.
479 @end deffn
480
481 @deffn {Procedure} set-vec2-x! @var{v} @var{x}
482 Set the X coordinate of the 2D vector @var{v} to @var{x}.
483 @end deffn
484
485 @deffn {Procedure} set-vec2-y! @var{v} @var{y}
486 Set the Y coordinate of the 2D vector @var{v} to @var{y}.
487 @end deffn
488
489 @deffn {Procedure} vec2-copy! @var{source} @var{target}
490 Copy the 2D vector @var{source} into the 2D vector @var{target}.
491 @end deffn
492
493 @deffn {Procedure} vec2-add! @var{v} @var{x}
494 Perform an in-place modification of the 2D vector @var{v} by adding
495 @var{x}, a 2D vector or a scalar.
496 @end deffn
497
498 @deffn {Procedure} vec2-sub! @var{v} @var{x}
499 Perform an in-place modification of the 2D vector @var{v} by
500 subtracting @var{x}, a 2D vector or a scalar.
501 @end deffn
502
503 @deffn {Procedure} vec2-mult! @var{v} @var{x}
504 Perform an in-place modification of the 2D vector @var{v} by
505 multiplying it by @var{x}, a 2D vector or a scalar.
506 @end deffn
507
508 @subsubsection 3D Vectors
509
510 @deffn {Procedure} vec3 @var{x} @var{y}
511 Return a new 2D vector with coordinates (@var{x}, @var{y}).
512 @end deffn
513
514 @deffn {Procedure} vec3? @var{obj}
515 Return @code{#t} if @var{obj} is a 3D vector.
516 @end deffn
517
518 @deffn {Procedure} vec3-x @var{v}
519 Return the X coordinate of the 3D vector @var{v}.
520 @end deffn
521
522 @deffn {Procedure} vec3-y @var{v}
523 Return the Y coordinate of the 3D vector @var{v}.
524 @end deffn
525
526 @deffn {Procedure} vec3-z @var{v}
527 Return the Z coordinate of the 3D vector @var{v}.
528 @end deffn
529
530 @deffn {Procedure} vec3-copy @var{v}
531 Return a fresh copy of the 3D vector @var{v}.
532 @end deffn
533
534 @deffn {Procedure} vec3-magnitude @var{v}
535 Return the magnitude of the 3D vector @var{v}.
536 @end deffn
537
538 @deffn {Procedure} vec3-dot-product @var{v1} @var{v2}
539 Return the dot product of the 3D vectors @var{v1} and @var{v2}.
540 @end deffn
541
542 @deffn {Procedure} vec3-normalize @var{v}
543 Return the normalized form of the 3D vector @var{v}.
544 @end deffn
545
546 @deffn {Procedure} vec3+ @var{v} @var{x}
547 Add @var{x}, either a 3D vector or a scalar (i.e. a real number), to
548 the 3D vector @var{v} and return a new vector containing the sum.
549 @end deffn
550
551 @deffn {Procedure} vec3- @var{v} @var{x}
552 Subtract @var{x}, either a 3D vector or a scalar, from the 3D vector
553 @var{v} and return a new vector containing the difference.
554 @end deffn
555
556 @deffn {Procedure} vec3* @var{v} @var{x}
557 Multiply the 3D vector @var{v} by @var{x}, a 3D vector or a scalar,
558 and return a new vector containing the product.
559 @end deffn
560
561 @deffn {Procedure} set-vec3-x! @var{v} @var{x}
562 Set the X coordinate of the 3D vector @var{v} to @var{x}.
563 @end deffn
564
565 @deffn {Procedure} set-vec3-y! @var{v} @var{y}
566 Set the Y coordinate of the 3D vector @var{v} to @var{y}.
567 @end deffn
568
569 @deffn {Procedure} set-vec3-z! @var{v} @var{z}
570 Set the Z coordinate of the 3D vector @var{v} to @var{z}.
571 @end deffn
572
573 @deffn {Procedure} vec3-copy! @var{source} @var{target}
574 Copy the 3D vector @var{source} into the 3D vector @var{target}.
575 @end deffn
576
577 @deffn {Procedure} vec3-add! @var{v} @var{x}
578 Perform an in-place modification of the 3D vector @var{v} by adding
579 @var{x}, a 3D vector or a scalar.
580 @end deffn
581
582 @deffn {Procedure} vec3-sub! @var{v} @var{x}
583 Perform an in-place modification of the 3D vector @var{v} by
584 subtracting @var{x}, a 3D vector or a scalar.
585 @end deffn
586
587 @deffn {Procedure} vec3-mult! @var{v} @var{x}
588 Perform an in-place modification of the 3D vector @var{v} by
589 multiplying it by @var{x}, a 3D vector or a scalar.
590 @end deffn
591
592 @node Rectangles
593 @subsection Rectangles
594
595 The @code{(chickadee math rect)} module provides an API for
596 manipulating axis-aligned bounding boxes (AABBs). AABBs are often
597 used for collision detection in games. Common use-cases are defining
598 ``hitboxes'' in platformers or using them for the ``broad phase'' of a
599 collision detection algorithm that uses a more complex (and thus
600 slower) method of determining the actual collisions.
601
602 Like some of the other math modules, there exists a collection of
603 functions that do in-place modification of rectangles for use in
604 performance critical code paths.
605
606 @deffn {Procedure} make-rect @var{x} @var{y} @var{width} @var{height}
607 Create a new rectangle that is @var{width} by @var{height} in size and
608 whose bottom-left corner is located at (@var{x}, @var{y}).
609 @end deffn
610
611 @deffn {Procedure} rect? @var{obj}
612 Return @code{#t} if @var{obj} is a rectangle.
613 @end deffn
614
615 @deffn {Procedure} rect-within? @var{rect1} @var{rect2}
616 Return @code{#t} if @var{rect2} is completely within @var{rect1}.
617 @end deffn
618
619 @deffn {Procedure} rect-intersects? @var{rect1} @var{rect2}
620 Return @code{#t} if @var{rect2} overlaps @var{rect1}.
621 @end deffn
622
623 @deffn {Procedure} rect-contains? @var{rect} @var{x} @var{y}
624 Return @code{#t} if the coordinates (@var{x}, @var{y}) are within
625 @var{rect}.
626 @end deffn
627
628 @deffn {Procedure} rect-contains-vec2? @var{rect} @var{v}
629 Return @code{#t} if the 2D vector @var{v} is within the bounds of
630 @var{rect}.
631 @end deffn
632
633 @deffn {Procedure} rect-x @var{rect}
634 Return the X coordinate of the lower-left corner of @var{rect}.
635 @end deffn
636
637 @deffn {Procedure} rect-y @var{rect}
638 Return the Y coordinate of the lower-left corner of @var{rect}.
639 @end deffn
640
641 @deffn {Procedure} rect-left @var{rect}
642 Return the left-most X coordinate of @var{rect}.
643 @end deffn
644
645 @deffn {Procedure} rect-right @var{rect}
646 Return the right-most X coordinate of @var{rect}.
647 @end deffn
648
649 @deffn {Procedure} rect-bottom @var{rect}
650 Return the bottom-most Y coordinate of @var{rect}.
651 @end deffn
652
653 @deffn {Procedure} rect-top @var{rect}
654 Return the top-most Y coordinate of @var{rect}.
655 @end deffn
656
657 @deffn {Procedure} rect-center-x @var{rect}
658 Return the X coordinate of the center of @var{rect}.
659 @end deffn
660
661 @deffn {Procedure} rect-center-y @var{rect}
662 Return the Y coordinate of the center of @var{rect}.
663 @end deffn
664
665 @deffn {Procedure} rect-width @var{rect}
666 Return the width of @var{rect}.
667 @end deffn
668
669 @deffn {Procedure} rect-height @var{rect}
670 Return the height of @var{rect}.
671 @end deffn
672
673 @deffn {Procedure} rect-area @var{rect}
674 Return the surface area covered by @var{rect}.
675 @end deffn
676
677 @deffn {Procedure} rect-clamp-x @var{rect} @var{x}
678 Restrict @var{x} to the portion of the X axis covered by @var{rect}.
679 @end deffn
680
681 @deffn {Procedure} rect-clamp-y @var{rect} @var{y}
682 Restrict @var{y} to the portion of the Y axis covered by @var{rect}.
683 @end deffn
684
685 @deffn {Procedure} rect-clamp @var{rect1} @var{rect2}
686 Return a new rect that adjusts the location of @var{rect1} so that it
687 is completely within @var{rect2}. An exception is thrown in the case
688 that @var{rect1} cannot fit completely within @var{rect2}.
689 @end deffn
690
691 @deffn {Procedure} rect-move @var{rect} @var{x} @var{y}
692 Return a new rectangle based on @var{rect} but moved to the
693 coordinates (@var{x}, @var{y}).
694 @end deffn
695
696 @deffn {Procedure} rect-move-vec2 @var{rect} @var{v}
697 Return a new rectangle based on @var{rect} but moved to the
698 coordinates in the 2D vector @var{v}.
699 @end deffn
700
701 @deffn {Procedure} rect-move-by @var{rect} @var{x} @var{y}
702 Return a new rectangle based on @var{rect} but moved by (@var{x},
703 @var{y}) units relative to its current location.
704 @end deffn
705
706 @deffn {Procedure} rect-move-by-vec2 @var{rect} @var{v}
707 Return a new rectangle based on @var{rect} but moved by the 2D vector
708 @var{v} relative to its current location.
709 @end deffn
710
711 @deffn {Procedure} rect-inflate @var{rect} @var{width} @var{height}
712 Return a new rectangle based on @var{rect}, but expanded by
713 @var{width} units on the X axis and @var{height} units on the Y axis,
714 while keeping the rectangle centered on the same point.
715 @end deffn
716
717 @deffn {Procedure} rect-union @var{rect1} @var{rect2}
718 Return a new rectangle that completely covers the area of @var{rect1}
719 and @var{rect2}.
720 @end deffn
721
722 @deffn {Procedure} rect-clip @var{rect1} @var{rect2}
723 Return a new rectangle that is the overlapping region of @var{rect1}
724 and @var{rect2}. If the two rectangles do not overlap, a rectangle of
725 0 width and 0 height is returned.
726 @end deffn
727
728 @deffn {Procedure} set-rect-x! @var{rect} @var{x}
729 Set the left X coordinate of @var{rect} to @var{x}.
730 @end deffn
731
732 @deffn {Procedure} set-rect-y! @var{rect} @var{y}
733 Set the bottom Y coordinate of @var{rect} to @var{y}.
734 @end deffn
735
736 @deffn {Procedure} set-rect-width! @var{rect} @var{width}
737 Set the width of @var{rect} to @var{width}.
738 @end deffn
739
740 @deffn {Procedure} set-rect-height! @var{rect} @var{height}
741 Set the height of @var{rect} to @var{height}.
742 @end deffn
743
744 @deffn {Procedure} rect-move! @var{rect} @var{x} @var{y}
745 Move @var{rect} to (@var{x}, @var{y}) in-place.
746 @end deffn
747
748 @deffn {Procedure} rect-move-vec2! @var{rect} @var{v}
749 Move @var{rect} to the 2D vector @var{v} in-place.
750 @end deffn
751
752 @deffn {Procedure} rect-move-by! @var{rect} @var{x} @var{y}
753 Move @var{rect} by (@var{x}, @var{y}) in-place.
754 @end deffn
755
756 @deffn {Procedure} rect-move-by-vec2! @var{rect} @var{v}
757 Move @var{rect} by the 2D vector @var{v} in-place.
758 @end deffn
759
760 @deffn {Procedure} rect-inflate! @var{rect} @var{width} @var{height}
761 Expand @var{rect} by @var{width} and @var{height} in-place.
762 @end deffn
763
764 @deffn {Procedure} rect-union! @var{rect1} @var{rect2}
765 Modify @var{rect1} in-place to completely cover the area of both
766 @var{rect1} and @var{rect2}.
767 @end deffn
768
769 @deffn {Procedure} rect-clip! @var{rect1} @var{rect2}
770 Modify @var{rect1} in-place to be the overlapping region of
771 @var{rect1} and @var{rect2}.
772 @end deffn
773
774 @deffn {Procedure} rect-clamp! @var{rect1} @var{rect2}
775 Adjust the location of @var{rect1} in-place so that its bounds are
776 completely within @var{rect2}. An exception is thrown in the case
777 that @var{rect1} cannot fit completely within @var{rect2}.
778 @end deffn
779
780 @deffn {Procedure} vec2-clamp-to-rect! @var{v} @var{rect}
781 Restrict the coordinates of the 2D vector @var{v} so that they are
782 within the bounds of @var{rect}. @var{v} is modified in-place.
783 @end deffn
784
785 @node Grid
786 @subsection Grid
787
788 The @code{(chickadee math grid)} module provides a simple spatial
789 partitioning system for axis-aligned bounding boxes
790 (@pxref{Rectangles}) in 2D space. The grid divides the world into
791 tiles and keeps track of which rectangles occupy which tiles. When
792 there are lots of moving objects in the game world that need collision
793 detection, the grid greatly speeds up the process. Instead of
794 checking collisions of each object against every other object (an
795 O(n^2) operation), the grid quickly narrows down which objects could
796 possibly be colliding and only performs collision testing against a
797 small set of objects.
798
799 In addition to checking for collisions, the grid also handles the
800 resolution of collisions. Exactly how each collision is resolved is
801 user-defined. A player bumping into a wall may slide against it. An
802 enemy colliding with a projectile shot by the player may get pushed
803 back in the opposite direction. Two players colliding may not need
804 resolution at all and will just pass through each other. The way this
805 works is that each time an object (A) is moved within the grid, the
806 grid looks for an object (B) that may possibly be colliding with A. A
807 user-defined procedure known as a ``filter'' is then called with both
808 A and B. If the filter returns @code{#f}, it means that even if A and
809 B are colliding, no collision resolution is needed. In this case the
810 grid won't waste time checking if they really do collide because it
811 doesn't matter. If A and B are collidable, then the filter returns a
812 procedure that implements the resolution technique. The grid will
813 then perform a collision test. If A and B are colliding, the resolver
814 procedure is called. It's the resolvers job to adjust the objects
815 such that they are no longer colliding. The grid module comes with a
816 very simple resolution procedure, @code{slide}, that adjusts object A
817 by the smallest amount so that it no longer overlaps with B. By using
818 this filtering technique, a game can resolve collisions between
819 different objects in different ways.
820
821 @deffn {Procedure} make-grid [@var{cell-size} 64]
822 Return a new grid partitioned into @var{cell-size} tiles.
823 @end deffn
824
825 @deffn {Procedure} grid? @var{obj}
826 Return @code{#t} if @var{obj} is a grid.
827 @end deffn
828
829 @deffn {Procedure} cell? @var{obj}
830 Return @code{#t} if @var{obj} is a grid cell.
831 @end deffn
832
833 @deffn {Procedure} cell-count @var{cell}
834 Return the number of items in @var{cell}.
835 @end deffn
836
837 @deffn {Procedure} grid-cell-size @var{grid}
838 Return the cell size of @var{grid}.
839 @end deffn
840
841 @deffn {Procedure} grid-cell-count @var{grid}
842 Return the number of cells currently in @var{grid}.
843 @end deffn
844
845 @deffn {Procedure} grid-item-count @var{grid}
846 Return the number of items in @var{grid}.
847 @end deffn
848
849 @deffn {Procedure} grid-add @var{grid} @var{item} @var{x} @var{y} @
850 @var{width} @var{height}
851
852 Add @var{item} to @var{grid} represented by the axis-aligned bounding
853 box whose lower-left corner is at (@var{x}, @var{y}) and is
854 @var{width} x @var{height} in size.
855 @end deffn
856
857 @deffn {Procedure} grid-remove @var{grid} @var{item}
858 Return @var{item} from @var{grid}.
859 @end deffn
860
861 @deffn {Procedure} grid-clear @var{grid}
862 Remove all items from @var{grid}.
863 @end deffn
864
865 @deffn {Procedure} grid-move @var{grid} @var{item} @var{position} @var{filter}
866 Attempt to move @var{item} in @var{grid} to @var{position} (a 2D
867 vector) and check for collisions. For each collision, @var{filter}
868 will be called with two arguments: @var{item} and the item it collided
869 with. If a collision occurs, @var{position} may be modified to
870 resolve the colliding objects.
871 @end deffn
872
873 @deffn {Procedure} for-each-cell @var{proc} @var{grid} [@var{rect}]
874 Call @var{proc} with each cell in @var{grid} that intersects
875 @var{rect}, or every cell if @var{rect} is @code{#f}.
876 @end deffn
877
878 @deffn {Procedure} for-each-item @var{proc} @var{grid}
879 Call @var{proc} for each item in @var{grid}.
880 @end deffn
881
882 @deffn {Procedure} slide @var{item} @var{item-rect} @
883 @var{other} @var{other-rect} @var{goal}
884
885 Resolve the collision that occurs between @var{item} and @var{other}
886 when moving @var{item-rect} to @var{goal} by sliding @var{item-rect}
887 the minimum amount needed to make it no longer overlap
888 @var{other-rect}.
889 @end deffn
890
891 @node Matrices
892 @subsection Matrices
893
894 The @code{(chickadee math matrix)} module provides an interface for
895 working with the most common type of matrices in game development: 4x4
896 transformation matrices.
897
898 @subsubsection Another Note About Performance
899
900 Much like the vector API, the matrix API is commonly used in
901 performance critical code paths. In order to reduce the amount of
902 garbage generated and improve matrix multiplication performance, there
903 are many procedures that perform in-place modifications of matrix
904 objects.
905
906 @subsubsection Matrix Operations
907
908 @deffn {Procedure} make-matrix4 @var{aa} @var{ab} @var{ac} @var{ad} @
909 @var{ba} @var{bb} @var{bc} @var{bd} @
910 @var{ca} @var{cb} @var{cc} @var{cd} @
911 @var{da} @var{db} @var{dc} @var{dd}
912
913 Return a new 4x4 matrix initialized with the given 16 values in
914 column-major format.
915 @end deffn
916
917 @deffn {Procedure} make-null-matrix4
918 Return a new 4x4 matrix with all values initialized to 0.
919 @end deffn
920
921 @deffn {Procedure} make-identity-matrix4
922 Return a new 4x4 identity matrix. Any matrix multiplied by the
923 identity matrix yields the original matrix. This procedure is
924 equivalent to the following code:
925
926 @example
927 (make-matrix4 1 0 0 0
928 0 1 0 0
929 0 0 1 0
930 0 0 0 1)
931 @end example
932
933 @end deffn
934
935 @deffn {Procedure} matrix4? @var{obj}
936 Return @code{#t} if @var{obj} is a 4x4 matrix.
937 @end deffn
938
939 @deffn {Procedure} matrix4* . @var{matrices}
940 Return a new 4x4 matrix containing the product of multiplying all of
941 the given @var{matrices}.
942
943 Note: Remember that matrix multiplication is @strong{not} commutative!
944 @end deffn
945
946 @deffn {Procedure} orthographic-projection @var{left} @var{right} @
947 @var{top} @var{bottom} @
948 @var{near} @var{far}
949
950 Return a new 4x4 matrix that represents an orthographic (2D)
951 projection for the horizontal clipping plane @var{top} and
952 @var{bottom}, the vertical clipping plane @var{top} and @var{bottom},
953 and the depth clipping plane @var{near} and @var{far}.
954 @end deffn
955
956 @deffn {Procedure} perspective-projection @var{fov} @
957 @var{aspect-ratio} @
958 @var{near} @var{far}
959
960 Return a new 4x4 matrix that represents a perspective (3D) projection
961 with a field of vision of @var{fov} radians, an aspect ratio of
962 @var{aspect-ratio}, and a depth clipping plane defined by @var{near}
963 and @var{far}.
964 @end deffn
965
966 @deffn {Procedure} matrix4-translate @var{x}
967 Return a new 4x4 matrix that represents a translation by @var{x}, a 2D
968 vector, a 3D vector, or a rectangle (in which case the bottom-left
969 corner of the rectangle is used).
970 @end deffn
971
972 @deffn {Procedure} matrix4-scale @var{s}
973 Return a new 4x4 matrix that represents a scaling along the X, Y, and
974 Z axes by the scaling factor @var{s}, a real number.
975 @end deffn
976
977 @deffn {Procedure} matrix4-rotate @var{q}
978 Return a new 4x4 matrix that represents a rotation about an arbitrary
979 axis defined by the quaternion @var{q}.
980 @end deffn
981
982 @deffn {Procedure} matrix4-rotate-z @var{theta}
983 Return a new 4x4 matrix that represents a rotation about the Z axis by
984 @var{theta} radians.
985 @end deffn
986
987 @deffn {Procedure} matrix4-identity! @var{matrix}
988 Modify @var{matrix} in-place to contain the identity matrix.
989 @end deffn
990
991 @deffn {Procedure} matrix4-mult! @var{dest} @var{a} @var{b}
992 Multiply the 4x4 matrix @var{a} by the 4x4 matrix @var{b} and store
993 the result in the 4x4 matrix @var{dest}.
994 @end deffn
995
996 @deffn {Procedure} matrix4-translate! @var{matrix} @var{x}
997 Modify @var{matrix} in-place to contain a translation by @var{x}, a 2D
998 vector, a 3D vector, or a rectangle (in which case the bottom-left
999 corner of the rectangle is used).
1000 @end deffn
1001
1002 @deffn {Procedure} matrix4-scale! @var{matrix} @var{s}
1003 Modify @var{matrix} in-place to contain a scaling along the X, Y, and
1004 Z axes by the scaling factor @var{s}, a real number.
1005 @end deffn
1006
1007 @deffn {Procedure} matrix4-rotate! @var{matrix} @var{q}
1008 Modify @var{matrix} in-place to contain a rotation about an arbitrary
1009 axis defined by the quaternion @var{q}.
1010 @end deffn
1011
1012 @deffn {Procedure} matrix4-rotate-z! @var{matrix} @var{theta}
1013 Modify @var{matrix} in-place to contain a rotation about the Z axis by
1014 @var{theta} radians.
1015 @end deffn
1016
1017 @deffn {Procedure} matrix4-2d-transform! @var{matrix} [#:origin] @
1018 [#:position] [#:rotation] @
1019 [#:scale] [#:skew]
1020
1021 Modify @var{matrix} in-place to contain the transformation described
1022 by @var{position}, a 2D vector or rectangle, @var{rotation}, a scalar
1023 representing a rotation about the Z axis, @var{scale}, a 2D vector,
1024 and @var{skew}, a 2D vector. The transformation happens with respect
1025 to @var{origin}, a 2D vector. If an argument is not provided, that
1026 particular transformation will not be included in the result.
1027 @end deffn
1028
1029 @deffn {Procedure} transform! @var{matrix} @var{v}
1030 Modify the 2D vector @var{v} in-place by multiplying it by the 4x4
1031 matrix @var{matrix}.
1032 @end deffn
1033
1034 @node Quaternions
1035 @subsection Quaternions
1036
1037 In game development, the quaternion is most often used to represent
1038 rotations. Why not use a matrix for that, you may ask. Unlike
1039 matrices, quaternions can be interpolated (animated) and produce a
1040 meaningful result. When interpolating two quaternions, there is a
1041 smooth transition from one rotation to another, whereas interpolating
1042 two matrices would yield garbage.
1043
1044 @deffn {Procedure} quaternion @var{x} @var{y} @var{z} @var{w}
1045 Return a new quaternion with values @var{x}, @var{y}, @var{z}, and
1046 @var{w}.
1047 @end deffn
1048
1049 @deffn {Procedure} quaternion? @var{obj}
1050 Return @code{#t} if @var{obj} is a quaternion.
1051 @end deffn
1052
1053 @deffn {Procedure} quaternion-w @var{q}
1054 Return the W component of the quaternion @var{q}.
1055 @end deffn
1056
1057 @deffn {Procedure} quaternion-x @var{q}
1058 Return the X component of the quaternion @var{q}.
1059 @end deffn
1060
1061 @deffn {Procedure} quaternion-y @var{q}
1062 Return the Y component of the quaternion @var{q}.
1063 @end deffn
1064
1065 @deffn {Procedure} quaternion-z @var{q}
1066 Return the Z component of the quaternion @var{q}.
1067 @end deffn
1068
1069 @deffn {Procedure} make-identity-quaternion
1070 Return the identity quaternion.
1071 @end deffn
1072
1073 @node Easings
1074 @subsection Easings
1075
1076 @deffn {Procedure} linear @var{t}
1077 @end deffn
1078
1079 @deffn {Procedure} smoothstep @var{t}
1080 @end deffn
1081
1082 @deffn {Procedure} ease-in-quad @var{t}
1083 @end deffn
1084
1085 @deffn {Procedure} ease-out-quad @var{t}
1086 @end deffn
1087
1088 @deffn {Procedure} ease-in-out-quad @var{t}
1089 @end deffn
1090
1091 @deffn {Procedure} ease-in-cubic @var{t}
1092 @end deffn
1093
1094 @deffn {Procedure} ease-out-cubic @var{t}
1095 @end deffn
1096
1097 @deffn {Procedure} ease-in-out-cubic @var{t}
1098 @end deffn
1099
1100 @deffn {Procedure} ease-in-quart @var{t}
1101 @end deffn
1102
1103 @deffn {Procedure} ease-out-quart @var{t}
1104 @end deffn
1105
1106 @deffn {Procedure} ease-in-out-quart @var{t}
1107 @end deffn
1108
1109 @deffn {Procedure} ease-in-quint @var{t}
1110 @end deffn
1111
1112 @deffn {Procedure} ease-out-quint @var{t}
1113 @end deffn
1114
1115 @deffn {Procedure} ease-in-out-quint @var{t}
1116 @end deffn
1117
1118 @deffn {Procedure} ease-in-sine @var{t}
1119 @end deffn
1120
1121 @deffn {Procedure} ease-out-sine @var{t}
1122 @end deffn
1123
1124 @deffn {Procedure} ease-in-out-sine @var{t}
1125 @end deffn
1126
1127 @node Bezier Curves
1128 @subsection Bezier Curves
1129
1130 The @code{(chickadee math bezier)} module provides an API for
1131 describing cubic Bezier curves in 2D space. These curves are notably
1132 used in font description, vector graphics programs, and when it comes
1133 to games: path building. With Bezier curves, it's somewhat easy to
1134 create a smooth looking path for an enemy to move along, for example.
1135 Bezier curves become particularly interesting when they are chained
1136 together to form a Bezier ``path'', where the end point of one curve
1137 becomes the starting point of the next.
1138
1139 Currently, the rendering of Bezier curves is rather crude and provided
1140 mostly for visualizing and debugging curves that would be unseen in
1141 the final game. See @xref{Lines and Shapes} for more information.
1142
1143 @deffn {Procedure} make-bezier-curve @var{p0} @var{p1} @var{p2} @var{p3}
1144 Return a new Bezier curve object whose starting point is @var{p0},
1145 ending point is @var{p3}, and control points are @var{p1} and
1146 @var{p2}. All points are 2D vectors.
1147 @end deffn
1148
1149 @deffn {Procedure} bezier-curve? @var{obj}
1150 Return @code{#t} if @var{obj} is a Bezier curve.
1151 @end deffn
1152
1153 @deffn {Procedure} bezier-curve-p0 @var{bezier}
1154 Return the starting point of @var{bezier}.
1155 @end deffn
1156
1157 @deffn {Procedure} bezier-curve-p1 @var{bezier}
1158 Return the first control point of @var{bezier}.
1159 @end deffn
1160
1161 @deffn {Procedure} bezier-curve-p2 @var{bezier}
1162 Return the second control point of @var{bezier}.
1163 @end deffn
1164
1165 @deffn {Procedure} bezier-curve-p3 @var{bezier}
1166 Return the end point of @var{bezier}.
1167 @end deffn
1168
1169 @deffn {Procedure} bezier-path . @var{control-points}
1170 Return a list of connected bezier curves defined by
1171 @var{control-points}. The first curve is defined by the first 4
1172 arguments and every additional curve thereafter requires 3 additional
1173 arguments.
1174 @end deffn
1175
1176 @deffn {Procedure} bezier-curve-point-at @var{bezier} @var{t}
1177 Return the coordinates for @var{bezier} at @var{t} (a value in the
1178 range [0, 1] representing how far from the start of the curve to
1179 check) as a 2D vector.
1180 @end deffn
1181
1182 @deffn {Procedure} bezier-curve-point-at! @var{dest} @var{bezier} @var{t}
1183 Modify the 2D vector @var{dest} in-place to contain the coordinates
1184 for @var{bezier} at @var{t}.
1185 @end deffn
1186
1187 @node Graphics
1188 @section Graphics
1189
1190 Chickadee aims to make hardware-accelerated graphics rendering as
1191 simple and efficient as possible by providing high-level APIs that
1192 interact with the low-level OpenGL API under the hood. Anyone that
1193 has worked with OpenGL directly knows that it has a steep learning
1194 curve and a lot of effort is needed to render even a single triangle.
1195 The Chickadee rendering engine attempts to make it easy to do common
1196 tasks like rendering a sprite while also providing all of the building
1197 blocks to implement additional rendering techniques.
1198
1199 @menu
1200 * Rendering Engine:: Rendering state management.
1201 * Textures:: 2D images.
1202 * Sprites:: Draw 2D images.
1203 * Tile Maps:: Draw 2D tile maps.
1204 * Lines and Shapes:: Draw line segments and polygons.
1205 * Fonts:: Drawing text.
1206 * Blending and Depth Testing:: Control how pixels are combined.
1207 * Vertex Arrays:: Create 2D/3D models.
1208 * Shaders:: Create custom GPU programs.
1209 * Framebuffers:: Render to texture.
1210 * Viewports:: Restrict rendering to
1211 @end menu
1212
1213 @node Rendering Engine
1214 @subsection Rendering Engine
1215
1216 Chickadee defines rendering using a metaphor familiar to Scheme
1217 programmers: procedure application. A shader (@pxref{Shaders}) is
1218 like a procedure for the GPU to apply. Shaders are passed arguments:
1219 A vertex array containing the geometry to render (@pxref{Vertex
1220 Arrays}) and zero or more keyword arguments that the shader
1221 understands. Similar to how Scheme has @code{apply} for calling
1222 procedures, Chickadee provides @code{gpu-apply} for calling shaders.
1223
1224 Additionally, there is some dynamic state that effects how
1225 @code{gpu-apply} will behave. Things like the current viewport,
1226 framebuffer, and blend mode are stored as dynamic state because it
1227 would be tedious to have to have to specify them each time
1228 @code{gpu-apply} is called.
1229
1230 The following procedures and syntax can be found in the
1231 @code{(chickadee render)} module.
1232
1233 @deffn {Syntax} gpu-apply @var{shader} @var{vertex-array} @
1234 [#:uniform-key @var{uniform-value} ...]
1235 @deffnx {Syntax} gpu-apply* @var{shader} @var{vertex-array} @
1236 @var{count} [#:uniform-key @var{uniform-value} ...]
1237
1238 Render @var{vertex-array} using @var{shader} with the uniform values
1239 specified in the following keyword arguments.
1240
1241 While @code{gpu-apply} will draw every vertex in @var{vertex-array},
1242 @code{gpu-apply*} will only draw @var{count} vertices.
1243
1244 @end deffn
1245
1246 @deffn {Procedure} current-viewport
1247 Return the currently bound viewport (@pxref{Viewports}).
1248 @end deffn
1249
1250 @deffn {Procedure} current-framebuffer
1251 Return the currently bound framebuffer (@pxref{Framebuffers}).
1252 @end deffn
1253
1254 @deffn {Procedure} current-blend-mode
1255 Return the currently bound blend mode (@pxref{Blending and Depth
1256 Testing}).
1257 @end deffn
1258
1259 @deffn {Procedure} current-depth-test
1260 Return @code{#t} if depth testing is currently enabled (@pxref{Blending and Depth Testing}).
1261 @end deffn
1262
1263 @deffn {Procedure} current-texture
1264 Return the currently bound texture (@pxref{Textures}).
1265 @end deffn
1266
1267 @deffn {Procedure} current-projection
1268 Return the currently bound projection matrix (@pxref{Matrices}).
1269 @end deffn
1270
1271 @deffn {Syntax} with-viewport @var{viewport} @var{body} ...
1272 Evaluate @var{body} with the current viewport bound to @var{viewport} (@pxref{Viewports}).
1273 @end deffn
1274
1275 @deffn {Syntax} with-framebuffer @var{framebuffer} @var{body} ...
1276 Evaluate @var{body} with the current framebuffer bound to
1277 @var{framebuffer} (@pxref{Framebuffers}).
1278 @end deffn
1279
1280 @deffn {Syntax} with-blend-mode @var{blend-mode} @var{body} ...
1281 Evaluate @var{body} with the current blend mode bound to
1282 @var{blend-mode} (@pxref{Blending and Depth Testing}).
1283 @end deffn
1284
1285 @deffn {Syntax} with-depth-test @var{depth-test?} @var{body} ...
1286 Evaluate @var{body} with the depth-test disabled if @var{depth-test?}
1287 is @code{#f}, or enabled otherwise (@pxref{Blending and Depth
1288 Testing}).
1289 @end deffn
1290
1291 @deffn {Syntax} with-texture @var{texture} @var{body} ...
1292 Evaluate @var{body} with the current texture bound to @var{texture}
1293 (@pxref{Textures}).
1294 @end deffn
1295
1296 @deffn {Syntax} with-projection @var{projection} @var{body} ...
1297 Evaluate @var{body} with the current projection matrix bound to
1298 @var{projection} (@pxref{Matrices}).
1299 @end deffn
1300
1301 @node Textures
1302 @subsection Textures
1303
1304 @deffn {Procedure} load-image @var{file} [#:min-filter nearest] @
1305 [#:mag-filter nearest] [#:wrap-s repeat] [#:wrap-t repeat]
1306
1307 Load the image data from @var{file} and return a new texture object.
1308
1309 @var{min-filter} and @var{mag-filter} describe the method that should
1310 be used for minification and magnification when rendering,
1311 respectively. Possible values are @code{nearest} and @code{linear}.
1312
1313 @var{wrap-s} and @var{wrap-t} describe how to interpret texture
1314 coordinates that are greater than @code{1.0}. Possible values are
1315 @code{repeat}, @code{clamp}, @code{clamp-to-border}, and
1316 @code{clamp-to-edge}.
1317
1318 @end deffn
1319
1320 @node Sprites
1321 @subsection Sprites
1322
1323 For those who are new to this game, a sprite is a 2D rectangular
1324 bitmap that is rendered to the screen. For 2D games, sprites are the
1325 most essential graphical abstraction. They are used for drawing maps,
1326 players, NPCs, items, particles, text, etc. In Chickadee, bitmaps are
1327 stored in textures (@pxref{Textures}) and can be used to draw sprites
1328 via the @code{draw-sprite} procedure.
1329
1330 @deffn {Procedure} draw-sprite @var{texture} @var{position} @
1331 [#:origin] [#:scale] [#:rotation] [#:blend-mode alpha] @
1332 [#:rect] [#:shader]
1333
1334 Draw @var{texture} at @var{position}.
1335
1336 Optionally, other transformations may be applied to the sprite.
1337 @var{rotation} specifies the angle to rotate the sprite, in radians.
1338 @var{scale} specifies the scaling factor as a 2D vector. All
1339 transformations are applied relative to @var{origin}, a 2D vector,
1340 which defaults to the lower-left corner.
1341
1342 Alpha blending is used by default but the blending method can be
1343 changed by specifying @var{blend-mode}.
1344
1345 The area drawn to is as big as the texture, by default. To draw to an
1346 arbitrary section of the screen, specify @var{rect}.
1347
1348 Finally, advanced users may specify @var{shader} to change the way the
1349 sprite is rendered entirely.
1350 @end deffn
1351
1352 It's not uncommon to need to draw hundreds or thousands of sprites
1353 each frame. However, GPUs (graphics processing units) are tricky
1354 beasts that prefer to be sent few, large chunks of data to render
1355 rather than many, small chunks. Using @code{draw-sprite} on its own
1356 will involve at least one GPU call @emph{per sprite}, which will
1357 quickly lead to poor performance. To deal with this, a technique
1358 known as ``sprite batching'' can be used. Instead of drawing each
1359 sprite immediately, the sprite batch will build up a large of buffer
1360 of sprites to draw and defer rendering until the last possible moment.
1361 Batching isn't a panacea, though. Batching only works if the sprites
1362 being drawn share as much in common as possible. Every time you draw
1363 a sprite with a different texture or blend mode, the batch will be
1364 sent off to the GPU. Therefore, batching is most useful if you
1365 minimize such changes. A good strategy for reducing texture changes
1366 is to stuff many bitmaps into a single image file and create a
1367 ``texture atlas'' (@pxref{Textures}) to access the sub-images within.
1368
1369 Taking advantage of sprite batching in Chickadee is easy, just wrap
1370 the code that is calling @code{draw-sprite} a lot in the
1371 @code{with-batched-sprites} form.
1372
1373 @deffn {Syntax} with-batched-sprites @var{body} @dots{}
1374 Use batched rendering for all @code{draw-sprite} calls within
1375 @var{body}.
1376 @end deffn
1377
1378 With a basic sprite abstraction in place, it's possible to build other
1379 abstractions on top of it. One such example is the ``nine patch''. A
1380 nine patch is a sprite that can be rendered at various sizes without
1381 becoming distorted. This is achieved by diving up the sprite into
1382 nine regions:
1383
1384 @itemize
1385 @item
1386 the center, which can be scaled horizontally and vertically
1387 @item
1388 the four corners, which can never be scaled
1389 @item
1390 the left and right sides, which can be scaled vertically
1391 @item
1392 the top and bottom sides, which can be scaled horizontally
1393 @end itemize
1394
1395 The one caveat is that the bitmap regions must be designed in such a
1396 way so that they are not distorted when stretched along the affected
1397 axes. For example, that means that the top and bottom sides could
1398 have varying colored pixels vertically, but not horizontally.
1399
1400 The most common application of this technique is for graphical user
1401 interface widgets like buttons and dialog boxes. By using a nine
1402 patch, they can be rendered at any size without unappealing scaling
1403 artifacts.
1404
1405 @deffn {Procedure} draw-nine-patch @var{texture} @var{rect} @
1406 [#:margin 0] [#:top-margin margin] [#:bottom-margin margin] @
1407 [#:left-margin margin] [#:right-margin margin] @
1408 [#:origin] [#:scale] [#:rotation] [#:blend-mode alpha] @
1409 [#:shader]
1410
1411 Draw a nine patch sprite. A nine patch sprite renders @var{texture}
1412 as a @var{width} x @var{height} rectangle whose stretchable areas are
1413 defined by the given margin measurements @var{top-margin},
1414 @var{bottom-margin}, @var{left-margin}, and @var{right-margin}. The
1415 @var{margin} argument may be used to configure all four margins at
1416 once.
1417
1418 Refer to @code{draw-sprite} (@pxref{Sprites}) for information about
1419 the other arguments.
1420 @end deffn
1421
1422 @node Tile Maps
1423 @subsection Tile Maps
1424
1425 A tile map is a scene created by composing lots of small sprites,
1426 called ``tiles'', into a larger image. One program for editing such
1427 maps is called @url{http://mapeditor.org,Tiled}. Chickadee has native
1428 support for loading and rendering Tiled maps in the @code{(chickadee
1429 render tiled)} module.
1430
1431 @deffn {Procedure} load-tile-map @var{file-name}
1432 Load the Tiled formatted map in @var{file-name} and return a new tile
1433 map object.
1434 @end deffn
1435
1436 @deffn {Procedure} draw-tile-map @var{tile-map} [#:layers] [#:region] @
1437 [#:origin] [#:position] [#:scale] [#:rotation]
1438
1439 Draw the layers of @var{tile-map}. By default, all layers are drawn.
1440 To draw a subset of the available layers, pass a list of layer ids
1441 using the @var{layers} keyword argument.
1442
1443 Refer to @code{draw-sprite} (@pxref{Sprites}) for information about
1444 the other arguments.
1445 @end deffn
1446
1447 @node Lines and Shapes
1448 @subsection Lines and Shapes
1449
1450 Sprites are fun, but sometimes simple, untextured lines and polygons
1451 are desired. That's where the @code{(chickadee render shapes)} module
1452 comes in!
1453
1454 @deffn {Procedure} draw-line @var{start} @var{end} @
1455 [#:thickness 0.5] [#:feather 1.0] [#:cap round] [#:color] @
1456 [#:shader]
1457
1458 Draw a line segment from @var{start} to @var{end}. The line will be
1459 @var{thickness} pixels thick with an antialiased border @var{feather}
1460 pixels wide. The line will be colored @var{color}. @var{cap}
1461 specifies the type of end cap that should be used to terminate the
1462 lines, either @code{none}, @code{butt}, @code{square}, @code{round},
1463 @code{triangle-in}, or @code{triangle-out}. Advanced users may use
1464 the @var{shader} argument to override the built-in line segment
1465 shader.
1466 @end deffn
1467
1468 @deffn {Procedure} draw-bezier-curve @var{bezier} [#:segments 32] @
1469 [#:control-points?] [#:tangents?] @
1470 [#:control-point-size 8] @
1471 [#:control-point-color yellow] @
1472 [#:tangent-color yellow] @
1473 [#:thickness 0.5] [#:feather 1.0] @
1474 [#:matrix]
1475
1476 Draw the curve defined by @var{bezier} using a resolution of N
1477 @var{segments}. When @var{control-points?} is @code{#t}, the control
1478 points are rendered as squares of size @var{control-point-size} pixels
1479 and a color of @var{control-point-color}. When @var{tangents?} is
1480 @code{#t}, the tangent lines from terminal point to control point are
1481 rendered using the color @var{tangent-color}.
1482
1483 All line segments rendered use @code{draw-line}, and thus the
1484 arguments @var{thickness} and @var{feather} have the same effect as in
1485 that procedure.
1486
1487 A custom @var{matrix} may be passed for applications that require more
1488 control over the final output.
1489 @end deffn
1490
1491 @deffn {Procedure} draw-bezier-path @var{path} [#:segments 32] @
1492 [#:control-points?] [#:tangents?] @
1493 [#:control-point-size 8] @
1494 [#:control-point-color yellow] @
1495 [#:tangent-color yellow] @
1496 [#:thickness 0.5] [#:feather 1.0] @
1497 [#:matrix]
1498
1499 Render @var{path}, a list of bezier curves. See the documentation for
1500 @code{draw-bezier-curve} for an explanation of all the keyword
1501 arguments.
1502 @end deffn
1503
1504 @node Fonts
1505 @subsection Fonts
1506
1507 Unlike the traditional TrueType font format that many are accustomed
1508 to, Chickadee loads and renders bitmap fonts in the
1509 @url{http://www.angelcode.com/products/bmfont/doc/file_format.html,
1510 Angel Code format}. But why use this seemingly obscure format? It's
1511 easy to find TTFs but not easy to find FNTs (the canonical file
1512 extension used for Angel Code fonts) and bitmap fonts don't scale
1513 well. The reason is efficiency.
1514
1515 If all of the glyphs of a font are pre-rendered and packed into an
1516 image file then it becomes possible to use a texture atlas
1517 (@pxref{Textures}) and a sprite batch (@pxref{Sprites}) when
1518 rendering, which is a more efficient way to render fonts than using,
1519 say, @url{https://www.libsdl.org/projects/SDL_ttf/, SDL_ttf} or other
1520 solutions that involve using the FreeType library directly.
1521
1522 Now what about scaling? In libraries that use TTF fonts, one must
1523 choose the size that the glyphs will be rasterized at up front. To
1524 use @code{n} sizes of the same font, one must load @code{n} variants
1525 of that font. If the size of the text is dynamic, some kind of
1526 texture scaling algorithm must be used and the text will inevitably
1527 look blurry. At first glance, using bitmap fonts seem to have an even
1528 worse issue. Instead of just loading the same font @code{n} times at
1529 different sizes, one would need to generate @code{n} image files for
1530 each font size needed. This is where the ``signed distance field''
1531 rendering technique comes in. Introduced by
1532 @url{http://www.valvesoftware.com/.../2007/SIGGRAPH2007_AlphaTestedMagnification.pdf,
1533 Valve} in 2007, signed distance field fonts can be efficiently stored
1534 in a bitmap and be rendered at arbitrary scale factors with good
1535 results.
1536
1537 While Chickadee does not yet offer a tool for converting TTF fonts
1538 into FNT fonts, tools such as
1539 @url{https://github.com/libgdx/libgdx/wiki/Hiero, Hiero} may be used
1540 in the meantime.
1541
1542 The following procedures can be found in the @code{(chickadee render
1543 font)} module.
1544
1545 @deffn {Procedure} load-font @var{file}
1546 Load the Angel Code formatted XML document in @var{file} and return a
1547 new font object.
1548 @end deffn
1549
1550 @deffn {Procedure} font? @var{obj}
1551 Return @code{#t} if @var{obj} is a font object.
1552 @end deffn
1553
1554 @deffn {Procedure} font-face @var{font}
1555 Return the name of @var{font}.
1556 @end deffn
1557
1558 @deffn {Procedure} font-line-height @var{font}
1559 Return the line height of @var{font}.
1560 @end deffn
1561
1562 @deffn {Procedure} font-line-height @var{font}
1563 Return the line height of @var{font}.
1564 @end deffn
1565
1566 @deffn {Procedure} font-bold? @var{font}
1567 Return @code{#t} if @var{font} is a bold font.
1568 @end deffn
1569
1570 @deffn {Procedure} font-italic? @var{font}
1571 Return @code{#t} if @var{font} is an italicized font.
1572 @end deffn
1573
1574 @deffn {Procedure} draw-text @var{font} @var{text} @var{position}
1575 [#:origin] [#:scale] [#:rotation] [#:blend-mode]
1576 [#:start 0] [#:end @code{(string-length text)}]
1577
1578 Draw the string @var{text} with the first character starting at
1579 @var{position} using @var{font}.
1580
1581 @example
1582 (draw-text font "Hello, world!" (vec2 128.0 128.0))
1583 @end example
1584
1585 To render a substring of @var{text}, use the @var{start} and @var{end}
1586 arguments.
1587
1588 Refer to @code{draw-sprite} (@pxref{Sprites}) for information about
1589 the other arguments.
1590 @end deffn
1591
1592 @node Blending and Depth Testing
1593 @subsection Blending and Depth Testing
1594
1595 @node Vertex Arrays
1596 @subsection Vertex Arrays
1597
1598 @node Shaders
1599 @subsection Shaders
1600
1601 Shaders are programs for the GPU to evaluate. They are written in the
1602 OpenGL Shading Language, or GLSL. Chickadee does not currently
1603 provide a Scheme-like domain specific language for writing shaders.
1604 Since shaders must be written in GLSL and not Scheme, they are
1605 considered an advanced feature.
1606
1607 @node Framebuffers
1608 @subsection Framebuffers
1609
1610 A framebuffer is a chunk of memory that the GPU can render things
1611 onto. By default, the framebuffer that is used for rendering is the
1612 one belonging to the game window, but custom framebuffers can be used
1613 as well. A common use-case for custom framebuffers is applying
1614 post-processing effects: The entire scene is rendered to a
1615 framebuffer, and then the contents of that framebuffer are applied to
1616 a post-processing shader and rendered to the game window. The
1617 post-processing shader could do any number of things: scaling,
1618 antialiasing, motion blur, etc.
1619
1620 @deffn {Procedure} make-framebuffer @var{width} @var{height} [#:min-filter 'linear] [#:mag-filter 'linear] [#:wrap-s 'repeat] [#:wrap-t 'repeat]
1621
1622 Create a new framebuffer that is @var{width} pixels wide and @var{height} pixels high.
1623
1624 @var{min-filter} and @var{mag-filter} determine the scaling algorithm
1625 applied to the framebuffer when rendering. By default, linear scaling
1626 is used in both cases. To perform no smoothing at all, use
1627 @code{nearest} for simple nearest neighbor scaling. This is typically
1628 the best choice for pixel art games.
1629 @end deffn
1630
1631 @deffn {Procedure} framebuffer? @var{obj}
1632 Return @code{#t} if @var{obj} is a framebuffer.
1633 @end deffn
1634
1635 @deffn {Procedure} framebuffer-texture @var{fb}
1636 Return the texture backing the framebuffer @var{fb}.
1637 @end deffn
1638
1639 @deffn {Procedure} framebuffer-viewport @var{fb}
1640 Return the default viewport (@pxref{Viewports}) used by the
1641 framebuffer @var{fb}.
1642 @end deffn
1643
1644 @deffn {Procedure} null-framebuffer
1645 The default framebuffer.
1646 @end deffn
1647
1648 @node Viewports
1649 @subsection Viewports
1650
1651 @node Scripting
1652 @section Scripting
1653
1654 Game logic is a web of asynchronous events that are carefully
1655 coordinated to bring the game world to life. In order to make an
1656 enemy follow and attack the player, or move an NPC back and forth in
1657 front of the item shop, or do both at the same time, a scripting
1658 system is a necessity. Chickadee comes with an asynchronous
1659 programming system in the @code{(chickadee scripting)} module.
1660 Lightweight, cooperative threads known as ``scripts'' allow the
1661 programmer to write asynchronous code as if it were synchronous, and
1662 allow many such ``threads'' to run concurrently.
1663
1664 But before we dig deeper into scripts, let's discuss the simple act
1665 of scheduling tasks.
1666
1667 @menu
1668 * Agendas:: Scheduling tasks.
1669 * Scripts:: Cooperative multitasking.
1670 * Tweening:: Animations.
1671 * Channels:: Publish data to listeners.
1672 @end menu
1673
1674 @node Agendas
1675 @subsection Agendas
1676
1677 To schedule a task to be performed later, an ``agenda'' is used.
1678 There is a default, global agenda that is ready to be used, or
1679 additional agendas may be created for different purposes. The
1680 following example prints the text ``hello'' when the agenda has
1681 advanced to time unit 10.
1682
1683 @example
1684 (at 10 (display "hello\n"))
1685 @end example
1686
1687 Most of the time it is more convenient to schedule tasks relative to
1688 the current time. This is where @code{after} comes in handy:
1689
1690 @example
1691 (after 10 (display "hello\n"))
1692 @end example
1693
1694 Time units in the agenda are in no way connected to real time. It's
1695 up to the programmer to decide what agenda time means. A simple and
1696 effective approach is to map each call of the update hook
1697 (@pxref{Kernel}) to 1 unit of agenda time, like so:
1698
1699 @example
1700 (add-hook! update-hook (lambda (dt) (update-agenda 1)))
1701 @end example
1702
1703 It is important to call @code{update-agenda} periodically, otherwise
1704 no tasks will ever be run!
1705
1706 In addition to using the global agenda, it is useful to have multiple
1707 agendas for different purposes. For example, the game world can use a
1708 different agenda than the user interface, so that pausing the game is
1709 a simple matter of not updating the world's agenda while continuing to
1710 update the user interface's agenda. The current agenda is dynamically
1711 scoped and can be changed using the @code{with-agenda} special form:
1712
1713 @example
1714 (define game-world-agenda (make-agenda))
1715
1716 (with-agenda game-world-agenda
1717 (at 60 (spawn-goblin))
1718 (at 120 (spawn-goblin))
1719 (at 240 (spawn-goblin-king)))
1720 @end example
1721
1722 @deffn {Procedure} make-agenda
1723 Return a new task scheduler.
1724 @end deffn
1725
1726 @deffn {Procedure} agenda? @var{obj}
1727 Return @code{#t} if @var{obj} is an agenda.
1728 @end deffn
1729
1730 @deffn {Procedure} current-agenda
1731 @deffnx {Procedure} current-agenda @var{agenda}
1732 When called with no arguments, return the current agenda. When called
1733 with one argument, set the current agenda to @var{agenda}.
1734 @end deffn
1735
1736 @deffn {Syntax} with-agenda @var{agenda} @var{body} @dots{}
1737 Evaluate @var{body} with the current agenda set to @var{agenda}.
1738 @end deffn
1739
1740 @deffn {Procedure} agenda-time
1741 Return the current agenda time.
1742 @end deffn
1743
1744 @deffn {Procedure} update-agenda @var{dt}
1745 Advance the current agenda by @var{dt}.
1746 @end deffn
1747
1748 @deffn {Procedure} schedule-at @var{time} @var{thunk}
1749 Schedule @var{thunk}, a procedure of zero arguments, to be run at
1750 @var{time}.
1751 @end deffn
1752
1753 @deffn {Procedure} schedule-after @var{delay} @var{thunk}
1754 Schedule @var{thunk}, a procedure of zero arguments, to be run after
1755 @var{delay}.
1756 @end deffn
1757
1758 @deffn {Procedure} schedule-every @var{interval} @var{thunk} [@var{n}]
1759 Schedule @var{thunk}, a procedure of zero arguments, to be run every
1760 @var{interval} amount of time. Repeat this @var{n} times, or
1761 indefinitely if not specified.
1762 @end deffn
1763
1764 @deffn {Syntax} at @var{time} @var{body} @dots{}
1765 Schedule @var{body} to be evaluated at @var{time}.
1766 @end deffn
1767
1768 @deffn {Syntax} after @var{delay} @var{body} @dots{}
1769 Schedule @var{body} to be evaluated after @var{delay}.
1770 @end deffn
1771
1772 @deffn {Syntax} every @var{interval} @var{body} @dots{}
1773 @deffnx {Syntax} every (@var{interval} @var{n}) @var{body} @dots{}
1774 Schedule @var{body} to be evaluated every @var{interval} amount of
1775 time. Repeat this @var{n} times, or indefinitely if not specified.
1776 @end deffn
1777
1778 @node Scripts
1779 @subsection Scripts
1780
1781 Now that we can schedule tasks, let's take things to the next level.
1782 It sure would be great if we could make procedures that described a
1783 series of actions that happened over time, especially if we could do
1784 so without contorting our code into a nest of callback procedures.
1785 This is where scripts come in. With scripts we can write code in a
1786 linear way, in a manner that appears to be synchronous, but with the
1787 ability to suspend periodically in order to let other scripts have a
1788 turn and prevent blocking the game loop. Building on top of the
1789 scheduling that agendas provide, here is a script that models a child
1790 trying to get their mother's attention:
1791
1792 @example
1793 (script
1794 (while #t
1795 (display "mom!")
1796 (newline)
1797 (sleep 60))) ; where 60 = 1 second of real time
1798 @end example
1799
1800 This code runs in an endless loop, but the @code{sleep} procedure
1801 suspends the script and schedules it to be run later by the agenda.
1802 So, after each iteration of the loop, control is returned back to the
1803 game loop and the program is not stuck spinning in a loop that will
1804 never exit. Pretty neat, eh?
1805
1806 Scripts can suspend to any capable handler, not just the agenda.
1807 The @code{yield} procedure will suspend the current script and pass
1808 its ``continuation'' to a handler procedure. This handler procedure
1809 could do anything. Perhaps the handler stashes the continuation
1810 somewhere where it will be resumed when the user presses a specific
1811 key on the keyboard, or maybe it will be resumed when the player picks
1812 up an item off of the dungeon floor; the sky is the limit.
1813
1814 Sometimes it is necessary to abruptly terminate a script after it has
1815 been started. For example, when an enemy is defeated their AI routine
1816 needs to be shut down. When a script is spawned, a handle to that
1817 script is returned that can be used to cancel it when desired.
1818
1819 @example
1820 (define script (script (while #t (display "hey\n") (sleep 60))))
1821 ;; sometime later
1822 (cancel-script script)
1823 @end example
1824
1825 @deffn {Procedure} spawn-script @var{thunk}
1826 Apply @var{thunk} as a script and return a handle to it.
1827 @end deffn
1828
1829 @deffn {Syntax} script @var{body} @dots{}
1830 Evaluate @var{body} as a script and return a handle to it.
1831 @end deffn
1832
1833 @deffn {Procedure} script? @var{obj}
1834 Return @code{#t} if @var{obj} is a script handle.
1835 @end deffn
1836
1837 @deffn {Procedure} script-cancelled? @var{obj}
1838 Return @code{#t} if @var{obj} has been cancelled.
1839 @end deffn
1840
1841 @deffn {Procedure} script-running? @var{obj}
1842 Return @code{#t} if @var{obj} has not yet terminated or been
1843 cancelled.
1844 @end deffn
1845
1846 @deffn {Procedure} script-complete? @var{obj}
1847 Return @code{#t} if @var{obj} has terminated.
1848 @end deffn
1849
1850 @deffn {Procedure} cancel-script @var{co}
1851 Prevent further execution of the script @var{co}.
1852 @end deffn
1853
1854 @deffn {Procedure} yield @var{handler}
1855 Suspend the current script and pass its continuation to the
1856 procedure @var{handler}.
1857 @end deffn
1858
1859 @deffn {Procedure} sleep @var{duration}
1860 Wait @var{duration} before resuming the current script.
1861 @end deffn
1862
1863 @deffn {Procedure} channel-get @var{channel}
1864 Wait for a message from @var{channel}.
1865 @end deffn
1866
1867 @deffn {Syntax} forever @var{body} @dots{}
1868 Evaluate @var{body} in an endless loop.
1869 @end deffn
1870
1871 @node Tweening
1872 @subsection Tweening
1873
1874 Tweening is the process of transitioning something from an initial
1875 state to a final state over a pre-determined period of time. In other
1876 words, tweening is a way to create animation. The @code{tween}
1877 procedure can be used within any script like so:
1878
1879 @example
1880 (define x 0)
1881 (script
1882 ;; 0 to 100 in 60 ticks of the agenda.
1883 (tween 60 0 100 (lambda (y) (set! x y))))
1884 @end example
1885
1886 @deffn {Procedure} tween @var{duration} @var{start} @var{end} @var{proc} [#:step 1 #:ease @code{smoothstep} #:interpolate @code{lerp}]
1887 Transition a value from @var{start} to @var{end} over @var{duration},
1888 sending each succesive value to @var{proc}. @var{step} controls the
1889 amount of time between each update of the animation.
1890
1891 To control how the animation goes from the initial to final state, an
1892 ``easing'' procedure may be specified. By default, the
1893 @code{smoothstep} easing is used, which is a more pleasing default
1894 than a simplistic linear function. @xref{Easings} for a complete list
1895 of available easing procedures.
1896
1897 The @var{interpolate} procedure computes the values in between
1898 @var{start} and @var{end}. By default, linear interpolation (``lerp''
1899 for short) is used.
1900 @end deffn
1901
1902 @node Channels
1903 @subsection Channels
1904
1905 Channels are a tool for communicating amongst different scripts. One
1906 script can write a value to the channel and another can read from it.
1907 Reading or writing to a channel suspends that script until there is
1908 someone on the other end of the line to complete the transaction.
1909
1910 Here's a simplistic example:
1911
1912 @example
1913 (define c (make-channel))
1914
1915 (script
1916 (forever
1917 (let ((item (channel-get c)))
1918 (pk 'got item))))
1919
1920 (script
1921 (channel-put c 'sword)
1922 (channel-put c 'shield)
1923 (channel-put c 'potion))
1924 @end example
1925
1926 @deffn {Procedure} make-channel
1927 Return a new channel
1928 @end deffn
1929
1930 @deffn {Procedure} channel? @var{obj}
1931 Return @code{#t} if @var{obj} is a channel.
1932 @end deffn
1933
1934 @deffn {Procedure} channel-get @var{channel}
1935 Retrieve a value from @var{channel}. The current script suspends
1936 until a value is available.
1937 @end deffn
1938
1939 @deffn {Procedure} channel-put @var{channel} @var{data}
1940 Send @var{data} to @var{channel}. The current script suspends until
1941 another script is available to retrieve the value.
1942 @end deffn