| 567 | } |
| 568 | |
| 569 | func (ppu *PPU) fetchSpritePattern(i, row int) uint32 { |
| 570 | tile := ppu.oamData[i*4+1] |
| 571 | attributes := ppu.oamData[i*4+2] |
| 572 | var address uint16 |
| 573 | if ppu.flagSpriteSize == 0 { |
| 574 | if attributes&0x80 == 0x80 { |
| 575 | row = 7 - row |
| 576 | } |
| 577 | table := ppu.flagSpriteTable |
| 578 | address = 0x1000*uint16(table) + uint16(tile)*16 + uint16(row) |
| 579 | } else { |
| 580 | if attributes&0x80 == 0x80 { |
| 581 | row = 15 - row |
| 582 | } |
| 583 | table := tile & 1 |
| 584 | tile &= 0xFE |
| 585 | if row > 7 { |
| 586 | tile++ |
| 587 | row -= 8 |
| 588 | } |
| 589 | address = 0x1000*uint16(table) + uint16(tile)*16 + uint16(row) |
| 590 | } |
| 591 | a := (attributes & 3) << 2 |
| 592 | lowTileByte := ppu.Read(address) |
| 593 | highTileByte := ppu.Read(address + 8) |
| 594 | var data uint32 |
| 595 | for i := 0; i < 8; i++ { |
| 596 | var p1, p2 byte |
| 597 | if attributes&0x40 == 0x40 { |
| 598 | p1 = (lowTileByte & 1) << 0 |
| 599 | p2 = (highTileByte & 1) << 1 |
| 600 | lowTileByte >>= 1 |
| 601 | highTileByte >>= 1 |
| 602 | } else { |
| 603 | p1 = (lowTileByte & 0x80) >> 7 |
| 604 | p2 = (highTileByte & 0x80) >> 6 |
| 605 | lowTileByte <<= 1 |
| 606 | highTileByte <<= 1 |
| 607 | } |
| 608 | data <<= 4 |
| 609 | data |= uint32(a | p1 | p2) |
| 610 | } |
| 611 | return data |
| 612 | } |
| 613 | |
| 614 | func (ppu *PPU) evaluateSprites() { |
| 615 | var h int |