2018-12-21 00:01:14 +00:00
|
|
|
auto VDP::Sprite::setup(uint9 voffset) -> void {
|
|
|
|
objectsValid = 0;
|
Update to v101r30 release.
byuu says:
Changelog:
- SMS: added cartridge ROM/RAM mirroring (fixes Alex Kidd)
- SMS: fixed 8x16 sprite mode (fixes Wonder Boy, Ys graphics)
- Z80: emulated "ex (sp),hl" instruction
- Z80: fixed INx NF (should be set instead of cleared)
- Z80: fixed loop condition check for CPxR, INxR, LDxR, OTxR (fixes
walking in Wonder Boy)
- SFC: removed Debugger and sfc/debugger.hpp
- icarus: connected MS, GG, MD importing to the scan dialog
- PCE: added emulation skeleton to higan and icarus
At this point, Master System games are fairly highly compatible, sans
audio. Game Gear games are running, but I need to crop the resolution
and support the higher color palette that they can utilize. It's really
something else the way they handled the resolution shrink on that thing.
The last change is obviously going to be the biggest news.
I'm very well aware it's not an ideal time to start on a new emulation
core, with the MS and MD cores only just now coming to life with no
audio support.
But, for whatever reason, my heart's really set on working on the PC
Engine. I wanted to write the final higan skeleton core, and get things
ready so that whenever I'm in the mood to work on the PCE, I can do so.
The skeleton is far and away the most tedious and obnoxious part of the
emulator development, because it's basically all just lots of
boilerplate templated code, lots of new files to create, etc.
I really don't know how things are going to proceed ... but I can say
with 99.9% certainty that this will be the final brand new core ever
added to higan -- at least one written by me, that is. This was
basically the last system from my childhood that I ever cared about.
It's the last 2D system with games that I really enjoy playing. No other
system is worth dividing my efforts and reducing the quality and amount
of time to work on the systems I have.
In the future, there will be potential for FDS, Mega CD and PCE-CD
support. But those will all be add-ons, and they'll all be really
difficult and challenge the entire design of higan's UI (it's entirely
cartridge-driven at this time.) None of them will be entirely new cores
like this one.
2017-01-11 20:27:30 +00:00
|
|
|
uint limit = vdp.io.spriteTile ? 15 : 7;
|
2018-12-21 00:01:14 +00:00
|
|
|
|
|
|
|
if(!vdp.io.mode.bit(3)) {
|
|
|
|
uint14 attributeAddress;
|
|
|
|
attributeAddress.bits(7,13) = vdp.io.spriteAttributeTableAddress;
|
|
|
|
for(uint index : range(32)) {
|
|
|
|
uint8 y = vdp.vram[attributeAddress++];
|
|
|
|
if(y == 0xd0) break;
|
|
|
|
|
|
|
|
uint8 x = vdp.vram[attributeAddress++];
|
|
|
|
uint8 pattern = vdp.vram[attributeAddress++];
|
|
|
|
uint8 extra = vdp.vram[attributeAddress++];
|
|
|
|
|
|
|
|
if(extra.bit(7)) x -= 32;
|
|
|
|
y += 1;
|
|
|
|
if(voffset < y) continue;
|
|
|
|
if(voffset > y + limit) continue;
|
|
|
|
|
|
|
|
if(limit == 15) pattern.bits(0,1) = 0;
|
|
|
|
|
|
|
|
objects[objectsValid] = {x, y, pattern, extra.bits(0,3)};
|
|
|
|
if(++objectsValid == 4) {
|
|
|
|
vdp.io.spriteOverflow = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
uint14 attributeAddress;
|
|
|
|
attributeAddress.bits(8,13) = vdp.io.spriteAttributeTableAddress.bits(1,6);
|
|
|
|
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(voffset < y) continue;
|
|
|
|
if(voffset > y + limit) continue;
|
|
|
|
|
|
|
|
if(limit == 15) pattern.bit(0) = 0;
|
|
|
|
|
|
|
|
objects[objectsValid] = {x, y, pattern};
|
|
|
|
if(++objectsValid == 8) {
|
|
|
|
vdp.io.spriteOverflow = 1;
|
|
|
|
break;
|
|
|
|
}
|
2016-12-30 07:24:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
auto VDP::Sprite::run(uint8 hoffset, uint9 voffset) -> void {
|
|
|
|
output = {};
|
|
|
|
switch(vdp.io.mode) {
|
|
|
|
case 0b0000: return graphics1(hoffset, voffset);
|
|
|
|
case 0b0001: return;
|
|
|
|
case 0b0010: return graphics2(hoffset, voffset);
|
|
|
|
case 0b0011: return;
|
|
|
|
case 0b0100: return;
|
|
|
|
case 0b0101: return;
|
|
|
|
case 0b0110: return;
|
|
|
|
case 0b0111: return;
|
|
|
|
case 0b1000: return graphics3(hoffset, voffset, 192);
|
|
|
|
case 0b1001: return;
|
|
|
|
case 0b1010: return graphics3(hoffset, voffset, 192);
|
|
|
|
case 0b1011: return graphics3(hoffset, voffset, 224);
|
|
|
|
case 0b1100: return graphics3(hoffset, voffset, 192);
|
|
|
|
case 0b1101: return;
|
|
|
|
case 0b1110: return graphics3(hoffset, voffset, 240);
|
|
|
|
case 0b1111: return graphics3(hoffset, voffset, 192);
|
|
|
|
}
|
|
|
|
}
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
auto VDP::Sprite::graphics1(uint8 hoffset, uint9 voffset) -> void {
|
|
|
|
//todo: are sprites different in graphics mode 1?
|
|
|
|
return graphics2(hoffset, voffset);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::Sprite::graphics2(uint8 hoffset, uint9 voffset) -> void {
|
|
|
|
uint limit = vdp.io.spriteTile ? 15 : 7;
|
|
|
|
for(uint objectIndex : range(objectsValid)) {
|
|
|
|
auto& o = objects[objectIndex];
|
|
|
|
if(hoffset < o.x) continue;
|
|
|
|
if(hoffset > o.x + limit) continue;
|
|
|
|
|
|
|
|
uint x = hoffset - o.x;
|
|
|
|
uint y = voffset - o.y;
|
|
|
|
|
|
|
|
uint14 address;
|
|
|
|
address.bits( 0,10) = (o.pattern << 3) + (x >> 3 << 4) + (y & limit);
|
|
|
|
address.bits(11,13) = vdp.io.spritePatternTableAddress;
|
|
|
|
|
|
|
|
uint3 index = x ^ 7;
|
|
|
|
if(vdp.vram[address].bit(index)) {
|
|
|
|
if(output.color) { vdp.io.spriteCollision = true; break; }
|
|
|
|
output.color = o.color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
auto VDP::Sprite::graphics3(uint8 hoffset, uint9 voffset, uint vlines) -> void {
|
Update to v101r30 release.
byuu says:
Changelog:
- SMS: added cartridge ROM/RAM mirroring (fixes Alex Kidd)
- SMS: fixed 8x16 sprite mode (fixes Wonder Boy, Ys graphics)
- Z80: emulated "ex (sp),hl" instruction
- Z80: fixed INx NF (should be set instead of cleared)
- Z80: fixed loop condition check for CPxR, INxR, LDxR, OTxR (fixes
walking in Wonder Boy)
- SFC: removed Debugger and sfc/debugger.hpp
- icarus: connected MS, GG, MD importing to the scan dialog
- PCE: added emulation skeleton to higan and icarus
At this point, Master System games are fairly highly compatible, sans
audio. Game Gear games are running, but I need to crop the resolution
and support the higher color palette that they can utilize. It's really
something else the way they handled the resolution shrink on that thing.
The last change is obviously going to be the biggest news.
I'm very well aware it's not an ideal time to start on a new emulation
core, with the MS and MD cores only just now coming to life with no
audio support.
But, for whatever reason, my heart's really set on working on the PC
Engine. I wanted to write the final higan skeleton core, and get things
ready so that whenever I'm in the mood to work on the PCE, I can do so.
The skeleton is far and away the most tedious and obnoxious part of the
emulator development, because it's basically all just lots of
boilerplate templated code, lots of new files to create, etc.
I really don't know how things are going to proceed ... but I can say
with 99.9% certainty that this will be the final brand new core ever
added to higan -- at least one written by me, that is. This was
basically the last system from my childhood that I ever cared about.
It's the last 2D system with games that I really enjoy playing. No other
system is worth dividing my efforts and reducing the quality and amount
of time to work on the systems I have.
In the future, there will be potential for FDS, Mega CD and PCE-CD
support. But those will all be add-ons, and they'll all be really
difficult and challenge the entire design of higan's UI (it's entirely
cartridge-driven at this time.) None of them will be entirely new cores
like this one.
2017-01-11 20:27:30 +00:00
|
|
|
uint limit = vdp.io.spriteTile ? 15 : 7;
|
2018-12-21 00:01:14 +00:00
|
|
|
for(uint objectIndex : range(objectsValid)) {
|
|
|
|
auto& o = objects[objectIndex];
|
|
|
|
if(hoffset < o.x) continue;
|
|
|
|
if(hoffset > o.x + 7) continue;
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
uint x = hoffset - o.x;
|
|
|
|
uint y = voffset - o.y;
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
uint14 address;
|
|
|
|
address.bits(2,12) = (o.pattern << 3) + (y & limit);
|
|
|
|
address.bit (13) = vdp.io.spritePatternTableAddress.bit(2);
|
2016-12-30 07:24:35 +00:00
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
uint3 index = x ^ 7;
|
2016-12-30 07:24:35 +00:00
|
|
|
uint4 color;
|
2018-12-21 00:01:14 +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);
|
2016-12-30 07:24:35 +00:00
|
|
|
if(color == 0) continue;
|
|
|
|
|
2018-12-21 00:01:14 +00:00
|
|
|
if(output.color) { vdp.io.spriteCollision = true; break; }
|
2016-12-30 07:24:35 +00:00
|
|
|
output.color = color;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
auto VDP::Sprite::power() -> void {
|
2018-05-28 01:16:27 +00:00
|
|
|
output = {};
|
2018-12-21 00:01:14 +00:00
|
|
|
objectsValid = 0;
|
2016-12-30 07:24:35 +00:00
|
|
|
}
|