diff --git a/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity b/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity index adea99e..2d477ba 100644 --- a/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity +++ b/AxibugEmuOnline.Client/Assets/Scene/EmuTest.unity @@ -123,6 +123,49 @@ NavMeshSettings: debug: m_Flags: 0 m_NavMeshData: {fileID: 0} +--- !u!1 &149545946 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 149545948} + - component: {fileID: 149545947} + m_Layer: 0 + m_Name: NesEmulator + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!114 &149545947 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149545946} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 39557e19783acee499ace6c68549e8f8, type: 3} + m_Name: + m_EditorClassIdentifier: +--- !u!4 &149545948 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 149545946} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 3 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &708549044 GameObject: m_ObjectHideFlags: 0 diff --git a/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef b/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef index afae401..46da217 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef +++ b/AxibugEmuOnline.Client/Assets/Script/AxibugEmuOnline.Client.asmdef @@ -2,7 +2,7 @@ "name": "AxibugEmuOnline.Client", "rootNamespace": "AxibugEmuOnline.Client", "references": [ - "GUID:0c194730510bd1b4fad0398ccfe4235b" + "GUID:390a2c4058e5c304a87e8be70c84d80b" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator.meta new file mode 100644 index 0000000..49f52ed --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5ff32bd86cd0f8245811007dc4e50768 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs new file mode 100644 index 0000000..d031095 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs @@ -0,0 +1,20 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using VirtualNes.Core.Debug; + +namespace AxibugEmuOnline.Client +{ + public class CoreDebuger : IDebugerImpl + { + public void Log(string message) + { + Debug.Log(message); + } + + public void LogError(string message) + { + Debug.LogError(message); + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs.meta new file mode 100644 index 0000000..b7a7572 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreDebuger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 06357866273334741b885e5a1ad23afd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs new file mode 100644 index 0000000..495360b --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using UnityEngine; +using VirtualNes.Core; + +namespace AxibugEmuOnline.Client +{ + public class CoreSupporter : ISupporterImpl + { + private static string RomDirectoryPath + { + get + { +#if UNITY_EDITOR + return "Assets/StreamingAssets/Roms"; +#else + return $"{Application.streamingAssetsPath}/Roms"; +#endif + } + } + + public Stream OpenRom(string fname) + { + try + { + var stream = File.Open($"{RomDirectoryPath}/{fname}", FileMode.Open); + return stream; + } + catch (Exception ex) + { + Debug.LogError(ex); + return null; + } + } + + public void GetRomPathInfo(string fname, out string fullPath, out string directPath) + { + directPath = RomDirectoryPath; + fullPath = $"{directPath}/{fname}"; + } + + public Stream OpenFile_DISKSYS() + { + return File.Open($"{Application.streamingAssetsPath}/Disksys.rom", FileMode.Open, FileAccess.Read); + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs.meta new file mode 100644 index 0000000..5bad9b0 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8207d923313517f448d7b4d54756e993 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs new file mode 100644 index 0000000..28d0241 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs @@ -0,0 +1,21 @@ +using UnityEngine; +using VirtualNes.Core; +using VirtualNes.Core.Debug; + +namespace AxibugEmuOnline.Client +{ + public class NesEmulator : MonoBehaviour + { + private void Start() + { + StartGame("Kirby.nes"); + } + + public void StartGame(string romName) + { + Supporter.Setup(new CoreSupporter()); + Debuger.Setup(new CoreDebuger()); + NES nes = new NES(romName); + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs.meta new file mode 100644 index 0000000..d178f30 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 39557e19783acee499ace6c68549e8f8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/StreamingAssets.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets.meta new file mode 100644 index 0000000..a8658aa --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 353264361911f2f43bb2c088c7e73fec +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom b/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom new file mode 100644 index 0000000..93a8d93 Binary files /dev/null and b/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom differ diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom.meta similarity index 62% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom.meta index 97eef8d..bfab4b0 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes.meta +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Disksys.rom.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 01dd757415143ae46921461228964dd5 -TextScriptImporter: +guid: 588a6a32c9d46b943b4909b1757f4572 +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms.meta similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms.meta diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Kirby.nes.bytes rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes.meta similarity index 62% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes.meta index cfcf910..803c960 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes.meta +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Kirby.nes.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: ecb5d904338d35c43bb3b98249b36394 -TextScriptImporter: +guid: 41cd7684d8de61f4499c3aa27a6c5b3a +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/Mario.nes.bytes rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes.meta similarity index 62% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes.meta index db26e21..66eb8f2 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes.meta +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/Mario.nes.meta @@ -1,6 +1,6 @@ fileFormatVersion: 2 -guid: 4933f61382c34574db545f3d9e72b51d -TextScriptImporter: +guid: 50dfce75937af2a44bafd221a0163501 +DefaultImporter: externalObjects: {} userData: assetBundleName: diff --git a/AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes similarity index 100% rename from AxibugEmuOnline.Client/Assets/Resources/Roms/tortoise4.nes.bytes rename to AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes diff --git a/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes.meta b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes.meta new file mode 100644 index 0000000..206dbb7 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/StreamingAssets/Roms/tortoise4.nes.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 7abf09a3e3fd84648852e5d972dfd260 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs index 02be71c..510f7b7 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/APU.cs @@ -19,6 +19,8 @@ namespace VirtualNes.Core public APU(NES parent) { + @internal = new APU_INTERNAL(); + exsound_select = 0; nes = parent; diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs.meta new file mode 100644 index 0000000..7a2e409 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7b37fc906e6cec64eb2608762f7f80bf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs new file mode 100644 index 0000000..4275dcf --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs @@ -0,0 +1,92 @@ +using Codice.CM.Client.Differences; +using System; +using System.Collections; +using System.Collections.Generic; +using Unity.VisualScripting.Antlr3.Runtime.Tree; +using UnityEngine; + +namespace VirtualNes.Core +{ + public static class CRC + { + const int CHAR_BIT = 8; + const ulong CRCPOLY1 = 0x04C11DB7UL; + const ulong CRCPOLY2 = 0xEDB88320UL; + + static bool m_Init; + static bool m_InitRev; + static ulong[] m_CrcTable = new ulong[byte.MaxValue + 1]; + static ulong[] m_CrcTableRev = new ulong[byte.MaxValue + 1]; + + public static ulong Crc(int size, Span c) + { + if (!m_Init) + { + MakeTable(); + m_Init = true; + } + + ulong r = 0xFFFFFFFFUL; + int step = 0; + while (--size >= 0) + { + r = (r << CHAR_BIT) ^ m_CrcTable[(byte)(r >> (32 - CHAR_BIT)) ^ c[step]]; + step++; + } + return ~r & 0xFFFFFFFFUL; + } + public static ulong CrcRev(int size, Span c) + { + if (!m_InitRev) + { + MakeTableRev(); + m_InitRev = true; + } + + ulong r = 0xFFFFFFFFUL; + int step = 0; + while (--size >= 0) + { + r = (r >> CHAR_BIT) ^ m_CrcTableRev[(byte)r ^ c[step]]; + step++; + } + return r ^ 0xFFFFFFFFUL; + } + + static void MakeTable() + { + int i, j; + ulong r; + + for (i = 0; i <= byte.MaxValue; i++) + { + r = (ulong)i << (32 - CHAR_BIT); + for (j = 0; j < CHAR_BIT; j++) + { + if ((r & 0x80000000UL) > 0) r = (r << 1) ^ CRCPOLY1; + else r <<= 1; + } + m_CrcTable[i] = r & 0xFFFFFFFFUL; + } + + } + static void MakeTableRev() + { + int i, j; + ulong r; + + for (i = 0; i <= byte.MaxValue; i++) + { + r = (ulong)i; + for (j = 0; j < CHAR_BIT; j++) + { + if ((r & 1) > 0) r = (r >> 1) ^ CRCPOLY2; + else r >>= 1; + } + m_CrcTableRev[i] = r; + } + } + + + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs.meta new file mode 100644 index 0000000..e8aecd4 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/CRC.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1939f721bc0cab42add18338dbff333 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs new file mode 100644 index 0000000..e316501 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace VirtualNes.Core +{ + public enum EnumRomControlByte1 : byte + { + ROM_VMIRROR = 0x01, + ROM_SAVERAM = 0x02, + ROM_TRAINER = 0x04, + ROM_4SCREEN = 0x08, + } + + public enum EnumRomControlByte2 : byte + { + ROM_VSUNISYSTEM = 0x01 + } + + public enum EnumRomType + { + InValid, + NES, + /// Nintendo Disk System + FDS, + NSF + } + + public struct NSFHEADER + { + byte[] ID; + byte Version; + byte TotalSong; + byte StartSong; + ushort LoadAddress; + ushort InitAddress; + ushort PlayAddress; + byte[] SongName; + byte[] ArtistName; + byte[] CopyrightName; + ushort SpeedNTSC; + byte[] BankSwitch; + ushort SpeedPAL; + byte NTSC_PALbits; + byte ExtraChipSelect; + byte[] Expansion; // must be 0 + + + public static int SizeOf() + { + return 128; + } + + public static NSFHEADER GetDefault() + { + var res = new NSFHEADER(); + res.ID = new byte[5]; + res.SongName = new byte[32]; + res.ArtistName = new byte[32]; + res.CopyrightName = new byte[32]; + res.BankSwitch = new byte[8]; + res.Expansion = new byte[4]; + return res; + } + } + + public struct NESHEADER + { + public byte[] ID; + public byte PRG_PAGE_SIZE; + public byte CHR_PAGE_SIZE; + public byte control1; + public byte control2; + public byte[] reserved; + + public bool CheckValid() + { + return GetRomType() != EnumRomType.InValid; + } + + public static int SizeOf() + { + return 16; + } + + public EnumRomType GetRomType() + { + if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 0x1A) + return EnumRomType.NES; + if (ID[0] == 'F' && ID[1] == 'D' && ID[2] == 'S' && ID[3] == 0x1A) + return EnumRomType.FDS; + if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 'M') + return EnumRomType.NSF; + + return EnumRomType.InValid; + } + + public static NESHEADER GetDefault() + { + var res = new NESHEADER(); + res.ID = new byte[4]; + res.reserved = new byte[8]; + return res; + } + + public static NESHEADER Read(Span data) + { + var res = new NESHEADER(); + res.ID = data.Slice(0, 4).ToArray(); + res.PRG_PAGE_SIZE = data[4]; + res.CHR_PAGE_SIZE = data[5]; + res.control1 = data[6]; + res.control2 = data[7]; + res.reserved = data.Slice(8, 8).ToArray(); + + return res; + } + + public byte[] DataToBytes() + { + byte[] res = new byte[16]; + res[0] = ID[0]; + res[1] = ID[1]; + res[2] = ID[2]; + res[3] = ID[3]; + res[4] = PRG_PAGE_SIZE; + res[5] = CHR_PAGE_SIZE; + res[6] = control1; + res[7] = control2; + res[8] = reserved[0]; + res[9] = reserved[1]; + res[10] = reserved[2]; + res[11] = reserved[3]; + res[12] = reserved[4]; + res[13] = reserved[5]; + res[14] = reserved[6]; + res[15] = reserved[7]; + + return res; + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs.meta new file mode 100644 index 0000000..da4c0eb --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/ROMClasses.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 65b1ea91f79171f4f82ab91106909f86 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs new file mode 100644 index 0000000..ed4d453 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs @@ -0,0 +1,426 @@ +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Remoting.Messaging; +using UnityEngine; + +namespace VirtualNes.Core +{ + public static class RomPatch + { + public static void DoPatch(ref ulong crc, ref byte[] lpPRG, ref byte[] lpCHR, ref int mapper, ref NESHEADER header) + { + // Mapper 000 + if (crc == 0x57970078) + { // F-1 Race(J) + lpPRG[0x078C] = 0x6C; + lpPRG[0x3FE1] = 0xFF; + lpPRG[0x3FE6] = 0x00; + } + if (crc == 0xaf2bbcbc // Mach Rider(JU) + || crc == 0x3acd4bf1 // Mach Rider(Alt)(JU) 無理矢理パッチ(^^; + || crc == 0x8bbe9bec) + { + lpPRG[0x090D] = 0x6E; + lpPRG[0x7FDF] = 0xFF; + lpPRG[0x7FE4] = 0x00; + + header.control1 = (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0xe16bb5fe) + { // Zippy Race(J) + header.control1 &= 0xf6; + } + if (crc == 0x85534474) + { // Lode Runner(J) + lpPRG[0x29E9] = 0xEA; // セーブメニューを出すパッチ + lpPRG[0x29EA] = 0xEA; + lpPRG[0x29F8] = 0xEA; + lpPRG[0x29F9] = 0xEA; + } + + // Mapper 001 + if (crc == 0x7831b2ff // America Daitouryou Senkyo(J) + || crc == 0x190a3e11 // Be-Bop-Highschool - Koukousei Gokuraku Densetsu(J) + || crc == 0x52449508 // Home Run Nighter - Pennant League!!(J) + || crc == 0x0973f714 // Jangou(J) + || crc == 0x7172f3d4 // Kabushiki Doujou(J) + || crc == 0xa5781280 // Kujaku Ou 2(J) + || crc == 0x8ce9c87b // Money Game, The(J) + || crc == 0xec47296d // Morita Kazuo no Shougi(J) + || crc == 0xcee5857b // Ninjara Hoi!(J) + || crc == 0xe63d9193 // Tanigawa Kouji no Shougi Shinan 3(J) + || crc == 0xd54f5da9 // Tsuppari Wars(J) + || crc == 0x1e0c7ea3) + { // AD&D Dragons of Flame(J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + if (crc == 0x1995ac4e) + { // Ferrari Grand Prix Challenge(J) 無理矢理パッチ(^^; + lpPRG[0x1F7AD] = 0xFF; + lpPRG[0x1F7BC] = 0x00; + } + + if (crc == 0x20d22251) + { // Top rider(J) 無理矢理パッチ(^^; + lpPRG[0x1F17E] = 0xEA; + lpPRG[0x1F17F] = 0xEA; + } + + if (crc == 0x11469ce3) + { // Viva! Las Vegas(J) 無理矢理パッチ(^^; + lpCHR[0x0000] = 0x01; + } + + if (crc == 0x3fccdc7b) + { // Baseball Star - Mezase Sankanou!!(J) 無理矢理パッチ(^^; + lpPRG[0x0F666] = 0x9D; + } + + if (crc == 0xdb564628) + { // Mario Open Golf(J) + lpPRG[0x30195] = 0xC0; + } + + // Mapper 002 + if (crc == 0x63af202f) + { // JJ - Tobidase Daisakusen Part 2(J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0x99a62e47) + { // Black Bass 2, The(J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0x0eaa7515 // Rod Land(J) + || crc == 0x22ab9694) + { // Rod Land(E) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0x2061772a) + { // Tantei Jinguji Taburou Tokino Sugiyukumamani (J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + // Mapper 003 + if (crc == 0x29401686) + { // Minna no Taabou no Nakayoshi Dai Sakusen(J) + // lpPRG[0x2B3E] = 0x60; + } + if (crc == 0x932a077a) + { // TwinBee(J) + mapper = 87; + } + if (crc == 0x8218c637) + { // Space Hunter(J) + // header.control1 &= 0xf6; + // header.control1 |= ROM_4SCREEN; + header.control1 = (byte)EnumRomControlByte1.ROM_VMIRROR; + } + if (crc == 0x2bb6a0f8 // Sherlock Holmes - Hakushaku Reijou Yuukai Jiken(J) + || crc == 0x28c11d24 // Sukeban Deka 3(J) + || crc == 0x02863604) + { // Sukeban Deka 3(J)(Alt) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + // Mapper 004 + if (crc == 0x58581770) + { // Rasaaru Ishii no Childs Quest(J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + if (crc == 0xf3feb3ab // Kunio Kun no Jidaigeki Dayo Zenin Shuugou! (J) + || crc == 0xa524ae9b // Otaku no Seiza - An Adventure in the Otaku Galaxy (J) + || crc == 0x46dc6e57 // SD Gundam - Gachapon Senshi 2 - Capsule Senki (J) + || crc == 0x66b2dec7 // SD Gundam - Gachapon Senshi 3 - Eiyuu Senki (J) + || crc == 0x92b07fd9 // SD Gundam - Gachapon Senshi 4 - New Type Story (J) + || crc == 0x8ee6463a // SD Gundam - Gachapon Senshi 5 - Battle of Universal Century (J) + || crc == 0xaf754426 // Ultraman Club 3 (J) + || crc == 0xfe4e5b11 // Ushio to Tora - Shinen no Daiyou (J) + || crc == 0x57c12c17) + { // Yamamura Misa Suspense - Kyouto Zaiteku Satsujin Jiken (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + if (crc == 0x42e03e4a) + { // RPG Jinsei Game (J) + mapper = 118; + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + if (crc == 0xfd0299c3) + { // METAL MAX(J) + lpPRG[0x3D522] = 0xA9; + lpPRG[0x3D523] = 0x19; + } + if (crc == 0x1d2e5018 // Rockman 3(J) + || crc == 0x6b999aaf) + { // Mega Man 3(U) + // lpPRG[0x3C179] = 0xBA;// + // lpPRG[0x3C9CC] = 0x9E; + } + + // Mapper 005 + if (crc == 0xe91548d8) + { // Shin 4 Nin Uchi Mahjong - Yakuman Tengoku (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + if (crc == 0x255b129c) + { // Gun Sight (J) / Gun Sight (J)[a1] + lpPRG[0x02D0B] = 0x01; + lpPRG[0x0BEC0] = 0x01; + } + + + // Mapper 010 + if (crc == 0xc9cce8f2) + { // Famicom Wars (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 016 + if (crc == 0x983d8175 // Datach - Battle Rush - Build Up Robot Tournament (J) + || crc == 0x894efdbc // Datach - Crayon Shin Chan - Ora to Poi Poi (J) + || crc == 0x19e81461 // Datach - Dragon Ball Z - Gekitou Tenkaichi Budou Kai (J) + || crc == 0xbe06853f // Datach - J League Super Top Players (J) + || crc == 0x0be0a328 // Datach - SD Gundam - Gundam Wars (J) + || crc == 0x5b457641 // Datach - Ultraman Club - Supokon Fight! (J) + || crc == 0xf51a7f46 // Datach - Yuu Yuu Hakusho - Bakutou Ankoku Bujutsu Kai (J) + || crc == 0x31cd9903 // Dragon Ball Z - Kyoushuu! Saiya Jin (J) + || crc == 0xe49fc53e // Dragon Ball Z 2 - Gekishin Freeza!! (J) + || crc == 0x09499f4d // Dragon Ball Z 3 - Ressen Jinzou Ningen (J) + || crc == 0x2e991109 // Dragon Ball Z Gaiden - Saiya Jin Zetsumetsu Keikaku (J) + || crc == 0x170250de) + { // Rokudenashi Blues(J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 019 + if (crc == 0x3296ff7a // Battle Fleet (J) + || crc == 0x429fd177 // Famista '90 (J) + || crc == 0xdd454208 // Hydlide 3 - Yami Kara no Houmonsha (J) + || crc == 0xb1b9e187 // Kaijuu Monogatari (J) + || crc == 0xaf15338f) + { // Mindseeker (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 026 + if (crc == 0x836cc1ab) + { // Mouryou Senki Madara (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 033 + if (crc == 0x547e6cc1) + { // Flintstones - The Rescue of Dino & Hoppy, The(J) + mapper = 48; + } + + // Mapper 065 + if (crc == 0xfd3fc292) + { // Ai Sensei no Oshiete - Watashi no Hoshi (J) + mapper = 32; + } + + // Mapper 068 + if (crc == 0xfde79681) + { // Maharaja (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 069 + if (crc == 0xfeac6916 // Honoo no Toukyuuji - Dodge Danpei 2(J) + || crc == 0x67898319) + { // Barcode World(J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 080 + if (crc == 0x95aaed34 // Mirai Shinwa Jarvas (J) + || crc == 0x17627d4b) + { // Taito Grand Prix - Eikou heno License (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 082 + if (crc == 0x4819a595) + { // Kyuukyoku Harikiri Stadium - Heisei Gannen Ban (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 086 + if (crc == 0xe63f7d0b) + { // Urusei Yatsura - Lum no Wedding Bell(J) + mapper = 101; + } + + // Mapper 118 + if (crc == 0x3b0fb600) + { // Ys 3 - Wonderers From Ys (J) + header.control1 |= (byte)EnumRomControlByte1.ROM_SAVERAM; + } + + // Mapper 180 + if (crc == 0xc68363f6) + { // Crazy Climber(J) + header.control1 &= 0xf6; + } + + // VS-Unisystem + if (crc == 0x70901b25) + { // VS Slalom + mapper = 99; + } + + if (crc == 0xd5d7eac4) + { // VS Dr. Mario + mapper = 1; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xffbef374 // VS Castlevania + || crc == 0x8c0c2df5) + { // VS Top Gun + mapper = 2; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xeb2dba63 // VS TKO Boxing + || crc == 0x98cfe016 // VS TKO Boxing (Alt) + || crc == 0x9818f656) + { // VS TKO Boxing (f1) + mapper = 4; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0x135adf7c) + { // VS Atari RBI Baseball + mapper = 4; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xf9d3b0a3 // VS Super Xevious + || crc == 0x9924980a // VS Super Xevious (b1) + || crc == 0x66bb838f) + { // VS Super Xevious (b2) + mapper = 4; + header.control1 &= 0xF6; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0x17ae56be) + { // VS Freedom Force + mapper = 4; + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xe2c0a2be) + { // VS Platoon + mapper = 68; + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (crc == 0xcbe85490 // VS Excitebike + || crc == 0x29155e0c // VS Excitebike (Alt) + || crc == 0xff5135a3) + { // VS Hogan's Alley + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + } + + if (crc == 0x0b65a917) + { // VS Mach Rider(Endurance Course) + lpPRG[0x7FDF] = 0xFF; + lpPRG[0x7FE4] = 0x00; + } + + if (crc == 0x8a6a9848 // VS Mach Rider(Endurance Course)(Alt) + || crc == 0xae8063ef) + { // VS Mach Rider(Japan, Fighting Course) + lpPRG[0x7FDD] = 0xFF; + lpPRG[0x7FE2] = 0x00; + } + + if (crc == 0x16d3f469) + { // VS Ninja Jajamaru Kun (J) + header.control1 &= 0xf6; + header.control1 |= (byte)EnumRomControlByte1.ROM_VMIRROR; + } + + if (crc == 0xc99ec059) + { // VS Raid on Bungeling Bay(J) + mapper = 99; + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + } + if (crc == 0xca85e56d) + { // VS Mighty Bomb Jack(J) + mapper = 99; + header.control1 &= 0xF6; + header.control1 |= (byte)EnumRomControlByte1.ROM_4SCREEN; + } + + + if (crc == 0xeb2dba63 // VS TKO Boxing + || crc == 0x9818f656 // VS TKO Boxing + || crc == 0xed588f00 // VS Duck Hunt + || crc == 0x8c0c2df5 // VS Top Gun + || crc == 0x16d3f469 // VS Ninja Jajamaru Kun + || crc == 0x8850924b // VS Tetris + || crc == 0xcf36261e // VS Sky Kid + || crc == 0xe1aa8214 // VS Star Luster + || crc == 0xec461db9 // VS Pinball + || crc == 0xe528f651 // VS Pinball (alt) + || crc == 0x17ae56be // VS Freedom Force + || crc == 0xe2c0a2be // VS Platoon + || crc == 0xff5135a3 // VS Hogan's Alley + || crc == 0x70901b25 // VS Slalom + || crc == 0x0b65a917 // VS Mach Rider(Endurance Course) + || crc == 0x8a6a9848 // VS Mach Rider(Endurance Course)(Alt) + || crc == 0xae8063ef // VS Mach Rider(Japan, Fighting Course) + || crc == 0xcc2c4b5d // VS Golf + || crc == 0xa93a5aee // VS Stroke and Match Golf + || crc == 0x86167220 // VS Lady Golf + || crc == 0xffbef374 // VS Castlevania + || crc == 0x135adf7c // VS Atari RBI Baseball + || crc == 0xd5d7eac4 // VS Dr. Mario + || crc == 0x46914e3e // VS Soccer + || crc == 0x70433f2c // VS Battle City + || crc == 0x8d15a6e6 // VS bad .nes + || crc == 0x1e438d52 // VS Goonies + || crc == 0xcbe85490 // VS Excitebike + || crc == 0x29155e0c // VS Excitebike (alt) + || crc == 0x07138c06 // VS Clu Clu Land + || crc == 0x43a357ef // VS Ice Climber + || crc == 0x737dd1bf // VS Super Mario Bros + || crc == 0x4bf3972d // VS Super Mario Bros + || crc == 0x8b60cc58 // VS Super Mario Bros + || crc == 0x8192c804 // VS Super Mario Bros + || crc == 0xd99a2087 // VS Gradius + || crc == 0xf9d3b0a3 // VS Super Xevious + || crc == 0x9924980a // VS Super Xevious + || crc == 0x66bb838f // VS Super Xevious + || crc == 0xc99ec059 // VS Raid on Bungeling Bay(J) + || crc == 0xca85e56d) + { // VS Mighty Bomb Jack(J) + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + if (mapper == 99 || mapper == 151) + { + header.control2 |= (byte)EnumRomControlByte2.ROM_VSUNISYSTEM; + } + + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs.meta new file mode 100644 index 0000000..1670952 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/CoreLibs/RomPatch.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 953873ef00535544abd9591708c8e7a5 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs index b5e2d22..66a5e55 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/NES.cs @@ -94,7 +94,6 @@ namespace VirtualNes.Core pad = new PAD(this); Debuger.Log("Loading ROM Image..."); - rom = new ROM(fname); } catch (Exception ex) diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs index be753df..a0d3a5f 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/ROM.cs @@ -1,4 +1,5 @@ -サソusing System; +サソusing Codice.CM.Client.Differences; +using System; using System.IO; using System.Linq; using VirtualNes.Core.Debug; @@ -8,6 +9,7 @@ namespace VirtualNes.Core public class ROM { protected NESHEADER header; + protected NSFHEADER nsfheader; protected string path; protected string name; protected string fullpath; @@ -21,8 +23,12 @@ namespace VirtualNes.Core protected byte[] lpDisk; protected ulong crc; protected ulong crcall; + protected ulong crcvrom; protected int mapper; protected int diskno; + protected ulong fdsmakerID; + protected ulong fdsgameID; + public ROM(string fname) { Stream fp = null; @@ -46,7 +52,7 @@ namespace VirtualNes.Core try { - fp = Supporter.OpenFile(fname); + fp = Supporter.OpenRom(fname); if (fp == null) { throw new System.Exception($"Open Rom Failed:[{fname}]"); @@ -69,7 +75,7 @@ namespace VirtualNes.Core throw new Exception($"rom file is not valid:[{fname}]"); ulong PRGoffset, CHRoffset; - long PRGsize, CHRsize; + long PRGsize = 0, CHRsize = 0; var romType = header.GetRomType(); if (romType == EnumRomType.NES) @@ -87,7 +93,6 @@ namespace VirtualNes.Core if (PRGsize <= 0 || (PRGsize + CHRsize) > FileSize) { - // NES蜒ソ蜒「蜒溷¢蝣主ソ「蛛ア蛛。 throw new Exception($"Invalid NesHeader:[{fname}]"); } @@ -164,7 +169,7 @@ namespace VirtualNes.Core lpPRG[3] = 0x1A; lpPRG[4] = (byte)diskno; - fp = Supporter.OpenFile("DISKSYS.ROM"); + fp = Supporter.OpenFile_DISKSYS(); if (fp == null) { throw new Exception($"Not found DISKSYS.ROM for [{fname}]"); @@ -183,13 +188,97 @@ namespace VirtualNes.Core lpDiskBios = new byte[8 * 1024]; if (bios[0] == 'N' && bios[1] == 'E' && bios[2] == 'S' && bios[3] == 0x1A) { + Array.Copy(bios, 0x6010, lpDiskBios, 0, lpDiskBios.Length); + } + else + { + Array.Copy(bios, lpDiskBios, lpDiskBios.Length); + } + bios = null; + } + else if (romType == EnumRomType.NSF) + { + bNSF = true; + header = NESHEADER.GetDefault(); + nsfheader = NSFHEADER.GetDefault(); + + PRGsize = FileSize - NSFHEADER.SizeOf(); + Debuger.Log($"PRGSIZE:{PRGsize}"); + PRGsize = (PRGsize + 0x0FFF) & ~0x0FFF; + Debuger.Log($"PRGSIZE:{PRGsize}"); + + lpPRG = new byte[PRGsize]; + Array.Copy(temp, NSFHEADER.SizeOf(), lpPRG, 0, FileSize - NSFHEADER.SizeOf()); + + NSF_PAGE_SIZE = (int)(PRGsize >> 12); + Debuger.Log($"PAGESIZE:{NSF_PAGE_SIZE}"); + } + else + { + throw new Exception($"Unsupport format:[{fname}]"); + } + + Supporter.GetFilePathInfo(fname, out fullpath, out path); + + if (!bNSF) + { + mapper = (header.control1 >> 4) | (header.control2 & 0xF0); + crc = crcall = crcvrom = 0; + + if (mapper != 20) + { + Span sTemp = temp; + if (IsTRAINER()) + { + crcall = CRC.CrcRev((int)(512 + PRGsize + CHRsize), sTemp.Slice(NESHEADER.SizeOf())); + crc = CRC.CrcRev((int)(512 + PRGsize), sTemp); + if (CHRsize > 0) + crcvrom = CRC.CrcRev((int)CHRsize, sTemp.Slice((int)(PRGsize + 512 + NESHEADER.SizeOf()))); + } + else + { + crcall = CRC.CrcRev((int)(PRGsize + CHRsize), sTemp.Slice(NESHEADER.SizeOf())); + crc = CRC.CrcRev((int)(PRGsize), sTemp.Slice(NESHEADER.SizeOf())); + if (CHRsize > 0) + crcvrom = CRC.CrcRev((int)CHRsize, sTemp.Slice((int)(PRGsize + NESHEADER.SizeOf()))); + } + + FileNameCheck(fname); + + RomPatch.DoPatch(ref crc, ref lpPRG, ref lpCHR, ref mapper, ref header); + + fdsmakerID = fdsgameID = 0; + } + else //mapper==20 + { + crc = crcall = crcvrom = 0; + + fdsmakerID = lpPRG[0x1F]; + fdsgameID = (ulong)((lpPRG[0x20] << 24) | (lpPRG[0x21] << 16) | (lpPRG[0x22] << 8) | (lpPRG[0x23] << 0)); } } - } - catch - { + else //NSF + { + mapper = 0x0100; // Private mapper + crc = crcall = crcvrom = 0; + fdsmakerID = fdsgameID = 0; + } + temp = null; + } + catch (Exception ex) + { + fp?.Dispose(); + temp = null; + bios = null; + lpPRG = null; + lpCHR = null; + lpTrainer = null; + lpDiskBios = null; + lpDisk = null; + + throw ex; } } @@ -197,98 +286,16 @@ namespace VirtualNes.Core { return (header.control1 & (byte)EnumRomControlByte1.ROM_TRAINER) > 0; } - } - public enum EnumRomControlByte1 : byte - { - ROM_VMIRROR = 0x01, - ROM_SAVERAM = 0x02, - ROM_TRAINER = 0x04, - ROM_4SCREEN = 0x08, - } - - public enum EnumRomType - { - InValid, - NES, - /// Nintendo Disk System - FDS, - NSF - } - - public struct NESHEADER - { - public byte[] ID; - public byte PRG_PAGE_SIZE; - public byte CHR_PAGE_SIZE; - public byte control1; - public byte control2; - public byte[] reserved; - - public bool CheckValid() + protected void FileNameCheck(string fname) { - return GetRomType() != EnumRomType.InValid; - } - - public static int SizeOf() - { - return 16; - } - - public EnumRomType GetRomType() - { - if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 0x1A) - return EnumRomType.NES; - if (ID[0] == 'F' && ID[1] == 'D' && ID[2] == 'S' && ID[3] == 0x1A) - return EnumRomType.FDS; - if (ID[0] == 'N' && ID[1] == 'E' && ID[2] == 'S' && ID[3] == 'M') - return EnumRomType.NSF; - - return EnumRomType.InValid; - } - - public static NESHEADER GetDefault() - { - var res = new NESHEADER(); - res.ID = new byte[4]; - res.reserved = new byte[8]; - return res; - } - - public static NESHEADER Read(Span data) - { - var res = new NESHEADER(); - res.ID = data.Slice(0, 4).ToArray(); - res.PRG_PAGE_SIZE = data[4]; - res.CHR_PAGE_SIZE = data[5]; - res.control1 = data[6]; - res.control2 = data[7]; - res.reserved = data.Slice(8, 8).ToArray(); - - return res; - } - - public byte[] DataToBytes() - { - byte[] res = new byte[16]; - res[0] = ID[0]; - res[1] = ID[1]; - res[2] = ID[2]; - res[3] = ID[3]; - res[4] = PRG_PAGE_SIZE; - res[5] = CHR_PAGE_SIZE; - res[6] = control1; - res[7] = control2; - res[8] = reserved[0]; - res[9] = reserved[1]; - res[10] = reserved[2]; - res[11] = reserved[3]; - res[12] = reserved[4]; - res[13] = reserved[5]; - res[14] = reserved[6]; - res[15] = reserved[7]; - - return res; + if (fname.Contains("(E)")) + { + bPAL = true; + return; + } } } + + } diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs index a4ae83d..884d34e 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs @@ -13,14 +13,27 @@ namespace VirtualNes.Core s_support = supporter; } - public static Stream OpenFile(string fname) + public static Stream OpenRom(string fname) { - return s_support.OpenFile(fname); + return s_support.OpenRom(fname); } + + public static void GetFilePathInfo(string fname, out string fullPath, out string directPath) + { + s_support.GetRomPathInfo(fname, out fullPath, out directPath); + } + + public static Stream OpenFile_DISKSYS() + { + return s_support.OpenFile_DISKSYS(); + } + } public interface ISupporterImpl { - Stream OpenFile(string fname); + Stream OpenRom(string fname); + void GetRomPathInfo(string fname, out string fullPath, out string directPath); + Stream OpenFile_DISKSYS(); } }