diff options
Diffstat (limited to 'docs/chapter31/README.md')
| -rw-r--r-- | docs/chapter31/README.md | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/docs/chapter31/README.md b/docs/chapter31/README.md new file mode 100644 index 00000000..f689944f --- /dev/null +++ b/docs/chapter31/README.md @@ -0,0 +1,185 @@ +# Chapter 31: Software Drawing, Time, and Graphical Games + +[Previous: Chapter 30 — Text Formatting and Diagnostics](../chapter30/README.md) + +In this chapter we use small graphical games to drive the language and library +work. We add graphics, sound, and time support, with a few small C adapters +for native services. We also add array initializers and read-only arrays, hex, +octal parsing, move constant arrays into the ELF constant pool. We then write +a few games, with the drawing and game logic written in Simple. + + +## Games and demos + +[Clock](examples/Clock.smp) is a classic clock demo. It shows local time as +digital digits or an analog dial. Click its button or press Space to switch +views. It combines timers, mouse input, text, and drawing in one event loop. + +[Graphical Tic-tac-toe](examples/TicTacToeGraphical.smp) accepts mouse +clicks or keys 1 through 9. It highlights the winning line and plays move and +result sounds. Game logic is the same as in the terminal version from +the prior chapter, with the graphics added to the event loop. + +[Breakout](examples/Breakout.smp) has a ball, a paddle, and a wall of +bricks. Move the paddle with the arrow keys or mouse. The ball's bounce angle +depends on where it hits the paddle. Deeper bricks score more points, make +higher-pitched sounds, and increase the ball's speed. Hitting the *back* of a +brick gives a one-time larger speed boost. Clear all the bricks before using +up three balls. + + +## Graphics and sound + +Graphics and sound are optional. The Simple language and compiler do not need +them. The `sys` library includes bindings to the native C backends, but you do +not need those backends for programs without a display or sound. Their +dependencies download with the existing `make init` setup command. + +Each pixel holds 24 bits of RGB color in a `u32`. A pixel buffer is a `u32[]`. + +[`sys.draw.Canvas`](../../src/main/smp/sys/draw/Canvas.smp) draws pixels, rectangles, +circles, thick lines, and text into a `u32[]` pixel buffer. Shapes clip to the +canvas. The 3x5 font includes digits, letters, and punctuation such as colons +and slashes. Its glyphs are stored in a read-only array. + +`sys.draw` supplies a few color constants plus `rgb(r,g,b)` to clamp and pack +computed color components. + +`sys.draw.Button` handles button hover, press, release, and disabled states. + +`sys.gfx` opens a window, presents pixels, and reads keyboard and mouse input. +The window backend uses MiniFB. `gfx.wait(timeout_ms)` waits for input or a +timeout, so animation need not spin continuously. + +`sys.audio` plays built-in cues or sample arrays generated in Simple. Its +optional miniaudio backend plays sound while the game continues. The games +can run silently when audio is unavailable. + +See [drawing](drawing.md), [windows](graphics.md), and +[audio](audio.md) for the APIs. + + +## Time library + +[`sys.time`](../../src/main/smp/sys/time.smp) provides wall-clock time, monotonic +time, sleep, calendar conversion, ISO date parsing, and formatting. Use +wall-clock time for dates. Use monotonic time for elapsed time and deadlines - +perfect for games. + +Instants and durations normally use `i64` milliseconds. Constants show their +units directly: `SECOND=1000`, `MINUTE=60*SECOND`, and `HOUR=60*MINUTE`. + +`sys.time.Timers` supports one-shot and repeating timers. The event loop polls +for due timer IDs; no timer thread or callback is needed. This might be a mindset +change for you game writers, it depends on what era you started writing them. +Here it is all single-threaded and event-loop driven - but when there is nothing +left to do, you need to wait for an event. + +Time also works in string interpolation: + +```simple +sys.io.p("UTC %tT(sys.time.now())\n"); +``` + +Millisecond parameters and fields end in `_ms` to distinguish them from other +integers. + +See [time and timers](time.md) for local-time formatting and other forms. + + +## Array initializers + +An array can use a list of values or an expression evaluated for each index: + +```simple +val primes = new int[]{2,3,5,7}; +val squares = new int[10]{int i -> i*i;}; +val names = new u8[~][~2]{"Alice","Bob"}; +``` + +The generator runs once per element, from index zero through length minus one. +Its body can contain statements and return the element value. It can read +surrounding locals but cannot reassign them; it is not a true function. + +If the array has a fixed initialization list, then the length can be inferred. + + +`[~n]` (or `[~]` with a list) makes an array read-only. `val` prevents +reassignment of the array variable, but not changes to its contents. In C, +this is the classic `const u8* const` distinction: the first `const` protects +the contents; the second protects the pointer. Array initialization normally +runs at runtime; read-only does not require compile-time evaluation. + +When the compiler knows a read-only integer array's complete contents, it can +emit them as static ELF data. Identical constant arrays can share storage, +just like strings. Canvas's font now uses this path instead of allocating +and filling its table at startup. The trigger is a `TypeConAry` constant type, +regardless of which node computes it. Constant lists are the first new +producer; generators still run at runtime. + +Initializers also allow arrays of non-null references: every element is +supplied before the array becomes accessible. In the example, `names` is a +read-only array of two non-null, read-only strings. + + +## Math support and intrinsics + +[`sys.math`](../../src/main/smp/sys/math.smp) provides the `PI` and `E` constants, +plus two operations: + +```simple +i64 bits = sys.math.f64Bits(1.0); // 0x3ff0000000000000 +f64 value = sys.math.f64FromBits(bits); // 1.0 +``` + +They *reinterpret* the same 64 bits, preserving signed zero and NaN payloads. +Ordinary assignments between integer and floating-point types still perform +numeric conversion. + +These functions introduce compiler intrinsics: C functions with fixed meanings +that the compiler recognizes and replaces with internal operations. For the +bit-reinterpretation operations, Simple uses plain register moves. Calls whose +targets remain unknown at compile time use the C implementations. Recognition +and expansion live in `Intrinsic.java`. + +See [the intrinsic contract](intrinsics.md) for the implemented behavior. + +Simple also now recognizes hexadecimal (`0xff0000`) and leading-zero octal +(`025755`) integer literals. + + +## Compiler fixes + +- Syntax errors raised through JUnit now show the source line and error pointer. + Actual compiler failures still report Java stack traces. +- Integer memory operations on x86 use the correct register class. This fixes + the instruction-encoding failure exposed by Dijkstra. +- Floating-point comparisons handle NaNs correctly in branches and Boolean + results. Floating-point negation also handles signed zero correctly. +- Array-initializer memory tracking no longer adds an unrelated function to + the returned result. Loop-load optimization checks that the pointer is + available before moving a load. +- Imported read-only primitive arrays retain their types. Object files can + represent more than 255 distinct memory regions. +- Floating-point constants and register copies preserve raw NaN bits. + +## Build and run + +From the `chapter31` directory: + +```sh +make libs CTAGS= # Download dependencies once. +make run-graphical-tictactoe CTAGS= +make run-clock CTAGS= +make run-breakout CTAGS= +``` + +Dependencies stay cached across `make clean`. The run targets build the needed +window and audio backends. Use `graphical-tictactoe`, `clock-example`, or +`breakout` to build an executable without opening a window. + +Run the ordinary tests without a display or audio device: + +```sh +make tests_nographics CTAGS= +``` |
