mirror of https://github.com/stella-emu/stella.git
Better emulation of the starfield effect in Cosmic Ark and Stay Frosty.
The movement was already correct, but one of the missiles has weird behaviour caused by 'confusing' the TIA. This results in a four colour-clock wide missile with the third pixel turned off. I don't know if this is entirely accurate, but I do know that the snow in Stay Frosty now looks exactly the same in emulation as is does on a real system, so I'm content to leave it for now. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1866 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
bf83ffde53
commit
8f8095073b
|
@ -813,7 +813,7 @@ inline void TIA::updateFrameScanline(uInt32 clocksToUpdate, uInt32 hpos)
|
|||
// Handle all other possible combinations
|
||||
else
|
||||
{
|
||||
// Update masks (M0 and M1 are done in updateFrame)
|
||||
// Update masks
|
||||
myCurrentBLMask = &TIATables::BLMask[myPOSBL & 0x03]
|
||||
[(myCTRLPF & 0x30) >> 4][160 - (myPOSBL & 0xFC)];
|
||||
myCurrentP0Mask = &TIATables::PxMask[myPOSP0 & 0x03]
|
||||
|
@ -829,20 +829,20 @@ inline void TIA::updateFrameScanline(uInt32 clocksToUpdate, uInt32 hpos)
|
|||
// what's really going on here.
|
||||
if(myHMM0mmr && myPOSM0 % 4 == 3)
|
||||
{
|
||||
// Stretch this missle so it's at least 2 pixels wide
|
||||
// Stretch this missle so it's 4 pixels wide, with the 3rd pixel
|
||||
// blanked out; this is indicated by using a size of '4'
|
||||
myCurrentM0Mask = &TIATables::MxMask[myPOSM0 & 0x03]
|
||||
[myNUSIZ0 & 0x07][((myNUSIZ0 & 0x30) >> 4) | 0x01]
|
||||
[160 - (myPOSM0 & 0xFC)];
|
||||
[myNUSIZ0 & 0x07][4][160 - (myPOSM0 & 0xFC)];
|
||||
}
|
||||
else
|
||||
myCurrentM0Mask = &TIATables::MxMask[myPOSM0 & 0x03]
|
||||
[myNUSIZ0 & 0x07][(myNUSIZ0 & 0x30) >> 4][160 - (myPOSM0 & 0xFC)];
|
||||
if(myHMM1mmr && myPOSM1 % 4 == 3)
|
||||
{
|
||||
// Stretch this missle so it's at least 2 pixels wide
|
||||
// Stretch this missle so it's 4 pixels wide, with the 3rd pixel
|
||||
// blanked out; this is indicated by using a size of '4'
|
||||
myCurrentM1Mask = &TIATables::MxMask[myPOSM1 & 0x03]
|
||||
[myNUSIZ1 & 0x07][((myNUSIZ1 & 0x30) >> 4) | 0x01]
|
||||
[160 - (myPOSM1 & 0xFC)];
|
||||
[myNUSIZ1 & 0x07][4][160 - (myPOSM1 & 0xFC)];
|
||||
}
|
||||
else
|
||||
myCurrentM1Mask = &TIATables::MxMask[myPOSM1 & 0x03]
|
||||
|
|
|
@ -208,7 +208,7 @@ void TIATables::buildPxMaskTable()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
// [4][8][4][320]
|
||||
// [4][8][5][320]
|
||||
// [alignment][number][size][pixel]
|
||||
void TIATables::buildMxMaskTable()
|
||||
{
|
||||
|
@ -217,68 +217,134 @@ void TIATables::buildMxMaskTable()
|
|||
|
||||
// Clear the missle table to start with
|
||||
for(number = 0; number < 8; ++number)
|
||||
for(size = 0; size < 4; ++size)
|
||||
for(size = 0; size < 5; ++size)
|
||||
for(x = 0; x < 160; ++x)
|
||||
MxMask[0][number][size][x] = false;
|
||||
|
||||
for(number = 0; number < 8; ++number)
|
||||
{
|
||||
for(size = 0; size < 4; ++size)
|
||||
for(size = 0; size < 5; ++size)
|
||||
{
|
||||
for(x = 0; x < 160 + 72; ++x)
|
||||
{
|
||||
// For the following, size index = 4 is almost exactly the same as
|
||||
// index = 2; that is, 1 << 2, or 4 colour clocks wide
|
||||
// To simulate the weirdness in the Cosmic Ark starfield effect,
|
||||
// each group of 4 pixels has its 3rd pixel blanked
|
||||
switch(number)
|
||||
{
|
||||
// Only one copy of the missle
|
||||
case 0x00:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Two copies - close
|
||||
case 0x01:
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Two copies - medium
|
||||
case 0x02:
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Three copies - close
|
||||
case 0x03:
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 16) >= 0) && ((x - 16) < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Two copies - wide
|
||||
case 0x04:
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
|
||||
// Three copies - medium
|
||||
case 0x06:
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
if(size != 4)
|
||||
{
|
||||
if((x >= 0) && (x < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
|
||||
MxMask[0][number][size][x % 160] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if((x >= 0) && (x < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 32) >= 0) && ((x - 32) < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
else if(((x - 64) >= 0) && ((x - 64) < (1 << 2)))
|
||||
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -295,7 +361,7 @@ void TIATables::buildMxMaskTable()
|
|||
{
|
||||
for(number = 0; number < 8; ++number)
|
||||
{
|
||||
for(size = 0; size < 4; ++size)
|
||||
for(size = 0; size < 5; ++size)
|
||||
{
|
||||
for(x = 0; x < 320; ++x)
|
||||
{
|
||||
|
@ -556,7 +622,7 @@ const Int16 TIATables::PokeDelay[64] = {
|
|||
};
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 TIATables::MxMask[4][8][4][320];
|
||||
uInt8 TIATables::MxMask[4][8][5][320];
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const bool TIATables::HMOVEBlankEnableCycles[76] = {
|
||||
|
|
|
@ -155,7 +155,10 @@ class TIATables
|
|||
|
||||
// Missle mask table (entries are true or false)
|
||||
// [alignment][number][size][pixel]
|
||||
static uInt8 MxMask[4][8][4][320];
|
||||
// There are actually only 4 possible size combinations on a real system
|
||||
// The fifth size is used for simulating the starfield effect in
|
||||
// Cosmic Ark and Stay Frosty
|
||||
static uInt8 MxMask[4][8][5][320];
|
||||
|
||||
// Ball mask table (entries are true or false)
|
||||
// [alignment][size][pixel]
|
||||
|
|
Loading…
Reference in New Issue