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:
parent
dac438ec02
commit
b95b3d5a5f
|
@ -21,8 +21,39 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
static byte CXPF = 0x10;
|
static byte CXPF = 0x10;
|
||||||
static byte CXBL = 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
|
struct playerData
|
||||||
{
|
{
|
||||||
|
public missileData missile;
|
||||||
public byte grp;
|
public byte grp;
|
||||||
public byte dgrp;
|
public byte dgrp;
|
||||||
public byte color;
|
public byte color;
|
||||||
|
@ -34,7 +65,6 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
public bool delay;
|
public bool delay;
|
||||||
public byte nusiz;
|
public byte nusiz;
|
||||||
public bool reset;
|
public bool reset;
|
||||||
public bool drawing;
|
|
||||||
public byte resetCnt;
|
public byte resetCnt;
|
||||||
public byte collisions;
|
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
|
// Increment counter
|
||||||
// When this reaches 8, we've run out of pixel
|
// When this reaches 8, we've run out of pixel
|
||||||
|
|
||||||
|
@ -200,6 +236,7 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
public bool hmoveEnabled;
|
public bool hmoveEnabled;
|
||||||
public bool hmoveJustStarted;
|
public bool hmoveJustStarted;
|
||||||
public bool lateHBlankReset;
|
public bool lateHBlankReset;
|
||||||
|
public bool decCntEnabled;
|
||||||
|
|
||||||
public bool player0Latch;
|
public bool player0Latch;
|
||||||
public bool player1Latch;
|
public bool player1Latch;
|
||||||
|
@ -207,6 +244,10 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
public bool missile1Latch;
|
public bool missile1Latch;
|
||||||
public bool ballLatch;
|
public bool ballLatch;
|
||||||
|
|
||||||
|
public bool missile0inf;
|
||||||
|
|
||||||
|
public byte hmoveDelayCnt;
|
||||||
|
|
||||||
public byte hmoveCnt;
|
public byte hmoveCnt;
|
||||||
|
|
||||||
public byte player0Cnt;
|
public byte player0Cnt;
|
||||||
|
@ -311,13 +352,19 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
|
|
||||||
|
|
||||||
// ---- Player 0 ----
|
// ---- 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 ----
|
// ---- Player 1 ----
|
||||||
collisions |= (byte)(player1.tick() ? CXP1 : 0x00);
|
collisions |= (player1.tick() ? CXP1 : (byte)0x00);
|
||||||
|
|
||||||
|
// ---- Missile 0 ----
|
||||||
|
collisions |= (player1.missile.tick() ? CXM1 : (byte)0x00);
|
||||||
|
|
||||||
// ---- Ball ----
|
// ---- Ball ----
|
||||||
collisions |= (byte)(ball.tick() ? CXBL : 0x00);
|
collisions |= (ball.tick() ? CXBL : (byte)0x00);
|
||||||
|
|
||||||
|
|
||||||
// Pick the pixel color from collisions
|
// Pick the pixel color from collisions
|
||||||
|
@ -348,12 +395,24 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
pixelColor = palette[playField.pfColor];
|
pixelColor = palette[playField.pfColor];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((collisions & CXM1) != 0)
|
||||||
|
{
|
||||||
|
player1.missile.collisions |= collisions;
|
||||||
|
pixelColor = palette[player1.color];
|
||||||
|
}
|
||||||
|
|
||||||
if ((collisions & CXP1) != 0)
|
if ((collisions & CXP1) != 0)
|
||||||
{
|
{
|
||||||
player1.collisions |= collisions;
|
player1.collisions |= collisions;
|
||||||
pixelColor = palette[player1.color];
|
pixelColor = palette[player1.color];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((collisions & CXM0) != 0)
|
||||||
|
{
|
||||||
|
player0.missile.collisions |= collisions;
|
||||||
|
pixelColor = palette[player0.color];
|
||||||
|
}
|
||||||
|
|
||||||
if ((collisions & CXP0) != 0)
|
if ((collisions & CXP0) != 0)
|
||||||
{
|
{
|
||||||
player0.collisions |= collisions;
|
player0.collisions |= collisions;
|
||||||
|
@ -402,19 +461,28 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
hmove.player0Latch = true;
|
hmove.player0Latch = true;
|
||||||
hmove.player0Cnt = 0;
|
hmove.player0Cnt = 0;
|
||||||
|
|
||||||
|
hmove.missile0Latch = true;
|
||||||
|
hmove.missile0inf = false;
|
||||||
|
hmove.missile0Cnt = 0;
|
||||||
|
|
||||||
hmove.player1Latch = true;
|
hmove.player1Latch = true;
|
||||||
hmove.player1Cnt = 0;
|
hmove.player1Cnt = 0;
|
||||||
|
|
||||||
|
hmove.missile1Latch = true;
|
||||||
|
hmove.missile1Cnt = 0;
|
||||||
|
|
||||||
hmove.ballLatch = true;
|
hmove.ballLatch = true;
|
||||||
hmove.ballCnt = 0;
|
hmove.ballCnt = 0;
|
||||||
|
|
||||||
hmove.hmoveCnt = 0;
|
hmove.hmoveCnt = 0;
|
||||||
|
|
||||||
hmove.hmoveCnt++;
|
//hmove.hmoveCnt++;
|
||||||
hmove.hmoveJustStarted = false;
|
hmove.hmoveJustStarted = false;
|
||||||
hmove.lateHBlankReset = true;
|
hmove.lateHBlankReset = true;
|
||||||
|
hmove.decCntEnabled = false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (hmove.decCntEnabled)
|
||||||
{
|
{
|
||||||
// Actually do stuff only evey 4 pulses
|
// Actually do stuff only evey 4 pulses
|
||||||
if (hmove.hmoveCnt == 0)
|
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 (hmove.player1Latch)
|
||||||
{
|
{
|
||||||
// If the move counter still has a bit in common with the HM register
|
// 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 (hmove.ballLatch)
|
||||||
{
|
{
|
||||||
// If the move counter still has a bit in common with the HM register
|
// 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.hmoveEnabled = false;
|
||||||
|
hmove.decCntEnabled = false;
|
||||||
|
hmove.hmoveDelayCnt = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hmove.hmoveJustStarted = false;
|
//hmove.hmoveJustStarted = false;
|
||||||
hmove.hmoveCnt++;
|
hmove.hmoveCnt++;
|
||||||
hmove.hmoveCnt %= 4;
|
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
|
// Increment the hsync counter
|
||||||
hsyncCnt++;
|
hsyncCnt++;
|
||||||
hsyncCnt %= 228;
|
hsyncCnt %= 228;
|
||||||
|
@ -522,6 +649,43 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
{
|
{
|
||||||
ushort maskedAddr = (ushort)(addr & 0x000F);
|
ushort maskedAddr = (ushort)(addr & 0x000F);
|
||||||
Console.WriteLine("TIA read: " + maskedAddr.ToString("x"));
|
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;
|
return 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,6 +723,7 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
else if (maskedAddr == 0x04) // NUSIZ0
|
else if (maskedAddr == 0x04) // NUSIZ0
|
||||||
{
|
{
|
||||||
player0.nusiz = (byte)(value & 0x37);
|
player0.nusiz = (byte)(value & 0x37);
|
||||||
|
player0.missile.size = (byte)((value & 0x30) >> 4);
|
||||||
}
|
}
|
||||||
else if (maskedAddr == 0x05) // NUSIZ1
|
else if (maskedAddr == 0x05) // NUSIZ1
|
||||||
{
|
{
|
||||||
|
@ -615,6 +780,14 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
{
|
{
|
||||||
player1.resetCnt = 0;
|
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
|
else if (maskedAddr == 0x14) // RESBL
|
||||||
{
|
{
|
||||||
ball.hPosCnt = 160-4;
|
ball.hPosCnt = 160-4;
|
||||||
|
@ -636,6 +809,17 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
{
|
{
|
||||||
player1.grp = value;
|
player1.grp = value;
|
||||||
player0.dgrp = player0.grp;
|
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
|
else if (maskedAddr == 0x1F) // ENABL
|
||||||
{
|
{
|
||||||
|
@ -649,6 +833,14 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
{
|
{
|
||||||
player1.HM = (byte)((value & 0xF0) >> 4);
|
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
|
else if (maskedAddr == 0x24) // HMBL
|
||||||
{
|
{
|
||||||
ball.HM = (byte)((value & 0xF0) >> 4);
|
ball.HM = (byte)((value & 0xF0) >> 4);
|
||||||
|
@ -661,20 +853,39 @@ namespace BizHawk.Emulation.Consoles.Atari
|
||||||
{
|
{
|
||||||
player1.delay = (value & 0x01) != 0;
|
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
|
else if (maskedAddr == 0x2A) // HMOVE
|
||||||
{
|
{
|
||||||
hmove.hmoveEnabled = true;
|
hmove.hmoveEnabled = true;
|
||||||
hmove.hmoveJustStarted = true;
|
hmove.hmoveJustStarted = true;
|
||||||
|
hmove.hmoveDelayCnt = 0;
|
||||||
}
|
}
|
||||||
else if (maskedAddr == 0x2B) // HMCLR
|
else if (maskedAddr == 0x2B) // HMCLR
|
||||||
{
|
{
|
||||||
player0.HM = 0;
|
player0.HM = 0;
|
||||||
|
player0.missile.HM = 0;
|
||||||
player1.HM = 0;
|
player1.HM = 0;
|
||||||
|
player1.missile.HM = 0;
|
||||||
ball.HM = 0;
|
ball.HM = 0;
|
||||||
}
|
}
|
||||||
else if (maskedAddr == 0x2C) // CXCLR
|
else if (maskedAddr == 0x2C) // CXCLR
|
||||||
{
|
{
|
||||||
|
player0.collisions = 0;
|
||||||
|
player0.missile.collisions = 0;
|
||||||
|
player1.collisions = 0;
|
||||||
|
player1.missile.collisions = 0;
|
||||||
|
ball.collisions = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue