@@ -45,12 +45,12 @@ enum CycleType
45
45
46
46
struct Tile
47
47
{
48
- uint16_t sBase ;
48
+ uint16_t s1, s2 ;
49
49
uint16_t sMask ;
50
50
bool sMirror ;
51
51
bool sClamp ;
52
52
53
- uint16_t tBase ;
53
+ uint16_t t1, t2 ;
54
54
uint16_t tMask;
55
55
bool tMirror;
56
56
bool tClamp;
@@ -365,8 +365,8 @@ inline uint32_t RDP::colorToAlpha(uint32_t color)
365
365
uint32_t RDP::getTexel (Tile &tile, int s, int t, bool rect)
366
366
{
367
367
// Offset the texture coordinates relative to the tile
368
- s -= tile.sBase ;
369
- t -= tile.tBase ;
368
+ s -= tile.s1 ;
369
+ t -= tile.t1 ;
370
370
371
371
// Fall back to nearest sampling, or filter based on https://www.shadertoy.com/view/Ws2fWV
372
372
if (!Settings::texFilter || !texFilter || cycleType >= COPY_MODE)
@@ -407,20 +407,14 @@ uint32_t RDP::getTexel(Tile &tile, int s, int t, bool rect)
407
407
uint32_t RDP::getRawTexel (Tile &tile, int s, int t)
408
408
{
409
409
// Clamp, mirror, or mask the S-coordinate based on tile settings
410
- if (tile.sClamp )
411
- s = std::max<int >(std::min<int >(s, tile.sMask ), 0 );
412
- else if (tile.sMirror )
413
- s = ((s & (tile.sMask + 1 )) ? ~s : s) & tile.sMask ;
414
- else
415
- s &= tile.sMask ;
410
+ if (tile.sClamp ) s = std::max<int >(std::min<int >(s, (tile.s2 - tile.s1 ) >> 5 ), 0 );
411
+ if (tile.sMirror && (s & (tile.sMask + 1 ))) s = ~s;
412
+ s &= tile.sMask ;
416
413
417
414
// Clamp, mirror, or mask the T-coordinate based on tile settings
418
- if (tile.tClamp )
419
- t = std::max<int >(std::min<int >(t, tile.tMask ), 0 );
420
- else if (tile.tMirror )
421
- t = ((t & (tile.tMask + 1 )) ? ~t : t) & tile.tMask ;
422
- else
423
- t &= tile.tMask ;
415
+ if (tile.tClamp ) t = std::max<int >(std::min<int >(t, (tile.t2 - tile.t1 ) >> 5 ), 0 );
416
+ if (tile.tMirror && (t & (tile.tMask + 1 ))) t = ~t;
417
+ t &= tile.tMask ;
424
418
425
419
// Get an RGBA32 texel from a tile at the given coordinates
426
420
switch (tile.format )
@@ -1438,40 +1432,48 @@ void RDP::setOtherModes()
1438
1432
1439
1433
void RDP::loadTlut ()
1440
1434
{
1441
- // Decode the operands
1435
+ // Decode the operands and set texture coordinate bounds
1442
1436
Tile &tile = tiles[(opcode[0 ] >> 24 ) & 0x7 ];
1443
- uint16_t indexL = ((opcode[0 ] >> 44 ) & 0xFFF ) >> 1 ;
1444
- uint16_t indexH = ((opcode[0 ] >> 12 ) & 0xFFF ) >> 1 ;
1445
-
1446
- // Copy 16-bit texture lookup values into TMEM
1447
- for (int i = indexL; i <= indexH; i += 2 )
1437
+ uint16_t s1 = (tile.s1 = ((opcode[0 ] >> 44 ) & 0xFFF ) << 3 ) >> 4 ;
1438
+ uint16_t t1 = (tile.t1 = ((opcode[0 ] >> 32 ) & 0xFFF ) << 3 ) >> 4 ;
1439
+ uint16_t s2 = (tile.s2 = ((opcode[0 ] >> 12 ) & 0xFFF ) << 3 ) >> 4 ;
1440
+ uint16_t t2 = (tile.t2 = ((opcode[0 ] >> 0 ) & 0xFFF ) << 3 ) >> 4 ;
1441
+
1442
+ // Copy 16-bit texture lookup values into TMEM, duplicated 4 times
1443
+ // TODO: actually use T-coordinates?
1444
+ for (int s = s1; s <= s2; s += 2 )
1448
1445
{
1449
- uint16_t src = Memory::read <uint16_t >(texAddress + i);
1450
- uint8_t *dst = &tmem[(tile.address + i * 4 ) & 0xFF8 ];
1451
- dst[0 ] = src >> 8 ;
1452
- dst[1 ] = src >> 0 ;
1446
+ uint16_t src = Memory::read <uint16_t >(texAddress + s);
1447
+ uint8_t *dst = &tmem[(tile.address + s * 4 ) & 0xFF8 ];
1448
+ for (int i = 0 ; i < 8 ; i += 2 )
1449
+ {
1450
+ dst[i + 0 ] = src >> 8 ;
1451
+ dst[i + 1 ] = src >> 0 ;
1452
+ }
1453
1453
}
1454
1454
}
1455
1455
1456
1456
void RDP::setTileSize ()
1457
1457
{
1458
- // Set the low texture coordinates for reference
1459
- // TODO: use the high coordinates for something?
1458
+ // Set the texture coordinate bounds
1460
1459
Tile &tile = tiles[(opcode[0 ] >> 24 ) & 0x7 ];
1461
- tile.sBase = ((opcode[0 ] >> 44 ) & 0xFFF ) << 3 ;
1462
- tile.tBase = ((opcode[0 ] >> 32 ) & 0xFFF ) << 3 ;
1460
+ tile.s1 = ((opcode[0 ] >> 44 ) & 0xFFF ) << 3 ;
1461
+ tile.t1 = ((opcode[0 ] >> 32 ) & 0xFFF ) << 3 ;
1462
+ tile.s2 = ((opcode[0 ] >> 12 ) & 0xFFF ) << 3 ;
1463
+ tile.t2 = ((opcode[0 ] >> 0 ) & 0xFFF ) << 3 ;
1463
1464
}
1464
1465
1465
1466
void RDP::loadBlock ()
1466
1467
{
1467
- // Decode the operands
1468
+ // Decode the operands and set texture coordinate bounds
1468
1469
Tile &tile = tiles[(opcode[0 ] >> 24 ) & 0x7 ];
1469
- uint16_t count = ((opcode[0 ] >> 12 ) & 0xFFF );
1470
- uint16_t dxt = (opcode[0 ] & 0xFFF );
1471
-
1472
- // Adjust the byte count based on the texel size
1473
- count = (count << 2 ) >> (~texFormat & 0x3 );
1470
+ uint16_t s1 = (tile.s1 = ((opcode[0 ] >> 44 ) & 0xFFF ) << 3 ) >> 1 ;
1471
+ uint16_t t1 = (tile.t1 = ((opcode[0 ] >> 32 ) & 0xFFF ) << 3 ) >> 1 ;
1472
+ uint16_t s2 = (tile.s2 = ((opcode[0 ] >> 12 ) & 0xFFF ) << 3 ) >> 1 ;
1473
+ uint16_t dxt = (tile.t2 = ((opcode[0 ] >> 0 ) & 0xFFF ) << 3 ) >> 3 ;
1474
1474
1475
+ // Adjust the byte count based on texel size
1476
+ uint16_t count = (s2 - s1) >> (~texFormat & 0x3 );
1475
1477
uint16_t d = 0 ;
1476
1478
bool odd = false ;
1477
1479
@@ -1523,16 +1525,12 @@ void RDP::loadBlock()
1523
1525
1524
1526
void RDP::loadTile ()
1525
1527
{
1526
- // Decode the operands
1528
+ // Decode the operands and set texture coordinate bounds
1527
1529
Tile &tile = tiles[(opcode[0 ] >> 24 ) & 0x7 ];
1528
- uint16_t t2 = ((opcode[0 ] >> 0 ) & 0xFFF ) >> 2 ;
1529
- uint16_t s2 = ((opcode[0 ] >> 12 ) & 0xFFF ) >> 2 ;
1530
- uint16_t t1 = ((opcode[0 ] >> 32 ) & 0xFFF ) >> 2 ;
1531
- uint16_t s1 = ((opcode[0 ] >> 44 ) & 0xFFF ) >> 2 ;
1532
-
1533
- // Save the low texture coordinates for reference
1534
- tile.sBase = ((opcode[0 ] >> 44 ) & 0xFFF ) << 3 ;
1535
- tile.tBase = ((opcode[0 ] >> 32 ) & 0xFFF ) << 3 ;
1530
+ uint16_t s1 = (tile.s1 = ((opcode[0 ] >> 44 ) & 0xFFF ) << 3 ) >> 5 ;
1531
+ uint16_t t1 = (tile.t1 = ((opcode[0 ] >> 32 ) & 0xFFF ) << 3 ) >> 5 ;
1532
+ uint16_t s2 = (tile.s2 = ((opcode[0 ] >> 12 ) & 0xFFF ) << 3 ) >> 5 ;
1533
+ uint16_t t2 = (tile.t2 = ((opcode[0 ] >> 0 ) & 0xFFF ) << 3 ) >> 5 ;
1536
1534
1537
1535
// Only support loading textures without conversion for now
1538
1536
if (texFormat != tile.format )
0 commit comments