misc. cleanup for Coleco and Intellivision

This commit is contained in:
adelikat 2017-04-24 12:24:56 -05:00
parent 4c71a34dfa
commit 7f663a0ed6
19 changed files with 349 additions and 266 deletions

View File

@ -97,20 +97,20 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
CoreComm.VsyncNum = 16000000; // 16.00 mhz refclock CoreComm.VsyncNum = 16000000; // 16.00 mhz refclock
CoreComm.VsyncDen = 16 * 105 * 159; CoreComm.VsyncDen = 16 * 105 * 159;
savebuff = new byte[LibLynx.BinStateSize(Core)]; _savebuff = new byte[LibLynx.BinStateSize(Core)];
savebuff2 = new byte[savebuff.Length + 13]; _savebuff2 = new byte[_savebuff.Length + 13];
int rot = game.OptionPresent("rotate") ? int.Parse(game.OptionValue("rotate")) : 0; int rot = game.OptionPresent("rotate") ? int.Parse(game.OptionValue("rotate")) : 0;
LibLynx.SetRotation(Core, rot); LibLynx.SetRotation(Core, rot);
if ((rot & 1) != 0) if ((rot & 1) != 0)
{ {
BufferWidth = HEIGHT; BufferWidth = Height;
BufferHeight = WIDTH; BufferHeight = Width;
} }
else else
{ {
BufferWidth = WIDTH; BufferWidth = Width;
BufferHeight = HEIGHT; BufferHeight = Height;
} }
SetupMemoryDomains(); SetupMemoryDomains();
} }
@ -131,9 +131,9 @@ namespace BizHawk.Emulation.Cores.Atari.Lynx
LibLynx.Reset(Core); LibLynx.Reset(Core);
} }
int samples = soundbuff.Length; int samples = _soundbuff.Length;
IsLagFrame = LibLynx.Advance(Core, GetButtons(), videobuff, soundbuff, ref samples); IsLagFrame = LibLynx.Advance(Core, GetButtons(), _videobuff, _soundbuff, ref samples);
numsamp = samples / 2; // sound provider wants number of sample pairs _numsamp = samples / 2; // sound provider wants number of sample pairs
if (IsLagFrame) if (IsLagFrame)
{ {
LagCount++; LagCount++;

View File

@ -46,18 +46,24 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public byte ReadPort1(IController c, bool left_mode, bool update_wheel) public byte ReadPort1(IController c, bool left_mode, bool update_wheel)
{ {
if (update_wheel) if (update_wheel)
{
wheel1 = Port1.Update_Wheel(c, wheel1); wheel1 = Port1.Update_Wheel(c, wheel1);
}
return Port1.Read(c, left_mode, wheel1); return Port1.Read(c, left_mode, wheel1);
} }
public byte ReadPort2(IController c, bool left_mode, bool update_wheel) public byte ReadPort2(IController c, bool left_mode, bool update_wheel)
{ {
if (update_wheel) if (update_wheel)
{
wheel2 = Port2.Update_Wheel(c, wheel2); wheel2 = Port2.Update_Wheel(c, wheel2);
}
return Port2.Read(c, left_mode, wheel2); return Port2.Read(c, left_mode, wheel2);
} }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
@ -94,10 +100,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
} }
public static string DefaultControllerName public static string DefaultControllerName => typeof(StandardController).DisplayName();
{
get { return typeof(StandardController).DisplayName(); }
}
} }
} }

View File

@ -9,7 +9,7 @@ using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.ColecoVision namespace BizHawk.Emulation.Cores.ColecoVision
{ {
/// <summary> /// <summary>
/// Represents a controller plugged into a controller port on the intellivision /// Represents a controller plugged into a controller port on the Colecovision
/// </summary> /// </summary>
public interface IPort public interface IPort
{ {
@ -41,14 +41,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
return 0; // needs checking return 0; // needs checking
} }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
// Do nothing // Do nothing
} }
public int PortNum { get; private set; } public int PortNum { get; }
public int Update_Wheel(IController c, int wheel) public int Update_Wheel(IController c, int wheel)
{ {
@ -70,11 +70,11 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}; };
} }
public int PortNum { get; private set; } public int PortNum { get; }
public byte Read(IController c, bool left_mode, int wheel) public byte Read(IController c, bool leftMode, int wheel)
{ {
if (left_mode) if (leftMode)
{ {
byte retval = 0x7F; byte retval = 0x7F;
if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0xFE; if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0xFE;
@ -109,7 +109,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
} }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
@ -146,13 +146,13 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}; };
} }
public int PortNum { get; private set; } public int PortNum { get; }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; }
public byte Read(IController c, bool left_mode, int wheel) public byte Read(IController c, bool leftMode, int wheel)
{ {
if (left_mode) if (leftMode)
{ {
byte retval = 0x4B; byte retval = 0x4B;
@ -163,7 +163,8 @@ namespace BizHawk.Emulation.Cores.ColecoVision
retval |= CalcDirection(x, y); retval |= CalcDirection(x, y);
return retval; return retval;
} else }
else
{ {
byte retval = 0x4B; byte retval = 0x4B;
if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0x3F; if (c.IsPressed(Definition.BoolButtons[0])) retval &= 0x3F;
@ -194,20 +195,28 @@ namespace BizHawk.Emulation.Cores.ColecoVision
y = -y; // vflip to match the arrangement of FloatControllerButtons y = -y; // vflip to match the arrangement of FloatControllerButtons
if (y >= 0 && x > 0) if (y >= 0 && x > 0)
{
return 0x10; return 0x10;
}
if (y >= 0 && x <= 0) if (y >= 0 && x <= 0)
{
return 0x30; return 0x30;
}
if (y < 0 && x <= 0) if (y < 0 && x <= 0)
{
return 0x20; return 0x20;
}
if (y < 0 && x > 0) if (y < 0 && x > 0)
{
return 0x00; return 0x00;
}
Console.WriteLine("Error"); Console.WriteLine("Error");
return 0x1F; return 0x1F;
} }
//private const int Deadzone = 50;
public int Update_Wheel(IController c, int wheel) public int Update_Wheel(IController c, int wheel)
{ {
return 0; return 0;
@ -230,8 +239,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
}; };
} }
public int wheel_state { get; set; }
public int PortNum { get; private set; } public int PortNum { get; private set; }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; private set; }
@ -299,19 +306,28 @@ namespace BizHawk.Emulation.Cores.ColecoVision
byte retval = 0; byte retval = 0;
if (wheel >= 0 && wheel < 180) if (wheel >= 0 && wheel < 180)
{
retval = 0x00; retval = 0x00;
}
if (wheel >= 180 && wheel < 360) if (wheel >= 180 && wheel < 360)
{
retval = 0x10; retval = 0x10;
if (wheel <0 && wheel > -180) }
if (wheel < 0 && wheel > -180)
{
retval = 0x20; retval = 0x20;
if (wheel <= -180 && wheel >-360) }
if (wheel <= -180 && wheel > -360)
{
retval = 0x30; retval = 0x30;
}
return retval; return retval;
} }
//private const int Deadzone = 50;
public int Update_Wheel(IController c, int wheel) public int Update_Wheel(IController c, int wheel)
{ {
int x = (int)c.GetFloat(Definition.FloatControls[0]); int x = (int)c.GetFloat(Definition.FloatControls[0]);
@ -321,10 +337,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
wheel += diff; wheel += diff;
if (wheel >= 360) if (wheel >= 360)
{
wheel = wheel - 360; wheel = wheel - 360;
}
if (wheel <= -360) if (wheel <= -360)
{
wheel = wheel + 360; wheel = wheel + 360;
}
return wheel; return wheel;
} }

View File

@ -5,6 +5,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public partial class ColecoVision public partial class ColecoVision
{ {
private SN76489 PSG; private SN76489 PSG;
private FakeSyncSound _fakeSyncSound; private readonly FakeSyncSound _fakeSyncSound;
} }
} }

View File

@ -9,8 +9,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
"ColecoHawk", "ColecoHawk",
"Vecna", "Vecna",
isPorted: false, isPorted: false,
isReleased: true isReleased: true)]
)]
[ServiceNotApplicable(typeof(ISaveRam), typeof(IDriveLight))] [ServiceNotApplicable(typeof(ISaveRam), typeof(IDriveLight))]
public sealed partial class ColecoVision : IEmulator, IDebuggable, IInputPollable, IStatable, ISettable<ColecoVision.ColecoSettings, ColecoVision.ColecoSyncSettings> public sealed partial class ColecoVision : IEmulator, IDebuggable, IInputPollable, IStatable, ISettable<ColecoVision.ColecoSettings, ColecoVision.ColecoSyncSettings>
{ {
@ -23,7 +22,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
private Z80A Cpu; private Z80A Cpu;
private TMS9918A VDP; private TMS9918A VDP;
public byte[] Ram = new byte[1024]; private byte[] Ram = new byte[1024];
private readonly TraceBuffer Tracer = new TraceBuffer(); private readonly TraceBuffer Tracer = new TraceBuffer();
[CoreConstructor("Coleco")] [CoreConstructor("Coleco")]
@ -74,12 +73,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public IEmulatorServiceProvider ServiceProvider { get; } public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition public ControllerDefinition ControllerDefinition => ControllerDeck.Definition;
{
get { return ControllerDeck.Definition; }
}
public ColecoVisionControllerDeck ControllerDeck { get; } private readonly ColecoVisionControllerDeck ControllerDeck;
public IController Controller { get; set; } public IController Controller { get; set; }
@ -97,12 +93,12 @@ namespace BizHawk.Emulation.Cores.ColecoVision
Cpu.Logger = (s) => Tracer.Put(s); Cpu.Logger = (s) => Tracer.Put(s);
} }
byte temp_ret1 = ControllerDeck.ReadPort1(Controller, true, true); byte tempRet1 = ControllerDeck.ReadPort1(Controller, true, true);
byte temp_ret2 = ControllerDeck.ReadPort2(Controller, true, true); byte tempRet2 = ControllerDeck.ReadPort2(Controller, true, true);
bool Int_pending = (!temp_ret1.Bit(4)) | (!temp_ret2.Bit(4)); bool intPending = (!tempRet1.Bit(4)) | (!tempRet2.Bit(4));
VDP.ExecuteFrame(Int_pending); VDP.ExecuteFrame(intPending);
PSG.EndFrame(Cpu.TotalExecutedCycles); PSG.EndFrame(Cpu.TotalExecutedCycles);
@ -116,7 +112,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
{ {
RomData = new byte[0x8000]; RomData = new byte[0x8000];
for (int i = 0; i < 0x8000; i++) for (int i = 0; i < 0x8000; i++)
{
RomData[i] = rom[i % rom.Length]; RomData[i] = rom[i % rom.Length];
}
// hack to skip colecovision title screen // hack to skip colecovision title screen
if (skipbios) if (skipbios)
@ -160,9 +158,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
if (port >= 0xA0 && port <= 0xBF) if (port >= 0xA0 && port <= 0xBF)
{ {
if ((port & 1) == 0) if ((port & 1) == 0)
{
VDP.WriteVdpData(value); VDP.WriteVdpData(value);
}
else else
{
VDP.WriteVdpControl(value); VDP.WriteVdpControl(value);
}
return; return;
} }
@ -187,7 +190,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public bool DeterministicEmulation => true; public bool DeterministicEmulation => true;
public void Dispose() { } public void Dispose()
{
}
public void ResetCounters() public void ResetCounters()
{ {

View File

@ -2,25 +2,8 @@
{ {
public partial class ColecoVision public partial class ColecoVision
{ {
/* public static readonly ControllerDefinition ColecoVisionControllerDefinition = new ControllerDefinition
{
Name = "ColecoVision Basic Controller",
BoolButtons =
{
"P1 Up", "P1 Down", "P1 Left", "P1 Right",
"P1 L", "P1 R",
"P1 Key 0", "P1 Key 1", "P1 Key 2", "P1 Key 3", "P1 Key 4", "P1 Key 5",
"P1 Key 6", "P1 Key 7", "P1 Key 8", "P1 Key 9", "P1 Star", "P1 Pound",
"P2 Up", "P2 Down", "P2 Left", "P2 Right",
"P2 L", "P2 R",
"P2 Key 0", "P2 Key 1", "P2 Key 2", "P2 Key 3", "P2 Key 4", "P2 Key 5",
"P2 Key 6", "P2 Key 7", "P2 Key 8", "P2 Key 9", "P2 Star", "P2 Pound"
}
};
*/
public enum InputPortMode { Left, Right } public enum InputPortMode { Left, Right }
InputPortMode InputPortSelection; private InputPortMode InputPortSelection;
private byte ReadController1() private byte ReadController1()
{ {
@ -58,7 +41,12 @@
return 0x7F; return 0x7F;
} }
public int Frame { get { return frame; } set { frame = value; } } public int Frame
{
get { return frame; }
private set { frame = value; }
}
private int frame; private int frame;
} }
} }

View File

@ -5,11 +5,19 @@
public byte ReadMemory(ushort addr) public byte ReadMemory(ushort addr)
{ {
if (addr >= 0x8000) if (addr >= 0x8000)
{
return RomData[addr & 0x7FFF]; return RomData[addr & 0x7FFF];
}
if (addr >= 0x6000) if (addr >= 0x6000)
{
return Ram[addr & 1023]; return Ram[addr & 1023];
}
if (addr < 0x2000) if (addr < 0x2000)
{
return BiosRom[addr]; return BiosRom[addr];
}
//Console.WriteLine("Unhandled read at {0:X4}", addr); //Console.WriteLine("Unhandled read at {0:X4}", addr);
return 0xFF; return 0xFF;

View File

@ -1,5 +1,4 @@
using System; using System;
using System.Globalization;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
@ -10,36 +9,35 @@ namespace BizHawk.Emulation.Cores.ColecoVision
public sealed class TMS9918A : IVideoProvider public sealed class TMS9918A : IVideoProvider
{ {
public byte[] VRAM = new byte[0x4000]; public byte[] VRAM = new byte[0x4000];
byte[] Registers = new byte[8]; private byte[] Registers = new byte[8];
byte StatusByte; private byte StatusByte;
bool VdpWaitingForLatchByte = true; private bool VdpWaitingForLatchByte = true;
byte VdpLatch; private byte VdpLatch;
ushort VdpAddress; private ushort VdpAddress;
byte VdpBuffer; private byte VdpBuffer;
int TmsMode; private int TmsMode;
bool Mode1Bit { get { return (Registers[1] & 16) > 0; } } private bool Mode1Bit => (Registers[1] & 16) > 0;
bool Mode2Bit { get { return (Registers[0] & 2) > 0; } } private bool Mode2Bit => (Registers[0] & 2) > 0;
bool Mode3Bit { get { return (Registers[1] & 8) > 0; } } private bool Mode3Bit => (Registers[1] & 8) > 0;
private bool EnableDoubledSprites => (Registers[1] & 1) > 0;
private bool EnableLargeSprites => (Registers[1] & 2) > 0;
private bool EnableInterrupts => (Registers[1] & 32) > 0;
private bool DisplayOn => (Registers[1] & 64) > 0;
private bool Mode16k => (Registers[1] & 128) > 0;
bool EnableDoubledSprites { get { return (Registers[1] & 1) > 0; } } private bool InterruptPending
bool EnableLargeSprites { get { return (Registers[1] & 2) > 0; } }
bool EnableInterrupts { get { return (Registers[1] & 32) > 0; } }
bool DisplayOn { get { return (Registers[1] & 64) > 0; } }
bool Mode16k { get { return (Registers[1] & 128) > 0; } }
bool InterruptPending
{ {
get { return (StatusByte & 0x80) != 0; } get { return (StatusByte & 0x80) != 0; }
set { StatusByte = (byte)((StatusByte & ~0x02) | (value ? 0x80 : 0x00)); } set { StatusByte = (byte)((StatusByte & ~0x02) | (value ? 0x80 : 0x00)); }
} }
int ColorTableBase; private int ColorTableBase;
int PatternGeneratorBase; private int PatternGeneratorBase;
int SpritePatternGeneratorBase; private int SpritePatternGeneratorBase;
int TmsPatternNameTableBase; private int TmsPatternNameTableBase;
int TmsSpriteAttributeBase; private int TmsSpriteAttributeBase;
public void ExecuteFrame(bool Int_pending) public void ExecuteFrame(bool Int_pending)
{ {
@ -58,7 +56,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
Cpu.ExecuteCycles(228); Cpu.ExecuteCycles(228);
Cpu.Interrupt = false; Cpu.Interrupt = false;
if (Int_pending && scanLine==50) if (Int_pending && scanLine==50)
{ {
@ -68,7 +65,6 @@ namespace BizHawk.Emulation.Cores.ColecoVision
Int_pending = false; Int_pending = false;
} }
} }
} }
} }
@ -165,7 +161,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
return value; return value;
} }
void CheckVideoMode() private void CheckVideoMode()
{ {
if (Mode1Bit) TmsMode = 1; if (Mode1Bit) TmsMode = 1;
else if (Mode2Bit) TmsMode = 2; else if (Mode2Bit) TmsMode = 2;
@ -176,7 +172,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
throw new Exception("TMS video mode 1! please tell vecna which game uses this!"); throw new Exception("TMS video mode 1! please tell vecna which game uses this!");
} }
void RenderScanline(int scanLine) private void RenderScanline(int scanLine)
{ {
if (scanLine >= 192) if (scanLine >= 192)
return; return;
@ -199,7 +195,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
// This may seem silly but if I ever implement mode 1, sprites are not rendered in that. // This may seem silly but if I ever implement mode 1, sprites are not rendered in that.
} }
void RenderBackgroundM0(int scanLine) private void RenderBackgroundM0(int scanLine)
{ {
if (DisplayOn == false) if (DisplayOn == false)
{ {
@ -271,7 +267,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
} }
void RenderBackgroundM3(int scanLine) private void RenderBackgroundM3(int scanLine)
{ {
if (DisplayOn == false) if (DisplayOn == false)
{ {
@ -306,18 +302,22 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
} }
byte[] ScanlinePriorityBuffer = new byte[256]; private readonly byte[] ScanlinePriorityBuffer = new byte[256];
byte[] SpriteCollisionBuffer = new byte[256]; private readonly byte[] SpriteCollisionBuffer = new byte[256];
void RenderTmsSprites(int scanLine) private void RenderTmsSprites(int scanLine)
{ {
if (EnableDoubledSprites == false) if (EnableDoubledSprites == false)
{
RenderTmsSpritesStandard(scanLine); RenderTmsSpritesStandard(scanLine);
}
else else
{
RenderTmsSpritesDouble(scanLine); RenderTmsSpritesDouble(scanLine);
}
} }
void RenderTmsSpritesStandard(int scanLine) private void RenderTmsSpritesStandard(int scanLine)
{ {
if (DisplayOn == false) return; if (DisplayOn == false) return;
@ -384,7 +384,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
} }
void RenderTmsSpritesDouble(int scanLine) private void RenderTmsSpritesDouble(int scanLine)
{ {
if (DisplayOn == false) return; if (DisplayOn == false) return;
@ -449,23 +449,23 @@ namespace BizHawk.Emulation.Cores.ColecoVision
} }
} }
Z80A Cpu; private readonly Z80A Cpu;
public TMS9918A(Z80A cpu) public TMS9918A(Z80A cpu)
{ {
this.Cpu = cpu; Cpu = cpu;
} }
public int[] FrameBuffer = new int[256 * 192]; public readonly int[] FrameBuffer = new int[256 * 192];
public int[] GetVideoBuffer() { return FrameBuffer; } public int[] GetVideoBuffer() { return FrameBuffer; }
public int VirtualWidth { get { return 293; } } public int VirtualWidth => 293;
public int VirtualHeight { get { return 192; } } public int VirtualHeight => 192;
public int BufferWidth { get { return 256; } } public int BufferWidth => 256;
public int BufferHeight { get { return 192; } } public int BufferHeight => 192;
public int BackgroundColor { get { return 0; } } public int BackgroundColor => 0;
int[] PaletteTMS9918 = new int[] private readonly int[] PaletteTMS9918 =
{ {
unchecked((int)0xFF000000), unchecked((int)0xFF000000),
unchecked((int)0xFF000000), unchecked((int)0xFF000000),
@ -498,8 +498,12 @@ namespace BizHawk.Emulation.Cores.ColecoVision
ser.EndSection(); ser.EndSection();
if (ser.IsReader) if (ser.IsReader)
{
for (int i = 0; i < Registers.Length; i++) for (int i = 0; i < Registers.Length; i++)
{
WriteRegister(i, Registers[i]); WriteRegister(i, Registers[i]);
}
}
} }
} }
} }

View File

@ -8,48 +8,51 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
public sealed class Cartridge : ICart public sealed class Cartridge : ICart
{ {
private ushort[] Data = new ushort[56320]; private readonly ushort[] Data = new ushort[56320];
private ushort[] Cart_Ram = new ushort[0x800]; private ushort[] Cart_Ram = new ushort[0x800];
// There are 10 mappers Intellivision games use (not counting intellicart which is handled seperately) // There are 10 mappers Intellivision games use (not counting intellicart which is handled seperately)
// we will pick the mapper from the game DB and default to 0 // we will pick the mapper from the game DB and default to 0
private int mapper = 0; private int _mapper = 0;
public string BoardName => $"Mapper {mapper}"; public string BoardName => $"Mapper {_mapper}";
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
ser.BeginSection("Cart"); ser.BeginSection("Cart");
ser.Sync("mapper", ref mapper); ser.Sync("mapper", ref _mapper);
ser.Sync("Cart_Ram", ref Cart_Ram, false); ser.Sync("Cart_Ram", ref Cart_Ram, false);
ser.EndSection(); ser.EndSection();
} }
public int Parse(byte[] Rom) public int Parse(byte[] rom)
{ {
// Combine every two bytes into a word. // Combine every two bytes into a word.
int index = 0; int index = 0;
while (index + 1 < Rom.Length) while (index + 1 < rom.Length)
{ {
Data[(index / 2)] = (ushort)((Rom[index++] << 8) | Rom[index++]); Data[(index / 2)] = (ushort)((rom[index++] << 8) | rom[index++]);
} }
// look up hash in gamedb to see what mapper to use // look up hash in gamedb to see what mapper to use
// if none found default is zero // if none found default is zero
string hash_sha1 = null; string hash_sha1 = null;
string s_mapper = null; string s_mapper = null;
hash_sha1 = "sha1:" + Rom.HashSHA1(16, Rom.Length - 16); hash_sha1 = "sha1:" + rom.HashSHA1(16, rom.Length - 16);
var gi = Database.CheckDatabase(hash_sha1); var gi = Database.CheckDatabase(hash_sha1);
if (gi != null) if (gi != null)
{ {
var dict = gi.GetOptionsDict(); var dict = gi.GetOptionsDict();
if (!dict.ContainsKey("board")) if (!dict.ContainsKey("board"))
{
throw new Exception("INTV gamedb entries must have a board identifier!"); throw new Exception("INTV gamedb entries must have a board identifier!");
}
s_mapper = dict["board"]; s_mapper = dict["board"];
} }
else else
@ -57,14 +60,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
s_mapper = "0"; s_mapper = "0";
} }
int.TryParse(s_mapper, out mapper); int.TryParse(s_mapper, out _mapper);
return Rom.Length; return rom.Length;
} }
public ushort? ReadCart(ushort addr, bool peek) public ushort? ReadCart(ushort addr, bool peek)
{ {
switch (mapper) switch (_mapper)
{ {
case 0: case 0:
if (addr >= 0x5000 && addr <= 0x6FFF) if (addr >= 0x5000 && addr <= 0x6FFF)
@ -228,13 +231,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
break; break;
} }
return null; return null;
} }
public bool WriteCart(ushort addr, ushort value, bool poke) public bool WriteCart(ushort addr, ushort value, bool poke)
{ {
switch (mapper) switch (_mapper)
{ {
case 4: case 4:
if (addr >= 0xD000 && addr <= 0xD3FF) if (addr >= 0xD000 && addr <= 0xD3FF)

View File

@ -71,7 +71,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
private readonly IPort Port1; private readonly IPort Port1;
private readonly IPort Port2; private readonly IPort Port2;
private static Dictionary<string, Type> _controllerTypes = null; private static Dictionary<string, Type> _controllerTypes;
public static Dictionary<string, Type> ValidControllerTypes public static Dictionary<string, Type> ValidControllerTypes
{ {
@ -90,10 +90,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
public static string DefaultControllerName public static string DefaultControllerName => typeof(FakeAnalogController).DisplayName();
{
get { return typeof(FakeAnalogController).DisplayName(); }
}
} }
} }

View File

@ -4,7 +4,6 @@ using System.ComponentModel;
using System.Linq; using System.Linq;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.ReflectionExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision namespace BizHawk.Emulation.Cores.Intellivision
@ -40,14 +39,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
return 0; return 0;
} }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
{ {
// Do nothing // Do nothing
} }
public int PortNum { get; private set; } public int PortNum { get; }
} }
[DisplayName("Standard Controller")] [DisplayName("Standard Controller")]
@ -64,7 +63,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
}; };
} }
public int PortNum { get; private set; } public int PortNum { get; }
public byte Read(IController c) public byte Read(IController c)
{ {
@ -80,7 +79,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
return result; return result;
} }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser) public void SyncState(Serializer ser)
@ -93,11 +92,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
"L", "R", "Top", "L", "R", "Top",
"Key 0", "Key 1", "Key 2", "Key 3", "Key 4", "Key 5", "Key 0", "Key 1", "Key 2", "Key 3", "Key 4", "Key 5",
"Key 6", "Key 7", "Key 8", "Key 9", "Enter", "Clear", "Key 6", "Key 7", "Key 8", "Key 9", "Enter", "Clear",
"N", "NNE", "NE", "ENE","E", "ESE", "SE", "SSE", "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE",
"S", "SSW", "SW", "WSW","W", "WNW", "NW", "NNW", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW",
}; };
private static byte[] HandControllerButtons = new byte[] { private static byte[] HandControllerButtons =
{
0x60, // OUTPUT_ACTION_BUTTON_BOTTOM_LEFT 0x60, // OUTPUT_ACTION_BUTTON_BOTTOM_LEFT
0xC0, // OUTPUT_ACTION_BUTTON_BOTTOM_RIGHT 0xC0, // OUTPUT_ACTION_BUTTON_BOTTOM_RIGHT
0xA0, // OUTPUT_ACTION_BUTTON_TOP 0xA0, // OUTPUT_ACTION_BUTTON_TOP
@ -149,9 +149,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
}; };
} }
public int PortNum { get; private set; } public int PortNum { get; }
public ControllerDefinition Definition { get; private set; } public ControllerDefinition Definition { get; }
public byte Read(IController c) public byte Read(IController c)
{ {
@ -183,7 +183,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
"Key 6", "Key 7", "Key 8", "Key 9", "Enter", "Clear" "Key 6", "Key 7", "Key 8", "Key 9", "Enter", "Clear"
}; };
private static byte[] BoolControllerButtons = new byte[] private static byte[] BoolControllerButtons =
{ {
0x60, // OUTPUT_ACTION_BUTTON_BOTTOM_LEFT 0x60, // OUTPUT_ACTION_BUTTON_BOTTOM_LEFT
0xC0, // OUTPUT_ACTION_BUTTON_BOTTOM_RIGHT 0xC0, // OUTPUT_ACTION_BUTTON_BOTTOM_RIGHT
@ -210,7 +210,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
y = -y; // vflip to match the arrangement of FloatControllerButtons y = -y; // vflip to match the arrangement of FloatControllerButtons
// deadzone: if we're less than ? units from the origin, return no direction // deadzone: if we're less than ? units from the origin, return no direction
if (x * x + y * y < Deadzone * Deadzone) if ((x * x) + (y * y) < Deadzone * Deadzone)
{ {
return 0; // nothing pressed return 0; // nothing pressed
} }
@ -223,7 +223,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
private const int Deadzone = 50; private const int Deadzone = 50;
private static byte[] FloatControllerButtons = new byte[] private static byte[] FloatControllerButtons =
{ {
0x02, // E 0x02, // E
0x06, // ENE 0x06, // ENE

View File

@ -4,7 +4,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
public interface ICart public interface ICart
{ {
int Parse(byte[] Rom); int Parse(byte[] rom);
ushort? ReadCart(ushort addr, bool peek); ushort? ReadCart(ushort addr, bool peek);
bool WriteCart(ushort addr, ushort value, bool poke); bool WriteCart(ushort addr, ushort value, bool poke);

View File

@ -16,11 +16,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
ser.EndSection(); ser.EndSection();
} }
private ushort[] Data = new ushort[65536]; private readonly ushort[] Data = new ushort[65536];
private bool[][] MemoryAttributes = new bool[32][]; private readonly bool[][] MemoryAttributes = new bool[32][];
private ushort[][] FineAddresses = new ushort[32][]; private readonly ushort[][] FineAddresses = new ushort[32][];
private ushort[] CRC16_table = private readonly ushort[] CRC16_table =
{ {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
@ -64,12 +64,15 @@ namespace BizHawk.Emulation.Cores.Intellivision
public int Parse(byte[] Rom) public int Parse(byte[] Rom)
{ {
int offset = 0; int offset = 0;
// Check to see if the header is valid. // Check to see if the header is valid.
if (Rom[offset++] != 0xA8 || Rom[offset++] != (0xFF ^ Rom[offset++])) if (Rom[offset++] != 0xA8 || Rom[offset++] != (0xFF ^ Rom[offset++]))
{ {
return -1; return -1;
} }
ushort crc, expected; ushort crc, expected;
// Parse for data segments. // Parse for data segments.
for (int segment = 0; segment < Rom[1]; segment++) for (int segment = 0; segment < Rom[1]; segment++)
{ {
@ -84,6 +87,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
throw new ArgumentException("Ranges can't start higher than they end."); throw new ArgumentException("Ranges can't start higher than they end.");
} }
for (int addr = start; addr <= end; addr++) for (int addr = start; addr <= end; addr++)
{ {
ushort data; ushort data;
@ -94,36 +98,46 @@ namespace BizHawk.Emulation.Cores.Intellivision
data = (ushort)((high << 8) | low); data = (ushort)((high << 8) | low);
Data[addr] = data; Data[addr] = data;
} }
expected = (ushort)((Rom[offset++] << 8) | Rom[offset++]); expected = (ushort)((Rom[offset++] << 8) | Rom[offset++]);
if (expected != crc) if (expected != crc)
{ {
throw new ArgumentException("Invalid CRC."); throw new ArgumentException("Invalid CRC.");
} }
} }
// Parse for memory attributes. // Parse for memory attributes.
for (int range = 0; range < 32; range++) for (int range = 0; range < 32; range++)
{ {
byte attributes = Rom[offset + (range >> 1)]; byte attributes = Rom[offset + (range >> 1)];
// Every second 2K block is stored in the upper 4 bits. // Every second 2K block is stored in the upper 4 bits.
if ((range & 0x1) != 0) if ((range & 0x1) != 0)
{ {
attributes = (byte)(attributes >> 4); attributes = (byte)(attributes >> 4);
} }
attributes &= 0xF; attributes &= 0xF;
MemoryAttributes[range] = new bool[4]; MemoryAttributes[range] = new bool[4];
// Readable. // Readable.
MemoryAttributes[range][0] = ((range & 0x1) != 0); MemoryAttributes[range][0] = (range & 0x1) != 0;
// Writeable. // Writeable.
MemoryAttributes[range][1] = ((range & 0x2) != 0); MemoryAttributes[range][1] = (range & 0x2) != 0;
// Narrow. // Narrow.
MemoryAttributes[range][2] = ((range & 0x4) != 0); MemoryAttributes[range][2] = (range & 0x4) != 0;
// Bank-switched. // Bank-switched.
MemoryAttributes[range][3] = ((range & 0x8) != 0); MemoryAttributes[range][3] = (range & 0x8) != 0;
} }
// Parse for fine addresses (Trimmed 2K ranges). // Parse for fine addresses (Trimmed 2K ranges).
for (int range = 0; range < 32; range++) for (int range = 0; range < 32; range++)
{ {
int index; int index;
// The lower and upper 2K in a 4K range are 16 addresses away from each other. // The lower and upper 2K in a 4K range are 16 addresses away from each other.
if ((range & 0x1) != 0) if ((range & 0x1) != 0)
{ {
@ -133,28 +147,34 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
index = offset + 32 + (range >> 1); index = offset + 32 + (range >> 1);
} }
int range_start = range * 2048;
ushort start = (ushort)((((Rom[index] >> 4) & 0x07) << 8) + range_start); int rangeStart = range * 2048;
ushort end = (ushort)((((Rom[index]) & 0x07) << 8) + 0xFF + range_start); ushort start = (ushort)((((Rom[index] >> 4) & 0x07) << 8) + rangeStart);
ushort end = (ushort)(((Rom[index] & 0x07) << 8) + 0xFF + rangeStart);
if (end < start) if (end < start)
{ {
throw new ArgumentException("Ranges can't start higher than they end."); throw new ArgumentException("Ranges can't start higher than they end.");
} }
FineAddresses[range] = new ushort[2]; FineAddresses[range] = new ushort[2];
FineAddresses[range][0] = start; FineAddresses[range][0] = start;
FineAddresses[range][1] = end; FineAddresses[range][1] = end;
} }
crc = 0xFFFF; crc = 0xFFFF;
for (int index = 0; index < 48; index++) for (int index = 0; index < 48; index++)
{ {
crc = UpdateCRC16(crc, Rom[offset++]); crc = UpdateCRC16(crc, Rom[offset++]);
} }
expected = (ushort)((Rom[offset++] << 8) | (Rom[offset++] & 0xFF)); expected = (ushort)((Rom[offset++] << 8) | (Rom[offset++] & 0xFF));
// Check if there is an invalid CRC for the memory attributes / fine addresses. // Check if there is an invalid CRC for the memory attributes / fine addresses.
if (expected != crc) if (expected != crc)
{ {
throw new ArgumentException("Invalid CRC."); throw new ArgumentException("Invalid CRC.");
} }
return offset; return offset;
} }
@ -166,6 +186,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
return Data[addr]; return Data[addr];
} }
return null; return null;
} }
@ -180,13 +201,16 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
value &= 0xFF; value &= 0xFF;
} }
if (attributes[3]) if (attributes[3])
{ {
throw new NotImplementedException("Bank-switched memory attribute not implemented."); throw new NotImplementedException("Bank-switched memory attribute not implemented.");
} }
Data[addr] = value; Data[addr] = value;
return true; return true;
} }
return false; return false;
} }
} }

View File

@ -6,7 +6,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
public IEmulatorServiceProvider ServiceProvider { get; } public IEmulatorServiceProvider ServiceProvider { get; }
public ControllerDefinition ControllerDefinition => ControllerDeck.Definition; public ControllerDefinition ControllerDefinition => _controllerDeck.Definition;
public IController Controller { get; set; } public IController Controller { get; set; }
@ -14,7 +14,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
if (_tracer.Enabled) if (_tracer.Enabled)
{ {
_cpu.TraceCallback = (s) => _tracer.Put(s); _cpu.TraceCallback = s => _tracer.Put(s);
} }
else else
{ {
@ -28,14 +28,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
GetControllerState(); GetControllerState();
// this timer tracks cycles stolen by the STIC during the visible part of the frame, quite a large number of them actually // this timer tracks cycles stolen by the STIC during the visible part of the frame, quite a large number of them actually
int delay_cycles = 700; int delayCycles = 700;
int delay_timer = -1; int delayTimer = -1;
_cpu.PendingCycles = 14934 - 3791 + _cpu.GetPendingCycles(); _cpu.PendingCycles = 14934 - 3791 + _cpu.GetPendingCycles();
_stic.Sr1 = true; _stic.Sr1 = true;
_islag = true; _islag = true;
bool active_display = _stic.active_display; bool activeDisplay = _stic.active_display;
// also at the start of every frame the color stack is reset // also at the start of every frame the color stack is reset
_stic.ColorSP = 0x0028; _stic.ColorSP = 0x0028;
@ -45,23 +45,25 @@ namespace BizHawk.Emulation.Cores.Intellivision
int cycles = _cpu.Execute(); int cycles = _cpu.Execute();
_psg.generate_sound(cycles); _psg.generate_sound(cycles);
if (delay_cycles>=0 && active_display) if (delayCycles >= 0 && activeDisplay)
delay_cycles += cycles;
if (delay_timer> 0 && active_display)
{ {
delay_timer -= cycles; delayCycles += cycles;
if (delay_timer<=0) }
if (delayTimer > 0 && activeDisplay)
{
delayTimer -= cycles;
if (delayTimer <= 0)
{ {
_stic.ToggleSr2(); _stic.ToggleSr2();
delay_cycles = 0; delayCycles = 0;
} }
} }
if (delay_cycles >= 750 && active_display) if (delayCycles >= 750 && activeDisplay)
{ {
delay_cycles = -1; delayCycles = -1;
delay_timer = 110; delayTimer = 110;
_stic.ToggleSr2(); _stic.ToggleSr2();
if (_sticRow >= 0) if (_sticRow >= 0)
{ {
@ -72,6 +74,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
_sticRow++; _sticRow++;
} }
Connect(); Connect();
} }
@ -106,17 +109,23 @@ namespace BizHawk.Emulation.Cores.Intellivision
_psg.generate_sound(cycles); _psg.generate_sound(cycles);
Connect(); Connect();
} }
_stic.in_vb_2 = false; _stic.in_vb_2 = false;
if (_islag) if (_islag)
{
_lagcount++; _lagcount++;
}
if (Controller.IsPressed("Power")) if (Controller.IsPressed("Power"))
{
HardReset(); HardReset();
}
if (Controller.IsPressed("Reset")) if (Controller.IsPressed("Reset"))
{
SoftReset(); SoftReset();
}
} }
public int Frame => _frame; public int Frame => _frame;

View File

@ -8,7 +8,8 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
get get
{ {
return _lagcount; } return _lagcount;
}
set set
{ {

View File

@ -3,7 +3,6 @@
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision namespace BizHawk.Emulation.Cores.Intellivision
{ {
public partial class Intellivision : IStatable public partial class Intellivision : IStatable
@ -61,7 +60,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
_stic.SyncState(ser); _stic.SyncState(ser);
_psg.SyncState(ser); _psg.SyncState(ser);
_cart.SyncState(ser); _cart.SyncState(ser);
ControllerDeck.SyncState(ser); _controllerDeck.SyncState(ser);
ser.EndSection(); ser.EndSection();
} }

View File

@ -9,8 +9,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
"IntelliHawk", "IntelliHawk",
"BrandonE, Alyosha", "BrandonE, Alyosha",
isPorted: false, isPorted: false,
isReleased: true isReleased: true)]
)]
[ServiceNotApplicable(typeof(ISaveRam), typeof(IDriveLight), typeof(IRegionable))] [ServiceNotApplicable(typeof(ISaveRam), typeof(IDriveLight), typeof(IRegionable))]
public sealed partial class Intellivision : IEmulator, IStatable, IInputPollable, IDisassemblable, public sealed partial class Intellivision : IEmulator, IStatable, IInputPollable, IDisassemblable,
IDebuggable, ISettable<Intellivision.IntvSettings, Intellivision.IntvSyncSettings> IDebuggable, ISettable<Intellivision.IntvSettings, Intellivision.IntvSyncSettings>
@ -24,12 +23,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
CoreComm = comm; CoreComm = comm;
_rom = rom; _rom = rom;
_gameInfo = game;
_settings = (IntvSettings)Settings ?? new IntvSettings(); _settings = (IntvSettings)Settings ?? new IntvSettings();
_syncSettings = (IntvSyncSettings)SyncSettings ?? new IntvSyncSettings(); _syncSettings = (IntvSyncSettings)SyncSettings ?? new IntvSyncSettings();
ControllerDeck = new IntellivisionControllerDeck(_syncSettings.Port1, _syncSettings.Port2); _controllerDeck = new IntellivisionControllerDeck(_syncSettings.Port1, _syncSettings.Port2);
_cart = new Intellicart(); _cart = new Intellicart();
if (_cart.Parse(_rom) == -1) if (_cart.Parse(_rom) == -1)
@ -74,10 +72,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
SetupMemoryDomains(); SetupMemoryDomains();
} }
public IntellivisionControllerDeck ControllerDeck { get; private set; } private readonly IntellivisionControllerDeck _controllerDeck;
private readonly byte[] _rom; private readonly byte[] _rom;
private readonly GameInfo _gameInfo;
private readonly ITraceable _tracer; private readonly ITraceable _tracer;
private readonly CP1610 _cpu; private readonly CP1610 _cpu;
private readonly STIC _stic; private readonly STIC _stic;
@ -87,14 +84,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
private int _frame; private int _frame;
private int _sticRow; private int _sticRow;
public void Connect() private void Connect()
{ {
_cpu.SetIntRM(_stic.GetSr1()); _cpu.SetIntRM(_stic.GetSr1());
_cpu.SetBusRq(_stic.GetSr2()); _cpu.SetBusRq(_stic.GetSr2());
_stic.SetSst(_cpu.GetBusAk()); _stic.SetSst(_cpu.GetBusAk());
} }
public void LoadExecutiveRom(byte[] erom) private void LoadExecutiveRom(byte[] erom)
{ {
if (erom.Length != 8192) if (erom.Length != 8192)
{ {
@ -110,7 +107,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
public void LoadGraphicsRom(byte[] grom) private void LoadGraphicsRom(byte[] grom)
{ {
if (grom.Length != 2048) if (grom.Length != 2048)
{ {
@ -124,10 +121,10 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
InputCallbacks.Call(); InputCallbacks.Call();
ushort port1 = ControllerDeck.ReadPort1(Controller); ushort port1 = _controllerDeck.ReadPort1(Controller);
_psg.Register[15] = (ushort)(0xFF - port1); _psg.Register[15] = (ushort)(0xFF - port1);
ushort port2 = ControllerDeck.ReadPort2(Controller); ushort port2 = _controllerDeck.ReadPort2(Controller);
_psg.Register[14] = (ushort)(0xFF - port2); _psg.Register[14] = (ushort)(0xFF - port2);
} }

View File

@ -1,13 +1,14 @@
using BizHawk.Common.NumberExtensions; using System;
using System;
using BizHawk.Common; using BizHawk.Common;
using BizHawk.Common.NumberExtensions;
using BizHawk.Emulation.Common; using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Intellivision namespace BizHawk.Emulation.Cores.Intellivision
{ {
public sealed class PSG : ISoundProvider public sealed class PSG : ISoundProvider
{ {
private BlipBuffer _blip = new BlipBuffer(4096); private readonly BlipBuffer _blip = new BlipBuffer(4096);
private short[] _sampleBuffer = new short[0]; private short[] _sampleBuffer = new short[0];
@ -18,7 +19,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
public ushort[] Register = new ushort[16]; public ushort[] Register = new ushort[16];
public int total_clock; // TODO: what is this uaed for? public int total_clock; // TODO: what is this used for?
public void Reset() public void Reset()
{ {
@ -44,15 +45,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
throw new NotSupportedException("Async is not available"); throw new NotSupportedException("Async is not available");
} }
public bool CanProvideAsync public bool CanProvideAsync => false;
{
get { return false; }
}
public SyncSoundMode SyncMode public SyncSoundMode SyncMode => SyncSoundMode.Sync;
{
get { return SyncSoundMode.Sync; }
}
public void SetSyncMode(SyncSoundMode mode) public void SetSyncMode(SyncSoundMode mode)
{ {
@ -70,7 +65,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
nsamp = _blip.SamplesAvailable(); nsamp = _blip.SamplesAvailable();
int targetLength = nsamp * 2; int targetLength = nsamp * 2;
if (_sampleBuffer.Length != targetLength) if (_sampleBuffer.Length != targetLength)
{
_sampleBuffer = new short[targetLength]; _sampleBuffer = new short[targetLength];
}
_blip.ReadSamplesLeft(_sampleBuffer, nsamp); _blip.ReadSamplesLeft(_sampleBuffer, nsamp);
for (int i = 0; i < _sampleBuffer.Length; i += 2) for (int i = 0; i < _sampleBuffer.Length; i += 2)
@ -86,34 +83,35 @@ namespace BizHawk.Emulation.Cores.Intellivision
throw new Exception(); throw new Exception();
} }
public static int[] volume_table = new int[16] {0x0000, 0x0055, 0x0079, 0x00AB, 0x00F1, 0x0155, 0x01E3, 0x02AA, private static readonly int[] VolumeTable =
0x03C5, 0x0555, 0x078B, 0x0AAB, 0x0F16, 0x1555, 0x1E2B, 0x2AAA}; {
0x0000, 0x0055, 0x0079, 0x00AB, 0x00F1, 0x0155, 0x01E3, 0x02AA,
0x03C5, 0x0555, 0x078B, 0x0AAB, 0x0F16, 0x1555, 0x1E2B, 0x2AAA
};
private int _sampleClock; private int _sampleClock;
private int _latchedSample; private int _latchedSample;
public int TotalExecutedCycles; private int TotalExecutedCycles;
public int PendingCycles; private int PendingCycles;
private int psg_clock;
private int sq_per_A, sq_per_B, sq_per_C;
private int clock_A, clock_B, clock_C;
private int vol_A, vol_B, vol_C;
private bool A_on, B_on, C_on;
private bool A_up, B_up, C_up;
private bool A_noise, B_noise, C_noise;
public int psg_clock; private int env_per;
private int env_clock;
private int env_shape;
private int env_E;
private int E_up_down;
private int env_vol_A, env_vol_B, env_vol_C;
public int sq_per_A, sq_per_B, sq_per_C; private int noise_clock;
public int clock_A, clock_B, clock_C; private int noise_per;
public int vol_A, vol_B, vol_C; private int noise = 0x1;
public bool A_on, B_on, C_on;
public bool A_up, B_up, C_up;
public bool A_noise, B_noise, C_noise;
public int env_per;
public int env_clock;
public int env_shape;
public int env_E;
public int E_up_down;
public int env_vol_A, env_vol_B, env_vol_C;
public int noise_clock;
public int noise_per;
public int noise = 0x1;
public Func<ushort, bool, ushort> ReadMemory; public Func<ushort, bool, ushort> ReadMemory;
public Func<ushort, ushort, bool, bool> WriteMemory; public Func<ushort, ushort, bool, bool> WriteMemory;
@ -150,27 +148,36 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
return (ushort)(Register[addr - 0x01F0]); return (ushort)(Register[addr - 0x01F0]);
} }
return null; return null;
} }
public void sync_psg_state() private void sync_psg_state()
{ {
sq_per_A = (Register[0] & 0xFF) | (((Register[4] & 0xF) << 8)); sq_per_A = (Register[0] & 0xFF) | (((Register[4] & 0xF) << 8));
if (sq_per_A == 0) if (sq_per_A == 0)
{
sq_per_A = 0x1000; sq_per_A = 0x1000;
}
sq_per_B = (Register[1] & 0xFF) | (((Register[5] & 0xF) << 8)); sq_per_B = (Register[1] & 0xFF) | (((Register[5] & 0xF) << 8));
if (sq_per_B == 0) if (sq_per_B == 0)
{
sq_per_B = 0x1000; sq_per_B = 0x1000;
}
sq_per_C = (Register[2] & 0xFF) | (((Register[6] & 0xF) << 8)); sq_per_C = (Register[2] & 0xFF) | (((Register[6] & 0xF) << 8));
if (sq_per_C == 0) if (sq_per_C == 0)
{
sq_per_C = 0x1000; sq_per_C = 0x1000;
}
env_per = (Register[3] & 0xFF) | (((Register[7] & 0xFF) << 8)); env_per = (Register[3] & 0xFF) | (((Register[7] & 0xFF) << 8));
if (env_per == 0) if (env_per == 0)
{
env_per = 0x10000; env_per = 0x10000;
}
env_per *= 2; env_per *= 2;
A_on = Register[8].Bit(0); A_on = Register[8].Bit(0);
@ -241,8 +248,10 @@ namespace BizHawk.Emulation.Cores.Intellivision
E_up_down = 1; E_up_down = 1;
} }
} }
return true; return true;
} }
return false; return false;
} }
@ -270,7 +279,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
noise_clock--; noise_clock--;
env_clock--; env_clock--;
//clock noise // clock noise
if (noise_clock == 0) if (noise_clock == 0)
{ {
noise = (noise >> 1) ^ (noise.Bit(0) ? 0x10004 : 0); noise = (noise >> 1) ^ (noise.Bit(0) ? 0x10004 : 0);
@ -286,7 +295,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (env_E == 16 || env_E == -1) if (env_E == 16 || env_E == -1)
{ {
//we just completed a period of the envelope, determine what to do now based on the envelope shape // we just completed a period of the envelope, determine what to do now based on the envelope shape
if (env_shape == 0 || env_shape == 1 || env_shape == 3 || env_shape == 9) if (env_shape == 0 || env_shape == 1 || env_shape == 3 || env_shape == 9)
{ {
E_up_down = 0; E_up_down = 0;
@ -344,24 +353,24 @@ namespace BizHawk.Emulation.Cores.Intellivision
sound_out_B = (noise.Bit(0) | B_noise) & (B_on | B_up); sound_out_B = (noise.Bit(0) | B_noise) & (B_on | B_up);
sound_out_C = (noise.Bit(0) | C_noise) & (C_on | C_up); sound_out_C = (noise.Bit(0) | C_noise) & (C_on | C_up);
//now calculate the volume of each channel and add them together // now calculate the volume of each channel and add them together
int v; int v;
if (env_vol_A == 0) if (env_vol_A == 0)
{ {
v = (short)(sound_out_A ? volume_table[vol_A] : 0); v = (short)(sound_out_A ? VolumeTable[vol_A] : 0);
} }
else else
{ {
int shift_A = 3 - env_vol_A; int shift_A = 3 - env_vol_A;
if (shift_A < 0) if (shift_A < 0)
shift_A = 0; shift_A = 0;
v = (short)(sound_out_A ? (volume_table[env_E] >> shift_A) : 0); v = (short)(sound_out_A ? (VolumeTable[env_E] >> shift_A) : 0);
} }
if (env_vol_B == 0) if (env_vol_B == 0)
{ {
v += (short)(sound_out_B ? volume_table[vol_B] : 0); v += (short)(sound_out_B ? VolumeTable[vol_B] : 0);
} }
else else
@ -369,19 +378,19 @@ namespace BizHawk.Emulation.Cores.Intellivision
int shift_B = 3 - env_vol_B; int shift_B = 3 - env_vol_B;
if (shift_B < 0) if (shift_B < 0)
shift_B = 0; shift_B = 0;
v += (short)(sound_out_B ? (volume_table[env_E] >> shift_B) : 0); v += (short)(sound_out_B ? (VolumeTable[env_E] >> shift_B) : 0);
} }
if (env_vol_C == 0) if (env_vol_C == 0)
{ {
v += (short)(sound_out_C ? volume_table[vol_C] : 0); v += (short)(sound_out_C ? VolumeTable[vol_C] : 0);
} }
else else
{ {
int shift_C = 3 - env_vol_C; int shift_C = 3 - env_vol_C;
if (shift_C < 0) if (shift_C < 0)
shift_C = 0; shift_C = 0;
v += (short)(sound_out_C ? (volume_table[env_E] >> shift_C) : 0); v += (short)(sound_out_C ? (VolumeTable[env_E] >> shift_C) : 0);
} }
if (v != _latchedSample) if (v != _latchedSample)
@ -393,7 +402,6 @@ namespace BizHawk.Emulation.Cores.Intellivision
_sampleClock++; _sampleClock++;
} }
} }
} }
} }
} }

View File

@ -55,19 +55,20 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
// gets called when a new border color is chosen // gets called when a new border color is chosen
public void Update_Border() private void Update_Border()
{ {
for (int i=0;i<176;i++) for (int i = 0; i < 176; i++)
{ {
for (int j=0;j<8;j++) for (int j = 0; j < 8; j++)
{ {
FrameBuffer[i + j * 176]= ColorToRGBA(Register[0x2C] & 0xF); FrameBuffer[i + j * 176]= ColorToRGBA(Register[0x2C] & 0xF);
FrameBuffer[i + j * 176 + 176*200] = ColorToRGBA(Register[0x2C] & 0xF); FrameBuffer[i + j * 176 + 176*200] = ColorToRGBA(Register[0x2C] & 0xF);
} }
} }
for (int j=8;j<(208-8);j++)
for (int j = 8; j < (208 - 8); j++)
{ {
for (int i=0;i<8;i++) for (int i = 0; i < 8; i++)
{ {
FrameBuffer[i + j * 176] = ColorToRGBA(Register[0x2C] & 0xF); FrameBuffer[i + j * 176] = ColorToRGBA(Register[0x2C] & 0xF);
FrameBuffer[i + 168 + j * 176] = ColorToRGBA(Register[0x2C] & 0xF); FrameBuffer[i + 168 + j * 176] = ColorToRGBA(Register[0x2C] & 0xF);
@ -75,18 +76,18 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
public int VirtualWidth { get { return 277; } } public int VirtualWidth => 277;
public int BufferWidth { get { return 176; } } public int BufferWidth => 176;
public int VirtualHeight { get { return 208; } } public int VirtualHeight => 208;
public int BufferHeight { get { return 208; } } public int BufferHeight => 208;
public int BackgroundColor { get { return 0; } } public int BackgroundColor => 0;
public void Reset() public void Reset()
{ {
Sr1 = true; Sr1 = true;
Sr2 = true; Sr2 = true;
for (int i=0;i<64;i++) for (int i = 0; i < 64; i++)
{ {
Register[i] = 0; Register[i] = 0;
write_reg(i, 0, false); write_reg(i, 0, false);
@ -149,12 +150,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
else if (reg < 0x33) else if (reg < 0x33)
{ {
if (reg==0x32) if (reg == 0x32)
{ {
value = (ushort)((value & 0x3) | 0x3FFC); value = (ushort)((value & 0x3) | 0x3FFC);
} }
else else
{
value = (ushort)((value & 0x7) | 0x3FF8); value = (ushort)((value & 0x7) | 0x3FF8);
}
} }
else if (reg < 0x40) else if (reg < 0x40)
{ {
@ -162,11 +165,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
Register[reg] = value; Register[reg] = value;
if (reg==0x21 && !poke) if (reg == 0x21 && !poke)
{ {
Fgbg = true; Fgbg = true;
} }
if (reg==0x20 && !poke)
if (reg == 0x20 && !poke)
{ {
active_display = true; active_display = true;
} }
@ -188,9 +192,10 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
Fgbg = false; Fgbg = false;
} }
return Register[addr]; return Register[addr];
} }
else if (addr>= 0x0040 && addr <= 0x007F && (in_vb_2 | !active_display)) else if (addr >= 0x0040 && addr <= 0x007F && (in_vb_2 | !active_display))
{ {
return Register[addr - 0x0040]; return Register[addr - 0x0040];
} }
@ -223,6 +228,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
break; break;
} }
return null; return null;
} }
@ -259,10 +265,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
break; break;
} }
return false; return false;
} }
public int ColorToRGBA(int color) private int ColorToRGBA(int color)
{ {
switch (color) switch (color)
{ {
@ -299,6 +306,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
case 15: case 15:
return 0xB51A58; return 0xB51A58;
} }
throw new ArgumentException("Specified color does not exist."); throw new ArgumentException("Specified color does not exist.");
} }
@ -307,15 +315,16 @@ namespace BizHawk.Emulation.Cores.Intellivision
// here we will also need to apply the 'delay' register values. // here we will also need to apply the 'delay' register values.
// this shifts the displayed portion of the screen relative to the BG // this shifts the displayed portion of the screen relative to the BG
// The background is a 20x12 grid of "cards". // The background is a 20x12 grid of "cards".
int bg = 0;
int bg=0;
for (int card_row = input_row; card_row < (input_row+1); card_row++) for (int card_row = input_row; card_row < (input_row+1); card_row++)
{ {
for (int card_col = 0; card_col < 20; card_col++) for (int card_col = 0; card_col < 20; card_col++)
{ {
int buffer_offset = (card_row * 159 * 8) + (card_col * 8); int buffer_offset = (card_row * 159 * 8) + (card_col * 8);
// The cards are stored sequentially in the System RAM. // The cards are stored sequentially in the System RAM.
ushort card = ReadMemory((ushort)(0x0200 + (card_row * 20) + card_col), false); ushort card = ReadMemory((ushort)(0x0200 + (card_row * 20) + card_col), false);
// Parse data from the card. // Parse data from the card.
bool gram = ((card & 0x0800) != 0); bool gram = ((card & 0x0800) != 0);
int card_num = card >> 3; int card_num = card >> 3;
@ -323,6 +332,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (Fgbg) if (Fgbg)
{ {
bg = ((card >> 9) & 0x0008) | ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003); bg = ((card >> 9) & 0x0008) | ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003);
// Only 64 of the GROM's cards can be used in FGBG Mode. // Only 64 of the GROM's cards can be used in FGBG Mode.
card_num &= 0x003F; card_num &= 0x003F;
} }
@ -334,6 +344,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
// GRAM only has 64 cards. // GRAM only has 64 cards.
card_num &= 0x003F; card_num &= 0x003F;
// The foreground color has an additional bit when not in Colored Squares mode. // The foreground color has an additional bit when not in Colored Squares mode.
if (squares) if (squares)
fg |= 0x0008; fg |= 0x0008;
@ -343,6 +354,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
// All of the GROM's 256 cards can be used in Color Stack Mode. // All of the GROM's 256 cards can be used in Color Stack Mode.
card_num &= 0x00FF; card_num &= 0x00FF;
} }
if (!gram && squares) if (!gram && squares)
{ {
// Colored Squares Mode. // Colored Squares Mode.
@ -353,9 +365,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
colors[2] = (card >> 6) & 0x0007; colors[2] = (card >> 6) & 0x0007;
colors[3] = ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003); colors[3] = ((card >> 11) & 0x0004) | ((card >> 9) & 0x0003);
for (int z=0;z<4;z++) for (int z = 0; z < 4; z++)
{ {
if (colors[z]==7) if (colors[z] == 7)
{ {
colors[z] = Register[ColorSP] & 0x000F; colors[z] = Register[ColorSP] & 0x000F;
square_col[z] = 0; square_col[z] = 0;
@ -377,6 +389,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
int color; int color;
int pixel = buffer_offset + (squares_row * 159) + squares_col; int pixel = buffer_offset + (squares_row * 159) + squares_col;
// Determine the color of the quadrant the pixel is in. // Determine the color of the quadrant the pixel is in.
if (squares_col < 4) if (squares_col < 4)
{ {
@ -426,9 +439,11 @@ namespace BizHawk.Emulation.Cores.Intellivision
ColorSP = 0x0028; ColorSP = 0x0028;
} }
} }
bg = Register[ColorSP] & 0x000F; bg = Register[ColorSP] & 0x000F;
} }
} }
for (int pict_row = 0; pict_row < 8; pict_row++) for (int pict_row = 0; pict_row < 8; pict_row++)
{ {
// Each picture is stored sequentially in the GROM / GRAM, and so are their rows. // Each picture is stored sequentially in the GROM / GRAM, and so are their rows.
@ -455,6 +470,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
// The pixels go right as the bits get less significant. // The pixels go right as the bits get less significant.
BGBuffer[pixel] = ColorToRGBA(fg); BGBuffer[pixel] = ColorToRGBA(fg);
// also if the pixel is on set it in the collision matrix // also if the pixel is on set it in the collision matrix
// note that the collision field is attached to the lower right corner of the BG // note that the collision field is attached to the lower right corner of the BG
// so we add 8 to x and 16 to y here // so we add 8 to x and 16 to y here
@ -468,6 +484,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
BGBuffer[pixel] = ColorToRGBA(bg); BGBuffer[pixel] = ColorToRGBA(bg);
} }
row >>= 1; row >>= 1;
} }
} }
@ -477,7 +494,6 @@ namespace BizHawk.Emulation.Cores.Intellivision
// now that we have the cards in BGbuffer, we can double vertical resolution to get Frame buffer // now that we have the cards in BGbuffer, we can double vertical resolution to get Frame buffer
// there is a trick here in that we move the displayed area of the screen relative to the BG buffer // there is a trick here in that we move the displayed area of the screen relative to the BG buffer
// this is done using the delay registers // this is done using the delay registers
int x_delay = Register[0x30] & 0x7; int x_delay = Register[0x30] & 0x7;
int y_delay = Register[0x31] & 0x7; int y_delay = Register[0x31] & 0x7;
@ -495,15 +511,14 @@ namespace BizHawk.Emulation.Cores.Intellivision
{ {
FrameBuffer[(j * 2) * 176 + (i+8) + BORDER_OFFSET] = BGBuffer[(j - y_delay) * 159 + i - x_delay]; FrameBuffer[(j * 2) * 176 + (i+8) + BORDER_OFFSET] = BGBuffer[(j - y_delay) * 159 + i - x_delay];
FrameBuffer[(j * 2 + 1) * 176 + (i+8) + BORDER_OFFSET] = BGBuffer[(j - y_delay) * 159 + i - x_delay]; FrameBuffer[(j * 2 + 1) * 176 + (i+8) + BORDER_OFFSET] = BGBuffer[(j - y_delay) * 159 + i - x_delay];
} else }
else
{ {
FrameBuffer[(j * 2) * 176 + (i + 8) + BORDER_OFFSET] = ColorToRGBA(bg); FrameBuffer[(j * 2) * 176 + (i + 8) + BORDER_OFFSET] = ColorToRGBA(bg);
FrameBuffer[(j * 2 + 1) * 176 + (i + 8) + BORDER_OFFSET] = ColorToRGBA(bg); FrameBuffer[(j * 2 + 1) * 176 + (i + 8) + BORDER_OFFSET] = ColorToRGBA(bg);
} }
} }
} }
} }
// see for more details: http://spatula-city.org/~im14u2c/intv/jzintv-1.0-beta3/doc/programming/stic.txt // see for more details: http://spatula-city.org/~im14u2c/intv/jzintv-1.0-beta3/doc/programming/stic.txt
@ -626,7 +641,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
//flip mobs accordingly // flip mobs accordingly
if (x_flip) if (x_flip)
{ {
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
@ -642,7 +657,8 @@ namespace BizHawk.Emulation.Cores.Intellivision
mobs[j] = (byte)(temp_0 + temp_1 + temp_2 + temp_3 + temp_4 + temp_5 + temp_6 + temp_7); mobs[j] = (byte)(temp_0 + temp_1 + temp_2 + temp_3 + temp_4 + temp_5 + temp_6 + temp_7);
} }
if (yres>1)
if (yres > 1)
{ {
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
@ -672,7 +688,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
byte temp_7 = mobs[7]; byte temp_7 = mobs[7];
if (yres==1) if (yres == 1)
{ {
mobs[0] = mobs[7]; mobs[0] = mobs[7];
mobs[1] = mobs[6]; mobs[1] = mobs[6];
@ -705,7 +721,7 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
//draw the mob and check for collision // draw the mob and check for collision
for (int j = 0; j < 8; j++) for (int j = 0; j < 8; j++)
{ {
for (int k = 0; k < 8; k++) for (int k = 0; k < 8; k++)
@ -723,8 +739,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (!(priority && (Collision[cur_x, loc_y * 2 + cur_y]&0x100)>0)) if (!(priority && (Collision[cur_x, loc_y * 2 + cur_y]&0x100)>0))
FrameBuffer[(loc_y * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color); FrameBuffer[(loc_y * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color);
} }
//a MOB does not need to be visible for it to be interracting
//special case: a mob with x position 0 is counted as off // a MOB does not need to be visible for it to be interracting
// special case: a mob with x position 0 is counted as off
if (intr && pixel && (cur_x) <= 167 && (loc_y * 2 + cur_y) < 210 && loc_x != 0) if (intr && pixel && (cur_x) <= 167 && (loc_y * 2 + cur_y) < 210 && loc_x != 0)
{ {
Collision[cur_x, loc_y * 2 + cur_y] |= (ushort)(1 << i); Collision[cur_x, loc_y * 2 + cur_y] |= (ushort)(1 << i);
@ -767,8 +784,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (!(priority && (Collision[cur_x, (loc_y + 4 * y_size) * 2 + cur_y] & 0x100) > 0)) if (!(priority && (Collision[cur_x, (loc_y + 4 * y_size) * 2 + cur_y] & 0x100) > 0))
FrameBuffer[((loc_y + 4 * y_size) * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color); FrameBuffer[((loc_y + 4 * y_size) * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color);
} }
//a MOB does not need to be visible for it to be interracting
//special case: a mob with x position 0 is counted as off // a MOB does not need to be visible for it to be interracting
// special case: a mob with x position 0 is counted as off
if (intr && pixel && (cur_x) <= 167 && ((loc_y + 4 * y_size) * 2 + cur_y) < 210 && loc_x != 0) if (intr && pixel && (cur_x) <= 167 && ((loc_y + 4 * y_size) * 2 + cur_y) < 210 && loc_x != 0)
{ {
Collision[cur_x, (loc_y + 4 * y_size) * 2 + cur_y] |= (ushort)(1 << i); Collision[cur_x, (loc_y + 4 * y_size) * 2 + cur_y] |= (ushort)(1 << i);
@ -781,8 +799,9 @@ namespace BizHawk.Emulation.Cores.Intellivision
if (!(priority && (Collision[cur_x + 1, (loc_y + 4 * y_size) * 2 + cur_y] & 0x100) > 0)) if (!(priority && (Collision[cur_x + 1, (loc_y + 4 * y_size) * 2 + cur_y] & 0x100) > 0))
FrameBuffer[((loc_y + 4 * y_size) * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) + 1 - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color); FrameBuffer[((loc_y + 4 * y_size) * 2 + cur_y - (16 - y_delay * 2)) * 176 + (cur_x + 8) + 1 - (8 - x_delay) + BORDER_OFFSET] = ColorToRGBA(loc_color);
} }
//a MOB does not need to be visible for it to be interracting
//special case: a mob with x position 0 is counted as off // a MOB does not need to be visible for it to be interracting
// special case: a mob with x position 0 is counted as off
if (intr && pixel && (cur_x + 1) <= 167 && ((loc_y + 4 * y_size) * 2 + cur_y) < 210 && loc_x != 0) if (intr && pixel && (cur_x + 1) <= 167 && ((loc_y + 4 * y_size) * 2 + cur_y) < 210 && loc_x != 0)
{ {
Collision[cur_x + 1, (loc_y + 4 * y_size) * 2 + cur_y] |= (ushort)(1 << i); Collision[cur_x + 1, (loc_y + 4 * y_size) * 2 + cur_y] |= (ushort)(1 << i);
@ -845,13 +864,12 @@ namespace BizHawk.Emulation.Cores.Intellivision
} }
} }
} }
// after we check for collision, we can clear that value for the next frame. // after we check for collision, we can clear that value for the next frame.
Collision[i, j] = 0; Collision[i, j] = 0;
} }
} }
} }
// end of Mobs function, we now have collision and graphics data for the mobs // end of Mobs function, we now have collision and graphics data for the mobs
} }
} }