diff options
-rw-r--r-- | doc/api.texi | 374 |
1 files changed, 132 insertions, 242 deletions
diff --git a/doc/api.texi b/doc/api.texi index 5b02d60..5bfad7a 100644 --- a/doc/api.texi +++ b/doc/api.texi @@ -1,9 +1,7 @@ @menu * Kernel:: The fundamental components. -* Input:: Keyboard, mouse, and controller input. * Math:: Linear algebra and more. * Graphics:: Eye candy. -* Audio:: Sound effects and music. * Scripting:: Bringing the game world to life. @end menu @@ -11,138 +9,126 @@ @section Kernel At the very core of Chickadee, in the @code{(chickadee)} module, lies -an event loop. This loop, or ``kernel'', is responsible for creating -and managing the game window, dispatching input events, ensuring that -the game is updated at the desired interval, and rendering graphics. +an event loop. This loop, or ``kernel'', is responsible for ensuring +that the game is updated at the desired interval, rendering the +current state of the game world, and handling errors if they occur. The kernel implements what is known as a ``fixed timestep'' game loop, meaning that the game simulation will be advanced by a fixed interval of time and will never vary from frame to frame, unlike some other styles of game loops. The appropriately named @code{run-game} and @code{abort-game} procedures are the entry and exit points to the -Chickadee kernel. +Chickadee game loop kernel. On its own, the kernel does not do very much at all. In order to -actually respond to input events, update game state, or draw something -to the game window, a hacker with a penchant for game development must -latch onto extension points built into the kernel, called ``hooks'', -and specify what action ought to be taken for any given event. For -example, the @code{key-press-hook} can be used to respond to the -@code{a} key being pressed by swinging the player's mighty sword. -There are many hooks available, so read on to learn about all of them. -For information about using Guile's hook API, see @xref{Hooks,,, -guile, GNU Guile Reference Manual}. - -@deffn {Procedure} run-game [#:window-title "Chickadee!"] @ - [#:window-width 640] [#:window-height 480] [#:window-fullscreen? #f] @ +actually respond to input events, update game state, or render output, +the programmer must provide an engine. But don’t worry, you don’t +have to start from scratch! Chickadee comes with a simple engine that +uses SDL to create a graphical window and handle input devices, and +OpenGL to handle rendering. This default engine is enough for most +users to get started writing games quickly. More advanced users may +want to write a custom engine that uses a different I/O system. +Perhaps you are writing a text adventure or roguelike that reads from +and writes to a terminal instead of a graphical window. The game loop +kernel makes no assumptions. + +@deffn {Procedure} run-game [#:update] [#:render] [#:time] [#:error] @ [#:update-hz 60] -Start the event loop. This procedure will not return until +Start the game loop. This procedure will not return until @code{abort-game} is called. -The @code{update-hook} will be run @var{update-hz} times per second. +The core game loop is generic and requires four additional procedures +to operate: -A new graphical window will be opened with @var{window-width} x -@var{window-height} as its dimensions, @var{window-title} as its -title, and in fullscreen mode if @var{window-fullscreen?} is -@code{#t}. -@end deffn +@itemize +@item +@var{update}: Called @var{update-hz} times per second to advance the +game simulation. This procedure is called with a single argument: The +amount of time that has passed since the last update, in milliseconds. +@item +@var{render}: Called each iteration of the loop to render the game to +the desired output device. This procedure is called with a single +argument: A value in the range [0, 1] which represents how much time +has past since the last game state update relative to the upcoming +game state update, as a percentage. Because the game state is updated +independent of rendering, it is often the case that rendering is +occuring between two updates. If the game is rendered as it was +during the last update, a strange side-effect will occur that makes +animation appear rough or ``choppy''. To counter this, the +@var{alpha} value can be used to perfrom a linear interpolation of a +moving object between its current position and its previous position. +This odd trick has the pleasing result of making the animation look +smooth again, but requires keeping track of previous state. +@item +@var{time}: Called to get the current time in milliseconds. This +procedure is called with no arguments. +@item +@var{error}: Called when an error from the @var{update} or +@var{render} procedures reaches the game loop. This procedure is +called with three arguments: The call stack, the error key, and the +error arguments. If no error handler is provided, the default +behavior is to simply re-throw the error. +@end itemize -@deffn {Procedure} abort-game -Stop the currently running Chickadee event loop. @end deffn -@deffn {Procedure} time -Return the current game time in milliseconds. +@deffn {Procedure} abort-game +Stop the currently running Chickadee game loop. @end deffn -@defvr {Variable} load-hook -A hook that is run once when the event loop boots, before any other -hook is run. This hook is run with zero arguments. - -@example -(add-hook! load-hook (lambda () (display "hello!\n"))) -@end example - -@end defvr - -@defvr {Variable} update-hook -A hook that is run every time the game simulation should be advanced. -This hook is run with a single argument @var{dt}, the fixed timestep -that was configured when the event loop was started, in milliseconds. - -@example -(add-hook! update-hook (lambda (dt) (display "tick!\n"))) -@end example +Since most users will want to write 2D/3D games with hardware +accelerated graphics rendering, controlled via keyboard, mouse, or +game controller, Chickadee comes with an easy to use engine just for +this purpose in the @code{(chickadee sdl)} module: +@code{run-game/sdl}. -@end defvr +@deffn {Procedure} run-game/sdl [#:window-title "Chickadee!"] @ + [#:window-width 640] [#:window-height 480] @ + [#:window-fullscreen? @code{#f}] [#:update-hz 60] @ + [#:load] [#:update] [#:draw] [#:quit] @ + [#:key-press] [#:key-release] [#:text-input] @ + [#:mouse-press] [#:mouse-release] [#:mouse-move] @ + [#:controller-add] [#:controller-remove] [#:controller-press] @ + [#:controller-release] [#:controller-move] [#:error] -@defvr {Variable} before-draw-hook -A hook that is run before a frame is rendered. This hook is run with -zero arguments. +Run the Chickadee game loop using the SDL engine. -@example -(add-hook! before-draw-hook (lambda () (display "about to draw!\n"))) -@end example - -@end defvr - -@defvr {Variable} after-draw-hook -A hook that is run after a frame is rendered. This hook is run with -zero arguments. - -@example -(add-hook! after-draw-hook (lambda () (display "done drawing!\n"))) -@end example - -Combined with @code{before-draw-hook}, one can perform a frames per -second calculation to monitor game performance and stability. - -@end defvr - -@defvr {Variable} draw-hook -A hook that is run each time a frame should be rendered. This hook is -run with a single argument @var{alpha}, a value in the range [0, 1] -which represents how much time has past since the last game state -update relative to the upcoming game state update, as a percentage. -Because the game state is updated independent of rendering, it is -often the case that rendering is occuring between two updates. If the -game is rendered as it was during the last update, a strange -side-effect will occur that makes animation appear rough or -``choppy''. To counter this, the @var{alpha} value can be used to -perfrom a linear interpolation of a moving object between its current -position and its previous position. This odd trick has the pleasing -result of making the animation look smooth again, but requires keeping -track of previous state. - -@c TODO: Add example of linear interpolation - -@example -(add-hook! draw-hook (lambda (alpha) (display "<(._.<) \n"))) -@end example +A new graphical window will be opened with @var{window-width} x +@var{window-height} as its dimensions, @var{window-title} as its +title, and in fullscreen mode if @var{window-fullscreen?} is +@code{#t}. -@end defvr +@itemize +@item +@var{load}: Called with zero arguments when the game window has opened +but before the game loop has started. Can be used to perform +initialization that requires an open window and OpenGL context such as +loading textures. -@defvr {Variable} quit-hook -A hook that is run when the user clicks the close button on the game -window. This hook is run with zero arguments. +@item +@var{update}: Called @var{update-hz} times per second with one +argument: The amount of time to advance the game simulation. -@example -(add-hook! quit-hook (lambda () (display "bye!\n"))) -@end example +@item +@var{draw}: Called each time a frame should be rendered with a single +argument known as the @code{alpha} value. See the documentation for +@code{run-game} for an explanation of this value. -@end defvr +@item +@var{quit}: Called with zero arguments when the user tries to close +the game window. The default behavior is to exit the game. -@defvr {Variable} key-press-hook -A hook that is run when a key is pressed on the keyboard. This hook -is run with four arguments: +@item +@var{key-press}: Called with four arguments when a key is pressed on +the keyboard: @enumerate @item @var{key}: The symbolic name of the ``virtual'' key that was pressed. For example: @code{backspace}. It's called a virtual key because the operating system may map a physical keyboard key to another key -entirely, such as how the author binds the ``caps lock'' key to mean -``control''. +entirely, such as how the author likes to bind the ``caps lock'' key +to mean ``control''. @item @var{scancode}: The symbolic name of the physical key that was @@ -158,19 +144,9 @@ include @code{ctrl}, @code{alt}, and @code{shift}. @end enumerate -@example -(add-hook! key-press-hook - (lambda (key scancode modifiers repeat?) - (display "pressed key: ") - (display key) - (newline))) -@end example - -@end defvr - -@defvr {Variable} key-release-hook -A hook that is run when a key is released on the keyboard. This hook -is run with three arguments: +@item +@var{key-release}: Called with three arguments when a key is released +on the keyboard: @enumerate @item @@ -186,18 +162,13 @@ were being held down when the key was released. @end enumerate -@end defvr - -@defvr {Variable} text-input-hook -A hook that is run when printable text is typed on the keyboard. This -hook is run with a single argument, @var{text}, a string containing -the text that was entered. -@end defvr - -@defvr {Variable} mouse-press-hook -A hook that is run when a mouse button is pressed. This hook is run -with four arguments: +@item +@var{text-input}: Called with a single argument, a string of text, +when printable text is typed on the keyboard. +@item +@var{mouse-press}: Called with four arguments when a mouse button is +pressed: @enumerate @item @@ -215,11 +186,9 @@ as @code{left}, @code{middle}, or @code{right}. @end enumerate -@end defvr - -@defvr {Variable} mouse-release-hook -A hook that is run when a mouse button is released. This hook is run -with three arguments: +@item +@var{mouse-release}: Called with three arguments when a mouse button +is released: @enumerate @@ -234,11 +203,8 @@ with three arguments: @end enumerate -@end defvr - -@defvr {Variable} mouse-move-hook -A hook that is run when the mouse is moved. This hook is run with -five arguments: +@item +@var{mouse-move}: Called with five arguments when the mouse is moved: @enumerate @@ -262,23 +228,17 @@ mouse was moved. @end enumerate -@end defvr - -@defvr {Variable} controller-add-hook -A hook that is run when a game controller is connected. This hook is -run with a single argument, @var{controller}, the controller that was -connected. -@end defvr +@item +@var{controller-add}: Called with a single argument, an SDL game +controller object, when a game controller is connected. -@defvr {Variable} controller-remove-hook -A hook that is run when a game controller is disconnected. This hook -is run with a single argument, @var{controller}, the controller that -was disconnected. -@end defvr +@item +@var{controller-remove}: Called with a single argument, an SDL game +controller object, when a game controller is disconnected. -@defvr {Variable} controller-press-hook -A hook that is run when a button on a game controller is pressed. -This hook is run with two arguments: +@item +@var{controller-press}: Called with two arguments when a button on a +game controller is pressed: @enumerate @@ -325,12 +285,9 @@ Possible buttons are: @end enumerate -@end defvr - -@defvr {Variable} controller-release-hook -A hook that is run when a button on a game controller is released. - -This hook is run with two arguments: +@item +@var{controller-release}: Called with two arguments when a button on a +game controller is released: @enumerate @@ -342,11 +299,9 @@ This hook is run with two arguments: @end enumerate -@end defvr - -@defvr {Variable} controller-move-hook -A hook that is run when an analog stick or trigger on a game -controller is moved. This hook is run with three arguments +@item +@var{controller-move}: Called with three arguments when an analog +stick or trigger on a game controller is moved: @enumerate @@ -374,27 +329,26 @@ values are: @end enumerate -@end defvr +@item +@var{error}: Called with three arguments when an error occurs: -@node Input -@section Input +@enumerate -Chickadee can handle input events from the keyboard, mouse, and game -controllers. +@item +@var{stack}: The call stack at the point of error. -@menu -* Keyboard:: Keyboard input. -@end menu +@item +@var{key}: The exception key. + +@item +@var{args}: The arguments thrown with the exception. -@node Keyboard -@subsection Keyboard +@end enumerate -@deffn {Procedure} key-pressed? @var{key} -Return @code{#t} if @var{key} is currently being pressed. -@end deffn +The default behavior is to re-throw the error. + +@end itemize -@deffn {Procedure} key-released? @var{key} -Return @code{#t} if @var{key} is not currently being pressed. @end deffn @node Math @@ -962,70 +916,6 @@ The default framebuffer. @node Viewports @subsection Viewports -@node Audio -@section Audio - -Chickadee has two data types for audio: samples and music. Samples -are for short sound effects like explosions. Music is for, well, -uh@dots{}, music. - -Supported file formats include WAV and OGG. - -@deffn {Procedure} load-sample @var{file} -Load audio sample from @var{file}. -@end deffn - -@deffn {Procedure} set-sample-volume! @var{volume} -Set the volume that all samples are played at to @var{volume}, an -integer value between 0 and 128. -@end deffn - -@deffn {Procedure} play-sample @var{sample} -Play @var{sample}. Pretty straightforward! -@end deffn - -@deffn {Procedure} load-music @var{file} -Load music from @var{file}. -@end deffn - -@deffn {Procedure} music-volume -Return the volume level for music, an integer value between 0 and 128. -@end deffn - -@deffn {Procedure} set-music-volume! @var{volume} -Set the volume that music is played at to @var{volume}, an integer -value between 0 and 128. -@end deffn - -@deffn {Procedure} play-music @var{music} [@var{loop?}] -Play @var{music}. If @var{loop?}, play it over and over and over and -over and@dots{} -@end deffn - -@deffn {Procedure} pause-music -Pause the current music track. -@end deffn - -@deffn {Procedure} resume-music -Resume the current music track. -@end deffn - -@deffn {Procedure} rewind-music -estart the current music track from the beginning. -@end deffn - -@deffn {Procedure} stop-music -Stop playing the current music track. -@end deffn - -@deffn {Procedure} music-playing? -Return @code{#t} if music is currently playing. -@end deffn - -@deffn {Procedure} music-paused? -Return @code{#t} if music is currently paused. -@end deffn - @node Scripting @section Scripting |