Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
gte-lighting.c
Go to the documentation of this file.
1// Lighting instructions: NCS, NCT, NCCS, NCCT, NCDS, NCDT, CC, CDP
2
3// NCS: normal color single (2-stage: normal->light, light->color)
4// clang-format off
5
6CESTER_TEST(ncs_z_normal_white_light, gte_tests,
7 gte_set_simple_light(); // L33=0x1000
8 gte_set_white_light_color(); // LC identity
10 // Normal pointing at light: (0, 0, 0x1000)
11 cop2_put(0, 0x00000000);
12 cop2_put(1, 0x1000);
13 cop2_put(6, 0x00808080); // RGBC (not used by NCS but CODE is)
15 cop2_cmd(COP2_NCS(1, 1));
16 int32_t mac1, mac2, mac3;
17 uint32_t rgb2;
18 cop2_get(25, mac1);
19 cop2_get(26, mac2);
20 cop2_get(27, mac3);
21 cop2_get(22, rgb2);
22 ramsyscall_printf("NCS z-normal: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
23 // Stage 1: L * normal = (0,0,0x1000).(0,0,0x1000) = only IR3 = 0x1000
24 // Stage 2: LC * (0,0,0x1000) + BK = (0,0,0x1000) since LC is identity, BK=0
25 // Color FIFO: MAC/16 = 0x1000/16 = 256 -> saturates to 255
29 cester_assert_uint_eq(0x00ff0000, rgb2);
30)
31
32// NCS with background color
33CESTER_TEST(ncs_with_background, gte_tests,
36 cop2_putc(13, 0x800); // RBK = 0x800
37 cop2_putc(14, 0x400); // GBK = 0x400
38 cop2_putc(15, 0x200); // BBK = 0x200
39 cop2_put(0, 0x00000000);
40 cop2_put(1, 0x1000);
41 cop2_put(6, 0x00000000);
44 int32_t mac1, mac2, mac3;
48 // Stage 1: IR = (0, 0, 0x1000)
49 // Stage 2: MAC = BK + LC*(0,0,0x1000) = (0x800+0, 0x400+0, 0x200+0x1000)
53)
54
55// NCT: normal color triple
56CESTER_TEST(nct_three_normals, gte_tests,
60 // V0 = (0, 0, 0x1000) - facing light
61 cop2_put(0, 0x00000000);
62 cop2_put(1, 0x1000);
63 // V1 = (0x1000, 0, 0) - perpendicular
64 cop2_put(2, (0 << 16) | 0x1000);
65 cop2_put(3, 0);
66 // V2 = (0, 0x1000, 0) - perpendicular
67 cop2_put(4, (0x1000 << 16) | 0);
68 cop2_put(5, 0);
69 cop2_put(6, 0x00000000);
71 cop2_cmd(COP2_NCT(1, 1));
72 uint32_t rgb0, rgb1, rgb2;
73 cop2_get(20, rgb0);
74 cop2_get(21, rgb1);
75 cop2_get(22, rgb2);
76 ramsyscall_printf("NCT: RGB0=0x%08x RGB1=0x%08x RGB2=0x%08x\n", rgb0, rgb1, rgb2);
77 // V0 facing light: should have color
78 // V1, V2 perpendicular: should be dark (light only in Z)
79 cester_assert_uint_eq(0x00ff0000, rgb0);
80 cester_assert_uint_eq(0x00000000, rgb1);
81 cester_assert_uint_eq(0x00000000, rgb2);
82)
83
84// NCCS: normal color color single (adds vertex color multiplication)
85CESTER_TEST(nccs_basic, gte_tests,
89 cop2_put(0, 0x00000000);
90 cop2_put(1, 0x1000);
91 cop2_put(6, 0x00808080); // R=0x80, G=0x80, B=0x80
94 int32_t mac1, mac2, mac3;
95 uint32_t rgb2;
96 cop2_get(25, mac1);
97 cop2_get(26, mac2);
98 cop2_get(27, mac3);
100 ramsyscall_printf("NCCS: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
101 // Stage 1: IR = (0, 0, 0x1000)
102 // Stage 2: MAC = LC*(0,0,0x1000) = (0, 0, 0x1000)
103 // Stage 3: MAC = (R<<4)*IR = (0x80<<4)*0 for R,G; (0x80<<4)*0x1000 for B... wait
104 // Actually after stage 2, IR1=0, IR2=0, IR3=0x1000
105 // Stage 3: MAC1 = (R<<4)*IR1 = 0x800*0 = 0
106 // Only B channel gets lit since only IR3 is non-zero
111)
112
113// NCCT: normal color color triple
118 cop2_put(0, 0x00000000);
119 cop2_put(1, 0x1000);
120 cop2_put(2, 0x00000000);
121 cop2_put(3, 0x1000);
122 cop2_put(4, 0x00000000);
123 cop2_put(5, 0x1000);
124 cop2_put(6, 0x00808080);
126 cop2_cmd(COP2_NCCT(1, 1));
127 uint32_t rgb0, rgb1, rgb2;
128 cop2_get(20, rgb0);
129 cop2_get(21, rgb1);
130 cop2_get(22, rgb2);
131 ramsyscall_printf("NCCT: RGB0=0x%08x RGB1=0x%08x RGB2=0x%08x\n", rgb0, rgb1, rgb2);
132 // All three normals identical -> all three results should match
133 cester_assert_uint_eq(0x00800000, rgb0);
134 cester_assert_uint_eq(0x00800000, rgb1);
135 cester_assert_uint_eq(0x00800000, rgb2);
136)
137
138// NCDS: normal color depth single (full 3-stage pipeline + depth cue)
139CESTER_TEST(ncds_no_depth, gte_tests,
144 cop2_put(0, 0x00000000);
145 cop2_put(1, 0x1000);
146 cop2_put(6, 0x00808080);
147 cop2_put(8, 0); // IR0 = 0 (no depth cue)
150 int32_t mac1, mac2, mac3;
151 uint32_t rgb2;
152 cop2_get(25, mac1);
153 cop2_get(26, mac2);
154 cop2_get(27, mac3);
155 cop2_get(22, rgb2);
156 ramsyscall_printf("NCDS no depth: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
160 cester_assert_uint_eq(0x00800000, rgb2);
161)
162
163// NCDS with depth cue
164CESTER_TEST(ncds_with_depth, gte_tests,
168 gte_set_far_color(0x1000, 0x1000, 0x1000);
169 cop2_put(0, 0x00000000);
170 cop2_put(1, 0x1000);
171 cop2_put(6, 0x00808080);
172 cop2_put(8, 0x0800); // IR0 = 0.5
174 cop2_cmd(COP2_NCDS(1, 1));
175 int32_t mac1, mac2, mac3;
176 uint32_t rgb2, flag;
177 cop2_get(25, mac1);
178 cop2_get(26, mac2);
179 cop2_get(27, mac3);
180 cop2_get(22, rgb2);
181 flag = gte_read_flag();
182 ramsyscall_printf("NCDS depth: MAC=(%d,%d,%d) RGB2=0x%08x FLAG=0x%08x\n",
183 mac1, mac2, mac3, rgb2, flag);
187 cester_assert_uint_eq(0x00c08080, rgb2);
188 cester_assert_uint_eq(0x00000000, flag);
189)
190
191// NCDT: normal color depth triple
192CESTER_TEST(ncdt_basic, gte_tests,
196 gte_set_far_color(0, 0, 0);
197 cop2_put(0, 0x00000000);
198 cop2_put(1, 0x1000);
199 cop2_put(2, 0x00000000);
200 cop2_put(3, 0x0800);
201 cop2_put(4, 0x00000000);
202 cop2_put(5, 0x0400);
203 cop2_put(6, 0x00808080);
204 cop2_put(8, 0);
207 uint32_t rgb0, rgb1, rgb2;
210 cop2_get(22, rgb2);
211 ramsyscall_printf("NCDT: RGB0=0x%08x RGB1=0x%08x RGB2=0x%08x\n", rgb0, rgb1, rgb2);
212 // V0 has strongest light (normal = 0x1000), V2 weakest (0x400)
216)
217
218// CC: color color (light-to-color + vertex color multiply)
222 // Pre-computed light intensity in IR1-3
223 cop2_put(9, 0x1000);
224 cop2_put(10, 0x0800);
225 cop2_put(11, 0x0400);
226 cop2_put(6, 0x00808080); // RGBC
228 cop2_cmd(COP2_CC(1, 1));
229 int32_t mac1, mac2, mac3;
230 uint32_t rgb2;
231 cop2_get(25, mac1);
232 cop2_get(26, mac2);
233 cop2_get(27, mac3);
234 cop2_get(22, rgb2);
235 ramsyscall_printf("CC: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
236 // Stage 1 (light to color): with white LC identity and zero BK,
237 // MAC = LC*IR = IR (identity)
238 // Stage 2 (color mult): MAC = (R<<4)*IR1 = 0x800*0x1000 = 0x800000
239 // After >>12 = 0x800, /16 = 128
243 cester_assert_uint_eq(0x00204080, rgb2);
244)
245
246// CDP: color depth cue with pre-computed light
247CESTER_TEST(cdp_basic, gte_tests,
250 gte_set_far_color(0x1000, 0x1000, 0x1000);
251 cop2_put(9, 0x1000);
252 cop2_put(10, 0x1000);
253 cop2_put(11, 0x1000);
254 cop2_put(6, 0x00808080);
255 cop2_put(8, 0); // IR0=0: no depth cue
258 int32_t mac1, mac2, mac3;
259 uint32_t rgb2;
260 cop2_get(25, mac1);
261 cop2_get(26, mac2);
262 cop2_get(27, mac3);
263 cop2_get(22, rgb2);
264 ramsyscall_printf("CDP: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
269)
270
271// CDP with depth cue
272CESTER_TEST(cdp_with_depth, gte_tests,
275 gte_set_far_color(0x1000, 0x1000, 0x1000);
276 cop2_put(9, 0x1000);
277 cop2_put(10, 0x1000);
278 cop2_put(11, 0x1000);
279 cop2_put(6, 0x00808080);
280 cop2_put(8, 0x0800); // IR0=0.5
282 cop2_cmd(COP2_CDP(1, 1));
283 int32_t mac1, mac2, mac3;
284 uint32_t rgb2, flag;
285 cop2_get(25, mac1);
286 cop2_get(26, mac2);
287 cop2_get(27, mac3);
288 cop2_get(22, rgb2);
289 flag = gte_read_flag();
290 ramsyscall_printf("CDP depth: MAC=(%d,%d,%d) RGB2=0x%08x FLAG=0x%08x\n",
291 mac1, mac2, mac3, rgb2, flag);
295 cester_assert_uint_eq(0x00c0c0c0, rgb2);
296 cester_assert_uint_eq(0x00000000, flag);
297)
298
299// Full lighting pipeline: light matrix with non-trivial light direction
300CESTER_TEST(ncs_full_light_matrix, gte_tests,
301 // Light from (0.707, 0, 0.707) direction - 45 degrees
302 // In 4.12 fixed: 0.707 ~ 0x0B50
303 cop2_putc(8, 0x00000b50); // L11=0x0B50, L12=0
304 cop2_putc(9, 0x00000000); // L13=0, L21=0
305 cop2_putc(10, 0x00000000); // L22=0, L23=0
306 cop2_putc(11, 0x00000000); // L31=0, L32=0
307 cop2_putc(12, 0x0b50); // L33=0x0B50
310 // Normal = (0x1000, 0, 0) - facing X
311 cop2_put(0, (0 << 16) | 0x1000);
312 cop2_put(1, 0);
313 cop2_put(6, 0x00000000);
315 cop2_cmd(COP2_NCS(1, 1));
316 int32_t mac1, mac2, mac3;
317 cop2_get(25, mac1);
318 cop2_get(26, mac2);
319 cop2_get(27, mac3);
320 ramsyscall_printf("NCS 45deg: MAC=(%d,%d,%d)\n", mac1, mac2, mac3);
321 // Stage 1: L * normal = (L11*VX, 0, L31*VX) = (0x0B50*0x1000, 0, 0)
322 // >> 12 = (0x0B50, 0, 0), so IR = (0x0B50, 0, 0)
323 // Stage 2: LC * IR = (0x0B50, 0, 0) since LC is identity, BK=0
324 // MAC1 = 0x0B50, MAC2 = 0, MAC3 = 0
328)
#define cop2_cmd(op)
Definition cop2.h:175
#define COP2_NCS(sf, lm)
Definition cop2.h:149
#define COP2_NCCS(sf, lm)
Definition cop2.h:151
#define cop2_put(reg, val)
Definition cop2.h:191
#define COP2_NCDS(sf, lm)
Definition cop2.h:153
#define COP2_NCCT(sf, lm)
Definition cop2.h:152
#define COP2_CDP(sf, lm)
Definition cop2.h:158
#define cop2_putc(reg, val)
Definition cop2.h:205
#define COP2_NCT(sf, lm)
Definition cop2.h:150
#define cop2_get(reg, dest)
Definition cop2.h:198
#define COP2_CC(sf, lm)
Definition cop2.h:157
#define COP2_NCDT(sf, lm)
Definition cop2.h:154
uint32_t flag
Definition gte-edgecase.c:38
uint32_t rgb1
Definition gte-lighting.c:207
int32_t mac1
Definition gte-lighting.c:44
gte_set_zero_bk()
ramsyscall_printf("NCCS: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2)
cester_assert_int_eq(0x800, mac1)
gte_set_far_color(0, 0, 0)
gte_set_white_light_color()
gte_set_simple_light()
gte_tests
Definition gte-lighting.c:33
CESTER_TEST(ncs_z_normal_white_light, gte_tests, gte_set_simple_light();gte_set_white_light_color();gte_set_zero_bk();cop2_put(0, 0x00000000);cop2_put(1, 0x1000);cop2_put(6, 0x00808080);gte_clear_flag();cop2_cmd(COP2_NCS(1, 1));int32_t mac1, mac2, mac3;uint32_t rgb2;cop2_get(25, mac1);cop2_get(26, mac2);cop2_get(27, mac3);cop2_get(22, rgb2);ramsyscall_printf("NCS z-normal: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);cester_assert_int_eq(0, mac1);cester_assert_int_eq(0, mac2);cester_assert_int_eq(4096, mac3);cester_assert_uint_eq(0x00ff0000, rgb2);) CESTER_TEST(ncs_with_background
cester_assert_uint_eq(0x00800000, rgb2)
int32_t mac2
Definition gte-lighting.c:44
gte_clear_flag()
int32_t mac3
Definition gte-lighting.c:44
uint32_t rgb2
Definition gte-lighting.c:95
uint32_t rgb0
Definition gte-lighting.c:207