diff --git a/AxibugEmuOnline.Client/Assets/Resources/NES/ControlSettings.asset b/AxibugEmuOnline.Client/Assets/Resources/NES/ControlSettings.asset new file mode 100644 index 0000000..d2b65d7 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Resources/NES/ControlSettings.asset @@ -0,0 +1,126 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 66fc8233a79cd254f8d005452dcd4ac0, type: 3} + m_Name: ControlSettings + m_EditorClassIdentifier: + Player1: + UP: + buttonType: 1 + keyCode: 119 + DOWN: + buttonType: 2 + keyCode: 115 + LEFT: + buttonType: 4 + keyCode: 97 + RIGHT: + buttonType: 8 + keyCode: 100 + A: + buttonType: 16 + keyCode: 107 + B: + buttonType: 32 + keyCode: 106 + SELECT: + buttonType: 64 + keyCode: 118 + START: + buttonType: 128 + keyCode: 98 + MIC: + buttonType: 256 + keyCode: 0 + Player2: + UP: + buttonType: 1 + keyCode: 0 + DOWN: + buttonType: 2 + keyCode: 0 + LEFT: + buttonType: 4 + keyCode: 0 + RIGHT: + buttonType: 8 + keyCode: 0 + A: + buttonType: 16 + keyCode: 0 + B: + buttonType: 32 + keyCode: 0 + SELECT: + buttonType: 64 + keyCode: 0 + START: + buttonType: 128 + keyCode: 0 + MIC: + buttonType: 256 + keyCode: 0 + Player3: + UP: + buttonType: 1 + keyCode: 0 + DOWN: + buttonType: 2 + keyCode: 0 + LEFT: + buttonType: 4 + keyCode: 0 + RIGHT: + buttonType: 8 + keyCode: 0 + A: + buttonType: 16 + keyCode: 0 + B: + buttonType: 32 + keyCode: 0 + SELECT: + buttonType: 64 + keyCode: 0 + START: + buttonType: 128 + keyCode: 0 + MIC: + buttonType: 256 + keyCode: 0 + Player4: + UP: + buttonType: 1 + keyCode: 0 + DOWN: + buttonType: 2 + keyCode: 0 + LEFT: + buttonType: 4 + keyCode: 0 + RIGHT: + buttonType: 8 + keyCode: 0 + A: + buttonType: 16 + keyCode: 0 + B: + buttonType: 32 + keyCode: 0 + SELECT: + buttonType: 64 + keyCode: 0 + START: + buttonType: 128 + keyCode: 0 + MIC: + buttonType: 256 + keyCode: 0 diff --git a/AxibugEmuOnline.Client/Assets/Resources/NES/ControlSettings.asset.meta b/AxibugEmuOnline.Client/Assets/Resources/NES/ControlSettings.asset.meta new file mode 100644 index 0000000..60582ad --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Resources/NES/ControlSettings.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fa3a6bfd9566da84eb494ff280abe34c +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/AudioProvider.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/AudioProvider.cs index f014cf5..f4335b7 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/AudioProvider.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/AudioProvider.cs @@ -3,7 +3,6 @@ using VirtualNes.Core; namespace AxibugEmuOnline.Client { - public class AudioProvider : MonoBehaviour { public NesEmulator NesEmu; @@ -40,7 +39,6 @@ namespace AxibugEmuOnline.Client data[i] = rawFloat; for (int fill = 1; fill < step; fill++) data[i + fill] = rawFloat; - } } diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs index ae72035..68e7e8c 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/CoreSupporter.cs @@ -98,5 +98,11 @@ namespace AxibugEmuOnline.Client var db = Resources.Load("NES/ROMDB"); return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo); } + + public ControllerState GetControllerState() + { + var mapper = Resources.Load("NES/ControlSettings"); + return mapper.CreateState(); + } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs new file mode 100644 index 0000000..82ebec0 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs @@ -0,0 +1,84 @@ +using System; +using UnityEngine; +using VirtualNes.Core; + +namespace AxibugEmuOnline.Client +{ + public class NesControllerMapper : ScriptableObject + { + public MapperSetter Player1 = new MapperSetter(); + public MapperSetter Player2 = new MapperSetter(); + public MapperSetter Player3 = new MapperSetter(); + public MapperSetter Player4 = new MapperSetter(); + + public ControllerState CreateState() + { + var state1 = Player1.GetButtons(); + var state2 = Player2.GetButtons(); + var state3 = Player3.GetButtons(); + var state4 = Player4.GetButtons(); + + return new ControllerState(state1, state2, state3, state4); + } + + [Serializable] + public class Mapper + { + public EnumButtonType buttonType; + public KeyCode keyCode; + + public Mapper(EnumButtonType buttonType) + { + this.buttonType = buttonType; + } + } + + [Serializable] + public class MapperSetter + { + public Mapper UP = new Mapper(EnumButtonType.UP); + public Mapper DOWN = new Mapper(EnumButtonType.DOWN); + public Mapper LEFT = new Mapper(EnumButtonType.LEFT); + public Mapper RIGHT = new Mapper(EnumButtonType.RIGHT); + public Mapper A = new Mapper(EnumButtonType.A); + public Mapper B = new Mapper(EnumButtonType.B); + public Mapper SELECT = new Mapper(EnumButtonType.SELECT); + public Mapper START = new Mapper(EnumButtonType.START); + public Mapper MIC = new Mapper(EnumButtonType.MIC); + + public EnumButtonType GetButtons() + { + EnumButtonType res = 0; + + if (Input.GetKey(UP.keyCode)) + res |= EnumButtonType.UP; + + if (Input.GetKey(DOWN.keyCode)) + res |= EnumButtonType.DOWN; + + if (Input.GetKey(LEFT.keyCode)) + res |= EnumButtonType.LEFT; + + if (Input.GetKey(RIGHT.keyCode)) + res |= EnumButtonType.RIGHT; + + if (Input.GetKey(A.keyCode)) + res |= EnumButtonType.A; + + if (Input.GetKey(B.keyCode)) + res |= EnumButtonType.B; + + if (Input.GetKey(SELECT.keyCode)) + res |= EnumButtonType.SELECT; + + if (Input.GetKey(START.keyCode)) + res |= EnumButtonType.START; + + if (Input.GetKey(MIC.keyCode)) + res |= EnumButtonType.MIC; + + return res; + } + } + } +} diff --git a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs.meta b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs.meta new file mode 100644 index 0000000..2350d8d --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesControllerMapper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 66fc8233a79cd254f8d005452dcd4ac0 +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 index e2e390c..1468598 100644 --- a/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs +++ b/AxibugEmuOnline.Client/Assets/Script/NesEmulator/NesEmulator.cs @@ -57,6 +57,8 @@ namespace AxibugEmuOnline.Client { if (NesCore != null) { + var controlState = Supporter.GetControllerState(); + NesCore.pad.Sync(controlState); NesCore.EmulateFrame(true); var screenBuffer = NesCore.ppu.GetScreenPtr(); diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PAD.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PAD.cs index 01f5df1..f9b6ccf 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PAD.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/PAD.cs @@ -1,5 +1,6 @@ using Codice.CM.Client.Differences; using System; +using System.Collections.Generic; namespace VirtualNes.Core { @@ -25,6 +26,19 @@ namespace VirtualNes.Core public uint pad1bit, pad2bit, pad3bit, pad4bit; + private static int[] ren10fps = new int[6] { 1, 1, 1, 0, 0, 0 }; + private static int[] ren15fps = new int[4] { 1, 1, 0, 0 }; + private static int[] ren20fps = new int[3] { 1, 1, 0 }; + private static int[] ren30fps = new int[2] { 1, 0 }; + private static int[] renmask = new int[4] { 6, 4, 3, 2 }; + public static Dictionary rentbl = new Dictionary() + { + {0,ren10fps }, + {1,ren15fps }, + {2,ren20fps }, + {3,ren30fps }, + }; + public PAD(NES parent) { nes = parent; @@ -405,6 +419,106 @@ namespace VirtualNes.Core } } + public void Sync(ControllerState state) + { + padbit[0] = SyncSub(0, state); + padbit[1] = SyncSub(1, state); + padbit[2] = SyncSub(2, state); + padbit[3] = SyncSub(3, state); + + // Mic + micbit = 0; + if (state.HasButton(1, EnumButtonType.MIC)) micbit |= 4; + + // For Excontroller + if (expad != null) + { + expad.Sync(); + } + } + + + + private byte SyncSub(int no, ControllerState state) + { + ushort bit = 0; + + // Up + if (state.HasButton(no, EnumButtonType.UP)) + bit |= 1 << 4; + // Down + if (state.HasButton(no, EnumButtonType.DOWN)) + bit |= 1 << 5; + // Left + if (state.HasButton(no, EnumButtonType.LEFT)) + bit |= 1 << 6; + // Right + if (state.HasButton(no, EnumButtonType.RIGHT)) + bit |= 1 << 7; + + // 同時入力を禁止する + // if( (bit&((1<<4)|(1<<5))) == ((1<<4)|(1<<5)) ) + // bit &= ~((1<<4)|(1<<5)); + if ((bit & ((1 << 6) | (1 << 7))) == ((1 << 6) | (1 << 7))) + bit = (byte)(bit & ~((1 << 6) | (1 << 7))); + + // A + if (state.HasButton(no, EnumButtonType.A)) bit |= 1 << 0; + // B + if (state.HasButton(no, EnumButtonType.B)) bit |= 1 << 1; + + // Select + if (state.HasButton(no, EnumButtonType.SELECT)) bit |= 1 << 2; + // Start + if (state.HasButton(no, EnumButtonType.START)) bit |= 1 << 3; + + // A rapid setup + if ((bit & (1 << 8)) != 0) + { + int spd = Supporter.Config.controller.nRapid[no][0]; + if (spd >= 3) spd = 3; + + int[] tbl = rentbl[spd]; + + if (padcnt[no][0] >= renmask[spd]) + padcnt[no][0] = 0; + + if ((tbl[padcnt[no][0]]) != 0) + bit |= (1 << 0); + else + bit = (byte)(bit & ~(1 << 0)); + + padcnt[no][0]++; + } + else + { + padcnt[no][0] = 0; + } + // B rapid setup + if ((bit & (1 << 9)) != 0) + { + int spd = Supporter.Config.controller.nRapid[no][1]; + if (spd >= 3) spd = 3; + int[] tbl = rentbl[spd]; + + if (padcnt[no][1] >= renmask[spd]) + padcnt[no][1] = 0; + + if ((tbl[padcnt[no][1]]) != 0) + bit |= (1 << 1); + else + bit = (byte)(bit & ~(1 << 1)); + + padcnt[no][1]++; + } + else + { + padcnt[no][1] = 0; + } + + return (byte)(bit & 0xFF); + } + internal bool IsZapperMode() { return bZapperMode; diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs new file mode 100644 index 0000000..418e35c --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs @@ -0,0 +1,51 @@ +using System; + +namespace VirtualNes.Core +{ + public struct ControllerState + { + private uint raw0; + private uint raw1; + private uint raw2; + private uint raw3; + + public ControllerState( + EnumButtonType player0_buttons, + EnumButtonType player1_buttons, + EnumButtonType player2_buttons, + EnumButtonType player3_buttons) + { + raw0 = (uint)player0_buttons; + raw1 = (uint)player1_buttons; + raw2 = (uint)player2_buttons; + raw3 = (uint)player3_buttons; + } + + public bool HasButton(int player, EnumButtonType button) + { + uint raw = 0; + switch (player) + { + case 0: raw = raw0; break; + case 1: raw = raw1; break; + case 2: raw = raw2; break; + case 3: raw = raw3; break; + } + return (raw & (uint)button) == (uint)button; + } + } + + [Flags] + public enum EnumButtonType + { + UP = 1, + DOWN = 2, + LEFT = 4, + RIGHT = 8, + A = 16, + B = 32, + SELECT = 64, + START = 128, + MIC = 256 + } +} diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs.meta b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs.meta new file mode 100644 index 0000000..aa3411a --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/ControllerState.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 88eb13b75812fc040ad7eb146af2bb80 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/CfgController.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/CfgController.cs index 9650980..ee4bf00 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/CfgController.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/CfgController.cs @@ -1,6 +1,27 @@ -namespace VirtualNes.Core +using Codice.CM.Client.Differences; + +namespace VirtualNes.Core { public class CfgController { + public ushort[][] nButton = new ushort[4][] + { + new ushort[64],new ushort[64], new ushort[64], new ushort[64], + }; + public ushort[][] nRapid = new ushort[4][] + { + new ushort[2],new ushort[2],new ushort[2],new ushort[2], + }; + + // 0:Crazy Climber + // 1:Famly Trainer + // 2:Exciting Boxing + // 3:Mahjang + public ushort[][] nExButton = new ushort[4][] + { + new ushort[64],new ushort[64], new ushort[64], new ushort[64], + }; + + public ushort[] nVSUnisystem = new ushort[64]; } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/EmulatorConfig.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/EmulatorConfig.cs index b24afe0..d552bef 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/EmulatorConfig.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/EmulatorConfig/EmulatorConfig.cs @@ -1,4 +1,6 @@ -namespace VirtualNes.Core +using System; + +namespace VirtualNes.Core { public class EmulatorConfig { diff --git a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs index 98f7b97..eb5a91f 100644 --- a/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs +++ b/AxibugEmuOnline.Client/Assets/VirtualNes.Core/Supporter/Supporter.cs @@ -54,6 +54,11 @@ namespace VirtualNes.Core return s_support.TryGetMapperNo(rom, out mapperNo); } + public static ControllerState GetControllerState() + { + return s_support.GetControllerState(); + } + public static EmulatorConfig Config => s_support.Config; } @@ -70,5 +75,6 @@ namespace VirtualNes.Core void SaveFile(byte[] fileData, string directPath, string fileName); Stream OpenFile(string directPath, string fileName); bool TryGetMapperNo(ROM rom, out int mapperNo); + ControllerState GetControllerState(); } } diff --git a/References/virtuanessrc097-master/NES/PAD.cpp b/References/virtuanessrc097-master/NES/PAD.cpp index 4712b1c..b778ba2 100644 Binary files a/References/virtuanessrc097-master/NES/PAD.cpp and b/References/virtuanessrc097-master/NES/PAD.cpp differ