aboutsummaryrefslogtreecommitdiff
path: root/docs/api.org
diff options
context:
space:
mode:
authorGene Pasquet <dev@etenil.net>2026-04-08 00:38:55 +0100
committerGene Pasquet <dev@etenil.net>2026-04-08 00:38:55 +0100
commit0c3a700aa94a0256c5e5b1a14819f10b3d3e869b (patch)
treec1b0dc233769bea9f6a545333687539ace5b3804 /docs/api.org
parentf8cc4a748bb8b6431a1023a876745b1bb473eb19 (diff)
Support scling
Diffstat (limited to 'docs/api.org')
-rw-r--r--docs/api.org45
1 files changed, 42 insertions, 3 deletions
diff --git a/docs/api.org b/docs/api.org
index 45593e4..c418ec8 100644
--- a/docs/api.org
+++ b/docs/api.org
@@ -17,6 +17,7 @@ The engine module provides the top-level game lifecycle and state management.
(title "Downstroke Game")
(width 640)
(height 480)
+ (scale 1)
(frame-delay 16)
(input-config *default-input-config*)
(preload #f)
@@ -31,8 +32,9 @@ Creates and initializes a game object. All parameters are optional keywords.
| Parameter | Type | Default | Description |
|-----------+------+---------+-------------|
| ~title~ | string | "Downstroke Game" | Window title |
-| ~width~ | integer | 640 | Game window width in pixels |
-| ~height~ | integer | 480 | Game window height in pixels |
+| ~width~ | integer | 640 | Logical game width in pixels |
+| ~height~ | integer | 480 | Logical game height in pixels |
+| ~scale~ | positive integer | 1 | Whole-game pixel scaling factor (window = width×scale by height×scale) |
| ~frame-delay~ | integer | 16 | Delay between frames in milliseconds (30 FPS ≈ 33) |
| ~input-config~ | input-config | *default-input-config* | Keyboard/controller mappings |
| ~preload~ | procedure/false | #f | Hook: ~(lambda (game) ...)~ called once before create |
@@ -43,13 +45,50 @@ Creates and initializes a game object. All parameters are optional keywords.
The game object is the central hub. Use it to store/retrieve assets, manage scenes, and access the current input state.
+*** Scaling
+
+The ~scale:~ parameter controls integer pixel scaling for the entire game. When ~scale:~ is greater than 1, the OS window is created at ~width×scale~ by ~height×scale~ pixels, but SDL2's logical renderer size is set to ~width~ by ~height~. This means all game code (rendering, physics, coordinates) works in the logical resolution — SDL2 handles the upscaling automatically.
+
+This affects everything uniformly: tiles, sprites, text, colored rectangles, and debug overlays. Mouse/touch input coordinates are also automatically mapped back to the logical resolution.
+
+#+begin_src scheme
+;; 320×240 game rendered in a 640×480 window (2× pixel scaling)
+(make-game title: "Pixel Art Game" width: 320 height: 240 scale: 2)
+
+;; 256×224 NES-style with 3× scaling → 768×672 window
+(make-game title: "Retro Game" width: 256 height: 224 scale: 3)
+#+end_src
+
+Only positive integers are accepted; fractional or zero values signal an error.
+
+*** Fullscreen
+
+Downstroke does not provide a built-in ~fullscreen:~ keyword, but you can make any game fullscreen by setting the SDL2 window flag after the game starts. Use the ~preload:~ hook (the window exists by then):
+
+#+begin_src scheme
+(make-game
+ title: "My Game" width: 320 height: 240 scale: 2
+ preload: (lambda (game)
+ ;; 'fullscreen-desktop scales to fill the screen without changing resolution
+ (sdl2:window-fullscreen-set! (game-window game) 'fullscreen-desktop)))
+#+end_src
+
+The two fullscreen modes are:
+
+| Mode | SDL2 symbol | Behavior |
+|------+-------------+-----------|
+| Desktop fullscreen | ~'fullscreen-desktop~ | Fills the screen at the desktop resolution; SDL2 handles scaling and letterboxing. Best for most games. |
+| Exclusive fullscreen | ~'fullscreen~ | Changes the display resolution to match ~width×scale~ by ~height×scale~. Use only when you need exclusive display control. |
+
+Combine with ~scale:~ to get pixel-perfect fullscreen: set your logical resolution small (e.g. 320×240), use ~scale:~ for the default windowed size, and let ~'fullscreen-desktop~ handle the rest.
+
** ~game-run!~
#+begin_src scheme
(game-run! game)
#+end_src
-Starts the main event loop. Initializes SDL2, opens the window, and runs the frame loop indefinitely until the user quits or the ~quit~ action is pressed. Never returns.
+Starts the main event loop. Initializes SDL2, opens the window (at ~width×scale~ by ~height×scale~ pixels), sets the logical render size when ~scale~ > 1, and runs the frame loop indefinitely until the user quits or the ~quit~ action is pressed. Never returns.
Lifecycle order within each frame:
1. Collect SDL2 events