Some work on the TIA class (I don't know how long the current code

will be used, but at least we can improve it a little).

Eliminated the 'alignment' dimension in the various TIATables masks,
reducing the size of the arrays by a factor of 4.  I could never
figure out what alignment meant, until I looked at old TIA code in
the repo.  It seems that originally, there was an optimization
in the code to fill the array on 32-bit boundaries, instead of the
current 8-bit boundary.  As a result, the masks had to be defined
as 32-bits, or 4 groups of 8-bits.  Ah, that's where the 'alignment'
comes from.

Related to this, the colors and pointers in the TIA class are now
8-bit as well.  Essentially, the TIA class has been doing extra
work to align everything to 32-bit and never actually using the
results.  And it's been this way for 4+ years.

Older state files will no longer work, so the version # has been
bumped.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2765 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2013-07-10 15:40:11 +00:00
parent 0842c96f7f
commit b6d3098e2c
5 changed files with 161 additions and 217 deletions

View File

@ -30,7 +30,7 @@
#include "StateManager.hxx"
#define STATE_HEADER "03070300state"
#define STATE_HEADER "03090100state"
#define MOVIE_HEADER "03030000movie"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -142,11 +142,11 @@ void TIA::reset()
myFrameCounter = myPALFrameCounter = 0;
myScanlineCountForLastFrame = 0;
myP0Mask = &TIATables::PxMask[0][0][0][0];
myP1Mask = &TIATables::PxMask[0][0][0][0];
myM0Mask = &TIATables::MxMask[0][0][0][0];
myM1Mask = &TIATables::MxMask[0][0][0][0];
myBLMask = &TIATables::BLMask[0][0][0];
myP0Mask = &TIATables::PxMask[0][0][0];
myP1Mask = &TIATables::PxMask[0][0][0];
myM0Mask = &TIATables::MxMask[0][0][0];
myM1Mask = &TIATables::MxMask[0][0][0];
myBLMask = &TIATables::BLMask[0][0];
myPFMask = TIATables::PFMask[0];
// Recalculate the size of the display
@ -173,27 +173,27 @@ void TIA::frameReset()
if(myFramerate > 55.0) // NTSC
{
myFixedColor[P0Color] = 0x30303030;
myFixedColor[P1Color] = 0x16161616;
myFixedColor[M0Color] = 0x38383838;
myFixedColor[M1Color] = 0x12121212;
myFixedColor[BLColor] = 0x7e7e7e7e;
myFixedColor[PFColor] = 0x76767676;
myFixedColor[BKColor] = 0x0a0a0a0a;
myFixedColor[HBLANKColor] = 0x0e0e0e0e;
myFixedColor[P0Color] = 0x30;
myFixedColor[P1Color] = 0x16;
myFixedColor[M0Color] = 0x38;
myFixedColor[M1Color] = 0x12;
myFixedColor[BLColor] = 0x7e;
myFixedColor[PFColor] = 0x76;
myFixedColor[BKColor] = 0x0a;
myFixedColor[HBLANKColor] = 0x0e;
myColorLossEnabled = false;
myMaximumNumberOfScanlines = 290;
}
else
{
myFixedColor[P0Color] = 0x62626262;
myFixedColor[P1Color] = 0x26262626;
myFixedColor[M0Color] = 0x68686868;
myFixedColor[M1Color] = 0x2e2e2e2e;
myFixedColor[BLColor] = 0xdededede;
myFixedColor[PFColor] = 0xd8d8d8d8;
myFixedColor[BKColor] = 0x1c1c1c1c;
myFixedColor[HBLANKColor] = 0x0e0e0e0e;
myFixedColor[P0Color] = 0x62;
myFixedColor[P1Color] = 0x26;
myFixedColor[M0Color] = 0x68;
myFixedColor[M1Color] = 0x2e;
myFixedColor[BLColor] = 0xde;
myFixedColor[PFColor] = 0xd8;
myFixedColor[BKColor] = 0x1c;
myFixedColor[HBLANKColor] = 0x0e;
myColorLossEnabled = mySettings.getBool("colorloss");
myMaximumNumberOfScanlines = 342;
}
@ -289,7 +289,7 @@ bool TIA::save(Serializer& out) const
out.putByte(myNUSIZ0);
out.putByte(myNUSIZ1);
out.putIntArray(myColor, 8);
out.putByteArray(myColor, 8);
out.putByte(myCTRLPF);
out.putByte(myPlayfieldPriorityAndScore);
@ -393,7 +393,7 @@ bool TIA::load(Serializer& in)
myNUSIZ0 = in.getByte();
myNUSIZ1 = in.getByte();
in.getIntArray(myColor, 8);
in.getByteArray(myColor, 8);
myCTRLPF = in.getByte();
myPlayfieldPriorityAndScore = in.getByte();
@ -576,23 +576,23 @@ inline void TIA::startFrame()
{
if(myScanlineCountForLastFrame & 0x01)
{
myColor[P0Color] |= 0x01010101;
myColor[P1Color] |= 0x01010101;
myColor[PFColor] |= 0x01010101;
myColor[BKColor] |= 0x01010101;
myColor[M0Color] |= 0x01010101;
myColor[M1Color] |= 0x01010101;
myColor[BLColor] |= 0x01010101;
myColor[P0Color] |= 0x01;
myColor[P1Color] |= 0x01;
myColor[PFColor] |= 0x01;
myColor[BKColor] |= 0x01;
myColor[M0Color] |= 0x01;
myColor[M1Color] |= 0x01;
myColor[BLColor] |= 0x01;
}
else
{
myColor[P0Color] &= 0xfefefefe;
myColor[P1Color] &= 0xfefefefe;
myColor[PFColor] &= 0xfefefefe;
myColor[BKColor] &= 0xfefefefe;
myColor[M0Color] &= 0xfefefefe;
myColor[M1Color] &= 0xfefefefe;
myColor[BLColor] &= 0xfefefefe;
myColor[P0Color] &= 0xfe;
myColor[P1Color] &= 0xfe;
myColor[PFColor] &= 0xfe;
myColor[BKColor] &= 0xfe;
myColor[M0Color] &= 0xfe;
myColor[M1Color] &= 0xfe;
myColor[BLColor] &= 0xfe;
}
}
myStartScanline = 0;
@ -1053,12 +1053,12 @@ void TIA::updateFrame(Int32 clock)
else
{
// Update masks
myP0Mask = &TIATables::PxMask[myPOSP0 & 0x03]
[mySuppressP0][myNUSIZ0 & 0x07][160 - (myPOSP0 & 0xFC)];
myP1Mask = &TIATables::PxMask[myPOSP1 & 0x03]
[mySuppressP1][myNUSIZ1 & 0x07][160 - (myPOSP1 & 0xFC)];
myBLMask = &TIATables::BLMask[myPOSBL & 0x03]
[(myCTRLPF & 0x30) >> 4][160 - (myPOSBL & 0xFC)];
myP0Mask = &TIATables::PxMask[mySuppressP0]
[myNUSIZ0 & 0x07][160 - (myPOSP0 & 0xFF)];
myP1Mask = &TIATables::PxMask[mySuppressP1]
[myNUSIZ1 & 0x07][160 - (myPOSP1 & 0xFF)];
myBLMask = &TIATables::BLMask[(myCTRLPF & 0x30) >> 4]
[160 - (myPOSBL & 0xFF)];
// TODO - 08-27-2009: Simulate the weird effects of Cosmic Ark and
// Stay Frosty. The movement itself is well understood, but there
@ -1074,24 +1074,22 @@ void TIA::updateFrame(Int32 clock)
case 3:
// Stretch this missle so it's 2 pixels wide and shifted one
// pixel to the left
myM0Mask = &TIATables::MxMask[(myPOSM0-1) & 0x03]
[myNUSIZ0 & 0x07][((myNUSIZ0 & 0x30) >> 4)|1]
[160 - ((myPOSM0-1) & 0xFC)];
myM0Mask = &TIATables::MxMask[myNUSIZ0 & 0x07]
[((myNUSIZ0 & 0x30) >> 4)|1][160 - ((myPOSM0-1) & 0xFF)];
break;
case 2:
// Missle is disabled on this line
myM0Mask = &TIATables::DisabledMask[0];
break;
default:
myM0Mask = &TIATables::MxMask[myPOSM0 & 0x03]
[myNUSIZ0 & 0x07][(myNUSIZ0 & 0x30) >> 4]
[160 - (myPOSM0 & 0xFC)];
myM0Mask = &TIATables::MxMask[myNUSIZ0 & 0x07]
[(myNUSIZ0 & 0x30) >> 4][160 - (myPOSM0 & 0xFF)];
break;
}
}
else
myM0Mask = &TIATables::MxMask[myPOSM0 & 0x03]
[myNUSIZ0 & 0x07][(myNUSIZ0 & 0x30) >> 4][160 - (myPOSM0 & 0xFC)];
myM0Mask = &TIATables::MxMask[myNUSIZ0 & 0x07]
[(myNUSIZ0 & 0x30) >> 4][160 - (myPOSM0 & 0xFF)];
if(myHMM1mmr)
{
switch(myPOSM1 % 4)
@ -1099,24 +1097,22 @@ void TIA::updateFrame(Int32 clock)
case 3:
// Stretch this missle so it's 2 pixels wide and shifted one
// pixel to the left
myM1Mask = &TIATables::MxMask[(myPOSM1-1) & 0x03]
[myNUSIZ1 & 0x07][((myNUSIZ1 & 0x30) >> 4)|1]
[160 - ((myPOSM1-1) & 0xFC)];
myM1Mask = &TIATables::MxMask[myNUSIZ1 & 0x07]
[((myNUSIZ1 & 0x30) >> 4)|1][160 - ((myPOSM1-1) & 0xFF)];
break;
case 2:
// Missle is disabled on this line
myM1Mask = &TIATables::DisabledMask[0];
break;
default:
myM1Mask = &TIATables::MxMask[myPOSM1 & 0x03]
[myNUSIZ1 & 0x07][(myNUSIZ1 & 0x30) >> 4]
[160 - (myPOSM1 & 0xFC)];
myM1Mask = &TIATables::MxMask[myNUSIZ1 & 0x07]
[(myNUSIZ1 & 0x30) >> 4][160 - (myPOSM1 & 0xFF)];
break;
}
}
else
myM1Mask = &TIATables::MxMask[myPOSM1 & 0x03]
[myNUSIZ1 & 0x07][(myNUSIZ1 & 0x30) >> 4][160 - (myPOSM1 & 0xFC)];
myM1Mask = &TIATables::MxMask[myNUSIZ1 & 0x07]
[(myNUSIZ1 & 0x30) >> 4][160 - (myPOSM1 & 0xFF)];
uInt8 enabledObjects = myEnabledObjects & myDisabledObjects;
uInt32 hpos = clocksFromStartOfScanLine - HBLANK;
@ -1496,48 +1492,41 @@ bool TIA::poke(uInt16 addr, uInt8 value)
case COLUP0: // Color-Luminance Player 0
{
uInt32 color = (uInt32)(value & 0xfe);
uInt8 color = value & 0xfe;
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myColor[P0Color] = myColor[M0Color] =
(((((color << 8) | color) << 8) | color) << 8) | color;
myColor[P0Color] = myColor[M0Color] = color;
break;
}
case COLUP1: // Color-Luminance Player 1
{
uInt32 color = (uInt32)(value & 0xfe);
uInt8 color = value & 0xfe;
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myColor[P1Color] = myColor[M1Color] =
(((((color << 8) | color) << 8) | color) << 8) | color;
myColor[P1Color] = myColor[M1Color] = color;
break;
}
case COLUPF: // Color-Luminance Playfield
{
uInt32 color = (uInt32)(value & 0xfe);
uInt8 color = value & 0xfe;
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myColor[PFColor] = myColor[BLColor] =
(((((color << 8) | color) << 8) | color) << 8) | color;
myColor[PFColor] = myColor[BLColor] = color;
break;
}
case COLUBK: // Color-Luminance Background
{
uInt32 color = (uInt32)(value & 0xfe);
uInt8 color = value & 0xfe;
if(myColorLossEnabled && (myScanlineCountForLastFrame & 0x01))
{
color |= 0x01;
}
myColor[BKColor] = (((((color << 8) | color) << 8) | color) << 8) | color;
myColor[BKColor] = color;
break;
}

View File

@ -468,9 +468,9 @@ class TIA : public Device
uInt8 myPlayfieldPriorityAndScore;
uInt8 myPriorityEncoder[2][256];
uInt32 myColor[8];
uInt32 myFixedColor[8];
uInt32* myColorPtr;
uInt8 myColor[8];
uInt8 myFixedColor[8];
uInt8* myColorPtr;
uInt8 myCTRLPF; // Playfield control register

View File

@ -90,19 +90,17 @@ void TIATables::buildCollisionMaskTable()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// [4][2][8][320]
// [alignment][suppress mode][nusiz][pixel]
// [suppress mode:2][nusiz:8][pixel:320]
// suppress=1: suppress on
// suppress=0: suppress off
void TIATables::buildPxMaskTable()
{
// First, calculate masks for alignment 0
Int32 x, suppress, nusiz;
// Set the player mask table to all zeros
for(nusiz = 0; nusiz < 8; ++nusiz)
for(x = 0; x < 160; ++x)
PxMask[0][0][nusiz][x] = PxMask[0][1][nusiz][x] = 0x00;
PxMask[0][nusiz][x] = PxMask[1][nusiz][x] = 0x00;
// Now, compute the player mask table
for(suppress = 0; suppress < 2; ++suppress)
@ -124,99 +122,82 @@ void TIATables::buildPxMaskTable()
{
case 0x00:
if((suppress == 0) && (x >= 0) && (x < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> x;
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
break;
case 0x01:
if((suppress == 0) && (x >= 0) && (x < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> x;
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
else if(((x - 16) >= 0) && ((x - 16) < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> (x - 16);
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 16);
break;
case 0x02:
if((suppress == 0) && (x >= 0) && (x < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> x;
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
else if(((x - 32) >= 0) && ((x - 32) < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> (x - 32);
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 32);
break;
case 0x03:
if((suppress == 0) && (x >= 0) && (x < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> x;
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
else if(((x - 16) >= 0) && ((x - 16) < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> (x - 16);
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 16);
else if(((x - 32) >= 0) && ((x - 32) < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> (x - 32);
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 32);
break;
case 0x04:
if((suppress == 0) && (x >= 0) && (x < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> x;
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
else if(((x - 64) >= 0) && ((x - 64) < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> (x - 64);
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 64);
break;
case 0x05:
// For some reason in double size nusiz the player's output
// is delayed by one pixel thus we use > instead of >=
if((suppress == 0) && (x > 0) && (x <= 16))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> ((x - 1)/2);
PxMask[suppress][nusiz][x % 160] = 0x80 >> ((x - 1)/2);
break;
case 0x06:
if((suppress == 0) && (x >= 0) && (x < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> x;
PxMask[suppress][nusiz][x % 160] = 0x80 >> x;
else if(((x - 32) >= 0) && ((x - 32) < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> (x - 32);
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 32);
else if(((x - 64) >= 0) && ((x - 64) < 8))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> (x - 64);
PxMask[suppress][nusiz][x % 160] = 0x80 >> (x - 64);
break;
case 0x07:
// For some reason in quad size nusiz the player's output
// is delayed by one pixel thus we use > instead of >=
if((suppress == 0) && (x > 0) && (x <= 32))
PxMask[0][suppress][nusiz][x % 160] = 0x80 >> ((x - 1)/4);
PxMask[suppress][nusiz][x % 160] = 0x80 >> ((x - 1)/4);
break;
}
}
// Copy data into wrap-around area
for(x = 0; x < 160; ++x)
PxMask[0][suppress][nusiz][x + 160] = PxMask[0][suppress][nusiz][x];
}
}
// Now, copy data for alignments of 1, 2 and 3
for(uInt32 align = 1; align < 4; ++align)
{
for(nusiz = 0; nusiz < 8; ++nusiz)
{
for(x = 0; x < 320; ++x)
{
PxMask[align][0][nusiz][x] =
PxMask[0][0][nusiz][(x + 320 - align) % 320];
PxMask[align][1][nusiz][x] =
PxMask[0][1][nusiz][(x + 320 - align) % 320];
}
PxMask[suppress][nusiz][x + 160] = PxMask[suppress][nusiz][x];
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// [4][8][5][320]
// [alignment][number][size][pixel]
// [number:8][size:5][pixel:320]
void TIATables::buildMxMaskTable()
{
// First, calculate masks for alignment 0
Int32 x, size, number;
// Clear the missle table to start with
for(number = 0; number < 8; ++number)
for(size = 0; size < 5; ++size)
for(x = 0; x < 160; ++x)
MxMask[0][number][size][x] = false;
MxMask[number][size][x] = false;
for(number = 0; number < 8; ++number)
{
@ -237,12 +218,12 @@ void TIATables::buildMxMaskTable()
if(size != 4)
{
if((x >= 0) && (x < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
}
else
{
if((x >= 0) && (x < (1 << 2)))
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
}
break;
@ -251,16 +232,16 @@ void TIATables::buildMxMaskTable()
if(size != 4)
{
if((x >= 0) && (x < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
}
else
{
if((x >= 0) && (x < (1 << 2)))
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
MxMask[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);
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
}
break;
@ -269,16 +250,16 @@ void TIATables::buildMxMaskTable()
if(size != 4)
{
if((x >= 0) && (x < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
}
else
{
if((x >= 0) && (x < (1 << 2)))
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
MxMask[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);
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
}
break;
@ -287,20 +268,20 @@ void TIATables::buildMxMaskTable()
if(size != 4)
{
if((x >= 0) && (x < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
else if(((x - 16) >= 0) && ((x - 16) < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
}
else
{
if((x >= 0) && (x < (1 << 2)))
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
MxMask[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);
MxMask[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);
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
}
break;
@ -309,16 +290,16 @@ void TIATables::buildMxMaskTable()
if(size != 4)
{
if((x >= 0) && (x < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
}
else
{
if((x >= 0) && (x < (1 << 2)))
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
MxMask[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);
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
}
break;
@ -327,20 +308,20 @@ void TIATables::buildMxMaskTable()
if(size != 4)
{
if((x >= 0) && (x < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
else if(((x - 32) >= 0) && ((x - 32) < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
else if(((x - 64) >= 0) && ((x - 64) < (1 << size)))
MxMask[0][number][size][x % 160] = true;
MxMask[number][size][x % 160] = true;
}
else
{
if((x >= 0) && (x < (1 << 2)))
MxMask[0][number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
MxMask[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);
MxMask[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);
MxMask[number][4][x % 160] = ((x - 2) % 4 == 0 ? false : true);
}
break;
}
@ -348,62 +329,37 @@ void TIATables::buildMxMaskTable()
// Copy data into wrap-around area
for(x = 0; x < 160; ++x)
MxMask[0][number][size][x + 160] =
MxMask[0][number][size][x];
}
}
// Now, copy data for alignments of 1, 2 and 3
for(uInt32 align = 1; align < 4; ++align)
{
for(number = 0; number < 8; ++number)
{
for(size = 0; size < 5; ++size)
{
for(x = 0; x < 320; ++x)
{
MxMask[align][number][size][x] =
MxMask[0][number][size][(x + 320 - align) % 320];
}
}
MxMask[number][size][x + 160] =
MxMask[number][size][x];
}
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// [4][4][320]
// [alignment][size][pixel]
// [size:4][pixel:320]
void TIATables::buildBLMaskTable()
{
// First, calculate masks for alignment 0
for(Int32 size = 0; size < 4; ++size)
{
Int32 x;
// Set all of the masks to false to start with
for(x = 0; x < 160; ++x)
BLMask[0][size][x] = false;
BLMask[size][x] = false;
// Set the necessary fields true
for(x = 0; x < 160 + 8; ++x)
if((x >= 0) && (x < (1 << size)))
BLMask[0][size][x % 160] = true;
BLMask[size][x % 160] = true;
// Copy fields into the wrap-around area of the mask
for(x = 0; x < 160; ++x)
BLMask[0][size][x + 160] = BLMask[0][size][x];
BLMask[size][x + 160] = BLMask[size][x];
}
// Now, copy data for alignments of 1, 2 and 3
for(uInt32 align = 1; align < 4; ++align)
for(uInt32 size = 0; size < 4; ++size)
for(uInt32 x = 0; x < 320; ++x)
BLMask[align][size][x] = BLMask[0][size][(x + 320 - align) % 320];
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// [2][160]
// [reflect, pixel]
// [reflect:2][pixel:160]
// reflect=1: reflection on
// reflect=0: reflection off
void TIATables::buildPFMaskTable()
@ -460,8 +416,7 @@ void TIATables::buildGRPReflectTable()
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// [8][160][160]
// [nusiz][old pixel][new pixel]
// [nusiz:8][old pixel:160][new pixel:160]
void TIATables::buildPxPosResetWhenTable()
{
uInt32 nusiz, oldx, newx;
@ -601,15 +556,6 @@ void TIATables::buildPxPosResetWhenTable()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIATables::BLMask[4][4][320];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt16 TIATables::CollisionMask[64];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIATables::DisabledMask[640];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Int16 TIATables::PokeDelay[64] = {
0, // VSYNC
@ -661,9 +607,6 @@ const Int16 TIATables::PokeDelay[64] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIATables::MxMask[4][8][5][320];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const bool TIATables::HMOVEBlankEnableCycles[76] = {
true, true, true, true, true, true, true, true, true, true, // 00
@ -759,13 +702,25 @@ const Int32 TIATables::CompleteMotion[76][16] = {
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIATables::PxMask[4][2][8][320];
uInt8 TIATables::PxMask[2][8][320];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int8 TIATables::PxPosResetWhen[8][160][160];
uInt8 TIATables::MxMask[8][5][320];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIATables::BLMask[4][320];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIATables::PFMask[2][160];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIATables::GRPReflect[256];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 TIATables::PFMask[2][160];
uInt16 TIATables::CollisionMask[64];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 TIATables::DisabledMask[640];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int8 TIATables::PxPosResetWhen[8][160][160];

View File

@ -143,12 +143,31 @@ class TIATables
*/
static void computeAllTables();
// Used to set the collision register to the correct value
static uInt16 CollisionMask[64];
// Player mask table
// [suppress mode][nusiz][pixel]
static uInt8 PxMask[2][8][320];
// Missle mask table (entries are true or false)
// [number][size][pixel]
// 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[8][5][320];
// Ball mask table (entries are true or false)
// [size][pixel]
static uInt8 BLMask[4][320];
// Playfield mask table for reflected and non-reflected playfields
// [reflect, pixel]
static uInt32 PFMask[2][160];
// A mask table which can be used when an object is disabled
static uInt8 DisabledMask[640];
// Used to set the collision register to the correct value
static uInt16 CollisionMask[64];
// Indicates the update delay associated with poking at a TIA address
static const Int16 PokeDelay[64];
@ -161,25 +180,6 @@ class TIATables
// Indicates if HMOVE blanks should occur for the corresponding cycle
static const bool HMOVEBlankEnableCycles[76];
// Player mask table
// [alignment][suppress mode][nusiz][pixel]
static uInt8 PxMask[4][2][8][320];
// Missle mask table (entries are true or false)
// [alignment][number][size][pixel]
// 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]
static uInt8 BLMask[4][4][320];
// Playfield mask table for reflected and non-reflected playfields
// [reflect, pixel]
static uInt32 PFMask[2][160];
// Used to reflect a players graphics
static uInt8 GRPReflect[256];