Nugget
Bare-metal libraries and examples for the original PlayStation
Loading...
Searching...
No Matches
gte-nclip.c
Go to the documentation of this file.
1// NCLIP: normal clipping (screen-space triangle winding / area)
2// MAC0 = SX0*(SY1-SY2) + SX1*(SY2-SY0) + SX2*(SY0-SY1)
3
4// clang-format off
5
6CESTER_TEST(nclip_ccw, gte_tests,
7 cop2_put(12, 0x00000000); // (0,0)
8 cop2_put(13, 0x00000064); // (100,0)
9 cop2_put(14, 0x00640000); // (0,100)
12 int32_t mac0;
13 cop2_get(24, mac0);
15 cester_assert_uint_eq(0, gte_read_flag());
16)
17
18CESTER_TEST(nclip_cw, gte_tests,
19 cop2_put(12, 0x00000000);
20 cop2_put(13, 0x00640000); // (0,100)
21 cop2_put(14, 0x00000064); // (100,0)
24 int32_t mac0;
25 cop2_get(24, mac0);
27)
28
29CESTER_TEST(nclip_collinear, gte_tests,
30 cop2_put(12, 0x00000000);
31 cop2_put(13, 0x00320032); // (50,50)
32 cop2_put(14, 0x00640064); // (100,100)
35 int32_t mac0;
36 cop2_get(24, mac0);
38)
39
40// NCLIP with large screen coords near saturation limits
41CESTER_TEST(nclip_large_coords, gte_tests,
42 // SXY values near the screen coord limits (-0x400..0x3FF)
43 cop2_put(12, (0xfc00 << 16) | 0x03ff); // (0x3FF, -0x400)
44 cop2_put(13, (0x03ff << 16) | 0xfc00); // (-0x400, 0x3FF)
45 cop2_put(14, 0x00000000); // (0, 0)
48 int32_t mac0;
49 uint32_t flag;
50 cop2_get(24, mac0);
51 flag = gte_read_flag();
52 // (0x3FF * 0x3FF) + (-0x400 * 0) + (0 * (-0x400))
53 // - (0x3FF * 0) - (-0x400 * (-0x400)) - (0 * 0x3FF)
54 // = 0x3FF*0x3FF - 0x400*0x400 = 1046529 - 1048576 = -2047
55 // Actually: SX0=0x3FF, SY0=-0x400, SX1=-0x400, SY1=0x3FF, SX2=0, SY2=0
56 // MAC0 = SX0*(SY1-SY2) + SX1*(SY2-SY0) + SX2*(SY0-SY1)
57 // = 0x3FF*(0x3FF-0) + (-0x400)*(0-(-0x400)) + 0*((-0x400)-0x3FF)
58 // = 0x3FF*0x3FF + (-0x400)*0x400
59 // = 1046529 - 1048576 = -2047
60 ramsyscall_printf("NCLIP large: MAC0=%d FLAG=0x%08x\n", mac0, flag);
63)
64
65// NCLIP MAC0 overflow: maximum possible cross product
66CESTER_TEST(nclip_overflow, gte_tests,
67 // Use values that produce MAC0 > 0x7FFFFFFF
68 // Max SX/SY after saturation is -0x400..0x3FF (11-bit signed)
69 // Max cross product: 0x3FF*0x3FF*2 + 0x400*0x400*2 ~ 4 million, no overflow
70 // Need unsaturated values: SXY registers are 16-bit signed
71 cop2_put(12, (0x7fff << 16) | 0x7fff); // (32767, 32767)
72 cop2_put(13, (0x8000 << 16) | 0x8000); // (-32768, -32768)
73 cop2_put(14, (0x7fff << 16) | 0x8000); // (-32768, 32767)
76 int32_t mac0;
77 uint32_t flag;
78 cop2_get(24, mac0);
79 flag = gte_read_flag();
80 ramsyscall_printf("NCLIP overflow: MAC0=%d FLAG=0x%08x\n", mac0, flag);
81 // Check if FLAG.16 or FLAG.15 (MAC0 overflow) is set
82 ramsyscall_printf(" FLAG.16=%u FLAG.15=%u\n", (flag >> 16) & 1, (flag >> 15) & 1);
84 uint32_t f15 = (flag >> 15) & 1;
86)
CESTER_TEST(cddaLevelHalf, test_instances, static const uint8_t atv[4]={0x40, 0x00, 0x40, 0x00};unsigned changes=0;int peak=cddaPeak(atv, 1, &changes);ramsyscall_printf("CD-DA level at half ATV: peak %i, %u sign changes\n", peak, changes);cester_assert_int_ge(peak, 11300);cester_assert_int_le(peak, 11800);cester_assert_uint_ge(changes, 4);) CESTER_TEST(cddaLevelClipped
cester_assert_uint_eq(5, cause1)
ramsyscall_printf("T21 phase=%s t=%u v=%02x cause=%u size=%u stat=%02x\n", phase, t/1000, response[0], cause, size,(nopCause==3 &&nopSize >=1) ? stat[0] :0xff)
#define cop2_cmd(op)
Definition cop2.h:175
#define cop2_put(reg, val)
Definition cop2.h:191
#define COP2_NCLIP
Definition cop2.h:133
#define cop2_get(reg, dest)
Definition cop2.h:198
gte_tests
Definition gte-depthcue.c:31
gte_clear_flag()
uint32_t flag
Definition gte-edgecase.c:38
int32_t mac0
Definition gte-edgecase.c:151
cester_assert_int_eq(3, xaCommand(CDL_SETMODE, &mode, 1, NULL, NULL))