First up, i notice that only Daimakaimura uses window 1 (set to 1023), and nothing else uses either window.
Yet still ... sgxtech says this:
Code: Select all
The VPC has two 10-bit registers which define the width of Window 1 and
Window 2. The windows start from the leftmost pixel of the physical screen,
not the active display area, which is a window width setting of $0040.
Values smaller than this disable the window, and values larger than this
make the window extend horizontally across the screen, from left to right,
A setting of $3FF makes the window take up the entire width of the screen.
But each VDC has its own H/V timing values, and of course the VCE has the clock frequency select of 5/7/10mhz.
So when it says it starts from the leftmost pixel of the physical screen, what is it talking about, exactly?
Given the regular resolutions are 256/340/512, should I assume that with a range of 1023, that a value of 66 is saying "the window affects one pixel at 256-width, one and a half pixels (roughly) at 340-width, two pixels at 512-width"?
I don't think it'd be rated at the full 21mhz, because then 1023 wouldn't cover the entire width of the screen. Let alone if you overdrive the width to its theoretical limits (~285/~380/~560).
Next problem is the priorities themselves ... what a mess. sgxtech lists it like this:
Code: Select all
Back Front
SP2 > BG2 > SP2' > SP1 > BG1 > SP1'
BG2 = VDC #2 background
SP2 = VDC #2 low priority sprites
SP2'= VDC #2 high priority sprites
BG1 = VDC #1 background
SP1 = VDC #1 low priority sprites
SP1'= VDC #1 high priority sprites
d8 => 0=background, 1=sprite
d7-d4 => palette index
d3-d0 => color
Which is also a direct index into CRAM, which is convenient.
I am also unsure what happens when both the background and sprite are off. It sounds like on a regular PCE, it returns 0x100 (so you use the sprite palette #0 color), and on the SGX, it returns 0x000 (so you use the background palette #0 color.) Is that right?
So with that in mind, we can refactor the default priority to:
BG2 > SP2 > BG1 > SP1
Which ... using > is a really poor choice. Up until just now I thought that meant BG2 had greater priority >_<
So this can be further refactored to this:
return VDC1.color ? VDC1 : VDC2;
But that's only for modes 0 and 3.
Code: Select all
The 2-bit priority field affects the layer ordering. The above default
priority setting is selected for values of 00b and 11b.
Code: Select all
For 01b, VDC #1 sprites are shown behind the VDC #2 background. However,
the VDC #1 background has missing sprite-shaped areas where it's sprites
are, even though they are hidden behind both background layers.
Code: Select all
SP1 = VDC #1 sprites
BG2 = VDC #2 background
SP2 = VDC #2 sprites
BG1 = VDC #1 background
And finally:
Code: Select all
For 10b, VDC #2 sprites are shown in front of the VDC #1 background and
behind VDC #1 sprites. However, low priority VDC #2 sprites are still
shown behind VDC #2 background tiles.
Code: Select all
BG2 = VDC #2 background
BG1 = VDC #1 background
SP2 = VDC #2 sprites
SP1 = VDC #1 sprites
Of course, the enable VDC1/2 flags come into play as well. So I skip them when said VDC is not enabled.
And if both VDCs aren't enable and we fall through, for now I'm returning 0x000 (CRAM color #0), is that right?
Thus, my code ends up looking like this:
(I know it's horribly unoptimized, it's just to get things working initially, then I'll revise.)
Code: Select all
auto VPC::bus(uint hclock) -> uint9 {
auto bus0 = vdc0.bus(); //0 = VDC1
auto bus1 = vdc1.bus(); //1 = VDC2
auto color0 = bus0.bits(0,3);
auto color1 = bus1.bits(0,3);
auto palette0 = bus0.bits(4,7);
auto palette1 = bus1.bits(4,7);
auto mode0 = bus0.bit(8); //0 = background, 1 = sprite
auto mode1 = bus1.bit(8);
bool window0 = window[0] >= 64 && (window[0] - 64) >= hclock / 2;
bool window1 = window[1] >= 64 && (window[1] - 64) >= hclock / 2;
uint2 mode;
if(!window0 && !window1) mode = 1;
if( window0 && !window1) mode = 0;
if(!window0 && window1) mode = 3;
if( window0 && window1) mode = 2;
//mode 0 = $08.d0-d3, 1 = $08.d4-d7, 2 = $09.d0-d3, 3 = $09.d4-d7
auto enableVDC0 = settings[mode].enableVDC0;
auto enableVDC1 = settings[mode].enableVDC1;
auto priority = settings[mode].priority;
if(priority == 0 || priority == 3) {
if( mode0 && enableVDC0) return bus0;
if(!mode0 && enableVDC0) return bus0;
if( mode1 && enableVDC1) return bus1;
if(!mode1 && enableVDC1) return bus1;
}
if(priority == 1) {
if(!mode0 && enableVDC0) return bus0;
if( mode1 && enableVDC1) return bus1;
if(!mode1 && enableVDC1) return bus1;
if( mode0 && enableVDC0) return bus0;
}
if(priority == 2) {
if( mode0 && enableVDC0) return bus0;
if( mode1 && enableVDC1) return bus1;
if(!mode0 && enableVDC0) return bus0;
if(!mode1 && enableVDC1) return bus1;
}
return 0x000;
}
Gallery of results here: http://imgur.com/a/1fE82
So ... what am I missing here? :/