Utilities

(require (planet "util.ss" ("kazzmir" "allegro.plt")))

Function list

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


top

procedure: (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.

width and height are the width and height of the graphics context, respectively. Typical width/height pairs are
640 480
800 600
1024 768
1240 1024

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

mode can be one of the following


top

procedure: (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 easy-init again.


top

procedure: (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.

;; Make a list of 10 greys from black to white.
(blend-palette (color 0 0 0) (color 255 255 255) 10)


top

procedure: (frames-per-second num) :: num
(fps num) :: num

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


top

procedure: (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 game-delay, the logic-proc function will be run specifically to create some side-affects. After at least one logic-proc cycle has occured draw-proc will be executed to display the current state of the game on the graphics context. game-loop will loop until logic-proc returns #t.

logic-proc :: (lambda () ...)
draw-proc :: (lambda (buffer) ...)
game-delay :: num

The buffer passed to draw-proc is an 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 examples chapter for an idea on how to use game-loop.


top

procedure: (set-color-conversion! arg) :: void

Should not be needed by regular users.


top

procedure: (apply-matrix matrix x y z) :: (values x y z)

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


top

procedure: (get-transformation-matrix scale x-rotation y-rotation z-rotation x y z) :: matrix

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


top

procedure: (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 set-projection-viewport.


top

procedure: (persp-project x y z) :: (values x y)

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


top

procedure: (set-projection-viewport x1 y1 x2 y2) :: void

Sets the viewport used to scale the output of the 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 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 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.


top

procedure: (polygon-z-normal v1 v2 v3) :: float

v1, v2, and v3 all have the type 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 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.


top

procedure: (set-add-blender! red green blue alpha) :: void

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


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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 :).


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (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.


top

procedure: (set-trans-blender! red green blue alpha) :: void

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

For alpha 0 is translucent and 255 is opaque.


top

procedure: (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.


top

procedure: (Cosine angle) :: float

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


top

procedure: (Sine angle) :: float

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


top

procedure: (calculate-angle x1 y1 x2 y2) :: float

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


top

procedure: (calculate-normal-angle x1 y1 x2 y2) :: float

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