TIA: Added missile graphics. Attempted to make hmove show cosmic ark's starfield correctly, with some luck. Still not correct though. Added collisions.

This commit is contained in:
pjgat09 2012-03-17 03:10:49 +00:00
parent dac438ec02
commit b95b3d5a5f
1 changed files with 221 additions and 10 deletions

View File

@ -21,8 +21,39 @@ namespace BizHawk.Emulation.Consoles.Atari
static byte CXPF = 0x10;
static byte CXBL = 0x10;
struct missileData
{
public bool enabled;
public bool resetToPlayer;
public byte hPosCnt;
public byte size;
public byte HM;
public byte collisions;
public bool tick()
{
bool result = false;
if (hPosCnt < (1 << size))
{
if (enabled && !resetToPlayer)
{
// Draw the missile
result = true;
}
}
// Increment the counter
hPosCnt++;
// Counter loops at 160
hPosCnt %= 160;
return result;
}
}
struct playerData
{
public missileData missile;
public byte grp;
public byte dgrp;
public byte color;
@ -34,7 +65,6 @@ namespace BizHawk.Emulation.Consoles.Atari
public bool delay;
public byte nusiz;
public bool reset;
public bool drawing;
public byte resetCnt;
public byte collisions;
@ -68,6 +98,12 @@ namespace BizHawk.Emulation.Consoles.Atari
}
}
// Reset missile, if desired
if (scanCnt == 0x04 && missile.resetToPlayer)
{
missile.hPosCnt = 0;
}
// Increment counter
// When this reaches 8, we've run out of pixel
@ -200,6 +236,7 @@ namespace BizHawk.Emulation.Consoles.Atari
public bool hmoveEnabled;
public bool hmoveJustStarted;
public bool lateHBlankReset;
public bool decCntEnabled;
public bool player0Latch;
public bool player1Latch;
@ -207,6 +244,10 @@ namespace BizHawk.Emulation.Consoles.Atari
public bool missile1Latch;
public bool ballLatch;
public bool missile0inf;
public byte hmoveDelayCnt;
public byte hmoveCnt;
public byte player0Cnt;
@ -311,13 +352,19 @@ namespace BizHawk.Emulation.Consoles.Atari
// ---- Player 0 ----
collisions |= (byte)(player0.tick() ? CXP0 : 0x00);
collisions |= (player0.tick() ? CXP0 : (byte)0x00);
// ---- Missile 0 ----
collisions |= (player0.missile.tick() ? CXM0 : (byte)0x00);
// ---- Player 1 ----
collisions |= (byte)(player1.tick() ? CXP1 : 0x00);
collisions |= (player1.tick() ? CXP1 : (byte)0x00);
// ---- Missile 0 ----
collisions |= (player1.missile.tick() ? CXM1 : (byte)0x00);
// ---- Ball ----
collisions |= (byte)(ball.tick() ? CXBL : 0x00);
collisions |= (ball.tick() ? CXBL : (byte)0x00);
// Pick the pixel color from collisions
@ -348,12 +395,24 @@ namespace BizHawk.Emulation.Consoles.Atari
pixelColor = palette[playField.pfColor];
}
if ((collisions & CXM1) != 0)
{
player1.missile.collisions |= collisions;
pixelColor = palette[player1.color];
}
if ((collisions & CXP1) != 0)
{
player1.collisions |= collisions;
pixelColor = palette[player1.color];
}
if ((collisions & CXM0) != 0)
{
player0.missile.collisions |= collisions;
pixelColor = palette[player0.color];
}
if ((collisions & CXP0) != 0)
{
player0.collisions |= collisions;
@ -402,19 +461,28 @@ namespace BizHawk.Emulation.Consoles.Atari
hmove.player0Latch = true;
hmove.player0Cnt = 0;
hmove.missile0Latch = true;
hmove.missile0inf = false;
hmove.missile0Cnt = 0;
hmove.player1Latch = true;
hmove.player1Cnt = 0;
hmove.missile1Latch = true;
hmove.missile1Cnt = 0;
hmove.ballLatch = true;
hmove.ballCnt = 0;
hmove.hmoveCnt = 0;
hmove.hmoveCnt++;
//hmove.hmoveCnt++;
hmove.hmoveJustStarted = false;
hmove.lateHBlankReset = true;
hmove.decCntEnabled = false;
}
else
if (hmove.decCntEnabled)
{
// Actually do stuff only evey 4 pulses
if (hmove.hmoveCnt == 0)
@ -438,6 +506,32 @@ namespace BizHawk.Emulation.Consoles.Atari
}
}
if (hmove.missile0Latch)
{
if (hmove.missile0Cnt == 15)
{ }
// If the move counter still has a bit in common with the HM register
if (hmove.missile0inf || ((15 - hmove.missile0Cnt) ^ ((player0.missile.HM & 0x07) | ((~(player0.missile.HM & 0x08)) & 0x08))) != 0x0F)
{
// "Clock-Stuffing"
player0.missile.tick();
// Increase by 1, max of 15
hmove.missile0Cnt++;
hmove.missile0Cnt %= 16;
if (hmove.missile0Cnt == 0)
{
hmove.missile0inf = true;
}
}
else
{
hmove.missile0Latch = false;
hmove.missile0Cnt = 0;
}
}
if (hmove.player1Latch)
{
// If the move counter still has a bit in common with the HM register
@ -456,6 +550,24 @@ namespace BizHawk.Emulation.Consoles.Atari
}
}
if (hmove.missile1Latch)
{
// If the move counter still has a bit in common with the HM register
if (((15 - hmove.missile1Cnt) ^ ((player1.missile.HM & 0x07) | ((~(player1.missile.HM & 0x08)) & 0x08))) != 0x0F)
{
// "Clock-Stuffing"
player1.missile.tick();
// Increase by 1, max of 15
hmove.missile1Cnt++;
hmove.missile1Cnt %= 16;
}
else
{
hmove.missile1Latch = false;
}
}
if (hmove.ballLatch)
{
// If the move counter still has a bit in common with the HM register
@ -474,18 +586,33 @@ namespace BizHawk.Emulation.Consoles.Atari
}
}
if (!hmove.player0Latch && !hmove.player1Latch && !hmove.ballLatch)
if (!hmove.player0Latch && !hmove.player1Latch && !hmove.ballLatch && !hmove.missile0Latch && !hmove.missile1Latch)
{
hmove.hmoveEnabled = false;
hmove.decCntEnabled = false;
hmove.hmoveDelayCnt = 0;
}
}
hmove.hmoveJustStarted = false;
//hmove.hmoveJustStarted = false;
hmove.hmoveCnt++;
hmove.hmoveCnt %= 4;
}
if (hmove.hmoveDelayCnt < 6)
{
hmove.hmoveDelayCnt++;
}
if (hmove.hmoveDelayCnt == 6)
{
hmove.hmoveDelayCnt++;
hmove.hmoveCnt = 0;
hmove.decCntEnabled = true;
}
}
// Increment the hsync counter
hsyncCnt++;
hsyncCnt %= 228;
@ -522,6 +649,43 @@ namespace BizHawk.Emulation.Consoles.Atari
{
ushort maskedAddr = (ushort)(addr & 0x000F);
Console.WriteLine("TIA read: " + maskedAddr.ToString("x"));
if (maskedAddr == 0x00) // CXM0P
{
return (byte)((((player0.missile.collisions & CXP1) != 0) ? 0x80 : 0x00) | (((player0.missile.collisions & CXP0) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x01) // CXM1P
{
return (byte)((((player1.missile.collisions & CXP0) != 0) ? 0x80 : 0x00) | (((player1.missile.collisions & CXP1) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x02) // CXP0FB
{
return (byte)((((player0.collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player0.collisions & CXBL) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x03) // CXP1FB
{
return (byte)((((player1.collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player1.collisions & CXBL) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x04) // CXM0FB
{
return (byte)((((player0.missile.collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player0.missile.collisions & CXBL) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x05) // CXM1FB
{
return (byte)((((player1.missile.collisions & CXPF) != 0) ? 0x80 : 0x00) | (((player1.missile.collisions & CXBL) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x06) // CXBLPF
{
return (byte)(((ball.collisions & CXPF) != 0) ? 0x80 : 0x00);
}
else if (maskedAddr == 0x07) // CXPPMM
{
return (byte)((((player0.collisions & CXP1) != 0) ? 0x80 : 0x00) | (((player0.missile.collisions & CXM1) != 0) ? 0x40 : 0x00));
}
else if (maskedAddr == 0x0C) // INPT4
{
return (byte)((core.ReadControls1() & 0x08) != 0 ? 0x80 : 0x00);
}
return 0x00;
}
@ -559,6 +723,7 @@ namespace BizHawk.Emulation.Consoles.Atari
else if (maskedAddr == 0x04) // NUSIZ0
{
player0.nusiz = (byte)(value & 0x37);
player0.missile.size = (byte)((value & 0x30) >> 4);
}
else if (maskedAddr == 0x05) // NUSIZ1
{
@ -615,6 +780,14 @@ namespace BizHawk.Emulation.Consoles.Atari
{
player1.resetCnt = 0;
}
else if (maskedAddr == 0x12) // RESM0
{
player0.missile.hPosCnt = 160 - 4;
}
else if (maskedAddr == 0x13) // RESM1
{
player1.missile.hPosCnt = 160 - 4;
}
else if (maskedAddr == 0x14) // RESBL
{
ball.hPosCnt = 160-4;
@ -636,6 +809,17 @@ namespace BizHawk.Emulation.Consoles.Atari
{
player1.grp = value;
player0.dgrp = player0.grp;
// TODO: Find a game that uses this functionality and test it
ball.denabled = ball.enabled;
}
else if (maskedAddr == 0x1D) // ENAM0
{
player0.missile.enabled = (value & 0x02) != 0;
}
else if (maskedAddr == 0x1E) // ENAM1
{
player1.missile.enabled = (value & 0x02) != 0;
}
else if (maskedAddr == 0x1F) // ENABL
{
@ -649,6 +833,14 @@ namespace BizHawk.Emulation.Consoles.Atari
{
player1.HM = (byte)((value & 0xF0) >> 4);
}
else if (maskedAddr == 0x22) // HMM0
{
player0.missile.HM = (byte)((value & 0xF0) >> 4);
}
else if (maskedAddr == 0x23) // HMM1
{
player1.missile.HM = (byte)((value & 0xF0) >> 4);
}
else if (maskedAddr == 0x24) // HMBL
{
ball.HM = (byte)((value & 0xF0) >> 4);
@ -661,20 +853,39 @@ namespace BizHawk.Emulation.Consoles.Atari
{
player1.delay = (value & 0x01) != 0;
}
else if (maskedAddr == 0x27) // VDELBL
{
ball.delay = (value & 0x01) != 0;
}
else if (maskedAddr == 0x28) // RESMP0
{
player0.missile.resetToPlayer = (value & 0x02) != 0;
}
else if (maskedAddr == 0x29) // RESMP1
{
player1.missile.resetToPlayer = (value & 0x02) != 0;
}
else if (maskedAddr == 0x2A) // HMOVE
{
hmove.hmoveEnabled = true;
hmove.hmoveJustStarted = true;
hmove.hmoveDelayCnt = 0;
}
else if (maskedAddr == 0x2B) // HMCLR
{
player0.HM = 0;
player0.missile.HM = 0;
player1.HM = 0;
player1.missile.HM = 0;
ball.HM = 0;
}
else if (maskedAddr == 0x2C) // CXCLR
{
player0.collisions = 0;
player0.missile.collisions = 0;
player1.collisions = 0;
player1.missile.collisions = 0;
ball.collisions = 0;
}
}