% quick.tex 
\documentclass{book} 
\usepackage{slatex} 

\author{Jon Rafkind}
\title{Allegro: Multimedia library and game utilities}
\date{\today}

\begin{document} 
\maketitle
\newcommand{\var}[1]{\scheme|#1|}
\newcommand{\num}[1]{\scheme|#1|}
\newcommand{\link}[1]{\hyperlink{#1}{#1}}
\newcommand{\makelink}[1]{\hypertarget{s_#1}{}\link{#1}\newline}
\newcommand{\mark}[1]{\hrule\hyperlink{s_#1}{top}\hypertarget{#1}{}\newline\newline}
\newcommand{\function}[2]{procedure: \scheme{#1 :: #2}}
\newcommand{\qfunction}[2]{\scheme{#1 :: #2}}

\begin{schemeregion}

Allegro offers a wide range of multimedia use such as graphics, sound, keyboard, and mouse handling. It also provides a set of game utilities for some of the mechanics real-time games need. The Allegro package is based on a C library, also named Allegro, by Shawn Hargreaves.

The goal of the C library and consequently the scheme package is to make multimedia, especially games, very easy and straight-forward to program. 

More information about the C library can be found here:

{\tt http://alleg.sf.net}

{\bf Where to start?}\newline
If you are just looking to write a game look at the \link{game-chapter} and \link{graphics-chapter} chapter. The allegro.plt package contains high-level and low-level mechanisms, but you don't need to be familiar with all of them to use it.

The Allegro package is quite large and I apologize in advance for any inconsistencies in this documentation. Please send any typos or other bugs in this documentation to jon@rafkind.com.

\subsection*{Installation}

Allegro can be installed via planet. Either require a file from the distribution in mzscheme/drscheme
\begin{schemedisplay}
(require (planet "util.ss" ("kazzmir" "allegro.plt")))
\end{schemedisplay}

Or download the allegro.plt file from the planet site and install it by hand

\begin{verbatim}
$ planet -f allegro.plt kazzmir X Y
\end{verbatim}

Where X and Y is the version of the package such as 1 1 or 1 6.

The planet package comes with the underlying C library. On Windows and OSX this library is a prebuilt shared library( dll or dylib ). On UNIX/Linux the C library is built from source which could potentially take a few minutes to complete. During this time you will not see any indication of what planet is doing, but it should complete and be useable in the time it takes to get a cup of coffee.

\tableofcontents

\chapter{Utilities}

\scheme{(require (planet "util.ss" ("kazzmir" "allegro.plt")))}

Function list

\makelink{easy-init}
\makelink{easy-exit}
\makelink{blend-palette}
\makelink{frames-per-second}
\makelink{game-loop}
\makelink{set-color-conversion!}
\makelink{apply-matrix}
\makelink{get-transformation-matrix}
\makelink{get-camera-matrix}
\makelink{persp-project}
\makelink{set-projection-viewport}
\makelink{polygon-z-normal}
\makelink{set-add-blender!}
\makelink{set-alpha-blender!}
\makelink{set-burn-blender!}
\makelink{Sine}
\makelink{Cosine}
\makelink{calculate-normal-angle}
\makelink{calculate-angle}
\makelink{set-color-blender!}
\makelink{set-difference-blender!}
\makelink{set-dissolve-blender!}
\makelink{set-dodge-blender!}
\makelink{set-drawing-mode-solid!}
\makelink{set-drawing-mode-translucent!}
\makelink{set-drawing-mode-xor!}
\makelink{set-hue-blender!}
\makelink{set-invert-blender!}
\makelink{set-luminance-blender!}
\makelink{set-multiply-blender!}
\makelink{set-saturation-blender!}
\makelink{set-screen-blender!}
\makelink{set-trans-blender!}
\makelink{set-write-alpha-blender!}

\mark{easy-init}
\function{(easy-init width height depth [mode])}{void}

Start up the Allegro environment and create a graphics window. The lowerlevel mechanisms to start up the Allegro environment are currently not provided by this package, you must use easy-init to instantiate a graphics context.

\var{width} and \var{height} are the width and height of the graphics context, respectively. Typical width/height pairs are
\newline
\num{640} \num{480}\newline
\num{800} \num{600}\newline
\num{1024} \num{768}\newline
\num{1240} \num{1024}\newline

\var{depth} is the number of bits per pixel. Possible choices are
\newline
\num{15} - 32,768 possible colors
\newline
\num{16} - 65,536 possible colors
\newline
\num{24} - 16,777,216 possible colors, without the alpha channel
\newline
\num{32} - 16,777,216 possible colors, with the alpha channel
\newline

\var{mode} can be one of the following
\begin{itemize}
	\item{\scheme|'WINDOWED| - Graphics context is a window}
	\item{\scheme|'FULLSCREEN| - Use entire monitor for graphics context}
\end{itemize}

\mark{easy-exit}
\function{(easy-exit)}{void}

Shut down the Allegro engine and destroy the current graphics context. It is not safe to use any Allegro function after this, but you can call \link{easy-init} again.

\mark{blend-palette}
\function{(blend-palette start-color end-color num-color)}{list-of num}

Returns a list of colors that can be used as pixel values. The colors are
calculated by interpolating the individual pixel components( red, green, blue
) from start color to end color. This is an easy way to make a color gradient.

\begin{schemedisplay}
;; Make a list of 10 greys from black to white.
(blend-palette (color 0 0 0) (color 255 255 255) 10)
\end{schemedisplay}

\mark{frames-per-second}
\function{(frames-per-second num)}{num}
\newline
\qfunction{(fps num)}{num}

Returns a value that can be given to \link{game-loop} for how fast a game will run. \var{num} is the number of logic cycles per second to run the game at.

\mark{game-loop}
\function{(game-loop logic-proc draw-proc game-delay)}{void}

The de-facto game loop which should satisfy most real-time game requirements. After enough time has passed, specified by \var{game-delay}, the \var{logic-proc} function will be run specifically to create some side-affects. After at least one \var{logic-proc} cycle has occured \var{draw-proc} will be executed to display the current state of the game on the graphics context. \var{game-loop} will loop until \var{logic-proc} returns #t.

\var{logic-proc} :: \scheme{(lambda () ...)}\newline
\var{draw-proc} :: \scheme{(lambda (buffer) ...)}\newline
\var{game-delay} :: \scheme{num}\newline

The buffer passed to draw-proc is an \link{image} that is safe to draw on. After the draw-proc is run this image will be copied to the screen so any previous data on the screen will be lost. It is upto the programmer to retain the state of the universe to be drawn on the buffer during the draw-proc. See the \link{examples} chapter for an idea on how to use game-loop.

\mark{set-color-conversion!}
\function{(set-color-conversion! arg)}{void}

Should not be needed by regular users.

\mark{apply-matrix}
\function{(apply-matrix matrix x y z)}{(values x y z)}

Apply \var{matrix} to the coordinates \var{x}, \var{y}, \var{z}. The result is a new set of 3d coordinates.

\mark{get-transformation-matrix}
\function{(get-transformation-matrix scale x-rotation y-rotation z-rotation x y z)}{matrix}

Create a matrix that will rotate coordinates by \var{x-rotation}, \var{y-rotation}, \var{z-rotation}, scale the coordinates by \var{scale}, and translate the coordinates by \var{x}, \var{y}, \var{z}. The result is a matrix, which is an opaque type.

\mark{get-camera-matrix}
\function{(get-camera-matrix x y z xfront yfront zfront xup yup zup fov aspect)}{matrix}

Constructs a camera matrix for translating world-space objects into a normalised view space, ready for the perspective projection. The x, y, and z parameters specify the camera position, xfront, yfront, and zfront are the 'in front' vector specifying which way the camera is facing (this can be any length: normalisation is not required), and xup, yup, and zup are the 'up' direction vector.  The fov parameter specifies the field of view (ie. width of the camera focus) in binary, 256 degrees to the circle format. For typical projections, a field of view in the region 32-48 will work well. 64 (90°) applies no extra scaling - so something which is one unit away from the viewer will be directly scaled to the viewport. A bigger FOV moves you closer to the viewing plane, so more objects will appear. A smaller FOV moves you away from the viewing plane, which means you see a smaller part of the world.  Finally, the aspect ratio is used to scale the Y dimensions of the image relative to the X axis, so you can use it to adjust the proportions of the output image (set it to 1 for no scaling - but keep in mind that the projection also performs scaling according to the viewport size).  Typically, you will pass (float)w/(float)h, where w and h are the parameters you passed to \link{set-projection-viewport}.

\mark{persp-project}
\function{(persp-project x y z)}{(values x y)}

Projects the 3d point (\var{x}, \var{y}, \var{z}) onto the 2d space as defined by \link{set-projection-viewport}.

\mark{set-projection-viewport}
\function{(set-projection-viewport x1 y1 x2 y2)}{void}

Sets the viewport used to scale the output of the \link{persp-project} function. Pass the dimensions of the screen area you want to draw onto, which will typically be 0, 0, window width, and window height. Also don't forget to pass an appropriate aspect ratio to \link{get-camera-matrix} later. The width and height you specify here will determine how big your viewport is in 3d space. So if an object in your 3D space is w units wide, it will fill the complete screen when you run into it (i.e., if it has a distance of 1.0 after the camera matrix was applied. The fov and aspect-ratio parameters to \link{get-camera-matrix} also apply some scaling though, so this isn't always completely true). If you pass -1/-1/2/2 as parameters, no extra scaling will be performed by the projection.

\mark{polygon-z-normal}
\function{(polygon-z-normal v1 v2 v3)}{float}

\var{v1}, \var{v2}, and \var{v3} all have the type \link{v3d}.

Finds the Z component of the normal vector to the specified three vertices (which must be part of a convex polygon). This is used mainly in back-face culling. The back-faces of closed polyhedra are never visible to the viewer, therefore they never need to be drawn. This can cull on average half the polygons from a scene. If the normal is negative the polygon can safely be culled. If it is zero, the polygon is perpendicular to the screen.  

However, this method of culling back-faces must only be used once the X and Y coordinates have been projected into screen space using \link{persp-project} (or if an orthographic (isometric) projection is being used). Note that this function will fail if the three vertices are co-linear (they lie on the same line) in 3D space.

\mark{set-add-blender!}
\function{(set-add-blender! red green blue alpha)}{void}

Enables an additive blender mode for combining translucent or lit truecolor pixels.

\mark{set-alpha-blender!}
\function{(set-alpha-blender! red green blue alpha)}{void}

Enables the special alpha-channel blending mode, which is used for drawing 32-bit RGBA sprites. After calling this function, you can use draw_trans_sprite() or draw_trans_rle_sprite() to draw a 32-bit source image onto any hicolor or truecolor destination. The alpha values will be taken directly from the source graphic, so you can vary the solidity of each part of the image. You can't use any of the normal translucency functions while this mode is active, though, so you should reset to one of the normal blender modes (eg. set_trans_blender()) before drawing anything other than 32-bit RGBA sprites.

\mark{set-burn-blender!}
\function{(set-burn-blender! red green blue alpha)}{void}

Enables a burn blender mode for combining translucent or lit truecolor pixels.  Here the lightness values of the colours of the source image reduce the lightness of the destination image, darkening the image.

\mark{set-color-blender!}
\function{(set-color-blender! red green blue alpha)}{void}

Enables a color blender mode for combining translucent or lit truecolor pixels.
Applies only the hue and saturation of the source image to the destination
image. The luminance of the destination image is not affected.

\mark{set-difference-blender!}
\function{(set-difference-blender! red green blue alpha)}{void}

Enables a difference blender mode for combining translucent or lit truecolor
pixels. This makes an image which has colours calculated by the difference
between the source and destination colours.

\mark{set-dissolve-blender!}
\function{(set-dissolve-blender! red green blue alpha)}{void}

Enables a dissolve blender mode for combining translucent or lit truecolor
pixels. Randomly replaces the colours of some pixels in the destination image
with those of the source image. The number of pixels replaced depends on the
alpha value (higher value, more pixels replaced; you get the idea :).

\mark{set-dodge-blender!}
\function{(set-dodge-blender! red green blue alpha)}{void}

Enables a dodge blender mode for combining translucent or lit truecolor pixels.
The lightness of colours in the source lighten the colours of the destination.
White has the most effect; black has none.

\mark{set-drawing-mode-solid!}
\function{(set-drawing-mode-solid!)}{void}

Pixels are drawn opaquely, meaning a pixel with an RGB color of 200,100,32 will be seen exactly as 200,100,32.

\mark{set-drawing-mode-translucent!}
\function{(set-drawing-mode-translucent!)}{void}

Pixels are drawn translucently, meaning a pixel with RGB color of 200,100,32 will be blended together with the pixel that already exists at its location.

\mark{set-drawing-mode-xor!}
\function{(set-drawing-mode-xor!)}{void}

Pixels are drawn using an xor operation so if you draw the same shape twice it will be erased the second time.

\mark{set-hue-blender!}
\function{(set-hue-blender! red green blue alpha)}{void}

Enables a hue blender mode for combining translucent or lit truecolor pixels. This applies the hue of the source to the destination.

\mark{set-invert-blender!}
\function{(set-invert-blender! red green blue alpha)}{void}

Enables an invert blender mode for combining translucent or lit truecolor pixels. Blends the inverse (or negative) colour of the source with the destination.

\mark{set-luminance-blender!}
\function{(set-luminance-blender! red green blue alpha)}{void}

Enables a luminance blender mode for combining translucent or lit truecolor pixels. Applies the luminance of the source to the destination.  The colour of the destination is not affected.

\mark{set-multiply-blender!}
\function{(set-multiply-blender! red green blue alpha)}{void}

Enables a multiply blender mode for combining translucent or lit truecolor pixels. Combines the source and destination images, multiplying the colours to produce a darker colour. If a colour is multiplied by white it remains unchanged; when multiplied by black it also becomes black.

\mark{set-saturation-blender!}
\function{(set-saturation-blender! red green blue alpha)}{void}

Enables a saturation blender mode for combining translucent or lit truecolor pixels. Applies the saturation of the source to the destination image.

\mark{set-screen-blender!}
\function{(set-screen-blender! red green blue alpha)}{void}

Enables a screen blender mode for combining translucent or lit truecolor pixels. This blender mode lightens the colour of the destination image by multiplying the inverse of the source and destination colours. Sort of like the opposite of the multiply blender mode.

\mark{set-trans-blender!}
\function{(set-trans-blender! red green blue alpha)}{void}

Enables a linear interpolator blender mode for combining translucent or lit truecolor pixels.
\newline
0 <= \var{red} <= 255\newline
0 <= \var{green} <= 255\newline
0 <= \var{blue} <= 255\newline
0 <= \var{alpha} <= 255\newline

For alpha 0 is translucent and 255 is opaque.

\mark{set-write-alpha-blender!}
\function{(set-write-alpha-blender! red green blue alpha)}{void}

Enables the special alpha-channel editing mode, which is used for drawing alpha channels over the top of an existing 32-bit RGB sprite, to turn it into an RGBA format image. After calling this function, you can set the drawing mode to DRAW_MODE_TRANS and then write draw color values (0-255) onto a 32-bit image.  This will leave the color values unchanged, but alter the alpha to whatever values you are writing. After enabling this mode you can also use draw_trans_sprite() to superimpose an 8-bit alpha mask over the top of an existing 32-bit sprite.

\mark{Cosine}
\function{(Cosine angle)}{float}

Calculate the cosine of angle specified in degrees from 0-360

\mark{Sine}
\function{(Sine angle)}{float}

Calculate the sine of an angle specified in degrees from 0-360

\mark{calculate-angle}
\function{(calculate-angle x1 y1 x2 y2)}{float}

Calculate the angle from \var{x1},\var{y1} to \var{x2},\var{y2} using the arc tangent. This only returns the vector in the first quadrant. Normally you should use \link{calculate-normal-angle}.

\mark{calculate-normal-angle}
\function{(calculate-normal-angle x1 y1 x2 y2)}{float}

Calculate the angle from \var{x1},\var{y1} to \var{x2},\var{y2} using the arc tangent. This angle is normalized so that \degree{270} increases the y coordinate, which is farther "down" the screen.

\chapter{Graphics}
\hypertarget{graphics-chapter}{}

\newcommand{\translucent}[1]{Like \link{#1} but use \var{red}, \var{blue}, \var{green}, and \var{alpha} to set the translucency. See \link{set-trans-blender!} and \link{set-drawing-mode-translucent!}.}
\newcommand{\screen}[1]{Exactly like \link{#1} except the first argument is implicitly \link{screen}.}

\scheme{(require (planet "image.ss" ("kazzmir" "allegro.plt")))}

Function list

\makelink{arc-screen/translucent}
\makelink{arc-screen}
\makelink{arc/translucent}
\makelink{arc}
\makelink{calculate-spline}
\makelink{circle-fill-screen/translucent}
\makelink{circle-fill-screen}
\makelink{circle-fill/translucent}
\makelink{circle-fill}
\makelink{circle-screen/translucent}
\makelink{circle-screen}
\makelink{circle/translucent}
\makelink{circle}
\makelink{clear-screen}
\makelink{clear}
\makelink{color}
\makelink{copy-masked-screen}
\makelink{copy-masked-stretch-screen}
\makelink{copy-masked-stretch}
\makelink{copy-masked}
\makelink{copy-screen}
\makelink{copy-stretch-screen}
\makelink{copy-stretch}
\makelink{copy}
\makelink{create-from-file}
\makelink{create-sub-screen}
\makelink{create-sub}
\makelink{create}
\makelink{destroy}
\makelink{draw-character-screen}
\makelink{draw-character}
\makelink{draw-gouraud-screen}
\makelink{draw-gouraud}
\makelink{draw-horizontal-flip-screen}
\makelink{draw-horizontal-flip}
\makelink{draw-lit}
\makelink{draw-pivot-scaled-screen}
\makelink{draw-pivot-scaled-vertical-flip-screen}
\makelink{draw-pivot-scaled-vertical-flip}
\makelink{draw-pivot-scaled}
\makelink{draw-pivot-screen}
\makelink{draw-pivot-vertical-flip-screen}
\makelink{draw-pivot-vertical-flip}
\makelink{draw-pivot}
\makelink{draw-rotate-scaled-screen}
\makelink{draw-rotate-scaled-vertical-flip-screen}
\makelink{draw-rotate-scaled-vertical-flip}
\makelink{draw-rotate-scaled}
\makelink{draw-rotate-screen}
\makelink{draw-rotate-vertical-flip-screen}
\makelink{draw-rotate-vertical-flip}
\makelink{draw-rotate}
\makelink{draw-screen}
\makelink{draw-stretched}
\makelink{draw-translucent}
\makelink{draw-vertical-flip-screen}
\makelink{draw-vertical-flip}
\makelink{draw-vertical-horizontal-flip-screen}
\makelink{draw-vertical-horizontal-flip}
\makelink{draw}
\makelink{duplicate-screen}
\makelink{duplicate}
\makelink{ellipse-fill-screen/translucent}
\makelink{ellipse-fill-screen}
\makelink{ellipse-fill/translucent}
\makelink{ellipse-fill}
\makelink{ellipse-screen/translucent}
\makelink{ellipse-screen}
\makelink{ellipse/translucent}
\makelink{ellipse}
\makelink{fastline-screen/translucent}
\makelink{fastline-screen}
\makelink{fastline/translucent}
\makelink{fastline}
\makelink{floodfill-screen/translucent}
\makelink{floodfill-screen}
\makelink{floodfill/translucent}
\makelink{floodfill}
\makelink{get-rgb}
\makelink{getpixel-screen}
\makelink{getpixel}
\makelink{height}
\makelink{line-screen/translucent}
\makelink{line-screen}
\makelink{line/translucent}
\makelink{line}
\makelink{mask-color-screen}
\makelink{mask-color}
\makelink{polygon-screen/translucent}
\makelink{polygon-screen}
\makelink{polygon/translucent}
\makelink{polygon3d-screen/translucent}
\makelink{polygon3d-screen}
\makelink{polygon3d/translucent}
\makelink{polygon3d}
\makelink{polygon}
\makelink{print-center-screen}
\makelink{print-center}
\makelink{print-screen}
\makelink{print-translucent}
\makelink{print}
\makelink{putpixel-screen/translucent}
\makelink{putpixel-screen}
\makelink{putpixel/translucent}
\makelink{putpixel}
\makelink{quad3d-screen/translucent}
\makelink{quad3d-screen}
\makelink{quad3d/translucent}
\makelink{quad3d}
\makelink{rectangle-fill-screen/translucent}
\makelink{rectangle-fill-screen}
\makelink{rectangle-fill/translucent}
\makelink{rectangle-fill}
\makelink{rectangle-screen/translucent}
\makelink{rectangle-screen}
\makelink{rectangle/translucent}
\makelink{rectangle}
\makelink{save-screen}
\makelink{save}
\makelink{screen}
\makelink{spline-screen/translucent}
\makelink{spline-screen}
\makelink{spline/translucent}
\makelink{spline}
\makelink{triangle-screen/translucent}
\makelink{triangle-screen}
\makelink{triangle/translucent}
\makelink{triangle3d-screen/translucent}
\makelink{triangle3d-screen}
\makelink{triangle3d/translucent}
\makelink{triangle3d}
\makelink{triangle}
\makelink{width}

Structure list

\makelink{image}
\makelink{v3d}

\mark{image}

\scheme{(define-struct image (bitmap width height))}

Image is a collection of width, height, and an opaque bitmap type which represents a rectangular set of pixels.

The normal struct accessors are not provided, however. Instead use the \link{width} and \link{height} functions provided by image.ss.

\mark{v3d}
\scheme{(define-struct v3d (x y z u v c))}

\var{v3d} is a structure that represents a 3d coordinate( \var{x}, \var{y}, \var{z} ) with texture mapped coordinates( \var{u}, \var{v} ), and a color \var{c}.

All the normal \scheme{define-struct} accessors are provided, \scheme{make-v3d}, \scheme{v3d-x}, \scheme{v3d-y}, \scheme{v3d-z}, \scheme{v3d-u}, \scheme{v3d-v}, \scheme{v3d-c}, but you cannot mutate a v3d.

\mark{width}
\function{(width image)}{num}

Returns the width of an image.

\mark{height}
\function{(height image)}{num}

Returns the height of an image.

\scheme{(define-struct image (bitmap width height))}

\mark{screen}
\function{(screen)}{image}

A special image that represents the current graphics context. This image can be used in every context any other image can be used, except for destroying it, but \var{screen} is physically different from images created by the user. \var{screen} is a video bitmap whereas other images are memory bitmaps. Memory bitmaps live entirely in RAM and can be accessed very quickly but video bitmaps live in the graphics card's memory and mutating that memory from software is quite slow. Therefore it is best to always draw on a memory bitmap and then copy the memory bitmap to the screen in one swoop with \link{copy}.

\mark{create}
\function{(create width height [depth])}{image}

Create an image with the specified \var{width} and \var{height}. If \var{depth} is given the image will use that for the number of bits per pixel, otherwise it will default to what the current graphics context uses. If there is not enough memory to create the image #f will be returned. Unless you are creating exceptionally large images you should not normally run out of memory.

\mark{color}
\function{(color red green blue)}{num}

Convert the three parts of a pixel, \var{red}, \var{green}, and \var{blue} into a single value that can be used wherever a color is required such as \link{putpixel}.
\newline
0 <= \var{red} <= 255\newline
0 <= \var{green} <= 255\newline
0 <= \var{blue} <= 255\newline

\begin{schemedisplay}
;; black
(color 0 0 0)
;; white
(color 255 255 255)
;; magic pink, the masking color
(color 255 0 255)
\end{schemedisplay}

\mark{get-rgb}
\function{(get-rgb color)}{(values red green blue)}

Convert a color into the three color components, red, green, and blue.

\mark{create-from-file}
\function{(create-from-file filename)}{image}

Load an image from disk and return it. This image is treated exactly the same as if it was created with \link{create} except the initial pixels are copied from the file. It is perfectly safe to mutate this image.

\mark{create-sub}
\function{(create-sub image x y width height)}{image}

Create a new image which is a cut out of the parent image. \var{x},\var{y} is the upper left hand corner of the new image and \var{width}, \var{height} are the width and height respectively. 0,0 of the new image is the equivalent to \var{x},\var{y} of the parent image. Any changes made to the sub bitmap are reflected in the parent bitmap. This is useful for create a very large bitmap and sectioning parts off to give to various functions that want to deal with absolute coordinates.

\begin{schemedisplay}
(define m (create-sub (screen) 100 100 20 20))

;; the next two lines do the same exact thing
(rectangle m 2 2 12 12 (color 255 0 0))
(rectangle (screen) 102 102 114 114 (color 255 0 0))
\end{schemedisplay}

\mark{create-sub-screen}
\function{(create-sub-screen x y width height)}{image}

\screen{create-sub}

\mark{putpixel}
\function{(putpixel image x y color)}{void}

Set the pixel on \var{image} at \var{x}, \var{y} to \var{color}.

\mark{putpixel-screen}
\function{(putpixel-screen x y color)}{void}

\screen{putpixel}

\mark{putpixel/translucent}
\function{(putpixel/translucent image red green blue alpha x y color)}{void}

\translucent{putpixel}

\mark{putpixel-screen/translucent}
\function{(putpixel-screen/translucent red green blue alpha x y color)}{void}

\screen{putpixel/translucent}

\mark{getpixel}
\function{(getpixel image x y)}{num}

Get the value of the pixel on \var{image} at \var{x}, \var{y}

\mark{getpixel-screen}
\function{(getpixel-screen x y)}{num}

\screen{getpixel}

\mark{quad3d}
\function{(quad3d image type texture v1 v2 v3 v4)}{void}

Draw a 3d quad onto \var{image}. \var{texture} will be painted on the face of the quad. \var{type} should be one of

\begin{schemedisplay}
texture :: image
v1 :: v3d
v2 :: v3d
v3 :: v3d
v4 :: v3d
\end{schemedisplay}

\scheme{'POLYTYPE-FLAT} =  A simple flat shaded polygon, taking the color from the \var{c} value of the first vertex. This polygon type is affected by the drawing mode( \link{set-drawing-mode-solid!}, \link{set-drawing-mode-translucent!}, \link{set-drawing-mode-xor!} ), so it can be used to render XOR or translucent polygons.\newline
\scheme{'POLYTYPE-GCOL} = A single-color gouraud shaded polygon. The colors for each vertex are taken from the \var{c} value, and interpolated across the polygon.\newline
\scheme{'POLYTYPE-GRGB} = A gouraud shaded polygon which interpolates RGB triplets rather than a single color. The colors for each vertex are taken from the \var{c} value, which is interpreted as a 24-bit RGB triplet (0xFF0000 is red, 0x00FF00 is green, and 0x0000FF is blue).\newline
\scheme{'POLYTYPE-ATEX} = An affine texture mapped polygon. This stretches the texture across the polygon with a simple 2d linear interpolation, which is fast but not mathematically correct. It can look ok if the polygon is fairly small or flat-on to the camera, but because it doesn't deal with perspective foreshortening, it can produce strange warping artifacts.\newline
\scheme{'POLYTYPE-PTEX} = A perspective-correct texture mapped polygon. This uses the \var{z} value from the vertex structure as well as the \var{u}/\var{v} coordinates, so textures are displayed correctly regardless of the angle they are viewed from. Because it involves division calculations in the inner texture mapping loop, this mode is a lot slower than \scheme{'POLYTYPE-ATEX}.\newline
\scheme{'POLYTYPE-ATEX-MASK} = Like \scheme{'POLYTYPE-ATEX} but pixels with a value of 0 are skipped.\newline
\scheme{'POLYTYPE-PTEX-MASK} = Like \scheme{'POLYTYPE-PTEX} but pixels with a value of 0 are skipped.\newline
\scheme{'POLYTYPE-ATEX-LIT} = Like \scheme{'POLYTYPE-ATEX} but blends the pixels using the light level taken from the \var{c} component of each vertex according to how \link{set-trans-blender!} was used.\newline
\scheme{'POLYTYPE-PTEX-LIT} = Like \scheme{'POLYTYPE-PTEX} but blends the pixels using the light level taken from the \var{c} component of each vertex according to how \link{set-trans-blender!} was used.\newline
\scheme{'POLYTYPE-ATEX-MASK-LIT} = A combination of \scheme{'POLYTYPE-ATEX-LIT} and \scheme{'POLYTYPE-ATEX-MASK}.\newline
\scheme{'POLYTYPE-PTEX-MASK-LIT} = A combination of \scheme{'POLYTYPE-PTEX-LIT} and \scheme{'POLYTYPE-PTEX-MASK}.\newline
\scheme{'POLYTYPE-ATEX-TRANS} = Like \scheme{'POLYTYPE-ATEX} but renders the texture translucently according to how \link{set-trans-blender!} was used.\newline
\scheme{'POLYTYPE-PTEX-TRANS} = Like \scheme{'POLYTYPE-PTEX} but renders the texture translucently according to how \link{set-trans-blender!} was used.\newline
\scheme{'POLYTYPE-ATEX-MASK-TRANS} = A combination of \scheme{'POLYTYPE-ATEX-MASK} and \scheme{'POLYTYPE-ATEX-TRANS}.\newline
\scheme{'POLYTYPE-PTEX-MASK-TRANS} = A combination of \scheme{'POLYTYPE-PTEX-MASK} and \scheme{'POLYTYPE-PTEX-TRANS}.\newline

All the rest act the same as their respective name minus the /ZBUF but these types account for z-buffering to cull quads that don't need to be drawn.
\scheme{'POLYTYPE-FLAT/ZBUF}\newline
\scheme{'POLYTYPE-GCOL/ZBUF}\newline
\scheme{'POLYTYPE-GRGB/ZBUF}\newline
\scheme{'POLYTYPE-ATEX/ZBUF}\newline
\scheme{'POLYTYPE-PTEX/ZBUF}\newline
\scheme{'POLYTYPE-ATEX-MASK/ZBUF}\newline
\scheme{'POLYTYPE-PTEX-MASK/ZBUF}\newline
\scheme{'POLYTYPE-ATEX-LIT/ZBUF}\newline
\scheme{'POLYTYPE-PTEX-LIT/ZBUF}\newline
\scheme{'POLYTYPE-ATEX-MASK-LIT/ZBUF}\newline
\scheme{'POLYTYPE-PTEX-MASK-LIT/ZBUF}\newline
\scheme{'POLYTYPE-ATEX-TRANS/ZBUF}\newline
\scheme{'POLYTYPE-PTEX-TRANS/ZBUF}\newline
\scheme{'POLYTYPE-ATEX-MASK-TRANS/ZBUF}\newline
\scheme{'POLYTYPE-PTEX-MASK-TRANS/ZBUF}\newline

\mark{quad3d-screen}
\function{(quad3d-screen type texture v1 v2 v3 v4)}{void}

\screen{quad3d}

\mark{quad3d/translucent}
\function{(quad3d/translucent image red green blue alpha type texture v1 v2 v3 v4)}{void}

\translucent{quad3d}

\mark{quad3d-screen/translucent}
\function{(quad3d-screen/translucent red green blue alpha type texture v1 v2 v3 v4)}{void}

\screen{quad3d/translucent}

\mark{polygon3d}
\function{(polgyon3d image type texture v3ds)}{void}

Like \link{quad3d} except \var{v3ds} is a list of at least 3 \link{v3d}'s.

\mark{polygon3d-screen}
\function{(polygon3d-screen type texture v3ds)}{void}

\screen{polygon3d}

\mark{polygon3d/translucent}
\function{(polygon3d/translucent image red green blue alpha type texture v3ds)}{void}

\translucent{polygon3d}

\mark{polygon3d-screen/translucent}
\function{(polygon3d-screen/translucen red green blue alpha type texture v3ds)}{void}

\screen{polygon3d/translucent}

\mark{triangle3d}
\function{(triangle3d image type texture v1 v2 v3)}{void}

Like \link{quad3d} except there are only 3 vertexes, \var{v1}, \var{v2}, and \var{v3}.

\mark{triangle3d-screen}
\function{(triangle3d-screen type texture v1 v2 v3)}{void}

\screen{triangle3d}

\mark{triangle3d/translucent}
\function{(triangle3d/translucent image red green blue alpha type texture v1 v2 v3)}{void}

\translucent{triangle3d}

\mark{triangle3d-screen/translucent}
\function{(triangle3d-screen/translucent image red green blue alpha type texture v1 v2 v3)}{void}

\screen{triangle3d/translucent}

\mark{mask-color}
\function{(mask-color image)}{num}

Return the masking color of an image. This is always \scheme{(color 255 0 255)} but the function is provided for your convienence.

\mark{mask-color-screen}
\function{(mask-color-screen)}{num}

Return the masking color of the screen.

\mark{destroy}
\function{(destroy image)}{void}

Destroy an image that was created by the user( basically anything except \link{screen} ).

\mark{duplicate}
\function{(duplicate image)}{image}

Create a new image and copy the contents from \var{image} onto it.

\mark{duplicate-screen}
\function{(duplicate-screen)}{image}

\screen{duplicate}

\mark{line}
\function{(line image x1 y1 x2 y2 color)}{void}

Draw a straight line from \var{x1},\var{y1} to \var{x2},\var{y2} using \var{color} for the pixel value. Clipping will be performed if the coordinates do not lie within \var{image}'s area.

\mark{line-screen}
\function{(line-screen x1 y1 x2 y2 color)}{void}

\screen{line}

\mark{line/translucent}
\function{(line/translucent image red green blue alpha x1 y1 x2 y2 color)}{void}

\translucent{line}

\mark{line-screen/translucent}
\function{(line-screen/translucent red green blue alpha x1 y1 x2 y2 color)}{void}

\screen{line/translucent}

\mark{fastline}
\function{(fastline image x1 y1 x2 y2 color)}{void}

Much like \link{line} except clipping is performed slightly differently in an optimized fashion. 

\mark{fastline-screen}
\function{(fastline-screen x1 y1 x2 y2 color)}{void}

\screen{fastline}

\mark{fastline/translucent}
\function{(fastline/translucent image red green blue alpha x1 y1 x2 y2 color)}{void}

\translucent{fastline}

\mark{fastline-screen/translucent}
\function{(fastline-screen/translucent red green blue alpha x1 y1 x2 y2 color)}{void}

\screen{fastline/translucent}

\mark{polygon}
\function{(polygon image points color)}{void}

Draws a polygon with an arbitrary list of coordinates onto \var{image} using \var{color} as the pixel values.\newline
\var{points} should be a flat list of coordinates pairs. The length of \var{points} {\bf must} be even.
\begin{schemedisplay}
;; draw a red triangle with vertexes at (10,10), (20, 20), and (50,50)
(polygon some-image '(10 10 20 20 50 50) (color 255 0 0))
\end{schemedisplay}

\mark{polygon-screen}
\function{(polygon-screen points color)}{void}

\screen{polygon}

\mark{polygon/translucent}
\function{(polygon/translucent image red green blue alpha points color)}{void}

\translucent{polygon}

\mark{polygon-screen/translucent}
\function{(polygon-screen/translucent red green blue alpha points color)}{void}

\screen{polygon/translucent}

\mark{arc}
\function{(arc image x y angle1 angle2 radius color)}{void}

Draws a circular arc with center \var{x}, \var{y} in an anticlockwise direction starting from the angle \var{angle1} and ending when it reaches \var{angle2}. The angles range from 0 to 256, with 256 equal to a full circle, 64 a right angle, etc. Zero is to the right of the center point, and larger values rotate anticlockwise from there. Example: 

\begin{schemedisplay}
;; draw a white arc from 4 to 1 o'clock
(arc (screen) 100 100 21 43 50 (color 255 255 255))
\end{schemedisplay}

\mark{arc-screen}
\function{(arc-screen x y angle1 angle2 radius color)}{void}

\screen{arc}

\mark{arc/translucent}
\function{(arc/translucent image red green blue alpha x y angle1 angle2 radius color)}{void}

\translucent{arc}

\mark{arc-screen/translucent}
\function{(arc-screen/translucent red green blue alpha x y angle1 angle2 radius color)}{void}

\screen{arc/translucent}

\mark{calculate-spline}
\function{(calculate-spline x1 y1 x2 y2 x3 y3 x4 y4 points)}{list-of x,y pairs}

Calculates a series of npts values along a bezier spline, return them as a list of x,y pairs. The bezier curve is specified by the four x/y control points in the points array: \var{x1}, \var{y1} contain the coordinates of the first control point, \var{x2}, \var{y2} are the second point, etc. Control points 1 and 4 are the ends of the spline, and points 2 and 3 are guides. The curve probably won't pass through points 2 and 3, but they affect the shape of the curve between points 1 and 4 (the lines p1-p2 and p3-p4 are tangents to the spline). The easiest way to think of it is that the curve starts at p1, heading in the direction of p2, but curves round so that it arrives at p4 from the direction of p3.  In addition to their role as graphics primitives, spline curves can be useful for constructing smooth paths around a series of control points.

\begin{schemedisplay}
;; calculate 4 points
(calculate-spline 1 1 10 10 5 9 20 3 4)
-> ((1 . 1) (7 . 7) (10 . 7) (20 . 3))

;; calculate 20 points
(calculate-spline 1 1 10 10 5 9 20 3 20)
-> ((1 . 1) (2 . 2) (3 . 4) (4 . 5) (5 . 5) (6 . 6) (6 . 7)
(7 . 7) (7 . 7) (8 . 8) (9 . 8) (9 . 8) (10 . 7) (11 . 7)
(12 . 7) (13 . 6) (14 . 5) (16 . 5) (18 . 4) (20 . 3))
\end{schemedisplay}

\mark{spline}
\function{(spline image x1 y1 x2 y2 x3 y3 x4 y4 color)}{void}

Draws a bezier spline using the four control points specified by \var{x1}, \var{y1}, \var{x2}, \var{y2}, \var{x3}, \var{y3}, \var{x4}, \var{y4}. Read the description of \link{calculate-spline} for information on how the spline is generated.

\mark{spline-screen}
\function{(spline-screen x1 y1 x2 y2 x3 y3 x4 y4 color)}{void}

\screen{spline}

\mark{spline/translucent}
\function{(spline/translucent image red green blue alpha x1 y1 x2 y2 x3 y3 x4 y4 color)}{void}

\translucent{spline}

\mark{spline-screen/translucent}
\function{(spline-screen/translucent red green blue alpha x1 y1 x2 y2 x3 y3 x4 y4 color)}{void}

\screen{spline/translucent}

\mark{floodfill}
\function{(floodfill image x y color)}{void}

Fill \var{image} with the specified \var{color} starting at \var{x}, \var{y}. All pixels with the same value at \var{x}, \var{y} that can be traced back to \var{x}, \var{y} without going over a gap will be overwritten with \var{color}.

\mark{floodfill-screen}
\function{(floodfill-screen x y color)}{void}

\screen{floodfill}

\mark{floodfill/translucent}
\function{(floodfill/translucent image red green blue alpha x y color)}{void}

\translucent{floodfill}

\mark{floodfill-screen/translucent}
\function{(floodfill-screen/translucent red green blue alpha x y color)}{void}

\screen{floodfill/translucent}

\mark{triangle}
\function{(triangle image x1 y1 x2 y2 x3 y3 color)}{void}

Draw a filled triangle on \var{image} using \var{x1}, \var{y1}, \var{x2}, \var{y2}, \var{x3}, \var{y3} as the vertexes with a pixel value of \var{color}.

\mark{triangle-screen}
\function{(triangle-screen x1 y1 x2 y2 x3 y3 color)}{void}

\screen{triangle}

\mark{triangle/translucent}
\function{(triangle/translucent image x1 y1 x2 y2 x3 y3 color)}{void}

\translucent{triangle}

\mark{triangle-screen/translucent}
\function{(triangle-screen/translucent x1 y1 x2 y2 x3 y3 color)}{void}

\screen{triangle/translucent}

\mark{circle}
\function{(circle image x y radius color)}{void}

Draw a circle on \var{image} at \var{x}, \var{y} with \var{radius} and a pixel value of \var{color}.

\mark{circle-screen}
\function{(circle-screen x y radius color)}{void}

\screen{circle}

\mark{circle/translucent}
\function{(circle/translucent image red green blue alpha x y radius color)}{void}

\translucent{circle}

\mark{circle-screen/translucent}
\function{(circle-screen/translucent red green blue alpha x y radius color)}{void}

\screen{circle/translucent}

\mark{circle-fill}
\function{(circle-fill image x y radius color)}{void}

Draws a filled circle on \var{image} at \var{x}, \var{y} with \var{radius} and a pixel value of \var{color}.

\mark{circle-fill-screen}
\function{(circle-fill-screen x y radius color)}{void}

\screen{circle-fill}

\mark{circle-fill/translucent}
\function{(circle-fill/translucent image red green blue alpha x y radius color)}{void}

\translucent{circle-fill}

\mark{circle-fill-screen/translucent}
\function{(circle-fill-screen/translucent red green blue alpha x y radius color)}{void}

\screen{circle-fill/translucent}

\mark{ellipse}
\function{(ellipse image x y rx ry color)}{void}

Draw an ellipse on \var{image} at \var{x}, \var{y} with an x radius of \var{rx} and a y radius of \var{ry} using a pixel value of \var{color}.

\mark{ellipse-screen}
\function{(ellipse-screen x y rx ry color)}{void}

\screen{ellipse}

\mark{ellipse/translucent}
\function{(ellipse/translucent image red green blue alpha x y rx ry color)}{void}

\translucent{ellipse}

\mark{ellipse-screen/translucent}
\function{(ellipse-screen/translucent red green blue alpha x y rx ry color)}{void}

\screen{ellipse/translucent}

\mark{ellipse-fill}
\function{(ellipse-fill image x y rx ry color)}{void}

Draw a filled ellipse on \var{image} at \var{x}, \var{y} with an x radius of \var{rx} and a y radius of \var{ry} using a pixel value of \var{color}.

\mark{ellipse-fill-screen}
\function{(ellipse-fill-screen x y rx ry color)}{void}

\screen{ellipse-fill}

\mark{ellipse-fill/translucent}
\function{(ellipse-fill/translucent image red green blue alpha x y rx ry color)}{void}

\translucent{ellipse-fill}

\mark{ellipse-fill-screen/translucent}
\function{(ellipse-fill-screen/translucent red green blue alpha x y rx ry color)}{void}

\screen{ellipse-fill/translucent}

\mark{rectangle}
\function{(rectangle image x1 y1 x2 y2 color)}{void}

Draw a rectangle on \var{image} from \var{x1},\var{y1} to \var{x2},\var{y2} with a pixel value of \var{color}.

\mark{rectangle-screen}
\function{(rectangle-screen x1 y1 x2 y2 color)}{void}

\screen{rectangle}

\mark{rectangle/translucent}
\function{(rectangle/translucent image red green blue alpha x1 y1 x2 y2 color)}{void}

\translucent{rectangle}

\mark{rectangle-screen/translucent}
\function{(rectangle-screen/translucent red green blue alpha x1 y1 x2 y2 color)}{void}

\screen{rectangle/translucent}

\mark{rectangle-fill}
\function{(rectangle-fill image x1 y1 x2 y2 color)}{void}

Draw a filled rectangle on \var{image} from \var{x1},\var{y1} to \var{x2},\var{y2} with a pixel value of \var{color}.

\mark{rectangle-fill-screen}
\function{(rectangle-fill-screen x1 y1 x2 y2 color)}{void}

\screen{rectangle-fill}

\mark{rectangle-fill/translucent}
\function{(rectangle-fill/translucent image red green blue alpha x1 y1 x2 y2 color)}{void}

\translucent{rectangle-fill}

\mark{rectangle-fill-screen/translucent}
\function{(rectangle-fill-screen/translucent red green blue alpha x1 y1 x2 y2 color)}{void}

\screen{rectangle-fill/translucent}

\mark{print}
\function{(print image x y color background-color message)}{void}

Print \var{message} on \var{image} starting at \var{x},\var{y}. The foreground color will be \var{color} and the backgrond color will be \var{background-color}. If you pass -1 for the \var{background-color} then the background will be left alone.

\begin{schemedisplay}
;; print hello world in red text
(print some-image 20 30 (color 255 0 0) -1 "Hello World!")
\end{schemedisplay}

\mark{print-screen}
\function{(print-screen x y color background-color message)}{void}

\screen{print-screen}

\mark{print-translucent}
\function{(print-translucent image x y color alpha message)}{void}

Print \var{message} onto \var{image} starting at \var{x}, \var{y} with an transparency level of \var{alpha}.\newline
0 <= \var{alpha} <= 255

Where 0 = translucent and 255 = opaque.

\mark{print-center}
\function{(print-center image x y color background-color message)}{void}

Like \link{print} except \var{x}, \var{y} will be the middle of the string instead of the left hand side.

\mark{print-center-screen}
\function{(print-center-screen x y color background-color message)}{void}

\screen{print-center}

\mark{clear}
\function{(clear image [color])}{void}

Set all pixels on \var{image} to \var{color}. If \var{color} is not specified it defaults to \scheme{(color 0 0 0)}, black.

\mark{clear-screen}
\function{(clear-screen)}

\screen{clear}

\mark{draw}
\function{(draw image sprite x y)}{void}

\scheme{sprite :: image}

Copy \var{sprite} onto \var{image} starting at \var{x}, \var{y} but not overwriting pixels in \var{image} when the pixel value in \var{sprite} is (color 255 0 255), the masking color.

\mark{draw-screen}
\function{(draw-screen sprite x y)}{void}

\screen{draw}

\mark{draw-translucent}
\function{(draw-translucent image sprite [x] [y])}{void}

Like \link{draw} except \var{sprite} is drawn translucently. Call \link{set-trans-blender!} at some point before using this function. If \var{x} and \var{y} are not given they default to 0, 0.

\mark{draw-lit}
\function{(draw-lit image sprite [x] [y] [alpha])}{void}

Like \link{draw} except \var{sprite} is drawn with a lightning level of \var{alpha}. Call \link{set-trans-blender!} at some point before using this function. If \var{x}, \var{y}, and \var{alpha} are not given they default to 0, 0, 0.

\mark{draw-vertical-flip}
\function{(draw-vertical-flip image sprite x y)}{void}

Like \link{draw} but flip \var{sprite} over the x-axis in the middle of the sprite.

\mark{draw-vertical-flip-screen}
\function{(draw-vertical-flip-screen sprite x y)}{void}

\screen{draw-vertical-flip}

\mark{draw-horizontal-flip}
\function{(draw-horizontal-flip image sprite x y)}{void}

Like \link{draw} but \var{sprite} is flipped over the y-axis in the middle of the sprite.

\mark{draw-horizontal-flip-screen}
\function{(draw-horizontal-flip-screen sprite x y)}{void}

\screen{draw-horizontal-flip-screen}

\mark{draw-vertical-horizontal-flip}
\function{(draw-vertical-horizontal-flip image sprite x y)}{void}

A combination of \link{draw-vertical-flip} and \link{draw-horizontal-flip}.

\mark{draw-vertical-horizontal-flip-screen}
\function{(draw-vertical-horizontal-flip-screen sprite x y)}{void}

\screen{draw-vertical-horizontal-flip}

\mark{draw-gouraud}
\function{(draw-gouraud image sprite x y upper-left upper-right lower-left lower-right)}{void}

0 <= \var{upper-left} <= 255\newline
0 <= \var{upper-right} <= 255\newline
0 <= \var{lower-left} <= 255\newline
0 <= \var{lower-right} <= 255\newline

Like \link{draw-lit} but the lighting is interpolated across the 4 corners.

\mark{draw-gouraud-screen}
\function{(draw-gouraud-screen sprite x y upper-left upper-right lower-left lower-right)}{void}

\screen{draw-gouraud}

\mark{draw-character}
\function{(draw-character image sprite x y color background)}{void}

Draws \var{sprite} onto \var{image} starting at \var{x}, \var{y} but only using \var{color} for the foreground pixels and transparent pixels in the \var{background} color, or skipping them completely if \var{backgrond} is -1.

\begin{schemedisplay}
;; draw logo silhouette in red
(draw-character some-image logo 200 200 (color 255 0 0) -1)
\end{schemedisplay}

\mark{draw-character-screen}
\function{(draw-character-screen sprite x y color background)}{void}

\screen{draw-character}

\mark{draw-rotate}
\function{(draw-rotate image sprite x y angle)}{void}

Like \link{draw} but rotate the sprite around its center using \var{angle}.

0 <= \var{angle} <= 255\newline
0 lies on the positive x-axis, 64 on the positive y-axis, 128 on the negative x-axis, and 192 on the negative y-axis.

\mark{draw-rotate-screen}
\function{(draw-rotate-screen sprite x y angle)}{void}

\screen{draw-rotate}

\mark{draw-rotate-vertical-flip}
\function{(draw-rotate-vertical-flip image sprite x y angle)}{void}

Like \link{draw-rotate} but \var{sprite} is flipped over the x-axis.

\mark{draw-rotate-vertical-flip-screen}
\function{(draw-rotate-vertical-flip-screen sprite x y angle)}{void}

\screen{draw-rotate-vertical-flip}

\mark{draw-rotate-scaled}
\function{(draw-rotate-scaled image sprite x y angle scale)}{void}

Like \link{draw-rotate} but \var{sprite} is scaled as well according to \var{scale}.

0 <= \var{angle} <= 255\newline
0 <= \var{scale} <= +infinity\newline

\mark{draw-rotate-scaled-screen}
\function{(draw-rotate-scaled-screen sprite x y angle scale)}{void}

\screen{draw-rotate-scaled-screen}

\mark{draw-rotate-scaled-vertical-flip}
\function{(draw-rotate-scaled-vertical-flip image sprite x y angle scale)}{void}

Like \link{draw-rotate-scaled} but flipped over the x-axis.

\mark{draw-rotate-scaled-vertical-flip-screen}
\function{(draw-rotate-scaled-vertical-flip-screen sprite x y angle scale)}{void}

\screen{draw-rotate-scaled-vertical-flip}

\mark{draw-pivot}
\function{(draw-pivot image sprite x y center-x center-y angle)}{void}

Draw \var{sprite} onto \var{image} at \var{x}, \var{y} rotating the sprite around \var{center-x}, \var{center-y} by \var{angle}.

\begin{schemedisplay}
;; draw my-sprite onto some-image at 50,100 anchoring my-sprite at 5,5
;; and rotating it 64 units( 90 degrees )
(draw-pivot some-image my-sprite 50 100 5 5 64)
\end{schemedisplay}

\mark{draw-pivot-screen}
\function{(draw-pivot-screen image sprite x y center-x center-y angle)}{void}

\screen{draw-pivot}

\mark{draw-pivot-vertical-flip}
\function{(draw-pivot-vertical-flip image sprite x y center-x center-y angle)}{void}

Like \link{draw-pivot} but flip \var{sprite} over the x-axis.

\mark{draw-pivot-vertical-flip-screen}
\function{(draw-pivot-vertical-flip-screen sprite x y center-x center-y angle)}{void}

\screen{draw-pivot-vertical-flip}

\mark{draw-pivot-scaled}
\function{(draw-pivot-scaled image sprite x y center-x center-y angle scale)}{void}

Like \link{draw-pivot} but scale \var{sprite} as well.

\mark{draw-pivot-scaled-screen}
\function{(draw-pivot-scaled-screen sprite x y center-x center-y angle scale)}{void}

\screen{draw-pivot-scaled}

\mark{draw-pivot-scaled-vertical-flip}
\function{(draw-pivot-scaled-vertical-flip image sprite x y center-x center-y angle scale)}{void}

A combination of \link{draw-pivot-scaled} and \link{draw-pivot-vertical-flip}.

\mark{draw-pivot-scaled-vertical-flip-screen}
\function{(draw-pivot-scaled-vertical-flip-screen sprite x y center-x center-y angle scale)}{void}

\screen{draw-pivot-scaled-vertical-flip}

\mark{copy}
\function{(copy image-dest image-src [x y] [width height] [dest-x dest-y])}{void}

Copy each pixel from \var{image-src} to \var{image-dest}. \var{x}, \var{y}, \var{dest-x}, and \var{dest-y} default to 0 if not given. \var{width} and \var{height} default to the dimensions of \var{image-src} if not given.

\var{x}, \var{y} specify the upper left corner within \var{image-src} to start copying pixels from.\newline
\var{width}, \var{height} specify the width and height respectively from \var{x}, \var{y} to copy from.\newline
\var{dest-x}, \var{dest-y} spcify the upper left corner within \var{image-dest} to copy pixels to.

\mark{copy-screen}
\function{(copy image-src [x y] [width height] [dest-x dest-y])}{void}

\screen{copy}

\mark{copy-masked}
\function{(copy-masked image-dest image-src [x y] [width height] [dest-x dest-y])}{void}

Like \link{copy} except masking pixels( \scheme{(color 255 0 255)} ) in \var{image-src} are not copied to \var{image-dest}.

\mark{copy-masked-screen}
\function{(copy-masked-screen image-src [x y] [width height] [dest-x dest-y])}{void}

\screen{copy-masked}

\mark{copy-stretch}
\function{(copy-stretch image-dest image-src source-x source-y source-width source-height dest-x dest-y dest-width dest-height)}{void}

Like \link{copy} except the area specified by \var{source-x}, \var{source-y}, \var{source-width}, \var{source-height} is copied in such a way to take up the area specified by \var{dest-x}, \var{dest-y}, \var{dest-width}, \var{dest-height}.

\mark{copy-stretch-screen}
\function{(copy-stretch-screen image-src source-x source-y source-width source-height dest-x dest-y dest-width dest-height)}{void}

\screen{copy-stretch}

\mark{copy-masked-stretch}
\function{(copy-masked-stretch image-dest image-src source-x source-y source-width source-height dest-x dest-y dest-width dest-height)}{void}

Like \link{copy-stretch} but skip masking pixels like \link{copy-masked}.

\mark{copy-masked-stretch-screen}
\function{(copy-masked-stretch-screen image-src source-x source-y source-width source-height dest-x dest-y dest-width dest-height)}{void}

\screen{copy-masked-stretch}

\mark{draw-stretched}
\function{(draw-stretched image sprite x y width height)}{void}

Draw \var{sprite} onto \var{image} like in \link{draw} but stretch the sprite so its width and height match that of \var{width} and \var{height}.

\mark{save}
\function{(save image filename)}{void}

Save \var{image} to a file named by \var{filename}.

\mark{save-screen}
\function{(save-screen filename)}{void}

\screen{save} Useful for screenshots.

\chapter{Sound}

\scheme{(require (planet "sound.ss" ("kazzmir" "allegro.plt")))}

Function list

\makelink{load-sound}
\makelink{destroy-sound}
\makelink{play-sound}
\makelink{play-sound-looped}
\makelink{stop-sound}

\mark{load-sound}
\function{(load-sound filename)}{sound}

Create a sound object from a filename. Available extensions for filenames are
  .wav
  .voc

\mark{destroy-sound}
\function{(destroy-sound sound)}{void}

Destroy a sound object. Sound objects are not garbage collected, you must destroy them yourself.

\mark{play-sound}
\function{(play-sound sound [volume] [pan] [frequency])}{void}

Plays a sound.\newline\newline
  \var{sound} - sound object\newline
  \var{volume} - 0 <= \var{volume} <= 255\newline
  \var{pan} - 0 <= \var{pan} <= 255. Pan determines which speaker the sound will come out of. 0 is left, 255 is right. 128 is in the middle.\newline
  \var{frequency} - What speed to play the sound at. 1000 is the default, less is slower, and more is faster.

\mark{play-sound-looped}
\function{(play-sound-looped sound [volume] [pan] [frequency])}{void}

Exactly like \link{play-sound} but the sound will loop until \link{stop-sound} is called on \var{sound}.

\mark{stop-sound}
\function{(stop-sound sound)}{void}

Stops playing \var{sound} if it is currently playing. There is no effect if \var{sound} is not currently playing.

\chapter{Keyboard}

\scheme{(require (planet "keyboard.ss" ("kazzmir" "allegro.plt")))}

Function List

\makelink{keypressed?}
\makelink{key-modifiers}
\makelink{readkey}
\makelink{simulate-keypress}
\makelink{clear-keyboard}
\makelink{current-keys}

\mark{keypressed?}
\function{(keypressed? key)}{boolean}

Returns #t if \var{key} is pressed, else #f. Possible values for \var{key} are

\scheme{'A}\newline
\scheme{'B}\newline
\scheme{'C}\newline
\scheme{'D}\newline
\scheme{'E}\newline
\scheme{'F}\newline
\scheme{'G}\newline
\scheme{'H}\newline
\scheme{'I}\newline
\scheme{'J}\newline
\scheme{'K}\newline
\scheme{'L}\newline
\scheme{'M}\newline
\scheme{'N}\newline
\scheme{'O}\newline
\scheme{'P}\newline
\scheme{'Q}\newline
\scheme{'R}\newline
\scheme{'S}\newline
\scheme{'T}\newline
\scheme{'U}\newline
\scheme{'V}\newline
\scheme{'W}\newline
\scheme{'X}\newline
\scheme{'Y}\newline
\scheme{'Z}\newline
\scheme{'NUM-0}\newline
\scheme{'NUM-1}\newline
\scheme{'NUM-2}\newline
\scheme{'NUM-3}\newline
\scheme{'NUM-4}\newline
\scheme{'NUM-5}\newline
\scheme{'NUM-6}\newline
\scheme{'NUM-7}\newline
\scheme{'NUM-8}\newline
\scheme{'NUM-9}\newline
\scheme{'PAD-0}\newline
\scheme{'PAD-1}\newline
\scheme{'PAD-2}\newline
\scheme{'PAD-3}\newline
\scheme{'PAD-4}\newline
\scheme{'PAD-5}\newline
\scheme{'PAD-6}\newline
\scheme{'PAD-7}\newline
\scheme{'PAD-8}\newline
\scheme{'PAD-9}\newline
\scheme{'F1}\newline
\scheme{'F2}\newline
\scheme{'F3}\newline
\scheme{'F4}\newline
\scheme{'F5}\newline
\scheme{'F6}\newline
\scheme{'F7}\newline
\scheme{'F8}\newline
\scheme{'F9}\newline
\scheme{'F10}\newline
\scheme{'F11}\newline
\scheme{'F12}\newline
\scheme{'ESC}\newline
\scheme{'TILDE}\newline
\scheme{'MINUS}\newline
\scheme{'EQUALS}\newline
\scheme{'BACKSPACE}\newline
\scheme{'TAB}\newline
\scheme{'OPENBRACE}\newline
\scheme{'CLOSEBRACE}\newline
\scheme{'ENTER}\newline
\scheme{'COLON}\newline
\scheme{'QUOTE}\newline
\scheme{'BACKSLASH}\newline
\scheme{'BACKSLASH2}\newline
\scheme{'COMMA}\newline
\scheme{'STOP}\newline
\scheme{'SLASH}\newline
\scheme{'SPACE}\newline
\scheme{'INSERT}\newline
\scheme{'DEL}\newline
\scheme{'HOME}\newline
\scheme{'END}\newline
\scheme{'PGUP}\newline
\scheme{'PGDN}\newline
\scheme{'LEFT}\newline
\scheme{'RIGHT}\newline
\scheme{'UP}\newline
\scheme{'DOWN}\newline
\scheme{'SLASH_PAD}\newline
\scheme{'ASTERISK}\newline
\scheme{'MINUS_PAD}\newline
\scheme{'PLUS_PAD}\newline
\scheme{'DEL_PAD}\newline
\scheme{'ENTER_PAD}\newline
\scheme{'PRTSCR}\newline
\scheme{'PAUSE}\newline
\scheme{'ABNT_C1}\newline
\scheme{'YEN}\newline
\scheme{'KANA}\newline
\scheme{'CONVERT}\newline
\scheme{'NOCONVERT}\newline
\scheme{'AT}\newline
\scheme{'CIRCUMFLEX}\newline
\scheme{'COLON2}\newline
\scheme{'KANJI}\newline
\scheme{'EQUALS_PAD}\newline
\scheme{'BACKQUOTE}\newline
\scheme{'SEMICOLON}\newline
\scheme{'COMMAND}\newline
\scheme{'UNKNOWN1}\newline
\scheme{'UNKNOWN2}\newline
\scheme{'UNKNOWN3}\newline
\scheme{'UNKNOWN4}\newline
\scheme{'UNKNOWN5}\newline
\scheme{'UNKNOWN6}\newline
\scheme{'UNKNOWN7}\newline
\scheme{'UNKNOWN8}\newline
\scheme{'MODIFIERS}\newline
\scheme{'LSHIFT}\newline
\scheme{'RSHIFT}\newline
\scheme{'LCONTROL}\newline
\scheme{'RCONTROL}\newline
\scheme{'ALT}\newline
\scheme{'ALTGR}\newline
\scheme{'LWIN}\newline
\scheme{'RWIN}\newline
\scheme{'MENU}\newline
\scheme{'SCRLOCK}\newline
\scheme{'NUMLOCK}\newline
\scheme{'CAPSLOCK}\newline

\mark{key-modifiers}
\function{(key-modifiers)}{list-of symbol}

Returns a list of key modifiers currently pressed. Possible values are

\scheme{'SHIFT}\newline
\scheme{'CTRL}\newline
\scheme{'ALT}\newline
\scheme{'LWIN}\newline
\scheme{'RWIN}\newline
\scheme{'MENU}\newline
\scheme{'COMMAND}\newline
\scheme{'SCROLOCK}\newline
\scheme{'NUMLOCK}\newline
\scheme{'CAPSLOCK}\newline
\scheme{'INALTSEQ}\newline
\scheme{'ACCENT1}\newline
\scheme{'ACCENT2}\newline
\scheme{'ACCENT3}\newline
\scheme{'ACCENT4}\newline

\mark{current-keys}
\function{(current-keys)}{list-of symbol}

Returns a list containing the current keys pressed and the current key modifiers pressed. In short it is about equivalent to the psuedo-code \scheme{(append (key-modifiers) (map keypressed? all-keys))}.

\mark{readkey}
\function{(readkey)}{symbol}

Returns the name of a key that was pressed. This function blocks until a key is pressed. The key names are the same for \link{keypressed?}.

\mark{simulate-keypress}
\function{(simulate-keypress key)}{void}

Puts \var{key} into the key buffer so that the next call to \link{readkey} will return that key.

\mark{clear-keyboard}
\function{(clear-keyboard)}{void}

Clears the keyboard buffer so that \link{readkey} will block until a key is pressed.

\chapter{Mouse}

\scheme{(require (planet "mouse.ss" ("kazzmir" "allegro.plt")))}

Note that it is usually best to prefix the mouse import because it exposes common names. I usually use this:\newline
\scheme{(require (prefix mouse- (planet "mouse.ss" ("kazzmir" "allegro.plt"))))}

Function list

\makelink{left-click?}
\makelink{right-click?}
\makelink{x}
\makelink{y}
\makelink{get-mickeys}

\mark{left-click?}
\function{(left-click?)}{boolean}

Returns #t if the left mouse button is being clicked, otherwise #f.

\mark{right-click?}
\function{(right-click?)}{boolean}

Returns #t if the right mouse button is being clicked, otherwise #f.

\mark{x}
\function{(x)}{num}

Returns the current x coordinate of the mouse on the graphics context.

\mark{y}
\function{(y)}{num}

Returns the current y coordinate of the mouse on the graphics context.

\mark{get-mickeys}
\function{(get-mickeys)}{(values dx dy)}

Returns two integers representing how far the mouse has just moved.

\chapter{Game Utilities}
\hypertarget{game-chapter}{}

\newcommand{\syntax}[1]{syntax: \scheme{#1}}

\scheme{(require (planet "game.ss" ("kazzmir" "allegro.plt")))}

\scheme{game.ss} provides some useful types and functions that remove much of the design work needed to create real-time games. Normally these games follow the same basic structure: execute a function to update the universe, draw the universe. The mechanism to do this is what \link{game-loop} gives you, but game.ss takes this a step further by providing the universe as well. All you must do is populate the universe with objects and you will have an instant game.

Of course with any framework game.ss forces you to follow one design. If you feel that this design is not what you need then roll your own. Once you understand how game.ss works its not terribly difficult to write a different version.

Look at "examples/simple.ss" in allegro.plt for a concrete example of how to use the game framework.

Function List

\makelink{add-object}
\makelink{constant}
\makelink{define-generator}
\makelink{define-object}
\makelink{get-mouse-movement}
\makelink{get-mouse-x}
\makelink{get-mouse-y}
\makelink{is-a?}
\makelink{left-clicking?}
\makelink{make-animation-from-files}
\makelink{make-world}
\makelink{make}
\makelink{me}
\makelink{right-clicking?}
\makelink{round*}
\makelink{say}
\makelink{start}

Structure List

\makelink{Animation}
\makelink{Basic}
\makelink{shape^}
\makelink{Shape}
\makelink{Point}
\makelink{Circle}
\makelink{Rectangle}
\makelink{World}

\mark{Basic}
\scheme{Basic :: class}

Basic is the root object of all objects in the game universe. Technically it is a class as defined by \scheme{class*} in \scheme{class.ss} but for the most part you can ignore this if you are just using whats in game.ss. Basic has the following methods

{\bf Fields}\newline
\scheme{phase} - Affects the order of drawing. Lower numbers are drawn first and higher numbers are drawn later. This defaults to 0.\newline
\scheme{x} - The x coordinate of this object. This is used for collision detection so do not provide your own x coordinate in your own objects.\newline
\scheme{y} - The y coordinate, with the same restrictions as x.\newline

{\bf Functions}

\function{(can-collide obj)}{boolean}

Returns #t if this object can collide with \var{obj}.

\function{(shapes)}{list-of shape}

Returns a list of shapes used for collision detection. An empty list means this object can't collide with anything and its \scheme{can-collide} method should probably return #f for all objects.

\function{(key world keys)}{void}

This procedure is run when the user presses a key. \var{keys} is a list of currently pressed keys and \var{world} is the current universe.

\function{(touch world obj)}{void}

This object collided with obj and can now perform any side-affects.

\function{(tick world)}{void}

The main update procedure. This procedure is run by the universe when a logic cycle is occuring. Moving around the universe should be done here.

\function{(draw world buffer)}{void}

This procedure is run when the object is allowed to draw itself. \var{buffer} is a  a plain \link{image}( not the screen ).

\function{(get-x)}{int}

Returns the x coordinate of this object

\function{(get-y)}{int}

Returns the y coordinate of this object

\mark{World}
\scheme{World :: class}

World is a special class that represents the universe. It derives from Basic. Normally you don't need to know about much of the internals of World but you would if you aren't using the predefined game-loop that is part of game.ss.

Functions

\function{(key keys)}{void}

Let all the objects know about \var{keys} through the \var{key} method.

\function{(add obj)}{void}

Add an object to the internal list of objects.

\function{(tick)}{void}

Call \var{tick} on all the objects.

\function{(draw buffer)}{void}

Call \var{draw} on all the objects.

\function{(remove obj)}{void}

Remove \var{obj} from the internal list of objects. All other objects in the list will receive the \scheme{death} message if they have it defined.

\function{(remove-all)}{void}

Clear the list of internal objects.

\function{(get-objects)}{list-of Basic}

Returns the internal list of objects.

\function{(get-object pred)}{Basic or #f}

\scheme{pred :: (lambda (obj) ..)}\newline
Return the first object that statisfies \var{pred}.

\function{(reset-collision)}{void}

Reset the collision detection objects.

\function{(collide)}{void}

Tests all objects for collisions using a binary space partition. Only objects that live in the same binary space partition {\bf and} both return #t from \scheme{can-collide} will be tested for collisions.

\mark{Animation}
\scheme{Animation :: class}

Animation encapsulates a set of images to be displayed.

Fields

\scheme{speed :: int} - The speed at which the animations change.

Functions

\function{(add-animation image)}{void}

Add an image to the list of images.

\function{(draw buffer x y)}{void}

Draw the current image onto \var{buffer}. \var{x}, \var{y} specify the {\bf middle} of the image, not the upper left hand corner.

\function{(next-animation)}{void}

Move the image to the next animation. This function should be called every logic cycle, not during the draw phase.

\mark{shape^}
\scheme{shape^ :: interface}

\scheme{shape^} is an interface that all shapes should implement. It has the following functions

\function{(min-x)}{int} - The left most x coordinate of this shape.\newline
\function{(max-x)}{int} - The right most x coordinate of this shape.\newline
\function{(min-y)}{int} - The top most y coordinate of this shape.\newline
\function{(max-y)}{int} - The bottom most y coordinate of this shape.\newline
\function{(collide x y shape sx sy)}{boolean} - Returns #t if this shape collides with \var{shape}. The middle coordinates of this shape are \var{x} and \var{y}. The middle coordinates of \var{shape} are \var{sx} and \var{sy}.\newline
\function{(inside x y sx sy)}{boolean} - Returns #t if the coordinates \var{sx}, \var{sy} lies inside this shape centered at \var{x}, \var{y}.

\mark{Shape}
\scheme{Shape :: class}

Shape is the base type for all shapes, but it does not implement \link{shape^}. It has 2 fields that affect how it acts

\var{center-x} - The x offset used to calculate the absolute position of this shape. Defaults to 0.
\var{center-y} - The y offset used to calculate the absolute position of this shape. Defaults to 0.

A shape's absolute position is calculated by \var{object-x} + \var{center-x}, \var{object-y} + \var{center-y}. If \var{center-x} and \var{center-y} are not changed the coordinates reduce to simply \var{object-x}, \var{object-y}.

There are 3 predefined shapes provided by game.ss: Point, Circle, and Rectangle.

\mark{Point}
\scheme{Point :: class}

Point derives from \link{Shape} and represents a single point in space. It has no fields of its own so creation requires no extra arguments, unless you want to provide center-x and center-y.

\begin{schemedisplay}
(make Point) ;; a regular point
(make Point (center-x 3) (center-y -2)) ;; a point offset by 3, -2
\end{schemedisplay}

\mark{Circle}
\scheme{Circle :: class}

Circle derives from \link{Shape} and represents a circular area in space. Its only field is radius.

\begin{schemedisplay}
(make Circle (radius 5)) ;; a circle with radius 5
(make Circle (radius 5) (center-x 2) (center-y -3)) ;; a circle with radius 5 offset by 2, -3
\end{schemedisplay}

\mark{Rectangle}
\scheme{Rectangle :: class}

Rectangle derives from \link{Shape} and represents a rectangular area in space. Its fields are width and height.

\begin{schemedisplay}
;; a rectangle with a width of 5 and a height of 10
(make Rectangle (width 5) (height 10))
;; a rectangle with a width of 5 and a height of 10 offset by 2, -3
(make Rectangle (width 5) (height 10) (center-x 2) (center-y -3))
\end{schemedisplay}

\mark{round*}
\function{(round* float)}{int}

Round \var{float} to an integer. This is useful to convert coordinates into values that can be passed to any drawing function.

\begin{schemedisplay}
(round* 2.3) -> 2
(round* 2.8) -> 3
\end{schemedisplay}

\mark{calculate-angle}
\function{(calculate-angle x1 y1 x2 y2)}{float}

Calculate the angle from \var{x1},\var{y1} to \var{x2},\var{y2} using the arc tangent. This angle is normalized so that \degree{270} increases the y coordinate, which is farther "down" the screen.

\mark{make-animation-from-files}
\function{(make-animation-from-files files speed)}{Animation}

\scheme{files :: list-of filename}\newline
\scheme{speed :: int}

Create an animation from the set of \var{files}.

\mark{make-world}
\function{(make-world)}{World}

Create a new world.

\mark{add-object}
\function{(add-object world obj)}{void}

Helper function to add \var{obj} to \var{world}.

\mark{get-mouse-x}
\function{(get-mouse-x)}{int}

Return the current x coordinate of the mouse.

\mark{get-mouse-y}
\function{(get-mouse-y)}{int}

Return the current y coordinate of the mouse.

\mark{me}
\syntax{me}

A reference to the current object, much like \var{this} in Java/C++ or \var{self} in Ruby/Python.

\mark{Cosine}
\function{Cosine angle}{float}

Returns the cosine of angle, specified in degrees from 0-360.

\mark{Sine}
\function{Sine angle}{float}

Returns the sine of an angle, specified in degrees from 0-360.

\mark{left-clicking?}
\function{(left-clicking?)}{boolean}

Returns #t if the left mouse button is being clicked.

\mark{right-clicking?}
\function{(right-clicking?)}{boolean}

Returns #t if the right mouse button is being clicked.

\mark{get-mouse-movement}
\function{(get-mouse-movement)}{(values x y)}

Returns the last movement of the mouse as an x,y pair. See \link{get-mickeys} for more details.

\mark{constant}
\syntax{(constant id expression)}

Define \var{id} to be \var{expression} and \var{id} cannot be mutated.

\mark{define-object}
\syntax{(define-object name (inherits ...) (vars ...) body ...)}

Define a new object that derives from \link{Basic}. You can use this syntax if you do not want to create a class by hand. \var{(inherits ...)} is a list of variables to inherit from Basic( x, y, and/or phase ). \var{(vars ...)} is a list of variables private to this object. \var{body ...} is any normal scheme expression.

To define methods use \var{define}. Methods that should override methods in \link{Basic} will be handled automatically as long as they are declared in the form \scheme{(define (name ...) ...)}.

\begin{schemedisplay}
;; define an object that moves right as time goes on
(define-object foo (x y) ()
  (define (tick world)
    (set! x (add1 x)))

  (define (draw world buffer)
    (circle-fill buffer x y 4 (color 255 0 0)))
  )
\end{schemedisplay}

When an object defined by \var{define-object} is created a method \var{create} is run immediately with no arguments. In this function you can initialize variables and do whatever else.
\begin{schemedisplay}
;; the example from above but set the radius in a variable
(define-object foo (x y) (radius)

  (constant five 5)

  (define (create)
    (set! radius five))

  (define (tick world)
    (set! x (add1 x)))

  (define (draw world buffer)
    (circle-fill buffer x y radius (color 255 0 0)))
  )
\end{schemedisplay}

Here \var{counter} is set to 5 when the object is created. Also you can see a usage of \link{constant}.

\mark{define-generator}
\syntax{(define-generator name (every expr proc))}

\var{define-generator} defines an object that derives from \link{Basic} like \link{define-object} except a generator's sole purpose in life is to execute a function every time a certain amount of time has passed by. This is useful for adding objects to the universe in descrete steps.

\begin{schemedisplay}
(define-generator thing

  ;; add something every 10 ticks
  (every 10 (lambda (world)
	      (add-object world (make something))))

  ;; add something-else every 20 ticks
  (every 20 (lambda (world)
              (add-object world (make something-else))))

  ;; add another at random
  (every (random 100) (lambda (world)
                        (add-object world (make another))))
  )
\end{schemedisplay}

To use a generator, create one and add it to the world.

\begin{schemedisplay}
(add-object world (make thing))
\end{schemedisplay}

\mark{say}
\syntax{(say obj method args ...)}{any}

Ask \var{obj} to perform a \var{method} and pass \var{args} to it. This works like normal method invocation except if \var{obj} does not have a method named \var{method} or accepts a different number of args then no function will be called. This can be a source of confusion as no warning or error will be printed, the method will just be silently ignored.

\begin{schemedisplay}
(define obj (make my-object))
;; tell obj to say hello
(say obj hello)
\end{schemedisplay}

\mark{is-a?}
\function{(is-a? obj class)}{boolean}

Returns #t if obj has a type of \var{class}.

\mark{make}
\syntax{(make class args ...)}{object}

Create a new object whose type is \var{class}. \var{args ...} should be a list of name/value s-expressions which initialize some field of the object.

\begin{schemedisplay}
(define-object my-object (x y) (age) (void))
(make my-object (x 5) (y 10) (age 18))
\end{schemedisplay}

\mark{start}
\function{(start world [before] [after])}{void}

\var{before :: (lambda (world) ...)}\newline
\var{after :: (lambda (world) ...)}

Given a world object this method will create the graphics context and start the game. If given \var{before} is executed immediately before the main game loop is executed and \var{after} is executed after the game ends. These methods allow you to perform arbitrary initialization that you could not otherwise do before the \var{start} method is called. I.e, you cannot call an image related function before \var{start} becuase the graphics context does not exist yet.

\begin{schemedisplay}
;; define blue, but set it in the before method when it is ok to do so
(define world (make-world))
(define blue #f)
(start world (lambda (w) (set! blue (color 0 0 255))))
\end{schemedisplay}

\chapter{Examples}

\hypertarget{examples}{}

There are a few example programs that come with the allegro.plt package. Type any of the following require lines into drscheme/mzscheme and call the (run) method to run them.

\begin{schemedisplay}
;; Demo of sound and using the mouse
(require (planet "piano.ss" ("kazzmir" "allegro.plt") "examples"))

;; Show Allegros ability to blend images together
(require (planet "exblend.ss" ("kazzmir" "allegro.plt") "examples"))

;; Hello world
(require (planet "exhello.ss" ("kazzmir" "allegro.plt") "examples"))

;; 3d bouncing boxes in various rendering modes
(require (planet "ex3d.ss" ("kazzmir" "allegro.plt") "examples"))

;; 3d simulation of flying through a wormhole, non-interactive 
(require (planet "wormhole.ss" ("kazzmir" "allegro.plt") "examples"))

;; A game wherein you must collect the white diamonds and escape through the
;; red portal. Left click to shoot
(require (planet "xquest.ss" ("kazzmir" "allegro.plt") "examples/xquest"))

;; A slightly different remake of xquest.ss using the game framework
(require (planet "simple.ss" ("kazzmir" "allegro.plt") "examples"))
\end{schemedisplay}

The following is a short tutorial on using Allegro. At each step I will add
some code and explain what it does.

1. Set up Allegro and quit. Pretty self explanatory.

\begin{schemedisplay}
;; this require will be used throughout
(require (planet "util.ss" ("kazzmir" "allegro.plt" 1 1)))
(require (planet "keyboard.ss" ("kazzmir" "allegro.plt" 1 1)))
(require (prefix image- (planet "image.ss" ("kazzmir" "allegro.plt" 1 1))))
(require (prefix mouse- (planet "mouse.ss" ("kazzmir" "allegro.plt" 1 1))))

(define (run)
  (easy-init 640 480 16) ;; set up Allegro. Use 640x480 for window demensions and 16 bits per pixel
  (easy-exit)) ;; Just quit Allegro
\end{schemedisplay}

2. Print hello world to the screen and quit when ESC is pressed.

\begin{schemedisplay}
(define (run)
  (easy-init 640 480 16)
  (game-loop
     (lambda ()
        (keypressed? 'ESC))
     (lambda (buffer)
        (image-print buffer 50 50 (image-color 255 255 255) -1 "Hello world"))
     (frames-per-second 30))
  (easy-exit))
\end{schemedisplay}

3. Print hello world wherever the mouse is.

\begin{schemedisplay}
(define (run)
  (easy-init 640 480 16)
  (game-loop
     (lambda ()
        (keypressed? 'ESC))
     (lambda (buffer)
        (let ((x (mouse-x))
	      (y (mouse-y)))
	 (image-print buffer x y (image-color 255 255 255) -1 "Hello world")))
     (frames-per-second 30))
  (easy-exit))
\end{schemedisplay}

4. Load a bitmap and show it where the mouse is.

\begin{schemedisplay}
(define (run)
  (easy-init 640 480 16)
  (let ((my-image (image-create-from-file "myimage.bmp")))
    (game-loop
      (lambda ()
        (keypressed? 'ESC))
      (lambda (buffer)
        (let ((x (mouse-x))
	      (y (mouse-y)))
	 (image-copy buffer my-image x y)))
     (frames-per-second 30))
  (easy-exit)))
\end{schemedisplay}

\chapter{FAQ}

Q. Where and how do I get the Allegro library itself to install?\newline
A. You dont need to install Allegro, it comes with the planet package.

Q. I get errors about the planet download not completing.\newline
A. Planet sometimes has problems with very large packages, like this one.
You can always download the latest package from my home page and install it
on the command line.

http://www.rafkind.com/jon/showproject.php?id=27

To install on the command line type the following\newline
{\tt \$ planet -f allegro.plt kazzmir 1 4}

Those last two parameters can really be whatever you want, they are just
version numbers, but they should probably match the version that you
downloaded.

Q. The planet package wont install. I am on Ubuntu.\newline
A. Ubuntu is a binary distribution which doesnt come with the tools necessary
to build Allegro from source. To get these tools goto the ubuntu package
manager and install the following packages:

  {\tt make}\newline
  {\tt libx11-dev}

Planet wont know if Allegro doesn't build correctly so you will need to
uninstall the package before trying to install it again. This can be
accomplished like so:\newline
{\tt \$ planet -r kazzmir allegro.plt 1 4}

Replace the last two parameters with the version of Allegro you are trying to
use.

Q. I get an error like "Scheme->C: expects argument of type <int32>; given 50.3".\newline
A. This means you passed in a floating point number to an allegro function that requires an integer. You can use the \link{round*} method to convert a float to an integer or use the following code:

\begin{schemedisplay}
(define (my-round i)
  (inexact->exact (round i)))
\end{schemedisplay}

\chapter{ChangeLog}

2.0 - 12/24/2006

* Renamed generator to define-generator
* Added translucency functions for all primitive drawing functions
* Added keyboard and graphics tests to the tests/ directory
* Renamed any class named foo\% to Foo
* Wrote new HTML documentation
* Fixed various minor bugs

1.6 - 11/19/2006

* Fixed Linux version to work with 3m. allegro.plt should work with 3m on all
supported platforms now.
* Improved documentation
* Collision detection fixed a little bit
* New 'generator' syntax for a simple way to make new objects in the game
framework
* Fix the 'start' method in game.ss so the last two arguments are optional

1.5 - 10/30/2006

* Added game framework
* Added more functions to keyboard.ss and image.ss

1.4 - 8/29/2006

* OSX( PPC ) support
* Added set-coordinates to mouse.ss which sets the x, y positions of the mouse

1.3 - 7/31/2006

* Added blender routines
* Added more keyboard support: simulate-keypress and readkey.
* Documented more functions

1.2 - 7/16/2006

* Added png support

1.1 - 7/8/2006

* When the window loses focus in Windows, run the program in the background
* Provided more drawing functions

1.0 - 6/26/2006

* Initial release. Some functionality provided, drawing, keyboard, mouse.

\end{schemeregion}

\end{document}
