ColecoHawk: Fix turbo controller
This commit is contained in:
parent
900a9e5322
commit
1cd82aa5d9
|
@ -44,27 +44,24 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
Definition.FloatRanges.AddRange(Port2.Definition.FloatRanges);
|
||||
}
|
||||
|
||||
private int wheel1;
|
||||
private int wheel2;
|
||||
public float wheel1;
|
||||
public float wheel2;
|
||||
|
||||
public float temp_wheel1;
|
||||
public float temp_wheel2;
|
||||
|
||||
public byte ReadPort1(IController c, bool leftMode, bool updateWheel)
|
||||
{
|
||||
if (updateWheel)
|
||||
{
|
||||
wheel1 = Port1.UpdateWheel(c, wheel1);
|
||||
}
|
||||
wheel1 = Port1.UpdateWheel(c);
|
||||
|
||||
return Port1.Read(c, leftMode, wheel1);
|
||||
return Port1.Read(c, leftMode, updateWheel, temp_wheel1);
|
||||
}
|
||||
|
||||
public byte ReadPort2(IController c, bool leftMode, bool updateWheel)
|
||||
{
|
||||
if (updateWheel)
|
||||
{
|
||||
wheel2 = Port2.UpdateWheel(c, wheel2);
|
||||
}
|
||||
wheel2 = Port2.UpdateWheel(c);
|
||||
|
||||
return Port2.Read(c, leftMode, wheel2);
|
||||
return Port2.Read(c, leftMode, updateWheel, temp_wheel2);
|
||||
}
|
||||
|
||||
public ControllerDefinition Definition { get; }
|
||||
|
@ -72,12 +69,12 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
public void SyncState(Serializer ser)
|
||||
{
|
||||
ser.BeginSection("Port1");
|
||||
ser.Sync("Wheel 1", ref wheel1);
|
||||
Port1.SyncState(ser);
|
||||
ser.Sync("temp_wheel1", ref temp_wheel1);
|
||||
ser.EndSection();
|
||||
|
||||
ser.BeginSection("Port2");
|
||||
ser.Sync("Wheel 2", ref wheel2);
|
||||
ser.Sync("temp_wheel2", ref temp_wheel2);
|
||||
Port2.SyncState(ser);
|
||||
ser.EndSection();
|
||||
}
|
||||
|
|
|
@ -13,9 +13,9 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
/// </summary>
|
||||
public interface IPort
|
||||
{
|
||||
byte Read(IController c, bool leftMode, int wheel);
|
||||
byte Read(IController c, bool leftMode, bool updateWheel, float wheelAngle);
|
||||
|
||||
int UpdateWheel(IController c, int wheel);
|
||||
float UpdateWheel(IController c);
|
||||
|
||||
ControllerDefinition Definition { get; }
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
};
|
||||
}
|
||||
|
||||
public byte Read(IController c, bool left_mode, int wheel)
|
||||
public byte Read(IController c, bool left_mode, bool updateWheel, float wheelAngle)
|
||||
{
|
||||
return 0x7F; // needs checking
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
public int PortNum { get; }
|
||||
|
||||
public int UpdateWheel(IController c, int wheel)
|
||||
public float UpdateWheel(IController c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
public int PortNum { get; }
|
||||
|
||||
public byte Read(IController c, bool leftMode, int wheel)
|
||||
public byte Read(IController c, bool leftMode, bool updateWheel, float wheelAngle)
|
||||
{
|
||||
if (leftMode)
|
||||
{
|
||||
|
@ -124,7 +124,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
"Key 6", "Key 7", "Key 8", "Key 9", "Pound", "Star"
|
||||
};
|
||||
|
||||
public int UpdateWheel(IController c, int wheel)
|
||||
public float UpdateWheel(IController c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
public ControllerDefinition Definition { get; }
|
||||
|
||||
public byte Read(IController c, bool leftMode, int wheel)
|
||||
public byte Read(IController c, bool leftMode, bool updateWheel, float wheelAngle)
|
||||
{
|
||||
if (leftMode)
|
||||
{
|
||||
|
@ -160,8 +160,45 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
int x = (int)c.GetFloat(Definition.FloatControls[0]);
|
||||
int y = (int)c.GetFloat(Definition.FloatControls[1]);
|
||||
retval |= CalcDirection(x, y);
|
||||
|
||||
float angle;
|
||||
|
||||
if (updateWheel)
|
||||
{
|
||||
angle = wheelAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = CalcDirection(x, y);
|
||||
}
|
||||
|
||||
byte temp2 = 0;
|
||||
|
||||
int temp1 = (int)Math.Floor(angle / 1.25);
|
||||
temp1 = temp1 % 4;
|
||||
|
||||
if (temp1 == 0)
|
||||
{
|
||||
temp2 = 0x10;
|
||||
}
|
||||
|
||||
if (temp1 == 1)
|
||||
{
|
||||
temp2 = 0x30;
|
||||
}
|
||||
if (temp1 == 2)
|
||||
{
|
||||
temp2 = 0x20;
|
||||
}
|
||||
|
||||
if (temp1 == 3)
|
||||
{
|
||||
temp2 = 0x00;
|
||||
}
|
||||
|
||||
|
||||
retval |= temp2;
|
||||
|
||||
return retval;
|
||||
}
|
||||
else
|
||||
|
@ -171,7 +208,44 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
int x = (int)c.GetFloat(Definition.FloatControls[0]);
|
||||
int y = (int)c.GetFloat(Definition.FloatControls[1]);
|
||||
retval |= CalcDirection(x, y);
|
||||
|
||||
float angle;
|
||||
|
||||
if (updateWheel)
|
||||
{
|
||||
angle = wheelAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = CalcDirection(x, y);
|
||||
}
|
||||
|
||||
byte temp2 = 0;
|
||||
|
||||
int temp1 = (int)Math.Floor(angle / 1.25);
|
||||
temp1 = temp1 % 4;
|
||||
|
||||
if (temp1 == 0)
|
||||
{
|
||||
temp2 = 0x10;
|
||||
}
|
||||
|
||||
if (temp1 == 1)
|
||||
{
|
||||
temp2 = 0x30;
|
||||
}
|
||||
if (temp1 == 2)
|
||||
{
|
||||
temp2 = 0x20;
|
||||
}
|
||||
|
||||
if (temp1 == 3)
|
||||
{
|
||||
temp2 = 0x00;
|
||||
}
|
||||
|
||||
|
||||
retval |= temp2;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -190,36 +264,30 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
// x and y are both assumed to be in [-127, 127]
|
||||
// x increases from left to right
|
||||
// y increases from top to bottom
|
||||
private static byte CalcDirection(int x, int y)
|
||||
private static float CalcDirection(int x, int y)
|
||||
{
|
||||
y = -y; // vflip to match the arrangement of FloatControllerButtons
|
||||
|
||||
if (y >= 0 && x > 0)
|
||||
// the wheel is arranged in a grey coded configuration of sensitivity ~2.5 degrees
|
||||
// for each signal
|
||||
// so overall the value returned changes every 1.25 degrees
|
||||
|
||||
float angle = (float)(Math.Atan2(y, x) * 180.0/Math.PI);
|
||||
|
||||
if (angle < 0)
|
||||
{
|
||||
return 0x10;
|
||||
angle = 360 + angle;
|
||||
}
|
||||
|
||||
if (y >= 0 && x <= 0)
|
||||
{
|
||||
return 0x30;
|
||||
}
|
||||
if (y < 0 && x <= 0)
|
||||
{
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
if (y < 0 && x > 0)
|
||||
{
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
Console.WriteLine("Error");
|
||||
return 0x1F;
|
||||
return angle;
|
||||
}
|
||||
|
||||
public int UpdateWheel(IController c, int wheel)
|
||||
public float UpdateWheel(IController c)
|
||||
{
|
||||
return 0;
|
||||
int x = (int)c.GetFloat(Definition.FloatControls[0]);
|
||||
int y = (int)c.GetFloat(Definition.FloatControls[1]);
|
||||
return CalcDirection(x, y);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,7 +311,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
public ControllerDefinition Definition { get; private set; }
|
||||
|
||||
public byte Read(IController c, bool left_mode, int wheel)
|
||||
public byte Read(IController c, bool left_mode, bool updateWheel, float wheelAngle)
|
||||
{
|
||||
if (left_mode)
|
||||
{
|
||||
|
@ -254,7 +322,45 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
if (c.IsPressed(Definition.BoolButtons[3])) retval &= 0xF7;
|
||||
if (c.IsPressed(Definition.BoolButtons[4])) retval &= 0x3F;
|
||||
|
||||
retval |= CalcDirection(wheel);
|
||||
int x = (int)c.GetFloat(Definition.FloatControls[0]);
|
||||
int y = (int)c.GetFloat(Definition.FloatControls[1]);
|
||||
|
||||
float angle;
|
||||
|
||||
if (updateWheel)
|
||||
{
|
||||
angle = wheelAngle;
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = CalcDirection(x, y);
|
||||
}
|
||||
|
||||
byte temp2 = 0;
|
||||
|
||||
int temp1 = (int)Math.Floor(angle / 1.25);
|
||||
temp1 = temp1 % 4;
|
||||
|
||||
if (temp1 == 0)
|
||||
{
|
||||
temp2 = 0x10;
|
||||
}
|
||||
|
||||
if (temp1 == 1)
|
||||
{
|
||||
temp2 = 0x30;
|
||||
}
|
||||
if (temp1 == 2)
|
||||
{
|
||||
temp2 = 0x20;
|
||||
}
|
||||
|
||||
if (temp1 == 3)
|
||||
{
|
||||
temp2 = 0x00;
|
||||
}
|
||||
|
||||
retval |= temp2;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -300,53 +406,30 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
"Purple", "Blue"
|
||||
};
|
||||
|
||||
// positive x represents spinning to the right, negative spinning to the left
|
||||
private static byte CalcDirection(int wheel)
|
||||
// x and y are both assumed to be in [-127, 127]
|
||||
// x increases from left to right
|
||||
// y increases from top to bottom
|
||||
private static float CalcDirection(int x, int y)
|
||||
{
|
||||
byte retval = 0;
|
||||
y = -y; // vflip to match the arrangement of FloatControllerButtons
|
||||
|
||||
if (wheel >= 0 && wheel < 180)
|
||||
// the wheel is arranged in a grey coded configuration of sensitivity ~2.5 degrees
|
||||
// for each signal
|
||||
// so overall the value returned changes every 1.25 degrees
|
||||
|
||||
float angle = (float)(Math.Atan2(y, x) * 180.0 / Math.PI);
|
||||
|
||||
if (angle < 0)
|
||||
{
|
||||
retval = 0x00;
|
||||
angle = 360 + angle;
|
||||
}
|
||||
|
||||
if (wheel >= 180 && wheel < 360)
|
||||
{
|
||||
retval = 0x10;
|
||||
}
|
||||
|
||||
if (wheel < 0 && wheel > -180)
|
||||
{
|
||||
retval = 0x20;
|
||||
}
|
||||
|
||||
if (wheel <= -180 && wheel > -360)
|
||||
{
|
||||
retval = 0x30;
|
||||
}
|
||||
|
||||
return retval;
|
||||
return angle;
|
||||
}
|
||||
|
||||
public int UpdateWheel(IController c, int wheel)
|
||||
public float UpdateWheel(IController c)
|
||||
{
|
||||
int x = (int)c.GetFloat(Definition.FloatControls[0]);
|
||||
|
||||
int diff = -x;
|
||||
|
||||
wheel += diff;
|
||||
|
||||
if (wheel >= 360)
|
||||
{
|
||||
wheel = wheel - 360;
|
||||
}
|
||||
|
||||
if (wheel <= -360)
|
||||
{
|
||||
wheel = wheel + 360;
|
||||
}
|
||||
|
||||
return wheel;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using BizHawk.Emulation.Common;
|
||||
using BizHawk.Common.NumberExtensions;
|
||||
using System;
|
||||
|
||||
namespace BizHawk.Emulation.Cores.ColecoVision
|
||||
{
|
||||
|
@ -25,8 +26,8 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
}
|
||||
|
||||
_frame++;
|
||||
_isLag = true;
|
||||
|
||||
_isLag = true;
|
||||
if (_tracer.Enabled)
|
||||
{
|
||||
_cpu.TraceCallback = s => _tracer.Put(s);
|
||||
|
@ -35,10 +36,42 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
{
|
||||
_cpu.TraceCallback = null;
|
||||
}
|
||||
byte tempRet1 = ControllerDeck.ReadPort1(controller, true, true);
|
||||
byte tempRet2 = ControllerDeck.ReadPort2(controller, true, true);
|
||||
byte tempRet1 = ControllerDeck.ReadPort1(controller, true, false);
|
||||
byte tempRet2 = ControllerDeck.ReadPort2(controller, true, false);
|
||||
|
||||
bool intPending = (!tempRet1.Bit(4)) | (!tempRet2.Bit(4));
|
||||
bool intPending = false;
|
||||
|
||||
// the return values represent the controller's current state, but the sampling rate is not high enough
|
||||
// to catch all changes in wheel orientation
|
||||
// so we use the wheel variable and interpolate between frames
|
||||
|
||||
// first determine how many degrees the wheels changed, and how many regions have been traversed
|
||||
float change1 = (float)(((ControllerDeck.wheel1 - ControllerDeck.temp_wheel1) % 180) / 1.25);
|
||||
float change2 = (float)(((ControllerDeck.wheel2 - ControllerDeck.temp_wheel2) % 180) / 1.25);
|
||||
|
||||
// special cases
|
||||
if ((ControllerDeck.temp_wheel1 > 270) && (ControllerDeck.wheel1 < 90))
|
||||
{
|
||||
change1 = (float)((ControllerDeck.wheel1 + (360 - ControllerDeck.temp_wheel1)) / 1.25);
|
||||
}
|
||||
|
||||
if ((ControllerDeck.wheel1 > 270) && (ControllerDeck.temp_wheel1 < 90))
|
||||
{
|
||||
change1 = -(float)((ControllerDeck.temp_wheel1 + (360 - ControllerDeck.wheel1)) / 1.25);
|
||||
}
|
||||
|
||||
if ((ControllerDeck.temp_wheel2 > 270) && (ControllerDeck.wheel2 < 90))
|
||||
{
|
||||
change2 = (float)((ControllerDeck.wheel2 + (360 - ControllerDeck.temp_wheel2)) / 1.25);
|
||||
}
|
||||
|
||||
if ((ControllerDeck.wheel2 > 270) && (ControllerDeck.temp_wheel2 < 90))
|
||||
{
|
||||
change2 = -(float)((ControllerDeck.temp_wheel2 + (360 - ControllerDeck.wheel2)) / 1.25);
|
||||
}
|
||||
|
||||
int changes_1 = change1 > 0 ? (int)Math.Floor(change1) : (int)Math.Ceiling(change1);
|
||||
int changes_2 = change2 > 0 ? (int)Math.Floor(change2) : (int)Math.Ceiling(change2);
|
||||
|
||||
for (int scanLine = 0; scanLine < 262; scanLine++)
|
||||
{
|
||||
|
@ -66,8 +99,45 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
}
|
||||
}
|
||||
|
||||
// starting from scanline 20, changes to the wheel are added once per scanline (up to 144)
|
||||
if (scanLine > 20)
|
||||
{
|
||||
if (changes_1 != 0)
|
||||
{
|
||||
if (changes_1 > 0)
|
||||
{
|
||||
ControllerDeck.temp_wheel1 = (float)((ControllerDeck.temp_wheel1 + 1.25) % 360);
|
||||
changes_1--;
|
||||
}
|
||||
else
|
||||
{
|
||||
ControllerDeck.temp_wheel1 = (float)((ControllerDeck.temp_wheel1 - 1.25) % 360);
|
||||
changes_1++;
|
||||
}
|
||||
}
|
||||
|
||||
if (changes_2 != 0)
|
||||
{
|
||||
if (changes_2 > 0)
|
||||
{
|
||||
ControllerDeck.temp_wheel2 = (float)((ControllerDeck.temp_wheel2 + 1.25) % 360);
|
||||
changes_2--;
|
||||
}
|
||||
else
|
||||
{
|
||||
ControllerDeck.temp_wheel2 = (float)((ControllerDeck.temp_wheel2 - 1.25) % 360);
|
||||
changes_2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tempRet1 = ControllerDeck.ReadPort1(controller, true, true);
|
||||
tempRet2 = ControllerDeck.ReadPort2(controller, true, true);
|
||||
|
||||
intPending = (!tempRet1.Bit(4) && temp_1_prev) | (!tempRet2.Bit(4) && temp_2_prev);
|
||||
|
||||
_cpu.FlagI = false;
|
||||
if (intPending && scanLine == 50)
|
||||
if (intPending)
|
||||
{
|
||||
if (_vdp.EnableInterrupts)
|
||||
{
|
||||
|
@ -75,8 +145,14 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
intPending = false;
|
||||
}
|
||||
}
|
||||
|
||||
temp_1_prev = tempRet1.Bit(4);
|
||||
temp_2_prev = tempRet2.Bit(4);
|
||||
}
|
||||
|
||||
ControllerDeck.temp_wheel1 = ControllerDeck.wheel1;
|
||||
ControllerDeck.temp_wheel2 = ControllerDeck.wheel2;
|
||||
|
||||
if (_isLag)
|
||||
{
|
||||
_lagCount++;
|
||||
|
|
|
@ -54,6 +54,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
|
||||
ser.BeginSection("Coleco");
|
||||
_vdp.SyncState(ser);
|
||||
ControllerDeck.SyncState(ser);
|
||||
PSG.SyncState(ser);
|
||||
SGM_sound.SyncState(ser);
|
||||
ser.Sync("UseSGM", ref use_SGM);
|
||||
|
@ -69,6 +70,7 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
ser.Sync("Frame", ref _frame);
|
||||
ser.Sync("LagCount", ref _lagCount);
|
||||
ser.Sync("IsLag", ref _isLag);
|
||||
|
||||
ser.EndSection();
|
||||
|
||||
if (ser.IsReader)
|
||||
|
|
|
@ -71,6 +71,8 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
public byte[] SGM_high_RAM = new byte[0x6000];
|
||||
public byte[] SGM_low_RAM = new byte[0x2000];
|
||||
|
||||
public bool temp_1_prev, temp_2_prev;
|
||||
|
||||
private int _frame;
|
||||
private IController _controller;
|
||||
|
||||
|
@ -245,13 +247,13 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
byte retval;
|
||||
if (_inputPortSelection == InputPortMode.Left)
|
||||
{
|
||||
retval = ControllerDeck.ReadPort1(_controller, true, false);
|
||||
retval = ControllerDeck.ReadPort1(_controller, true, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (_inputPortSelection == InputPortMode.Right)
|
||||
{
|
||||
retval = ControllerDeck.ReadPort1(_controller, false, false);
|
||||
retval = ControllerDeck.ReadPort1(_controller, false, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -264,13 +266,13 @@ namespace BizHawk.Emulation.Cores.ColecoVision
|
|||
byte retval;
|
||||
if (_inputPortSelection == InputPortMode.Left)
|
||||
{
|
||||
retval = ControllerDeck.ReadPort2(_controller, true, false);
|
||||
retval = ControllerDeck.ReadPort2(_controller, true, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if (_inputPortSelection == InputPortMode.Right)
|
||||
{
|
||||
retval = ControllerDeck.ReadPort2(_controller, false, false);
|
||||
retval = ControllerDeck.ReadPort2(_controller, false, true);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue