support bsnes xml files and super road blaster MSU-1 game
This commit is contained in:
parent
f3a8cee8bc
commit
df99f36464
|
@ -261,16 +261,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer.Length < offset + count) throw new IndexOutOfRangeException();
|
||||
fixed (byte* pbuffer = &buffer[offset])
|
||||
buf.Read((IntPtr)pbuffer, count);
|
||||
if(buffer.Length != 0)
|
||||
fixed (byte* pbuffer = &buffer[offset])
|
||||
buf.Read((IntPtr)pbuffer, count);
|
||||
return count;
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer.Length < offset + count) throw new IndexOutOfRangeException();
|
||||
fixed (byte* pbuffer = &buffer[offset])
|
||||
buf.Write((IntPtr)pbuffer, count);
|
||||
if(buffer.Length != 0)
|
||||
fixed (byte* pbuffer = &buffer[offset])
|
||||
buf.Write((IntPtr)pbuffer, count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -646,11 +648,11 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
return ret;
|
||||
}
|
||||
|
||||
public bool snes_load_cartridge_normal(string rom_xml, byte[] rom_data)
|
||||
public bool snes_load_cartridge_normal(byte[] rom_xml, byte[] rom_data)
|
||||
{
|
||||
WritePipeMessage(eMessage.eMessage_snes_load_cartridge_normal);
|
||||
WritePipeString(rom_xml ?? "");
|
||||
WritePipeBlob(rom_data);
|
||||
WritePipeBlob(rom_xml ?? new byte[0]);
|
||||
WritePipeBlob(rom_data ?? new byte[0]);
|
||||
//not a very obvious order.. because we do tons of work immediately after the last param goes down and need to answer messages
|
||||
WaitForCompletion();
|
||||
bool ret = brPipe.ReadBoolean();
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
@ -101,15 +103,36 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
|
||||
string snes_path_request(int slot, string hint)
|
||||
{
|
||||
//heres how to get MSU-1 working:
|
||||
//if (hint == "msu1.rom") return @"c:\roms\SuperRoadBlaster\SuperRoadBlaster.msu";
|
||||
//if (Path.GetExtension(hint).ToLower() == ".pcm")
|
||||
// return Path.Combine(@"c:\roms\SuperRoadBlaster\", hint);
|
||||
//to do this accurately, we should be loading the xml file.
|
||||
//perhaps, if we do that, bsnes will be asking us for the correct paths. at the very least, we could parse the xml ourselves and return the correct thing for msu1.rom
|
||||
//every rom requests msu1.rom... why? who knows.
|
||||
//also handle msu-1 pcm files here
|
||||
bool is_msu1_rom = hint == "msu1.rom";
|
||||
bool is_msu1_pcm = Path.GetExtension(hint).ToLower() == ".pcm";
|
||||
if (is_msu1_rom || is_msu1_pcm)
|
||||
{
|
||||
//well, check if we have an msu-1 xml
|
||||
if (romxml != null && romxml["cartridge"] != null && romxml["cartridge"]["msu1"] != null)
|
||||
{
|
||||
var msu1 = romxml["cartridge"]["msu1"];
|
||||
if (is_msu1_rom && msu1["rom"].Attributes["name"] != null)
|
||||
return CoreComm.AcquireSubfilePath(msu1["rom"].Attributes["name"].Value);
|
||||
if (is_msu1_pcm)
|
||||
{
|
||||
//return @"D:\roms\snes\SuperRoadBlaster\SuperRoadBlaster-1.pcm";
|
||||
//return "";
|
||||
int wantsTrackNumber = int.Parse(hint.Replace("track-", "").Replace(".pcm", ""));
|
||||
wantsTrackNumber++;
|
||||
string wantsTrackString = wantsTrackNumber.ToString();
|
||||
foreach (var child in msu1.ChildNodes.Cast<XmlNode>())
|
||||
{
|
||||
if (child.Name == "track" && child.Attributes["number"].Value == wantsTrackString)
|
||||
return CoreComm.AcquireSubfilePath(child.Attributes["name"].Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//every rom requests this byuu homemade rom
|
||||
if (hint == "msu1.rom") return "";
|
||||
//not found.. what to do? (every rom will get here when msu1.rom is requested)
|
||||
return "";
|
||||
}
|
||||
|
||||
//build romfilename
|
||||
string test = Path.Combine(CoreComm.SNES_FirmwaresPath ?? "", hint);
|
||||
|
@ -143,6 +166,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
}
|
||||
|
||||
public LibsnesApi api;
|
||||
System.Xml.XmlDocument romxml;
|
||||
|
||||
public LibsnesCore(CoreComm comm)
|
||||
{
|
||||
|
@ -155,7 +179,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
LibsnesApi.snes_trace_t tracecb;
|
||||
LibsnesApi.snes_audio_sample_t soundcb;
|
||||
|
||||
public void Load(GameInfo game, byte[] romData, byte[] sgbRomData, bool DeterministicEmulation)
|
||||
public void Load(GameInfo game, byte[] romData, byte[] sgbRomData, bool DeterministicEmulation, byte[] xmlData)
|
||||
{
|
||||
ScanlineHookManager = new MyScanlineHookManager(this);
|
||||
|
||||
|
@ -181,12 +205,13 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
InitAudio();
|
||||
|
||||
//strip header
|
||||
if ((romData.Length & 0x7FFF) == 512)
|
||||
{
|
||||
var newData = new byte[romData.Length - 512];
|
||||
Array.Copy(romData, 512, newData, 0, newData.Length);
|
||||
romData = newData;
|
||||
}
|
||||
if(romData != null)
|
||||
if ((romData.Length & 0x7FFF) == 512)
|
||||
{
|
||||
var newData = new byte[romData.Length - 512];
|
||||
Array.Copy(romData, 512, newData, 0, newData.Length);
|
||||
romData = newData;
|
||||
}
|
||||
|
||||
if (game["SGB"])
|
||||
{
|
||||
|
@ -197,8 +222,22 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
}
|
||||
else
|
||||
{
|
||||
//we may need to get some information out of the cart, even during the following bootup/load process
|
||||
if (xmlData != null)
|
||||
{
|
||||
romxml = new System.Xml.XmlDocument();
|
||||
romxml.Load(new MemoryStream(xmlData));
|
||||
|
||||
//bsnes wont inspect the xml to load the necessary sfc file.
|
||||
//so, we have to do that here and pass it in as the romData :/
|
||||
if (romxml["cartridge"] != null && romxml["cartridge"]["rom"] != null)
|
||||
romData = File.ReadAllBytes(CoreComm.AcquireSubfilePath(romxml["cartridge"]["rom"].Attributes["name"].Value));
|
||||
else
|
||||
throw new Exception("Could not find rom file specification in xml file. Please check the integrity of your xml file");
|
||||
}
|
||||
|
||||
SystemId = "SNES";
|
||||
if (!api.snes_load_cartridge_normal(null, romData))
|
||||
if (!api.snes_load_cartridge_normal(xmlData, romData))
|
||||
throw new Exception("snes_load_cartridge_normal() failed");
|
||||
}
|
||||
|
||||
|
@ -822,14 +861,15 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
|
|||
{
|
||||
MemoryDomains = new List<MemoryDomain>();
|
||||
|
||||
var romDomain = new MemoryDomain("CARTROM", romData.Length, Endian.Little,
|
||||
(addr) => romData[addr],
|
||||
(addr, value) => romData[addr] = value);
|
||||
|
||||
|
||||
if (romData != null)
|
||||
{
|
||||
var romDomain = new MemoryDomain("CARTROM", romData.Length, Endian.Little,
|
||||
(addr) => romData[addr],
|
||||
(addr, value) => romData[addr] = value);
|
||||
MemoryDomains.Add(romDomain);
|
||||
}
|
||||
|
||||
MainMemory = MakeMemoryDomain("WRAM", LibsnesApi.SNES_MEMORY.WRAM, Endian.Little);
|
||||
MemoryDomains.Add(romDomain);
|
||||
|
||||
//someone needs to comprehensively address these in SGB mode, and go hook them up in the gameboy core
|
||||
if (!IsSGB)
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using System.Text;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
namespace BizHawk
|
||||
{
|
||||
public class CoreComm
|
||||
|
@ -15,6 +17,8 @@ namespace BizHawk
|
|||
public string SNES_FirmwaresPath;
|
||||
public string C64_FirmwaresPath;
|
||||
|
||||
public Func<string, string> AcquireSubfilePath;
|
||||
|
||||
public string SNES_ExePath;
|
||||
public string SNES_Profile;
|
||||
public bool SNES_UseRingBuffer;
|
||||
|
|
|
@ -1793,7 +1793,7 @@ namespace BizHawk.MultiClient
|
|||
if (path == null) return false;
|
||||
using (var file = new HawkFile())
|
||||
{
|
||||
string[] romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL" };
|
||||
string[] romExtensions = new[] { "SMS", "SMC", "SFC", "PCE", "SGX", "GG", "SG", "BIN", "GEN", "MD", "SMD", "GB", "NES", "FDS", "ROM", "INT", "GBC", "UNF", "A78", "CRT", "COL", "XML" };
|
||||
|
||||
//lets not use this unless we need to
|
||||
//file.NonArchiveExtensions = romExtensions;
|
||||
|
@ -1927,6 +1927,17 @@ namespace BizHawk.MultiClient
|
|||
rom = new RomGame(file);
|
||||
game = rom.GameInfo;
|
||||
|
||||
bool isXml = false;
|
||||
|
||||
//right now, xml is always snes.
|
||||
//later, we may need to inspect the XML ourselves to dispatch it to the correct system (if any other systems ever use xml...)
|
||||
if (file.Extension.ToLower() == ".xml")
|
||||
{
|
||||
game.System = "SNES";
|
||||
isXml = true;
|
||||
}
|
||||
|
||||
|
||||
RETRY:
|
||||
switch (game.System)
|
||||
{
|
||||
|
@ -1934,9 +1945,20 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
game.System = "SNES";
|
||||
nextComm.SNES_ExePath = SNES_Prepare(Global.Config.SNESProfile);
|
||||
|
||||
//this isnt completely correct. might need to deal with the archive somehow.
|
||||
//once done, code should be factored out to be useful in other platforms as well
|
||||
//BUT!!! right now bsnes needs to open the file itself. lame.
|
||||
//nextComm.AcquireSubfile = (subpath) =>
|
||||
// File.OpenRead(Path.Combine(Path.GetDirectoryName(path),subpath));
|
||||
nextComm.AcquireSubfilePath = (subpath) =>
|
||||
Path.Combine(Path.GetDirectoryName(path),subpath);
|
||||
|
||||
var snes = new LibsnesCore(nextComm);
|
||||
nextEmulator = snes;
|
||||
snes.Load(game, rom.FileData, null, deterministicemulation);
|
||||
byte[] romData = isXml?null:rom.FileData;
|
||||
byte[] xmlData = isXml?rom.FileData:null;
|
||||
snes.Load(game, romData, null, deterministicemulation, xmlData);
|
||||
}
|
||||
break;
|
||||
case "SMS":
|
||||
|
@ -2081,7 +2103,7 @@ namespace BizHawk.MultiClient
|
|||
var snes = new LibsnesCore(nextComm);
|
||||
nextEmulator = snes;
|
||||
game.FirmwareHash = Util.BytesToHexString(System.Security.Cryptography.SHA1.Create().ComputeHash(sgbrom));
|
||||
snes.Load(game, rom.FileData, sgbrom, deterministicemulation);
|
||||
snes.Load(game, rom.FileData, sgbrom, deterministicemulation, null);
|
||||
}
|
||||
}
|
||||
//}
|
||||
|
@ -3596,11 +3618,11 @@ namespace BizHawk.MultiClient
|
|||
if (INTERIM)
|
||||
{
|
||||
ofd.Filter = FormatFilter(
|
||||
"Rom Files", "*.nes;*.fds;*.sms;*.gg;*.sg;*.pce;*.sgx;*.bin;*.smd;*.rom;*.a26;*.a78;*.cue;*.exe;*.gb;*.gbc;*.gen;*.md;*.col;.int;*.smc;*.sfc;*.prg;*.d64;*.g64;*.crt;*.sgb;%ARCH%",
|
||||
"Rom Files", "*.nes;*.fds;*.sms;*.gg;*.sg;*.pce;*.sgx;*.bin;*.smd;*.rom;*.a26;*.a78;*.cue;*.exe;*.gb;*.gbc;*.gen;*.md;*.col;.int;*.smc;*.sfc;*.prg;*.d64;*.g64;*.crt;*.sgb;*.xml;%ARCH%",
|
||||
"Music Files", "*.psf;*.sid",
|
||||
"Disc Images", "*.cue",
|
||||
"NES", "*.nes;*.fds;%ARCH%",
|
||||
"Super NES", "*.smc;*.sfc;%ARCH%",
|
||||
"Super NES", "*.smc;*.sfc;*.xml;%ARCH%",
|
||||
"Master System", "*.sms;*.gg;*.sg;%ARCH%",
|
||||
"PC Engine", "*.pce;*.sgx;*.cue;%ARCH%",
|
||||
"TI-83", "*.rom;%ARCH%",
|
||||
|
@ -3621,10 +3643,10 @@ namespace BizHawk.MultiClient
|
|||
else
|
||||
{
|
||||
ofd.Filter = FormatFilter(
|
||||
"Rom Files", "*.nes;*.fds;*.sms;*.gg;*.sg;*.gb;*.gbc;*.pce;*.sgx;*.bin;*.smd;*.gen;*.md;*.smc;*.sfc;*.a26;*.a78;*.col;*.rom;*.cue;*.sgb;%ARCH%",
|
||||
"Rom Files", "*.nes;*.fds;*.sms;*.gg;*.sg;*.gb;*.gbc;*.pce;*.sgx;*.bin;*.smd;*.gen;*.md;*.smc;*.sfc;*.a26;*.a78;*.col;*.rom;*.cue;*.sgb;*.xml;%ARCH%",
|
||||
"Disc Images", "*.cue",
|
||||
"NES", "*.nes;*.fds;%ARCH%",
|
||||
"Super NES", "*.smc;*.sfc;%ARCH%",
|
||||
"Super NES", "*.smc;*.sfc;*.xml;%ARCH%",
|
||||
"Gameboy", "*.gb;*.gbc;*.sgb;%ARCH%",
|
||||
"Master System", "*.sms;*.gg;*.sg;%ARCH%",
|
||||
"PC Engine", "*.pce;*.sgx;*.cue;%ARCH%",
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -507,11 +507,16 @@ void RunMessageLoop()
|
|||
|
||||
case eMessage_snes_load_cartridge_normal:
|
||||
{
|
||||
std::string xml = ReadPipeString();
|
||||
Blob rom_data = ReadPipeBlob();
|
||||
Blob xml = ReadPipeBlob();
|
||||
xml.push_back(0); //make sure the xml is null terminated
|
||||
const char* xmlptr = NULL;
|
||||
if(xml != "") xmlptr = xml.c_str();
|
||||
bool ret = snes_load_cartridge_normal(xmlptr,(unsigned char*)&rom_data[0],rom_data.size());
|
||||
if(xml.size() != 1) xmlptr = &xml[0];
|
||||
|
||||
Blob rom_data = ReadPipeBlob();
|
||||
const unsigned char* rom_ptr = NULL;
|
||||
if(rom_data.size() != 0) rom_ptr = (unsigned char*)&rom_data[0];
|
||||
|
||||
bool ret = snes_load_cartridge_normal(xmlptr,rom_ptr,rom_data.size());
|
||||
WritePipe(eMessage_Complete);
|
||||
WritePipe((char)(ret?1:0));
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue