1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
//! Headless render-test harness (`software_renderer` / `Platform::Memory`
//! backend).
//!
//! Tier-2 tests use this module to render frames without opening a window. The
//! `software_renderer` feature activates the rlsw memory platform, which
//! writes pixels into a CPU-side framebuffer instead of an on-screen surface.
//! Because raylib is single-init per process, a test file initialises the
//! context **once** via [`with_headless`], executes draws inside the closure,
//! then probes pixel values with [`pixel_at`] / [`assert_pixel`].
//!
//! ## Readback format
//!
//! [`render_frame`] returns a **normalised** top-left RGBA image: the harness
//! corrects the raw rlsw readback (which is BGRA bytes and Y-inverted) so
//! callers use natural draw coordinates and colours — a `Color::RED` rectangle
//! drawn at screen `(x, y)` reads back as red at `(x, y)`. Use
//! [`render_frame_raw`] if you specifically need the un-normalised BGRA +
//! Y-inverted buffer.
//!
//! ## All-modules link requirement
//!
//! The harness links all five raylib content modules:
//! `SUPPORT_MODULE_RTEXTURES`, `SUPPORT_MODULE_RSHAPES`,
//! `SUPPORT_MODULE_RTEXT`, `SUPPORT_MODULE_RMODELS`, and
//! `SUPPORT_MODULE_RAUDIO`. Omitting any of them — or omitting
//! `SUPPORT_IMAGE_GENERATION` (required on MSVC) — produces link errors.
//! The `software_renderer` feature in `raylib-sys` enables the correct set;
//! do not mix `software_renderer` with individual module-disable flags.
//!
//! # Example
//!
//! ```no_run
//! use raylib::prelude::*;
//! use raylib::test_harness::*;
//!
//! with_headless(320, 240, |rl, thread| {
//! let img = render_frame(rl, thread, |d| {
//! d.clear_background(Color::BLACK);
//! });
//! assert_pixel(&img, 0, 0, Color::BLACK, 0);
//! });
//! ```
use crateRaylibDrawHandle;
use crate*;
/// Initialise a windowless, software-rendered context of `w`×`h`, run
/// `body` with the handle and thread token, then tear down.
///
/// **Call at most once per test process.**
///
/// # Panics
///
/// Panics if raylib has already been initialised in this process; raylib is
/// single-init per process (enforced by `RaylibHandle`).
/// Draw one frame via the `draw` closure and read the software framebuffer back
/// **without normalization** — the returned [`Image`] is in raw rlsw readback
/// form: bytes are BGRA (R and B swapped vs. what was drawn) and rows are
/// Y-inverted (`y_img = (h - 1) - y_screen`). Prefer [`render_frame`] unless you
/// specifically need the raw readback; see `notes/ws4b-complete.md`.
///
/// Uses the scoped [`begin_drawing`](RaylibHandle::begin_drawing) handle so the
/// `EndDrawing` flush on drop is guaranteed to complete (flushing rlsw into the
/// memory framebuffer) before
/// [`load_image_from_screen`](RaylibHandle::load_image_from_screen) reads it.
/// Draw one frame via the `draw` closure, then read the software framebuffer
/// back as a **normalized** top-left RGBA [`Image`].
///
/// The raw rlsw readback is BGRA + Y-inverted (deterministic on every OS; see
/// `notes/ws4b-complete.md`). This function corrects both so callers use natural
/// draw coordinates and colors: a `Color::RED` rectangle reads back as red at the
/// screen `(x, y)` it was drawn at. Use [`render_frame_raw`] for the un-normalized
/// buffer.
/// Correct the rlsw readback in place: flip vertically and correct the
/// BGRA-as-RGBA byte order, yielding a true top-left RGBA image.
/// A single RGBA pixel read from a framebuffer [`Image`].
/// Read the pixel at `(x, y)` from `img` as a [`Px`].
/// Assert that pixel `(x, y)` in `img` matches `expected` within a per-channel
/// tolerance of `tol`.
///
/// Only the R, G, and B channels are compared. Alpha is intentionally ignored:
/// the Memory-platform framebuffer readback can report alpha values that don't
/// match an opaque `Color`'s `a`, which would make probes fail spuriously.
///
/// Panics with a descriptive message showing the actual vs expected pixel and
/// position on failure.