bsnes/higan/ms/vdp/sprite.cpp

72 lines
1.7 KiB
C++
Raw Normal View History

auto VDP::Sprite::scanline() -> void {
state.x = 0;
state.y = vdp.io.vcounter;
objects.reset();
bool large = vdp.io.extendedHeight;
uint14 attributeAddress = vdp.io.spriteAttributeTableAddress << 8;
for(uint index : range(64)) {
uint8 y = vdp.vram[attributeAddress + index];
uint8 x = vdp.vram[attributeAddress + 0x80 + (index << 1)];
uint8 pattern = vdp.vram[attributeAddress + 0x81 + (index << 1)];
if(vdp.vlines() == 192 && y == 0xd0) break;
if(vdp.io.spriteShift) x -= 8;
y += 1;
if(state.y < y) continue;
if(state.y > y + (large ? 15 : 7)) continue;
if(large) pattern.bit(0) = 0;
objects.append({x, y, pattern});
if(objects.size() == 8) {
vdp.io.spriteOverflow = 1;
break;
}
}
}
auto VDP::Sprite::run() -> void {
output.color = 0;
if(state.y >= vdp.vlines()) return;
bool large = vdp.io.extendedHeight;
for(auto& o : objects) {
if(state.x < o.x) continue;
if(state.x > o.x + 7) continue;
uint x = o.x - state.x;
uint y = o.y - state.y;
uint14 address = vdp.io.spritePatternTableAddress << 13;
address += o.pattern << 5;
address += (y & (large ? 15 : 7)) << 2;
Update to v101r27 release. byuu says: Changelog: - SMS: emulated the generic Sega memory mapper (none of the more limited forms of it yet) - (missing ROM shift, ROM write enable emulation -- no commercial games use either, though) - SMS: bus I/O returns 0xff instead of 0x00 so games don't think every key is being pressed at once - (this is a hack until I implement proper controller pad reading) - SMS: very limited protection against reading/writing past the end of ROM/RAM (todo: should mirror) - SMS: VDP background HSCROLL subtracts, rather than adds, to the offset (unlike VSCROLL) - SMS: VDP VSCROLL is 9-bit, modulates voffset+vscroll to 224 in 192-line mode (32x28 tilemap) - SMS: VDP tiledata for backgrounds and sprites use `7-(x&7)` rather than `(x&7)` - SMS: fix output color to be 6-bit rather than 5-bit - SMS: left clip uses register `#7`, not palette color `#7` - (todo: do we want `color[reg7]` or `color[16 + reg7]`?) - SMS: refined handling of 0xcb, 0xed prefixes in the Z80 core and its disassembler - SMS: emulated (0xfd, 0xdd) 0xcb opcodes 0x00-0x0f (still missing 0x10-0xff) - SMS: fixed 0xcb 0b-----110 opcodes to use direct HL and never allow (IX,IY)+d - SMS: fixed major logic bug in (IX,IY)+d displacement - (was using `read(x)` instead of `operand()` for the displacement byte fetch before) - icarus: fake there always being 32KiB of RAM in all SMS cartridges for the time being - (not sure how to detect this stuff yet; although I've read it's not even really possible `>_>`) TODO: remove processor/z80/dissassembler.cpp code block at line 396 (as it's unnecessary.) Lots of commercial games are starting to show trashed graphical output now.
2017-01-06 08:11:38 +00:00
auto index = 7 - (x & 7);
uint4 color;
Update to v101r27 release. byuu says: Changelog: - SMS: emulated the generic Sega memory mapper (none of the more limited forms of it yet) - (missing ROM shift, ROM write enable emulation -- no commercial games use either, though) - SMS: bus I/O returns 0xff instead of 0x00 so games don't think every key is being pressed at once - (this is a hack until I implement proper controller pad reading) - SMS: very limited protection against reading/writing past the end of ROM/RAM (todo: should mirror) - SMS: VDP background HSCROLL subtracts, rather than adds, to the offset (unlike VSCROLL) - SMS: VDP VSCROLL is 9-bit, modulates voffset+vscroll to 224 in 192-line mode (32x28 tilemap) - SMS: VDP tiledata for backgrounds and sprites use `7-(x&7)` rather than `(x&7)` - SMS: fix output color to be 6-bit rather than 5-bit - SMS: left clip uses register `#7`, not palette color `#7` - (todo: do we want `color[reg7]` or `color[16 + reg7]`?) - SMS: refined handling of 0xcb, 0xed prefixes in the Z80 core and its disassembler - SMS: emulated (0xfd, 0xdd) 0xcb opcodes 0x00-0x0f (still missing 0x10-0xff) - SMS: fixed 0xcb 0b-----110 opcodes to use direct HL and never allow (IX,IY)+d - SMS: fixed major logic bug in (IX,IY)+d displacement - (was using `read(x)` instead of `operand()` for the displacement byte fetch before) - icarus: fake there always being 32KiB of RAM in all SMS cartridges for the time being - (not sure how to detect this stuff yet; although I've read it's not even really possible `>_>`) TODO: remove processor/z80/dissassembler.cpp code block at line 396 (as it's unnecessary.) Lots of commercial games are starting to show trashed graphical output now.
2017-01-06 08:11:38 +00:00
color.bit(0) = vdp.vram[address + 0].bit(index);
color.bit(1) = vdp.vram[address + 1].bit(index);
color.bit(2) = vdp.vram[address + 2].bit(index);
color.bit(3) = vdp.vram[address + 3].bit(index);
if(color == 0) continue;
if(output.color) {
vdp.io.spriteCollision = true;
break;
}
output.color = color;
}
state.x++;
}
auto VDP::Sprite::power() -> void {
}
auto VDP::Sprite::reset() -> void {
memory::fill(&state, sizeof(State));
memory::fill(&output, sizeof(Output));
}