From 08283ce8448f9ebf6be28fecf8c730e9f99e3f47 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 21 Apr 2023 22:23:13 -0400 Subject: Add syntax highlighting to html manual. --- Makefile.am | 4 +- doc/api.texi | 136 ++++++++++++++++++++++++++--------------------------- doc/chickadee.texi | 20 ++++---- guix.scm | 3 +- 4 files changed, 82 insertions(+), 81 deletions(-) diff --git a/Makefile.am b/Makefile.am index ba5ac74..b593603 100644 --- a/Makefile.am +++ b/Makefile.am @@ -184,8 +184,8 @@ doc_chickadee_TEXINFOS = \ doc/fdl.texi \ doc/api.texi -AM_MAKEINFOHTMLFLAGS = --css-ref=https://dthompson.us/css/dthompson.css \ - --css-include=doc/manual.css +html-local: + $(GUILE) --no-auto-compile doc/build-html.scm publish: distcheck gpg --sign --detach-sign --armor --yes chickadee-$(VERSION).tar.gz && \ diff --git a/doc/api.texi b/doc/api.texi index c36a36b..6ec5f9b 100644 --- a/doc/api.texi +++ b/doc/api.texi @@ -586,9 +586,9 @@ release. Here's a quick example of adding two vectors: -@example +@lisp (define v (vec2+ (vec2 1 2) (vec2 3 4))) -@end example +@end lisp @emph{A Note About Performance} @@ -1013,11 +1013,11 @@ Return a new 3x3 identity matrix. Any matrix multiplied by the identity matrix yields the original matrix. This procedure is equivalent to the following code: -@example +@lisp (make-matrix3 1 0 0 0 1 0 0 0 1) -@end example +@end lisp @end deffn @@ -1125,12 +1125,12 @@ Return a new 4x4 identity matrix. Any matrix multiplied by the identity matrix yields the original matrix. This procedure is equivalent to the following code: -@example +@lisp (make-matrix4 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1) -@end example +@end lisp @end deffn @@ -1468,18 +1468,18 @@ depending on what's most convenient. The first is @code{make-color}, where you specify each channel exactly as described above. This is fully opaque magenta: -@example +@lisp (make-color 1.0 0.0 1.0 1.0) -@end example +@end lisp Many people are used to representing colors as 6 or 8 digit hexadecimal numbers, so Chickadee also allows that. Here's magenta, again: -@example +@lisp (rgba #xFF00FFFF) (rgb #xFF00FF) ; equivalent to the above -@end example +@end lisp @deffn {Procedure} make-color r g b a Return a new color object with a red value of @var{r}, a green value @@ -1531,12 +1531,12 @@ transparent. Convert the hexadecimal color code in the string @var{s} to a color object. The following string formats are supported: -@example +@lisp (string->color "#FF00FFFF") (string->color "FF00FFFF") (string->color "#FF00FF") (string->color "FF00FF") -@end example +@end lisp @end deffn @@ -2005,9 +2005,9 @@ as they are the same. Printing text to the screen is quite easy: -@example +@lisp (draw-text "Hello, world" (vec2 100.0 100.0)) -@end example +@end lisp Chickadee supports OpenType/TrueType fonts (via the FreeType library), bitmap fonts in Angel Code bmfont format, and simple sprite sheet @@ -2064,9 +2064,9 @@ Draw the string @var{text} with the first character starting at @var{position} using @var{font}. If @var{font} is not specified, a built-in font is used. -@example +@lisp (draw-text "Hello, world!" (vec2 128.0 128.0)) -@end example +@end lisp To render a substring of @var{text}, use the @var{start} and @var{end} arguments. @@ -2097,14 +2097,14 @@ the first. @deffn {Procedure} path . commands Return a new path that follows @var{commands}. -@example +@lisp (path (move-to (vec2 50.0 50.0)) (line-to (vec2 500.0 50.0)) (line-to (vec2 400.0 200.0)) (bezier-to (vec2 500.0 250.0) (vec2 380.0 300.0) (vec2 400.0 400.0)) (line-to (vec2 300.0 400.0)) (close-path)) -@end example +@end lisp @end deffn @@ -2231,11 +2231,11 @@ Possible style attributes are: @item @code{stroke-cap} @end itemize -@example +@lisp (with-style ((stroke-color green) (stroke-width 4.0)) (stroke (circle (vec2 100.0 100.0) 50.0))) -@end example +@end lisp @end deffn @@ -2427,11 +2427,11 @@ manipulating particle systems. Below is an example of a very simple particle system that utilizes nearly all of the default configuration settings: -@example +@lisp (use-modules (chickadee graphics particles)) (define texture (load-image "particle.png")) (define particles (make-particles 2000 #:texture texture)) -@end example +@end lisp In order to put particles into a particle system, a particle ``emitter'' is needed. Emitters know where to spawn new particles, @@ -2440,11 +2440,11 @@ how many of them to spawn, and for how long they should do it. Below is an example of an emitter that spawns 16 particles per frame at the coordinates @code{(320, 240)}: -@example +@lisp (use-modules (chickadee math rect)) (define emitter (make-particle-emitter (make-rect 0.0 0.0 320.0 240.0) 16)) (add-particle-emitter particles emitter) -@end example +@end lisp To see all of the tweakable knobs and switches, read on! @@ -2794,7 +2794,7 @@ formats. Here's some basic boilerplate to render a 3D model: -@example +@lisp (use-modules (chickadee graphics light) (chickadee graphics model) (chickadee graphics skybox)) @@ -2808,7 +2808,7 @@ Here's some basic boilerplate to render a 3D model: (define (draw alpha) (with-projection projection (draw-model model world view camera-position -@end example +@end lisp @deffn {Procedure} load-obj file-name Load the OBJ formatted model in @var{file-name} and return a 3D model @@ -3278,7 +3278,7 @@ In OpenGL terminology, a chunk of data allocated on the GPU is a that could be transformed into a GPU buffer that packs together vertex position and texture coordinates: -@example +@lisp (use-modules (chickadee graphics buffer) (srfi srfi-4)) (define data (f32vector -8.0 -8.0 ; 2D vertex @@ -3289,15 +3289,15 @@ position and texture coordinates: 1.0 1.0 ; 2D texture coordinate -8.0 8.0 ; 2D vertex 0.0 1.0)) ; 2D texture coordinate -@end example +@end lisp This data represents a textured 16x16 square centered on the origin. To send this data to the GPU, the @code{make-buffer} procedure is needed: -@example +@lisp (define buffer (make-buffer data #:stride 16)) -@end example +@end lisp The @code{#:stride} keyword argument indicates how many bytes make up each element of the buffer. In this case, there are 4 floats per @@ -3310,7 +3310,7 @@ particular data type. In this case, there are two attributes packed into the buffer. To define vertex attributes, the @code{make-vertex-attribute} procedure is needed: -@example +@lisp (define vertices (make-vertex-attribute #:buffer buffer #:type 'vec2 @@ -3322,7 +3322,7 @@ into the buffer. To define vertex attributes, the #:component-type 'float #:length 4 #:offset 8)) -@end example +@end lisp To render a square, the GPU needs to draw two triangles, which means we need 6 vertices in total. However, the above buffer only contains @@ -3331,7 +3331,7 @@ for a square, but 2 of them must be repeated for each triangle. To work with deduplicated vertex data, an ``index buffer'' must be created. -@example +@lisp (define index-buffer (make-buffer (u32vector 0 3 2 0 2 1) #:target 'index) @@ -3339,7 +3339,7 @@ created. (make-vertex-attribute #:type 'scalar #:component-type 'unsigned-int #:buffer index-buffer)) -@end example +@end lisp Note the use of the @code{#:target} keyword argument. It is required because the GPU treats index data in a special way and must be told @@ -3351,12 +3351,12 @@ each vertex attribute with an attribute index on the GPU. The indices that are chosen must correspond with the indices that the shader (@pxref{Shaders}) expects for each attribute. -@example +@lisp (define vertex-array (make-vertex-array #:indices indices #:attributes `((0 . ,vertices) (1 . ,texcoords)))) -@end example +@end lisp With the vertex array created, the GPU is now fully aware of how to interpret the data that it has been given in the original buffer. @@ -3573,11 +3573,11 @@ attributes @var{indices} and the vertex attribute data within @var{attributes} is an alist mapping shader attribute indices to vertex attributes: -@example +@lisp `((1 . ,vertex-attribute-a) (2 . ,vertex-attribute-b) - @dots{}) -@end example + ...) +@end lisp By default, the vertex array is interpreted as containing a series of triangles. If another primtive type is desired, the @var{mode} @@ -3684,11 +3684,11 @@ Chickadee uses, is to think about it as a function call: The shader is a function, and it is applied to some ``attributes'' (positional arguments), and some ``uniforms'' (keyword arguments). -@example +@lisp (define my-shader (load-shader "vert.glsl" "frag.glsl")) -(define vertices (make-vertex-array @dots{})) +(define vertices (make-vertex-array ...)) (shader-apply my-shader vertices #:color red) -@end example +@end lisp @xref{Rendering Engine} for more details about the @code{shader-apply} procedure. @@ -3807,7 +3807,7 @@ shader struct. Some example code will explain this concept best. Here is the Scheme equivalent of the @code{Light} struct: -@example +@lisp (define-shader-type make-light light? @@ -3818,7 +3818,7 @@ equivalent of the @code{Light} struct: (float-vec4 color light-color) (float intensity light-intensity) (float cut-off light-cut-off)) -@end example +@end lisp The macro @code{define-shader-type} closely resembles the familiar @code{define-record-type} from SRFI-9, but with one notable @@ -4407,11 +4407,11 @@ and state changes happen within the context of this engine. Performing a custom draw call could look something like this: -@example +@lisp (with-graphics-state ((g:blend-mode blend:alpha) (g:texture-0 my-texture)) (shader-apply my-shader #:foo 1)) -@end example +@end lisp @subsubsection Render States @@ -4495,11 +4495,11 @@ The basics of playing audio are very simple. Just load an audio file in the load hook (or anywhere else once the game loop is running) and play it! -@example +@lisp (define sample (load-audio "neat-sound-effect.wav")) (audio-play sample) -@end example +@end lisp For more advanced usage, check out the full API reference in the following sections. @@ -4962,26 +4962,26 @@ additional agendas may be created for different purposes. The following example prints the text ``hello'' when the agenda has advanced to time unit 10. -@example +@lisp (at 10 (display "hello\n")) -@end example +@end lisp Most of the time it is more convenient to schedule tasks relative to the current time. This is where @code{after} comes in handy: -@example +@lisp (after 10 (display "hello\n")) -@end example +@end lisp Time units in the agenda are in no way connected to real time. It's up to the programmer to decide what agenda time means. A simple and effective approach is to map each call of the update procedure (@pxref{Kernel}) to 1 unit of agenda time, like so: -@example +@lisp (define (update dt) (update-agenda 1)) -@end example +@end lisp It is important to call @code{update-agenda} periodically, otherwise no tasks will ever be run! @@ -4993,14 +4993,14 @@ a simple matter of not updating the world's agenda while continuing to update the user interface's agenda. The current agenda is dynamically scoped and can be changed using the @code{with-agenda} special form: -@example +@lisp (define game-world-agenda (make-agenda)) (with-agenda game-world-agenda (at 60 (spawn-goblin)) (at 120 (spawn-goblin)) (at 240 (spawn-goblin-king))) -@end example +@end lisp @deffn {Procedure} make-agenda Return a new task scheduler. @@ -5081,13 +5081,13 @@ turn and prevent blocking the game loop. Building on top of the scheduling that agendas provide, here is a script that models a child trying to get their mother's attention: -@example +@lisp (script (while #t (display "mom!") (newline) (sleep 60))) ; where 60 = 1 second of real time -@end example +@end lisp This code runs in an endless loop, but the @code{sleep} procedure suspends the script and schedules it to be run later by the agenda. @@ -5108,11 +5108,11 @@ been started. For example, when an enemy is defeated their AI routine needs to be shut down. When a script is spawned, a handle to that script is returned that can be used to cancel it when desired. -@example +@lisp (define script (script (while #t (display "hey\n") (sleep 60)))) ;; sometime later (cancel-script script) -@end example +@end lisp @deffn {Procedure} spawn-script thunk Apply @var{thunk} as a script and return a handle to it. @@ -5159,11 +5159,11 @@ Wait @var{duration} before resuming the current script. @deffn {Syntax} wait-until condition Wait until @var{condition} is met before resuming the current script. -@example +@lisp (script (wait-until (key-pressed? 'z)) (display "you pressed the Z key!\n")) -@end example +@end lisp @end deffn @@ -5179,12 +5179,12 @@ state to a final state over a pre-determined period of time. In other words, tweening is a way to create animation. The @code{tween} procedure can be used within any script like so: -@example +@lisp (define x 0) (script ;; 0 to 100 in 60 ticks of the agenda. (tween 60 0 100 (lambda (y) (set! x y)))) -@end example +@end lisp @deffn {Procedure} tween duration start end proc @ [#:step @code{1}] [#:ease @code{smoothstep}] @ @@ -5214,7 +5214,7 @@ someone on the other end of the line to complete the transaction. Here's a simplistic example: -@example +@lisp (define c (make-channel)) (script @@ -5226,7 +5226,7 @@ Here's a simplistic example: (channel-put c 'sword) (channel-put c 'shield) (channel-put c 'potion)) -@end example +@end lisp @deffn {Procedure} make-channel Return a new channel @@ -5652,7 +5652,7 @@ map implementation! The example below defines a very simple town map and finds the quickest way to get from the town common to the school. -@example +@lisp (define world-map '((town-common . (town-hall library)) (town-hall . (town-common school)) @@ -5665,7 +5665,7 @@ quickest way to get from the town common to the school. (define (distance a b) 1) (define pf (make-path-finder)) (a* pf 'town-common 'school neighbors cost distance) -@end example +@end lisp In this case, the @code{a*} procedure will return the list @code{(town-common town-hall school)}, which is indeed the shortest diff --git a/doc/chickadee.texi b/doc/chickadee.texi index a87a346..84d7a92 100644 --- a/doc/chickadee.texi +++ b/doc/chickadee.texi @@ -99,10 +99,10 @@ Chickadee depends on the following packages: One of the simplest programs we can make with Chickadee is rendering the text ``Hello, world'' on screen. Here's what that looks like: -@example +@lisp (define (draw alpha) (draw-text "Hello, world!" (vec2 64.0 240.0))) -@end example +@end lisp The @code{draw} procedure is called frequently to draw the game scene. For the sake of simplicity, we will ignore the @code{alpha} variable @@ -116,7 +116,7 @@ chickadee play hello.scm This is a good start, but it's boring. Let's make the text move! -@example +@lisp (define position (vec2 0.0 240.0)) (define (draw alpha) @@ -124,7 +124,7 @@ This is a good start, but it's boring. Let's make the text move! (define (update dt) (set-vec2-x! position (+ (vec2-x position) (* 100.0 dt)))) -@end example +@end lisp The @code{vec2} type is used to store 2D coordinates (@pxref{Vectors}.) A variable named @code{position} contains the @@ -140,7 +140,7 @@ This is neat, but after a few seconds the text moves off the screen completely, never to be seen again. It would be better if the text bounced back and forth against the sides of the window. -@example +@lisp (define position (vec2 0.0 240.0)) (define (draw alpha) @@ -159,7 +159,7 @@ bounced back and forth against the sides of the window. (while #t (tween duration start end update-x) (tween duration end start update-x)))) -@end example +@end lisp This final example uses Chickadee's scripting features (@pxref{Scripting}) to bounce the text between the edges of the window @@ -355,12 +355,12 @@ let's get back to reality. To get started with bundling, simply add a @file{bundle.scm} file to the root of the project directory. It could look something like this: -@example +@lisp '((asset-directories . ("images" "models")) (bundle-name . "the-legend-of-emacs-1.0") (code . "the-legend-of-emacs.scm") (launcher-name . "the-legend-of-emacs")) -@end example +@end lisp To create the bundle, simply run @command{chickadee bundle}. Upon success, the file @file{the-legend-of-emacs-1.0.tar.gz} would be @@ -465,7 +465,7 @@ Then, in the game loop's update procedure, call @code{poll-coop-repl-server} and pass the REPL object. Here is a template to follow: -@example +@lisp (use-modules (chickadee) (system repl coop-server)) @@ -476,7 +476,7 @@ template to follow: ...) (run-game #:update update ...) -@end example +@end lisp To use the REPL, connect to it via port 37146. Telnet will do the trick, but using the @uref{https://www.nongnu.org/geiser/, Geiser} diff --git a/guix.scm b/guix.scm index 046e7d6..076203b 100644 --- a/guix.scm +++ b/guix.scm @@ -52,6 +52,7 @@ (gnu packages readline) (gnu packages texinfo) (gnu packages guile) + (gnu packages guile-xyz) (gnu packages gl) (gnu packages sdl) (gnu packages maths) @@ -133,7 +134,7 @@ SDL2 C shared library via the foreign function interface.") (lambda _ (invoke "sh" "bootstrap")))))) (native-inputs - (list autoconf automake pkg-config texinfo)) + (list autoconf automake guile-syntax-highlight pkg-config texinfo)) (inputs (list freetype target-guile -- cgit v1.2.3