Nugget
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)
4CESTER_TEST(ncs_z_normal_white_light, gte_tests,
5 gte_set_simple_light(); // L33=0x1000
6 gte_set_white_light_color(); // LC identity
8 // Normal pointing at light: (0, 0, 0x1000)
9 cop2_put(0, 0x00000000);
10 cop2_put(1, 0x1000);
11 cop2_put(6, 0x00808080); // RGBC (not used by NCS but CODE is)
13 cop2_cmd(COP2_NCS(1, 1));
14 int32_t mac1, mac2, mac3;
16 cop2_get(25, mac1);
17 cop2_get(26, mac2);
18 cop2_get(27, mac3);
19 cop2_get(22, rgb2);
20 ramsyscall_printf("NCS z-normal: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
21 // Stage 1: L * normal = (0,0,0x1000).(0,0,0x1000) = only IR3 = 0x1000
22 // Stage 2: LC * (0,0,0x1000) + BK = (0,0,0x1000) since LC is identity, BK=0
23 // Color FIFO: MAC/16 = 0x1000/16 = 256 -> saturates to 255
27 cester_assert_uint_eq(0x00ff0000, rgb2);
28)
29
30// NCS with background color
31CESTER_TEST(ncs_with_background, gte_tests,
34 cop2_putc(13, 0x800); // RBK = 0x800
35 cop2_putc(14, 0x400); // GBK = 0x400
36 cop2_putc(15, 0x200); // BBK = 0x200
37 cop2_put(0, 0x00000000);
38 cop2_put(1, 0x1000);
39 cop2_put(6, 0x00000000);
42 int32_t mac1, mac2, mac3;
46 // Stage 1: IR = (0, 0, 0x1000)
47 // Stage 2: MAC = BK + LC*(0,0,0x1000) = (0x800+0, 0x400+0, 0x200+0x1000)
51)
52
53// NCT: normal color triple
54CESTER_TEST(nct_three_normals, gte_tests,
58 // V0 = (0, 0, 0x1000) - facing light
59 cop2_put(0, 0x00000000);
60 cop2_put(1, 0x1000);
61 // V1 = (0x1000, 0, 0) - perpendicular
62 cop2_put(2, (0 << 16) | 0x1000);
63 cop2_put(3, 0);
64 // V2 = (0, 0x1000, 0) - perpendicular
65 cop2_put(4, (0x1000 << 16) | 0);
66 cop2_put(5, 0);
67 cop2_put(6, 0x00000000);
69 cop2_cmd(COP2_NCT(1, 1));
71 cop2_get(20, rgb0);
72 cop2_get(21, rgb1);
73 cop2_get(22, rgb2);
74 ramsyscall_printf("NCT: RGB0=0x%08x RGB1=0x%08x RGB2=0x%08x\n", rgb0, rgb1, rgb2);
75 // V0 facing light: should have color
76 // V1, V2 perpendicular: should be dark (light only in Z)
77 cester_assert_uint_eq(0x00ff0000, rgb0);
78 cester_assert_uint_eq(0x00000000, rgb1);
79 cester_assert_uint_eq(0x00000000, rgb2);
80)
81
82// NCCS: normal color color single (adds vertex color multiplication)
83CESTER_TEST(nccs_basic, gte_tests,
87 cop2_put(0, 0x00000000);
88 cop2_put(1, 0x1000);
89 cop2_put(6, 0x00808080); // R=0x80, G=0x80, B=0x80
92 int32_t mac1, mac2, mac3;
94 cop2_get(25, mac1);
95 cop2_get(26, mac2);
96 cop2_get(27, mac3);
98 ramsyscall_printf("NCCS: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
99 // Stage 1: IR = (0, 0, 0x1000)
100 // Stage 2: MAC = LC*(0,0,0x1000) = (0, 0, 0x1000)
101 // Stage 3: MAC = (R<<4)*IR = (0x80<<4)*0 for R,G; (0x80<<4)*0x1000 for B... wait
102 // Actually after stage 2, IR1=0, IR2=0, IR3=0x1000
103 // Stage 3: MAC1 = (R<<4)*IR1 = 0x800*0 = 0
104 // Only B channel gets lit since only IR3 is non-zero
109)
110
111// NCCT: normal color color triple
116 cop2_put(0, 0x00000000);
117 cop2_put(1, 0x1000);
118 cop2_put(2, 0x00000000);
119 cop2_put(3, 0x1000);
120 cop2_put(4, 0x00000000);
121 cop2_put(5, 0x1000);
122 cop2_put(6, 0x00808080);
124 cop2_cmd(COP2_NCCT(1, 1));
126 cop2_get(20, rgb0);
127 cop2_get(21, rgb1);
128 cop2_get(22, rgb2);
129 ramsyscall_printf("NCCT: RGB0=0x%08x RGB1=0x%08x RGB2=0x%08x\n", rgb0, rgb1, rgb2);
130 // All three normals identical -> all three results should match
131 cester_assert_uint_eq(0x00800000, rgb0);
132 cester_assert_uint_eq(0x00800000, rgb1);
133 cester_assert_uint_eq(0x00800000, rgb2);
134)
135
136// NCDS: normal color depth single (full 3-stage pipeline + depth cue)
137CESTER_TEST(ncds_no_depth, gte_tests,
142 cop2_put(0, 0x00000000);
143 cop2_put(1, 0x1000);
144 cop2_put(6, 0x00808080);
145 cop2_put(8, 0); // IR0 = 0 (no depth cue)
148 int32_t mac1, mac2, mac3;
150 cop2_get(25, mac1);
151 cop2_get(26, mac2);
152 cop2_get(27, mac3);
153 cop2_get(22, rgb2);
154 ramsyscall_printf("NCDS no depth: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
158 cester_assert_uint_eq(0x00800000, rgb2);
159)
160
161// NCDS with depth cue
162CESTER_TEST(ncds_with_depth, gte_tests,
166 gte_set_far_color(0x1000, 0x1000, 0x1000);
167 cop2_put(0, 0x00000000);
168 cop2_put(1, 0x1000);
169 cop2_put(6, 0x00808080);
170 cop2_put(8, 0x0800); // IR0 = 0.5
172 cop2_cmd(COP2_NCDS(1, 1));
173 int32_t mac1, mac2, mac3;
175 cop2_get(25, mac1);
176 cop2_get(26, mac2);
177 cop2_get(27, mac3);
178 cop2_get(22, rgb2);
179 flag = gte_read_flag();
180 ramsyscall_printf("NCDS depth: MAC=(%d,%d,%d) RGB2=0x%08x FLAG=0x%08x\n",
181 mac1, mac2, mac3, rgb2, flag);
185 cester_assert_uint_eq(0x00c08080, rgb2);
186 cester_assert_uint_eq(0x00000000, flag);
187)
188
189// NCDT: normal color depth triple
190CESTER_TEST(ncdt_basic, gte_tests,
194 gte_set_far_color(0, 0, 0);
195 cop2_put(0, 0x00000000);
196 cop2_put(1, 0x1000);
197 cop2_put(2, 0x00000000);
198 cop2_put(3, 0x0800);
199 cop2_put(4, 0x00000000);
200 cop2_put(5, 0x0400);
201 cop2_put(6, 0x00808080);
202 cop2_put(8, 0);
208 cop2_get(22, rgb2);
209 ramsyscall_printf("NCDT: RGB0=0x%08x RGB1=0x%08x RGB2=0x%08x\n", rgb0, rgb1, rgb2);
210 // V0 has strongest light (normal = 0x1000), V2 weakest (0x400)
214)
215
216// CC: color color (light-to-color + vertex color multiply)
220 // Pre-computed light intensity in IR1-3
221 cop2_put(9, 0x1000);
222 cop2_put(10, 0x0800);
223 cop2_put(11, 0x0400);
224 cop2_put(6, 0x00808080); // RGBC
226 cop2_cmd(COP2_CC(1, 1));
227 int32_t mac1, mac2, mac3;
229 cop2_get(25, mac1);
230 cop2_get(26, mac2);
231 cop2_get(27, mac3);
232 cop2_get(22, rgb2);
233 ramsyscall_printf("CC: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
234 // Stage 1 (light to color): with white LC identity and zero BK,
235 // MAC = LC*IR = IR (identity)
236 // Stage 2 (color mult): MAC = (R<<4)*IR1 = 0x800*0x1000 = 0x800000
237 // After >>12 = 0x800, /16 = 128
241 cester_assert_uint_eq(0x00204080, rgb2);
242)
243
244// CDP: color depth cue with pre-computed light
245CESTER_TEST(cdp_basic, gte_tests,
248 gte_set_far_color(0x1000, 0x1000, 0x1000);
249 cop2_put(9, 0x1000);
250 cop2_put(10, 0x1000);
251 cop2_put(11, 0x1000);
252 cop2_put(6, 0x00808080);
253 cop2_put(8, 0); // IR0=0: no depth cue
256 int32_t mac1, mac2, mac3;
258 cop2_get(25, mac1);
259 cop2_get(26, mac2);
260 cop2_get(27, mac3);
261 cop2_get(22, rgb2);
262 ramsyscall_printf("CDP: MAC=(%d,%d,%d) RGB2=0x%08x\n", mac1, mac2, mac3, rgb2);
267)
268
269// CDP with depth cue
270CESTER_TEST(cdp_with_depth, gte_tests,
273 gte_set_far_color(0x1000, 0x1000, 0x1000);
274 cop2_put(9, 0x1000);
275 cop2_put(10, 0x1000);
276 cop2_put(11, 0x1000);
277 cop2_put(6, 0x00808080);
278 cop2_put(8, 0x0800); // IR0=0.5
280 cop2_cmd(COP2_CDP(1, 1));
281 int32_t mac1, mac2, mac3;
283 cop2_get(25, mac1);
284 cop2_get(26, mac2);
285 cop2_get(27, mac3);
286 cop2_get(22, rgb2);
287 flag = gte_read_flag();
288 ramsyscall_printf("CDP depth: MAC=(%d,%d,%d) RGB2=0x%08x FLAG=0x%08x\n",
289 mac1, mac2, mac3, rgb2, flag);
293 cester_assert_uint_eq(0x00c0c0c0, rgb2);
294 cester_assert_uint_eq(0x00000000, flag);
295)
296
297// Full lighting pipeline: light matrix with non-trivial light direction
298CESTER_TEST(ncs_full_light_matrix, gte_tests,
299 // Light from (0.707, 0, 0.707) direction - 45 degrees
300 // In 4.12 fixed: 0.707 ~ 0x0B50
301 cop2_putc(8, 0x00000b50); // L11=0x0B50, L12=0
302 cop2_putc(9, 0x00000000); // L13=0, L21=0
303 cop2_putc(10, 0x00000000); // L22=0, L23=0
304 cop2_putc(11, 0x00000000); // L31=0, L32=0
305 cop2_putc(12, 0x0b50); // L33=0x0B50
308 // Normal = (0x1000, 0, 0) - facing X
309 cop2_put(0, (0 << 16) | 0x1000);
310 cop2_put(1, 0);
311 cop2_put(6, 0x00000000);
313 cop2_cmd(COP2_NCS(1, 1));
314 int32_t mac1, mac2, mac3;
315 cop2_get(25, mac1);
316 cop2_get(26, mac2);
317 cop2_get(27, mac3);
318 ramsyscall_printf("NCS 45deg: MAC=(%d,%d,%d)\n", mac1, mac2, mac3);
319 // Stage 1: L * normal = (L11*VX, 0, L31*VX) = (0x0B50*0x1000, 0, 0)
320 // >> 12 = (0x0B50, 0, 0), so IR = (0x0B50, 0, 0)
321 // Stage 2: LC * IR = (0x0B50, 0, 0) since LC is identity, BK=0
322 // MAC1 = 0x0B50, MAC2 = 0, MAC3 = 0
326)
#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:182
#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:196
#define COP2_NCT(sf, lm)
Definition cop2.h:150
#define cop2_get(reg, dest)
Definition cop2.h:189
#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:36
uint32_t rgb1
Definition gte-lighting.c:205
int32_t mac1
Definition gte-lighting.c:42
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:31
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:42
gte_clear_flag()
int32_t mac3
Definition gte-lighting.c:42
uint32_t rgb2
Definition gte-lighting.c:93
uint32_t rgb0
Definition gte-lighting.c:205
void uint32_t(classId, spec)