aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/api.org45
-rw-r--r--docs/guide.org27
2 files changed, 69 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
diff --git a/docs/guide.org b/docs/guide.org
index 380f04b..1c5a8f3 100644
--- a/docs/guide.org
+++ b/docs/guide.org
@@ -216,6 +216,32 @@ See =demo/platformer.scm= in the engine source for a complete working example.
* Development Tips
+** Pixel Scaling
+
+Retro-style games often use a small logical resolution (e.g. 320×240) but need a larger window so players can actually see things. Use ~scale:~ to scale everything uniformly:
+
+#+begin_src scheme
+(make-game title: "Pixel Art" width: 320 height: 240 scale: 2)
+;; Creates a 640×480 window; all coordinates remain in 320×240 space
+#+end_src
+
+This is integer-only scaling. All rendering — tiles, sprites, text, debug overlays — is scaled automatically by SDL2. Game logic and coordinates are unaffected.
+
+See =demo/scaling.scm= for a complete example.
+
+** Fullscreen
+
+Use SDL2 window flags in the ~preload:~ hook to go fullscreen:
+
+#+begin_src scheme
+(make-game
+ title: "Fullscreen Game" width: 320 height: 240 scale: 2
+ preload: (lambda (game)
+ (sdl2:window-fullscreen-set! (game-window game) 'fullscreen-desktop)))
+#+end_src
+
+~'fullscreen-desktop~ fills the screen without changing display resolution; SDL2 handles letterboxing and scaling. ~'fullscreen~ uses exclusive fullscreen at the window size.
+
** Debug Mode
During development, enable ~debug?: #t~ on ~make-game~ to visualize collision boxes and the tile grid. This helps you understand what the physics engine "sees" and debug collision problems:
@@ -252,6 +278,7 @@ Downstroke includes several demo games that showcase different features:
| Sprite Font | =demo/spritefont.scm= | Bitmap text rendering using non-contiguous tileset ranges |
| Menu | =demo/menu.scm= | State machine menus, keyboard navigation, TTF text rendering |
| Tweens | =demo/tweens.scm= | Easing curves, =tween-step=, =#:skip-pipelines= with tile collision |
+| Scaling | =demo/scaling.scm= | Integer pixel scaling with =scale: 2=, 2× upscaled rendering |
Each demo is self-contained and serves as a working reference for a particular game mechanic.