saturnus: start working on controller hook up. there's something wrong with the CD stuff though, and games don't work

This commit is contained in:
nattthebear 2017-06-04 21:13:48 -04:00
parent 87ce1086cb
commit d7b8464a9b
5 changed files with 212 additions and 27 deletions

View File

@ -1150,6 +1150,7 @@
<Compile Include="Consoles\Sega\Saturn\LibSaturnus.cs" />
<Compile Include="Consoles\Sega\Saturn\LibYabause.cs" />
<Compile Include="Consoles\Sega\Saturn\Saturnus.cs" />
<Compile Include="Consoles\Sega\Saturn\SaturnusControllerDeck.cs" />
<Compile Include="Consoles\Sega\Saturn\Yabause.cs" />
<Compile Include="Consoles\Sega\Saturn\Yabause.IDriveLight.cs">
<DependentUpon>Yabause.cs</DependentUpon>

View File

@ -26,7 +26,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
[StructLayout(LayoutKind.Sequential)]
public struct Track
{
public int Address;
public int Adr;
public int Control;
public int Lba;
public int Valid;
@ -44,14 +44,16 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
[FieldOffset(8)]
public IntPtr Pixels;
[FieldOffset(16)]
public long MasterCycles;
public IntPtr Controllers;
[FieldOffset(24)]
public int SoundBufMaxSize;
[FieldOffset(28)]
public int SoundBufSize;
public long MasterCycles;
[FieldOffset(32)]
public int Width;
public int SoundBufMaxSize;
[FieldOffset(36)]
public int SoundBufSize;
[FieldOffset(40)]
public int Width;
[FieldOffset(44)]
public int Height;
};
@ -76,5 +78,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
public abstract void SetDisk(int disk, bool open);
[BizImport(CC)]
public abstract void FrameAdvance([In, Out]FrameAdvanceInfo f);
[BizImport(CC)]
public abstract void SetupInput(int[] portdevices, int[] multitaps);
}
}

View File

@ -20,6 +20,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
private Disc[] _disks;
private DiscSectorReader[] _diskReaders;
private bool _isPal;
private SaturnusControllerDeck _controllerDeck;
public Saturnus(CoreComm comm, IEnumerable<Disc> disks)
{
@ -45,10 +46,18 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
SetFirmwareCallbacks();
SetCdCallbacks();
if (!_core.Init(_disks.Length))
throw new InvalidOperationException("Core rejected the disks!");
ClearAllCallbacks();
_controllerDeck = new SaturnusControllerDeck(new[] { false, false },
new[] { SaturnusControllerDeck.Device.Gamepad, SaturnusControllerDeck.Device.None },
_core);
ControllerDefinition = _controllerDeck.Definition;
ControllerDefinition.Name = "Saturn Controller";
ControllerDefinition.BoolButtons.Add("Power");
ControllerDefinition.BoolButtons.Add("Reset"); // not yet hooked up
_exe.Seal();
SetCdCallbacks();
_core.SetDisk(0, false);
@ -56,14 +65,19 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
public unsafe void FrameAdvance(IController controller, bool render, bool rendersound = true)
{
if (controller.IsPressed("Power"))
_core.HardReset();
fixed (short* _sp = _soundBuffer)
fixed (int* _vp = _videoBuffer)
fixed (int* _vp = _videoBuffer)
fixed (byte* _cp = _controllerDeck.Poll(controller))
{
var info = new LibSaturnus.FrameAdvanceInfo
{
SoundBuf = (IntPtr)_sp,
SoundBufMaxSize = _soundBuffer.Length / 2,
Pixels = (IntPtr)_vp
Pixels = (IntPtr)_vp,
Controllers = (IntPtr)_cp
};
_core.FrameAdvance(info);
@ -101,7 +115,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
public string SystemId { get { return "SAT"; } }
public bool DeterministicEmulation { get; private set; }
public CoreComm CoreComm { get; }
public ControllerDefinition ControllerDefinition => NullController.Instance.Definition;
public ControllerDefinition ControllerDefinition { get; }
#region Callbacks
@ -176,7 +190,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
t.DiskType = (int)tin.Session1Format;
for (int i = 0; i < 101; i++)
{
t.Tracks[i].Address = 1; // ????
t.Tracks[i].Adr = 1; // ????
t.Tracks[i].Lba = tin.TOCItems[i].LBA;
t.Tracks[i].Control = (int)tin.TOCItems[i].Control;
t.Tracks[i].Valid = tin.TOCItems[i].Exists ? 1 : 0;
@ -184,6 +198,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
}
private void CDSectorCallback(int disk, int lba, IntPtr dest)
{
Console.WriteLine("servicing " + lba);
var buff = new byte[2448];
_diskReaders[disk].ReadLBA_2448(lba, buff, 0);
Marshal.Copy(buff, 0, dest, 2448);

View File

@ -0,0 +1,140 @@
using BizHawk.Emulation.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
{
public class SaturnusControllerDeck
{
private const int DataSize = 32;
private static readonly Type[] Implementors =
{
typeof(None),
typeof(Gamepad),
typeof(None),
typeof(None),
typeof(None),
typeof(None),
typeof(None),
typeof(None)
};
private readonly IDevice[] _devices;
private readonly ControlDefUnMerger[] _unmerger;
private readonly byte[] _data;
public ControllerDefinition Definition { get; }
public SaturnusControllerDeck(bool[] multitap, Device[] devices, LibSaturnus core)
{
int count = 2 + multitap.Count(b => b) * 5;
int[] dev = new int[12];
int[] mt = new int[2];
for (int i = 0; i < 12; i++)
dev[i] = (int)(i < count ? devices[i] : Device.None);
for (int i = 0; i < 2; i++)
mt[i] = multitap[i] ? 1 : 0;
core.SetupInput(dev, mt);
_devices = dev.Take(count)
.Select(i => Activator.CreateInstance(Implementors[i]))
.Cast<IDevice>()
.ToArray();
_data = new byte[count * DataSize];
List<ControlDefUnMerger> cdum;
Definition = ControllerDefinitionMerger.GetMerged(_devices.Select(d => d.Definition),
out cdum);
_unmerger = cdum.ToArray();
}
public byte[] Poll(IController controller)
{
for (int i = 0, offset = 0; i < _devices.Length; i++, offset += DataSize)
_devices[i].Update(_unmerger[i].UnMerge(controller), _data, offset);
return _data;
}
public enum Device
{
None,
Gamepad,
ThreeDeePad,
Mouse,
Wheel,
Mission,
DualMission,
Keyboard
}
private interface IDevice
{
void Update(IController controller, byte[] dest, int offset);
ControllerDefinition Definition { get; }
}
private class None : IDevice
{
private static readonly ControllerDefinition NoneDefition = new ControllerDefinition();
public ControllerDefinition Definition => NoneDefition;
public void Update(IController controller, byte[] dest, int offset)
{
}
}
private abstract class ButtonedDevice : IDevice
{
protected ButtonedDevice()
{
Definition = new ControllerDefinition
{
BoolButtons = ButtonNames.Where(s => s != null).ToList()
};
}
protected abstract string[] ButtonNames { get; }
public ControllerDefinition Definition { get; }
public virtual void Update(IController controller, byte[] dest, int offset)
{
byte data = 0;
int pos = 0;
int bit = 0;
for (int i = 0; i < ButtonNames.Length; i++)
{
if (ButtonNames[i] != null && controller.IsPressed(ButtonNames[i]))
data |= (byte)(1 << bit);
if (++bit == 8)
{
bit = 0;
dest[offset + pos++] = data;
data = 0;
}
}
if (bit != 0)
dest[offset] = data;
}
}
private class Gamepad : ButtonedDevice
{
private static readonly string[] _buttonNames =
{
"0Z", "0Y", "0X", "0R",
"0Up", "0Down", "0Left", "0Right",
"0B", "0C", "0A", "0Start",
null,null, null, "0L"
};
protected override string[] ButtonNames => _buttonNames;
}
}
}

View File

@ -9,10 +9,10 @@
#define EXPORT extern "C" ECL_EXPORT
using namespace MDFN_IEN_SS;
static int32 (*FirmwareSizeCallback)(const char* filename);
static void (*FirmwareDataCallback)(const char* filename, uint8* dest);
static int32 (*FirmwareSizeCallback)(const char *filename);
static void (*FirmwareDataCallback)(const char *filename, uint8 *dest);
std::unique_ptr<MemoryStream> GetFirmware(const char* filename)
std::unique_ptr<MemoryStream> GetFirmware(const char *filename)
{
int32 length = FirmwareSizeCallback(filename);
auto buffer = new uint8[length];
@ -24,7 +24,7 @@ std::unique_ptr<MemoryStream> GetFirmware(const char* filename)
return ms;
}
EXPORT void SetFirmwareCallbacks(int32 (*sizecallback)(const char *filename), void (*datacallback)(const char* filename, uint8* dest))
EXPORT void SetFirmwareCallbacks(int32 (*sizecallback)(const char *filename), void (*datacallback)(const char *filename, uint8 *dest))
{
FirmwareSizeCallback = sizecallback;
FirmwareDataCallback = datacallback;
@ -37,7 +37,7 @@ struct FrontendTOC
int32 DiskType;
struct
{
int32 Address;
int32 Adr;
int32 Control;
int32 Lba;
int32 Valid;
@ -55,7 +55,7 @@ EXPORT void SetCDCallbacks(void (*toccallback)(int disk, FrontendTOC *dest), voi
class MyCDIF : public CDIF
{
private:
private:
int disk;
public:
@ -68,10 +68,10 @@ class MyCDIF : public CDIF
disc_toc.disc_type = t.DiskType;
for (int i = 0; i < 101; i++)
{
disc_toc.tracks[i].adr = t.Tracks[i].Address;
disc_toc.tracks[i].adr = t.Tracks[i].Adr;
disc_toc.tracks[i].control = t.Tracks[i].Control;
disc_toc.tracks[i].lba = t.Tracks[i].Lba;
disc_toc.tracks[i].valid = t.Tracks[i].Valid;
disc_toc.tracks[i].valid = t.Tracks[i].Valid;
}
}
@ -91,7 +91,7 @@ class MyCDIF : public CDIF
};
static std::vector<CDIF *> CDInterfaces;
static uint32* FrameBuffer;
static uint32 *FrameBuffer;
static uint8 IsResetPushed; // 1 or 0
namespace MDFN_IEN_SS
@ -100,7 +100,7 @@ extern bool LoadCD(std::vector<CDIF *> *CDInterfaces);
}
EXPORT bool Init(int numDisks)
{
FrameBuffer = (uint32*)alloc_invisible(1024 * 1024);
FrameBuffer = (uint32 *)alloc_invisible(1024 * 1024);
for (int i = 0; i < numDisks; i++)
CDInterfaces.push_back(new MyCDIF(i));
auto ret = LoadCD(&CDInterfaces);
@ -140,9 +140,11 @@ extern void Emulate(EmulateSpecStruct *espec_arg);
struct FrameAdvanceInfo
{
int16* SoundBuf;
int16 *SoundBuf;
uint32* Pixels;
uint32 *Pixels;
uint8* Controllers;
int64 MasterCycles;
@ -164,7 +166,9 @@ struct FrameAdvanceInfo
// bool InterlaceField;
};
EXPORT void FrameAdvance(FrameAdvanceInfo& f)
static uint8 ControllerInput[12 * 32];
EXPORT void FrameAdvance(FrameAdvanceInfo &f)
{
EmulateSpecStruct e;
int32 LineWidths[1024];
@ -173,6 +177,8 @@ EXPORT void FrameAdvance(FrameAdvanceInfo& f)
e.LineWidths = LineWidths;
e.SoundBuf = f.SoundBuf;
e.SoundBufMaxSize = f.SoundBufMaxSize;
memcpy(ControllerInput, f.Controllers, sizeof(ControllerInput));
Emulate(&e);
f.SoundBufSize = e.SoundBufSize;
f.MasterCycles = e.MasterCycles;
@ -181,8 +187,8 @@ EXPORT void FrameAdvance(FrameAdvanceInfo& f)
for (int i = 0; i < e.h; i++)
w = std::max(w, LineWidths[i]);
const uint32* src = FrameBuffer;
uint32* dst = f.Pixels;
const uint32 *src = FrameBuffer;
uint32 *dst = f.Pixels;
const int srcp = 1024;
const int dstp = w;
src += e.y * srcp + e.x;
@ -195,6 +201,26 @@ EXPORT void FrameAdvance(FrameAdvanceInfo& f)
f.Height = e.h;
}
static const char *DeviceNames[] =
{
"none",
"gamepad",
"3dpad",
"mouse",
"wheel",
"mission",
"dmission",
"keyboard"
};
EXPORT void SetupInput(const int* portdevices, const int* multitaps)
{
for (int i = 0; i < 2; i++)
SMPC_SetMultitap(i, multitaps[i]);
for (int i = 0; i < 12; i++)
SMPC_SetInput(i, DeviceNames[portdevices[i]], ControllerInput + i * 32);
}
/*void VDP2REND_SetGetVideoParams(MDFNGI* gi, const bool caspect, const int sls, const int sle, const bool show_h_overscan, const bool dohblend)
{
CorrectAspect = caspect;
@ -241,7 +267,6 @@ void SetGetVideoParams(MDFNGI* gi, const bool caspect, const int sls, const int
VDP2REND_SetGetVideoParams(gi, caspect, sls, sle, show_h_overscan, dohblend);
}*/
// if (BackupRAM_Dirty)SaveBackupRAM();
// if (CART_GetClearNVDirty())SaveCartNV();