导入Axibug/UMAME.Core项目,待接入
This commit is contained in:
parent
20e277f6a2
commit
5a9e472c1b
8
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core.meta
Normal file
8
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 799083da753bb1c4a906a6fbe48281d9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/MAME.Core.dll
Normal file
BIN
AxibugEmuOnline.Client/Assets/Plugins/Mame.Core/MAME.Core.dll
Normal file
Binary file not shown.
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 271a8a6401146c04ab5fb754032a2dd5
|
8
AxibugEmuOnline.Client/Assets/Resources/MAME.meta
Normal file
8
AxibugEmuOnline.Client/Assets/Resources/MAME.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61f0db825f947a34b8a0fbd5817485ae
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8
AxibugEmuOnline.Client/Assets/Resources/MAME/emu.meta
Normal file
8
AxibugEmuOnline.Client/Assets/Resources/MAME/emu.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7288a5cba2eb779418cc490967d981b2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/000-lo.lo.bytes
Normal file
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/000-lo.lo.bytes
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 65816e3cba19de446b225f8eead5ec1f
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/1.png.bytes
Normal file
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/1.png.bytes
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8653d87eab52e6941a87038ef06a2dea
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59fd575d698130a43a79dc166d4051d3
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
8046
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/mame.xml.bytes
Normal file
8046
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/mame.xml.bytes
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 61b2fc8f46ed4f64da4d5f87cd7362c2
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb2d5e2ca3a42074897b32eb592df77c
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 422f76db48bff6940ae7ab6677628565
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d3a1ac26f228c844fbdabcdb4c2a5710
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d319336d09b4a184fbdd51107048ab45
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
Detail: https://www.codeproject.com/Articles/1275365/MAME-NET
|
||||
You should install Microsoft .NET Framework 3.5 or higher before running the program. You should download MAME.NET ROM files in roms directory.
|
||||
Hotkey: F3 -- soft reset, F7 -- load state, Shift+F7 -- save state, F8 -- replay input, Shift+F8 -- record input (start and stop), 0-9 and A-Z after state related hotkey -- handle certain files, F10 -- toggle global throttle, P -- pause and continue, shift+P -- skip a frame.
|
||||
Control key: 1 -- P1 start, 2 -- P2 start, 5 -- P1 coin, 6 -- P2 coin, R -- Service 1, T -- Service, W -- P1 up, S -- P1 down, A -- P1 left, D -- P1 right, J -- P1 button1, K -- P1 button 2, L -- P1 button 3, U -- P1 button 4, I -- P1 button 5, O -- P1 button 6, Up -- P2 up, Down -- P2 down, Left -- P2 left, Right -- P2 right, NumPad1 -- P2 button 1, NumPad2 -- P2 button 2, NumPad3 -- P2 button 3, NumPad4 -- P2 button 4, NumPad5 -- P2 button 5, NumPad6 -- P2 button 6.
|
||||
Mouse supported games: Operation Wolf.
|
||||
When the ROMs of a game are loaded, the emulator is auto paused. Press P to continue.
|
||||
Occasionally GDI+ error occurs and a red cross is shown. You can click "File-Reset picturebox" to handle the error.
|
||||
MAME.NET ROM files: https://pan.baidu.com/s/14bR2wEzU2Qqx5hM7hJXMZA https://drive.google.com/folderview?id=11brIxHTJ_M4yOkm08wR3LOibZyEitcAw
|
||||
program reference: https://pan.baidu.com/s/1u9B9tBH0SNcJA3vIu75awA https://drive.google.com/folderview?id=1-BEXXjVYUK5s2zDAp4AfQzCbpcGrcItF
|
||||
Email: shunninghuang@gmail.com
|
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a511236317e4874594088e125a1a39c
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/sfix.sfix.bytes
Normal file
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/sfix.sfix.bytes
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 60a7b0e5c8b772d409dcbec7b6695f74
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/sm1.sm1.bytes
Normal file
BIN
AxibugEmuOnline.Client/Assets/Resources/MAME/emu/sm1.sm1.bytes
Normal file
Binary file not shown.
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6d2848c0a1e76cf49b3e091adc79da62
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
5412
AxibugEmuOnline.Client/Assets/Resources/UMAME.prefab
Normal file
5412
AxibugEmuOnline.Client/Assets/Resources/UMAME.prefab
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1cb6308e67105bf48aea153ebcdb2d76
|
||||
PrefabImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b56c11278238d6c4e902a42ae6948279
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6019649657419e146ab2b4796835be14
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99dcde864a2f2cd41a7fa7e6289820c9
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,33 @@
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
public class UniMAMESetting
|
||||
{
|
||||
public static UniMAMESetting instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (mInstance == null)
|
||||
mInstance = new UniMAMESetting();
|
||||
return mInstance;
|
||||
}
|
||||
}
|
||||
private static UniMAMESetting mInstance;
|
||||
|
||||
const string KEY_LASTGAMEROM = "MAME_LASTGAMEROM";
|
||||
|
||||
public string LastGameRom
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PlayerPrefs.HasKey(KEY_LASTGAMEROM))
|
||||
return PlayerPrefs.GetString(KEY_LASTGAMEROM);
|
||||
return string.Empty;
|
||||
}
|
||||
set
|
||||
{
|
||||
PlayerPrefs.SetString(KEY_LASTGAMEROM, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e93a2fd757533948a43218e424841a7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,71 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class FloatingJoystick : Joystick
|
||||
{
|
||||
public Image mImgBg;
|
||||
public Image mImgHandle;
|
||||
public Image mImgArrow;
|
||||
|
||||
public bool mIsMounseDown = false;
|
||||
|
||||
public static Color ShowColor = new Color(1F, 1f, 1F, 0.7f);
|
||||
public static Color HideColor = new Color(1F, 1f, 1F, 0.3f);
|
||||
|
||||
//一次新的摇杆移动
|
||||
public static bool bNewTouchWithSkill = false;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected override void Start()
|
||||
{
|
||||
base.Start();
|
||||
mImgBg = background.transform.GetComponent<Image>();
|
||||
mImgHandle = background.transform.Find("Handle").GetComponent<Image>();
|
||||
mArrow = transform.Find("Background/Arrow").GetComponent<RectTransform>();
|
||||
mImgArrow = transform.Find("Background/Arrow/imgArrow").GetComponent<Image>();
|
||||
mArrow.gameObject.SetActive(false);
|
||||
//background.gameObject.SetActive(false);
|
||||
background.gameObject.SetActive(true);
|
||||
background.transform.localPosition = new Vector3(256f, 256f, 0);
|
||||
mImgBg.color = HideColor;
|
||||
mImgHandle.color = HideColor;
|
||||
mImgArrow.color = HideColor;
|
||||
mIsMounseDown = false;
|
||||
}
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
//background.anchoredPosition = ScreenPointToAnchoredPosition(eventData.position);
|
||||
//background.gameObject.SetActive(true);
|
||||
mImgBg.color = ShowColor;
|
||||
mImgHandle.color = ShowColor;
|
||||
mImgArrow.color = ShowColor;
|
||||
mIsMounseDown = true;
|
||||
base.OnPointerDown(eventData);
|
||||
bNewTouchWithSkill = true;
|
||||
}
|
||||
|
||||
public override void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
//background.gameObject.SetActive(false);
|
||||
PointerUp();
|
||||
bNewTouchWithSkill = false;
|
||||
}
|
||||
|
||||
public override void PointerUp()
|
||||
{
|
||||
if (background == null)
|
||||
return;
|
||||
|
||||
background.transform.localPosition = new Vector3(256f, 256f, 0);
|
||||
mImgBg.color = HideColor;
|
||||
mImgHandle.color = HideColor;
|
||||
mIsMounseDown = false;
|
||||
base.PointerUp();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7a47f546fc70ec8428172694e78e4288
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,167 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
public class Joystick : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
|
||||
{
|
||||
|
||||
public Vector2Int RawInputV2
|
||||
{
|
||||
get
|
||||
{
|
||||
return InputForEmu;
|
||||
}
|
||||
}
|
||||
|
||||
public float HandleRange
|
||||
{
|
||||
get { return handleRange; }
|
||||
set { handleRange = Mathf.Abs(value); }
|
||||
}
|
||||
|
||||
public float DeadZone
|
||||
{
|
||||
get { return deadZone; }
|
||||
set { deadZone = Mathf.Abs(value); }
|
||||
}
|
||||
|
||||
public AxisOptions AxisOptions { get { return AxisOptions; } set { axisOptions = value; } }
|
||||
|
||||
[SerializeField] private float handleRange = 1;
|
||||
[SerializeField] private float deadZone = 0f;
|
||||
[SerializeField] private AxisOptions axisOptions = AxisOptions.Both;
|
||||
[SerializeField] private bool snapX = false;
|
||||
[SerializeField] private bool snapY = false;
|
||||
|
||||
[SerializeField] protected RectTransform background = null;
|
||||
[SerializeField] private RectTransform handle = null;
|
||||
[SerializeField] protected RectTransform mArrow;
|
||||
private RectTransform baseRect = null;
|
||||
|
||||
private Canvas canvas;
|
||||
private Camera cam;
|
||||
|
||||
private Vector2 input = Vector2.zero;
|
||||
public Vector2Int InputForEmu = Vector2Int.zero;
|
||||
|
||||
public static Joystick joystickInstance;
|
||||
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
|
||||
HandleRange = handleRange;
|
||||
DeadZone = deadZone;
|
||||
baseRect = GetComponent<RectTransform>();
|
||||
canvas = GetComponentInParent<Canvas>();
|
||||
if (canvas == null)
|
||||
Debug.LogError("The Joystick is not placed inside a canvas");
|
||||
else
|
||||
{
|
||||
if (cam == null)
|
||||
{
|
||||
if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
|
||||
cam = canvas.worldCamera;
|
||||
}
|
||||
}
|
||||
|
||||
Vector2 center = new Vector2(0.5f, 0.5f);
|
||||
background.pivot = center;
|
||||
handle.anchorMin = center;
|
||||
handle.anchorMax = center;
|
||||
handle.pivot = center;
|
||||
handle.anchoredPosition = Vector2.zero;
|
||||
|
||||
joystickInstance = this;
|
||||
}
|
||||
|
||||
public virtual void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
OnDrag(eventData);
|
||||
}
|
||||
|
||||
Vector2 mArrowTop = new Vector2(0,1);
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
if (cam == null)
|
||||
{
|
||||
if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
|
||||
cam = canvas.worldCamera;
|
||||
}
|
||||
|
||||
Vector2 position = RectTransformUtility.WorldToScreenPoint(cam, background.position);
|
||||
Vector2 radius = background.sizeDelta / 2;
|
||||
input = (eventData.position - position) / (radius * canvas.scaleFactor);
|
||||
//FormatInput();
|
||||
HandleInput(input.magnitude, input.normalized, radius, cam);
|
||||
handle.anchoredPosition = input * radius * handleRange;
|
||||
}
|
||||
|
||||
protected virtual void HandleInput(float magnitude, Vector2 normalised, Vector2 radius, Camera cam)
|
||||
{
|
||||
if (magnitude > deadZone)
|
||||
{
|
||||
if (magnitude > 1)
|
||||
{
|
||||
input = normalised;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
input = Vector2.zero;
|
||||
}
|
||||
|
||||
|
||||
if (magnitude > deadZone && input != Vector2.zero)
|
||||
{
|
||||
if (!mArrow.gameObject.activeSelf) mArrow.gameObject.SetActive(true);
|
||||
float angle = Vector2.Angle(mArrowTop, input.normalized);
|
||||
|
||||
if (input.x > 0)
|
||||
angle *= -1;
|
||||
mArrow.rotation = Quaternion.Euler(0, 0, angle);
|
||||
}
|
||||
else
|
||||
if (mArrow.gameObject.activeSelf) mArrow.gameObject.SetActive(false);
|
||||
|
||||
|
||||
if (input.x < -1 * deadZone)
|
||||
InputForEmu.x = -1;
|
||||
else if (input.x > deadZone)
|
||||
InputForEmu.x = 1;
|
||||
else
|
||||
InputForEmu.x = 0;
|
||||
|
||||
if (input.y < -1 * deadZone)
|
||||
InputForEmu.y = -1;
|
||||
else if (input.y > deadZone)
|
||||
InputForEmu.y = 1;
|
||||
else
|
||||
InputForEmu.y = 0;
|
||||
}
|
||||
|
||||
public virtual void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
PointerUp();
|
||||
}
|
||||
|
||||
public virtual void PointerUp()
|
||||
{
|
||||
input = Vector2.zero;
|
||||
InputForEmu = Vector2Int.zero;
|
||||
handle.anchoredPosition = Vector2.zero;
|
||||
mArrow.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
protected Vector2 ScreenPointToAnchoredPosition(Vector2 screenPosition)
|
||||
{
|
||||
Vector2 localPoint = Vector2.zero;
|
||||
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(baseRect, screenPosition, cam, out localPoint))
|
||||
{
|
||||
Vector2 pivotOffset = baseRect.pivot * baseRect.sizeDelta;
|
||||
return localPoint - (background.anchorMax * baseRect.sizeDelta) + pivotOffset;
|
||||
}
|
||||
return Vector2.zero;
|
||||
}
|
||||
}
|
||||
|
||||
public enum AxisOptions { Both, Horizontal, Vertical }
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b9fca4100a7477741b3973b4ff2c405f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,25 @@
|
||||
using MAME.Core;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class UILongClickButton : Button
|
||||
{
|
||||
public bool bHotKey { get; private set; } = false;
|
||||
public long[] Key;
|
||||
protected override void OnEnable()
|
||||
{
|
||||
base.OnEnable();
|
||||
bHotKey = false;
|
||||
}
|
||||
|
||||
public override void OnPointerDown(PointerEventData eventData)
|
||||
{
|
||||
base.OnPointerDown(eventData);
|
||||
bHotKey = true;
|
||||
}
|
||||
public override void OnPointerUp(PointerEventData eventData)
|
||||
{
|
||||
base.OnPointerUp(eventData);
|
||||
bHotKey = false;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce5791c690e1b11489049aab664fb925
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,262 @@
|
||||
using AxiReplay;
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class UMAME : MonoBehaviour
|
||||
{
|
||||
public static UMAME instance { get; private set; }
|
||||
public MAMEEmu emu { get; private set; }
|
||||
UniLog mUniLog;
|
||||
UniMouse mUniMouse;
|
||||
[HideInInspector]
|
||||
public UniVideoPlayer mUniVideoPlayer;
|
||||
UniSoundPlayer mUniSoundPlayer;
|
||||
UniKeyboard mUniKeyboard;
|
||||
UniResources mUniResources;
|
||||
public Text mFPS;
|
||||
public Button btnStop;
|
||||
public Button btnStart;
|
||||
public Button btnRePlay;
|
||||
public Button btnRePayySave;
|
||||
public Button btnRomDir;
|
||||
public Button btnSaveState;
|
||||
public Button btnLoadState;
|
||||
public Dictionary<string, RomInfo> ALLGame;
|
||||
public List<RomInfo> HadGameList = new List<RomInfo>();
|
||||
string mChangeRomName = string.Empty;
|
||||
public UniTimeSpan mTimeSpan;
|
||||
public bool bQuickTestRom = false;
|
||||
public string mQuickTestRom = string.Empty;
|
||||
public ReplayWriter mReplayWriter;
|
||||
public ReplayReader mReplayReader;
|
||||
public long currEmuFrame => emu.currEmuFrame;
|
||||
|
||||
Dropdown optionDropdown;
|
||||
|
||||
public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
public static bool bInGame { get; private set; }
|
||||
|
||||
|
||||
#if UNITY_EDITOR_WIN
|
||||
public static string EmuDataPath => "G:/MAME.Core";
|
||||
#elif UNITY_ANDROID
|
||||
public static string EmuDataPath => Application.persistentDataPath;
|
||||
#elif UNITY_PSP2
|
||||
public static string EmuDataPath => "ux0:data/MAME.Unity";
|
||||
#else
|
||||
public static string EmuDataPath => Application.persistentDataPath;
|
||||
#endif
|
||||
|
||||
public static string RomPath => EmuDataPath + "/roms/";
|
||||
public static string SavePath => EmuDataPath + "/sav/";
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 强制横屏
|
||||
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
||||
|
||||
instance = this;
|
||||
mFPS = GameObject.Find("FPS").GetComponent<Text>();
|
||||
optionDropdown = GameObject.Find("optionDropdown").GetComponent<Dropdown>();
|
||||
emu = new MAMEEmu();
|
||||
mUniLog = new UniLog();
|
||||
mUniMouse = this.gameObject.AddComponent<UniMouse>();
|
||||
mUniVideoPlayer = this.gameObject.AddComponent<UniVideoPlayer>();
|
||||
mUniSoundPlayer = GameObject.Find("Audio").transform.GetComponent<UniSoundPlayer>();
|
||||
mUniKeyboard = this.gameObject.AddComponent<UniKeyboard>();
|
||||
mUniResources = new UniResources();
|
||||
mChangeRomName = UniMAMESetting.instance.LastGameRom;
|
||||
mTimeSpan = new UniTimeSpan();
|
||||
|
||||
emu.Init(RomPath, mUniLog, mUniResources, mUniVideoPlayer, mUniSoundPlayer, mUniKeyboard, mUniMouse, mTimeSpan);
|
||||
ALLGame = emu.GetGameList();
|
||||
|
||||
Debug.Log($"ALLGame:{ALLGame.Count}");
|
||||
|
||||
#if !UNITY_EDITOR
|
||||
bQuickTestRom = false;
|
||||
#endif
|
||||
|
||||
if (bQuickTestRom)
|
||||
mChangeRomName = mQuickTestRom;
|
||||
|
||||
GetHadRomList();
|
||||
|
||||
if (bQuickTestRom)
|
||||
LoadGame();
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
btnStop.onClick.AddListener(StopGame);
|
||||
btnStart.onClick.AddListener(() => { LoadGame(false); });
|
||||
btnRePlay.onClick.AddListener(() => { LoadGame(true); });
|
||||
btnRePayySave.onClick.AddListener(() => SaveReplay());
|
||||
btnSaveState.onClick.AddListener(SaveState);
|
||||
btnLoadState.onClick.AddListener(LoadState);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
|
||||
void LoadGame(bool bReplay = false)
|
||||
{
|
||||
//Application.targetFrameRate = 60;
|
||||
|
||||
mReplayWriter = new ReplayWriter(mChangeRomName, "fuck", ReplayData.ReplayFormat.FM32IP64, Encoding.UTF8);
|
||||
mChangeRomName = HadGameList[optionDropdown.value].Name;
|
||||
UniMAMESetting.instance.LastGameRom = mChangeRomName;
|
||||
StopGame();
|
||||
//读取ROM
|
||||
emu.LoadRom(mChangeRomName);
|
||||
//读取成功
|
||||
if (emu.bRom)
|
||||
{
|
||||
if (bReplay)
|
||||
{
|
||||
string Path = SavePath + Machine.sName + ".rp";
|
||||
mReplayReader = new ReplayReader(Path);
|
||||
mUniKeyboard.SetRePlay(true);
|
||||
}
|
||||
|
||||
//读取ROM之后获得宽高初始化画面
|
||||
int _width; int _height; IntPtr _framePtr;
|
||||
emu.GetGameScreenSize(out _width, out _height, out _framePtr);
|
||||
Debug.Log($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}");
|
||||
mUniVideoPlayer.Initialize(_width, _height, _framePtr);
|
||||
//初始化音频
|
||||
mUniSoundPlayer.Initialize();
|
||||
//开始游戏
|
||||
emu.StartGame();
|
||||
bInGame = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"ROM加载失败");
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")}");
|
||||
|
||||
if (!bInGame)
|
||||
return;
|
||||
|
||||
//采集本帧Input
|
||||
mUniKeyboard.UpdateInputKey();
|
||||
//放行下一帧
|
||||
//emu.UnlockNextFreme();
|
||||
//推帧
|
||||
emu.UpdateFrame();
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.F1))
|
||||
{
|
||||
SaveReplay();
|
||||
}
|
||||
|
||||
if (Input.GetKeyDown(KeyCode.F2))
|
||||
{
|
||||
string Path = SavePath + Machine.sName + ".rp";
|
||||
string dbgPath = SavePath + Machine.sName + ".rpread";
|
||||
mReplayReader = new ReplayReader(Path, true, dbgPath);
|
||||
mUniKeyboard.Init(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveReplay()
|
||||
{
|
||||
string Path = SavePath + Machine.sName + ".rp";
|
||||
string dbgPath = SavePath + Machine.sName + ".rpwrite";
|
||||
mReplayWriter.SaveData(Path, true, dbgPath);
|
||||
}
|
||||
|
||||
void StopGame()
|
||||
{
|
||||
if (bInGame)
|
||||
{
|
||||
emu.StopGame();
|
||||
mUniVideoPlayer.StopVideo();
|
||||
mUniSoundPlayer.StopPlay();
|
||||
bInGame = false;
|
||||
}
|
||||
}
|
||||
|
||||
void GetHadRomList()
|
||||
{
|
||||
HadGameList.Clear();
|
||||
optionDropdown.options.Clear();
|
||||
|
||||
Debug.Log($"GetHadRomList:{RomPath}");
|
||||
string[] directoryEntries = Directory.GetDirectories(RomPath);
|
||||
for (int i = 0; i < directoryEntries.Length; i++)
|
||||
{
|
||||
string path = directoryEntries[i];
|
||||
string dirName = Path.GetFileName(path);
|
||||
if (ALLGame.ContainsKey(dirName))
|
||||
{
|
||||
HadGameList.Add(ALLGame[dirName]);
|
||||
optionDropdown.options.Add(new Dropdown.OptionData(dirName));
|
||||
}
|
||||
}
|
||||
Debug.Log($"HadGameList:{HadGameList.Count}");
|
||||
|
||||
RomInfo tempCurrRom = HadGameList.Where(w => w.Name == mChangeRomName).FirstOrDefault();
|
||||
if (tempCurrRom != null)
|
||||
{
|
||||
optionDropdown.value = HadGameList.IndexOf(tempCurrRom);
|
||||
}
|
||||
else
|
||||
{
|
||||
optionDropdown.value = 0;
|
||||
}
|
||||
optionDropdown.RefreshShownValue();
|
||||
}
|
||||
|
||||
void OpenFolderRomPath()
|
||||
{
|
||||
System.Diagnostics.Process.Start("explorer.exe", "/select," + RomPath);
|
||||
}
|
||||
|
||||
void SaveState()
|
||||
{
|
||||
if (!Directory.Exists(SavePath))
|
||||
Directory.CreateDirectory(SavePath);
|
||||
|
||||
FileStream fs = new FileStream(SavePath + Machine.sName + ".sta", FileMode.Create);
|
||||
BinaryWriter bw = new BinaryWriter(fs);
|
||||
emu.SaveState(bw);
|
||||
bw.Close();
|
||||
fs.Close();
|
||||
|
||||
byte[] screenData = UMAME.instance.mUniVideoPlayer.GetScreenImg();
|
||||
|
||||
FileStream fsImg = new FileStream(SavePath + Machine.sName + ".jpg", FileMode.Create);
|
||||
fsImg.Write(screenData, 0, screenData.Length);
|
||||
fsImg.Close();
|
||||
}
|
||||
void LoadState()
|
||||
{
|
||||
string Path = SavePath + Machine.sName + ".sta";
|
||||
if (!File.Exists(Path))
|
||||
{
|
||||
Debug.Log($"文件不存在{Path}");
|
||||
return;
|
||||
}
|
||||
|
||||
FileStream fs = new FileStream(Path, FileMode.Open, FileAccess.Read);
|
||||
BinaryReader br = new BinaryReader(fs);
|
||||
emu.LoadState(br);
|
||||
br.Close();
|
||||
fs.Close();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 49349ac585d920c4f937c48232c8dfd7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9747519294fc9f04fbb6f1657c6d1dca
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,299 @@
|
||||
using MAME.Core;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class UniKeyboard : MonoBehaviour, IKeyboard
|
||||
{
|
||||
#region UIButton
|
||||
public UILongClickButton btnP1;
|
||||
public UILongClickButton btnCoin1;
|
||||
public UILongClickButton btnA;
|
||||
public UILongClickButton btnB;
|
||||
public UILongClickButton btnC;
|
||||
public UILongClickButton btnD;
|
||||
//public UILongClickButton btnE;
|
||||
//public UILongClickButton btnF;
|
||||
public UILongClickButton btnAB;
|
||||
public UILongClickButton btnCD;
|
||||
public UILongClickButton btnABC;
|
||||
public Transform tfKeyPad;
|
||||
public FloatingJoystick mJoystick;
|
||||
public List<UILongClickButton> mUIBtns = new List<UILongClickButton>();
|
||||
#endregion
|
||||
|
||||
public static Dictionary<KeyCode, MotionKey> dictKeyCfgs = new Dictionary<KeyCode, MotionKey>();
|
||||
public static KeyCode[] CheckList;
|
||||
bool bReplayMode;
|
||||
PlayMode mPlayMode;
|
||||
ReplayMode mReplayMode;
|
||||
ulong last_CurryInpuAllData_test = 0;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
mJoystick = GameObject.Find("tfJoystick").GetComponent<FloatingJoystick>();
|
||||
tfKeyPad = GameObject.Find("tfKeyPad").transform;
|
||||
btnP1 = GameObject.Find("btnP1").GetComponent<UILongClickButton>();
|
||||
btnCoin1 = GameObject.Find("btnCoin1").GetComponent<UILongClickButton>();
|
||||
btnA = GameObject.Find("btnA").GetComponent<UILongClickButton>();
|
||||
btnB = GameObject.Find("btnB").GetComponent<UILongClickButton>();
|
||||
btnC = GameObject.Find("btnC").GetComponent<UILongClickButton>();
|
||||
btnD = GameObject.Find("btnD").GetComponent<UILongClickButton>();
|
||||
//btnE = GameObject.Find("btnE")?.GetComponent<UILongClickButton>();
|
||||
//btnF = GameObject.Find("btnF")?.GetComponent<UILongClickButton>();
|
||||
btnAB = GameObject.Find("btnAB").GetComponent<UILongClickButton>();
|
||||
btnCD = GameObject.Find("btnCD").GetComponent<UILongClickButton>();
|
||||
btnABC = GameObject.Find("btnABC").GetComponent<UILongClickButton>();
|
||||
|
||||
mUIBtns.Add(btnP1);
|
||||
mUIBtns.Add(btnCoin1);
|
||||
mUIBtns.Add(btnA);
|
||||
mUIBtns.Add(btnB);
|
||||
mUIBtns.Add(btnC);
|
||||
mUIBtns.Add(btnD);
|
||||
mUIBtns.Add(btnAB);
|
||||
mUIBtns.Add(btnCD);
|
||||
mUIBtns.Add(btnABC);
|
||||
|
||||
//if (btnE != null)
|
||||
//{
|
||||
// mUIBtns.Add(btnE);
|
||||
// btnE.gameObject.SetActive(false);
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// mUIBtns.Add(btnF);
|
||||
// btnF.gameObject.SetActive(false);
|
||||
//}
|
||||
|
||||
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
|
||||
tfKeyPad.gameObject.SetActive(false);
|
||||
#endif
|
||||
Init(false);
|
||||
}
|
||||
|
||||
public MotionKey[] GetPressedKeys()
|
||||
{
|
||||
MotionKey[] currkey;
|
||||
ulong InputData;
|
||||
if (!bReplayMode)
|
||||
currkey = mPlayMode.GetPressedKeys(out InputData);
|
||||
else
|
||||
currkey = mReplayMode.GetPressedKeys(out InputData);
|
||||
#if UNITY_EDITOR
|
||||
if (last_CurryInpuAllData_test != InputData)
|
||||
{
|
||||
string TempStr = "";
|
||||
foreach (var item in currkey)
|
||||
{
|
||||
TempStr += $"{item.ToString()}|";
|
||||
}
|
||||
Debug.Log($"{UMAME.instance.mUniVideoPlayer.mFrame} | {EmuTimer.get_current_time().attoseconds} |{EmuTimer.get_current_time().seconds} | {InputData} | {TempStr}");
|
||||
last_CurryInpuAllData_test = InputData;
|
||||
}
|
||||
#endif
|
||||
return currkey;
|
||||
}
|
||||
|
||||
public void UpdateInputKey()
|
||||
{
|
||||
UpdateLogic();
|
||||
}
|
||||
|
||||
#region
|
||||
|
||||
public void SetRePlay(bool IsReplay)
|
||||
{
|
||||
bReplayMode = IsReplay;
|
||||
}
|
||||
|
||||
public void Init(bool IsReplay)
|
||||
{
|
||||
bReplayMode = IsReplay;
|
||||
dictKeyCfgs.Clear();
|
||||
//dictKeyCfgs.Add(KeyCode.P, MotionKey.EMU_PAUSED);
|
||||
dictKeyCfgs.Add(KeyCode.Alpha1, MotionKey.P1_GAMESTART);
|
||||
dictKeyCfgs.Add(KeyCode.Alpha5, MotionKey.P1_INSERT_COIN);
|
||||
dictKeyCfgs.Add(KeyCode.W, MotionKey.P1_UP);
|
||||
dictKeyCfgs.Add(KeyCode.S, MotionKey.P1_DOWN);
|
||||
dictKeyCfgs.Add(KeyCode.A, MotionKey.P1_LEFT);
|
||||
dictKeyCfgs.Add(KeyCode.D, MotionKey.P1_RIGHT);
|
||||
dictKeyCfgs.Add(KeyCode.J, MotionKey.P1_BTN_1);
|
||||
dictKeyCfgs.Add(KeyCode.K, MotionKey.P1_BTN_2);
|
||||
dictKeyCfgs.Add(KeyCode.L, MotionKey.P1_BTN_3);
|
||||
dictKeyCfgs.Add(KeyCode.U, MotionKey.P1_BTN_4);
|
||||
dictKeyCfgs.Add(KeyCode.KeypadDivide, MotionKey.P2_GAMESTART);
|
||||
dictKeyCfgs.Add(KeyCode.KeypadMultiply, MotionKey.P2_INSERT_COIN);
|
||||
dictKeyCfgs.Add(KeyCode.UpArrow, MotionKey.P2_UP);
|
||||
dictKeyCfgs.Add(KeyCode.DownArrow, MotionKey.P2_DOWN);
|
||||
dictKeyCfgs.Add(KeyCode.LeftArrow, MotionKey.P2_LEFT);
|
||||
dictKeyCfgs.Add(KeyCode.RightArrow, MotionKey.P2_RIGHT);
|
||||
dictKeyCfgs.Add(KeyCode.Keypad1, MotionKey.P2_BTN_1);
|
||||
dictKeyCfgs.Add(KeyCode.Keypad2, MotionKey.P2_BTN_2);
|
||||
dictKeyCfgs.Add(KeyCode.Keypad3, MotionKey.P2_BTN_3);
|
||||
dictKeyCfgs.Add(KeyCode.Keypad4, MotionKey.P2_BTN_4);
|
||||
CheckList = dictKeyCfgs.Keys.ToArray();
|
||||
|
||||
btnP1.Key = new long[] { (long)MotionKey.P1_GAMESTART };
|
||||
btnCoin1.Key = new long[] { (long)MotionKey.P1_INSERT_COIN };
|
||||
btnA.Key = new long[] { (long)MotionKey.P1_BTN_1 };
|
||||
btnB.Key = new long[] { (long)MotionKey.P1_BTN_2 };
|
||||
btnC.Key = new long[] { (long)MotionKey.P1_BTN_3 };
|
||||
btnD.Key = new long[] { (long)MotionKey.P1_BTN_4 };
|
||||
//btnE.Key = new long[] { (long)MotionKey.P1_BTN_5 };
|
||||
//btnF.Key = new long[] { (long)MotionKey.P1_BTN_6 };
|
||||
btnAB.Key = new long[] { (long)MotionKey.P1_BTN_1, (long)MotionKey.P1_BTN_2 };
|
||||
btnCD.Key = new long[] { (long)MotionKey.P1_BTN_3, (long)MotionKey.P1_BTN_4 };
|
||||
btnABC.Key = new long[] { (long)MotionKey.P1_BTN_1, (long)MotionKey.P1_BTN_2, (long)MotionKey.P1_BTN_3 };
|
||||
|
||||
mPlayMode = new PlayMode(this);
|
||||
mReplayMode = new ReplayMode();
|
||||
}
|
||||
|
||||
public void UpdateLogic()
|
||||
{
|
||||
if (bReplayMode) return;
|
||||
mPlayMode.UpdateLogic();
|
||||
}
|
||||
public class PlayMode
|
||||
{
|
||||
Dictionary<KeyCode, MotionKey> dictKeyCfgs => UniKeyboard.dictKeyCfgs;
|
||||
UniKeyboard mUniKeyboard;
|
||||
KeyCode[] CheckList => UniKeyboard.CheckList;
|
||||
ulong tempInputAllData = 0;
|
||||
List<MotionKey> temp = new List<MotionKey>();
|
||||
public ulong CurryInpuAllData = 0;
|
||||
public MotionKey[] mCurrKey = new MotionKey[0];
|
||||
|
||||
public PlayMode(UniKeyboard uniKeyboard)
|
||||
{
|
||||
this.mUniKeyboard = uniKeyboard;
|
||||
}
|
||||
|
||||
public void UpdateLogic()
|
||||
{
|
||||
tempInputAllData = 0;
|
||||
temp.Clear();
|
||||
for (int i = 0; i < CheckList.Length; i++)
|
||||
{
|
||||
if (Input.GetKey(CheckList[i]))
|
||||
{
|
||||
MotionKey mk = dictKeyCfgs[CheckList[i]];
|
||||
temp.Add(mk);
|
||||
tempInputAllData |= (ulong)mk;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mUniKeyboard.mUIBtns.Count; i++)
|
||||
{
|
||||
if (mUniKeyboard.mUIBtns[i].bHotKey)
|
||||
{
|
||||
for (int j = 0; j < mUniKeyboard.mUIBtns[i].Key.Length; j++)
|
||||
{
|
||||
MotionKey mk = (MotionKey)mUniKeyboard.mUIBtns[i].Key[j];
|
||||
temp.Add(mk);
|
||||
tempInputAllData |= (ulong)mk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector2Int inputV2 = mUniKeyboard.mJoystick.RawInputV2;
|
||||
//Debug.Log($"{inputV2.x},{inputV2.y}");
|
||||
if (inputV2.x > 0)
|
||||
{
|
||||
temp.Add(MotionKey.P1_RIGHT);
|
||||
tempInputAllData |= (ulong)MotionKey.P1_RIGHT;
|
||||
}
|
||||
else if (inputV2.x < 0)
|
||||
{
|
||||
temp.Add(MotionKey.P1_LEFT);
|
||||
tempInputAllData |= (ulong)MotionKey.P1_LEFT;
|
||||
}
|
||||
if (inputV2.y > 0)
|
||||
{
|
||||
temp.Add(MotionKey.P1_UP);
|
||||
tempInputAllData |= (ulong)MotionKey.P1_UP;
|
||||
}
|
||||
else if (inputV2.y < 0)
|
||||
{
|
||||
temp.Add(MotionKey.P1_DOWN);
|
||||
tempInputAllData |= (ulong)MotionKey.P1_DOWN;
|
||||
}
|
||||
CurryInpuAllData = tempInputAllData;
|
||||
mCurrKey = temp.ToArray();
|
||||
}
|
||||
|
||||
public MotionKey[] GetPressedKeys(out ulong InputData)
|
||||
{
|
||||
//UMAME.instance.mReplayWriter.NextFramebyFrameIdx((int)UMAME.instance.mUniVideoPlayer.mFrame, CurryInpuAllData);
|
||||
UMAME.instance.mReplayWriter.NextFramebyFrameIdx((int)UMAME.instance.mUniVideoPlayer.mFrame, CurryInpuAllData);
|
||||
InputData = CurryInpuAllData;
|
||||
return mCurrKey;
|
||||
}
|
||||
}
|
||||
public class ReplayMode
|
||||
{
|
||||
public MotionKey[] mCurrKey = new MotionKey[0];
|
||||
MotionKey[] ReplayCheckKey;
|
||||
ulong currInputData;
|
||||
List<MotionKey> temp = new List<MotionKey>();
|
||||
|
||||
public ReplayMode()
|
||||
{
|
||||
ReplayCheckKey = dictKeyCfgs.Values.ToArray();
|
||||
}
|
||||
|
||||
public MotionKey[] GetPressedKeys(out ulong InputData)
|
||||
{
|
||||
//有变化
|
||||
//if (UMAME.instance.mReplayReader.NextFrame(out AxiReplay.ReplayStep stepData))
|
||||
int targetFrame = (int)UMAME.instance.mUniVideoPlayer.mFrame;
|
||||
//if (UMAME.instance.mReplayReader.NextFramebyFrameIdx(targetFrame, out AxiReplay.ReplayStep stepData))
|
||||
//{
|
||||
// temp.Clear();
|
||||
// //有数据
|
||||
// for (int i = 0; i < ReplayCheckKey.Length; i++)
|
||||
// {
|
||||
// if ((stepData.InPut & (ulong)ReplayCheckKey[i]) > 0)
|
||||
// temp.Add(ReplayCheckKey[i]);
|
||||
// }
|
||||
// mCurrKey = temp.ToArray();
|
||||
//}
|
||||
AxiReplay.ReplayStep stepData;
|
||||
|
||||
if (UMAME.instance.mReplayReader.NextFramebyFrameIdx(targetFrame, out stepData))
|
||||
{
|
||||
temp.Clear();
|
||||
//List<MotionKey> temp = new List<MotionKey>();
|
||||
//temp.Clear();
|
||||
////有数据
|
||||
//for (int i = 0; i < ReplayCheckKey.Length; i++)
|
||||
//{
|
||||
// if ((stepData.InPut & (ulong)ReplayCheckKey[i]) > 0)
|
||||
// temp.Add(ReplayCheckKey[i]);
|
||||
//}
|
||||
//mCurrKey = temp.ToArray();
|
||||
foreach (MotionKey key in GetStepDataToMotionKey(stepData))
|
||||
{
|
||||
temp.Add(key);
|
||||
}
|
||||
mCurrKey = temp.ToArray();
|
||||
currInputData = stepData.InPut;
|
||||
}
|
||||
InputData = currInputData;
|
||||
return mCurrKey;
|
||||
}
|
||||
|
||||
IEnumerable<MotionKey> GetStepDataToMotionKey(AxiReplay.ReplayStep stepData)
|
||||
{
|
||||
//有数据
|
||||
for (int i = 0; i < ReplayCheckKey.Length; i++)
|
||||
{
|
||||
if ((stepData.InPut & (ulong)ReplayCheckKey[i]) > 0)
|
||||
yield return ReplayCheckKey[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 383edf8c0a98c9345849990416ef860f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,10 @@
|
||||
using MAME.Core;
|
||||
using UnityEngine;
|
||||
|
||||
public class UniLog : ILog
|
||||
{
|
||||
public void Log(string msg)
|
||||
{
|
||||
Debug.Log(msg);
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41107c5bd92323948a491a37e8760f3a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,23 @@
|
||||
using MAME.Core;
|
||||
using UnityEngine;
|
||||
|
||||
public class UniMouse : MonoBehaviour, IMouse
|
||||
{
|
||||
static int mX, mY;
|
||||
public byte[] buttons = new byte[2];
|
||||
void Update()
|
||||
{
|
||||
mX = (int)Input.mousePosition.x;
|
||||
mY = (int)Input.mousePosition.y;
|
||||
buttons[0] = Input.GetMouseButton(0) ? (byte)1 : (byte)0;
|
||||
buttons[1] = Input.GetMouseButton(1) ? (byte)1 : (byte)0;
|
||||
}
|
||||
|
||||
public void MouseXY(out int X, out int Y, out byte[] MouseButtons)
|
||||
{
|
||||
X = mX;
|
||||
Y = mY * -1;
|
||||
MouseButtons = buttons;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0e566345b50ca464fb8bd492a22c043b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,29 @@
|
||||
using MAME.Core;
|
||||
using UnityEngine;
|
||||
|
||||
public class UniResources : IResources
|
||||
{
|
||||
const string ResourceRoot = "MAME/emu/";
|
||||
|
||||
public byte[] mcu => Resources.Load<TextAsset>(ResourceRoot + "cus64-64a1.mcu").bytes;
|
||||
|
||||
public byte[] sfix => Resources.Load<TextAsset>(ResourceRoot + "sfix.sfix").bytes;
|
||||
|
||||
public byte[] _000_lo => Resources.Load<TextAsset>(ResourceRoot + "000-lo.lo").bytes;
|
||||
|
||||
public byte[] sm1 => Resources.Load<TextAsset>(ResourceRoot + "sm1.sm1").bytes;
|
||||
|
||||
public byte[] mainbios => Resources.Load<TextAsset>(ResourceRoot + "neogeo_mainbios.rom").bytes;
|
||||
|
||||
public byte[] pgmmainbios => Resources.Load<TextAsset>(ResourceRoot + "pgm_mainbios.rom").bytes;
|
||||
|
||||
public byte[] pgmvideobios => Resources.Load<TextAsset>(ResourceRoot + "pgm_t01s.rom").bytes;
|
||||
|
||||
public byte[] pgmaudiobios => Resources.Load<TextAsset>(ResourceRoot + "pgm_m01s.rom").bytes;
|
||||
|
||||
public byte[] _1 => Resources.Load<TextAsset>(ResourceRoot + "1.png").bytes;
|
||||
|
||||
public byte[] readme => Resources.Load<TextAsset>(ResourceRoot + "readme.txt").bytes;
|
||||
|
||||
public string mame => Resources.Load<TextAsset>(ResourceRoot + "mame.xml").text;//ok
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: badc6676adc52b34da8dbda2d4aa0aba
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,93 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
public class UniSoundPlayer : MonoBehaviour, ISoundPlayer
|
||||
{
|
||||
[SerializeField]
|
||||
private AudioSource m_as;
|
||||
private RingBuffer<float> _buffer = new RingBuffer<float>(4096);
|
||||
private TimeSpan lastElapsed;
|
||||
public double audioFPS { get; private set; }
|
||||
float lastData = 0;
|
||||
|
||||
|
||||
void Awake()
|
||||
{
|
||||
AudioClip dummy = AudioClip.Create("dummy", 1, 2, AudioSettings.outputSampleRate, false);
|
||||
dummy.SetData(new float[] { 1, 1 }, 0);
|
||||
m_as.clip = dummy;
|
||||
m_as.loop = true;
|
||||
m_as.spatialBlend = 1;
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (!m_as.isPlaying)
|
||||
{
|
||||
m_as.Play();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopPlay()
|
||||
{
|
||||
if (m_as.isPlaying)
|
||||
{
|
||||
m_as.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
void OnAudioFilterRead(float[] data, int channels)
|
||||
{
|
||||
if (!UMAME.bInGame) return;
|
||||
int step = channels;
|
||||
for (int i = 0; i < data.Length; i += step)
|
||||
{
|
||||
float rawFloat = lastData;
|
||||
float rawData;
|
||||
if (_buffer.TryRead(out rawData))
|
||||
{
|
||||
rawFloat = rawData;
|
||||
}
|
||||
|
||||
data[i] = rawFloat;
|
||||
for (int fill = 1; fill < step; fill++)
|
||||
data[i + fill] = rawFloat;
|
||||
lastData = rawFloat;
|
||||
}
|
||||
}
|
||||
|
||||
public void SubmitSamples(byte[] buffer, int samples_a)
|
||||
{
|
||||
var current = UMAME.sw.Elapsed;
|
||||
var delta = current - lastElapsed;
|
||||
lastElapsed = current;
|
||||
audioFPS = 1d / delta.TotalSeconds;
|
||||
|
||||
|
||||
for (int i = 0; i < samples_a; i++)
|
||||
{
|
||||
short left = BitConverter.ToInt16(buffer, i * 2 * 2);
|
||||
//short right = BitConverter.ToInt16(buffer, i * 2 * 2 + 2);
|
||||
_buffer.Write(left / 32767.0f);
|
||||
//_buffer.Write(right / 32767.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void BufferWirte(int Off, byte[] Data)
|
||||
{
|
||||
}
|
||||
|
||||
public void GetCurrentPosition(out int play_position, out int write_position)
|
||||
{
|
||||
play_position = 0;
|
||||
write_position = 0;
|
||||
}
|
||||
|
||||
public void SetVolume(int Vol)
|
||||
{
|
||||
if (m_as)
|
||||
return;
|
||||
m_as.volume = Vol;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89abab1d3b1020340a147d74e60751ce
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,41 @@
|
||||
using MAME.Core;
|
||||
|
||||
public class UniTimeSpan : ITimeSpan
|
||||
{
|
||||
public ulong tick;
|
||||
double tickDetailus = 16666.666667;
|
||||
object tickLock = new object();
|
||||
|
||||
public void SetTick(ulong nexttick)
|
||||
{
|
||||
//lock (tickLock)
|
||||
{
|
||||
tick = nexttick;
|
||||
}
|
||||
}
|
||||
|
||||
//Õâ¸öº¯ÊýÎÞÒâÒå
|
||||
public uint GetTickCount()
|
||||
{
|
||||
//lock (tickLock)
|
||||
{
|
||||
//return (uint)(tick * tickDetail);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public bool QueryPerformanceCounter(ref long lpPerformanceCount)
|
||||
{
|
||||
lock (tickLock)
|
||||
{
|
||||
lpPerformanceCount = (long)tick;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool QueryPerformanceFrequency(ref long PerformanceFrequency)
|
||||
{
|
||||
PerformanceFrequency = (long)(1000000 / tickDetailus);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a35bf49414a7b194eb8d359004336a8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,88 @@
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class UniVideoPlayer : MonoBehaviour, IVideoPlayer
|
||||
{
|
||||
[SerializeField]
|
||||
private int mWidth;
|
||||
[SerializeField]
|
||||
private int mHeight;
|
||||
[SerializeField]
|
||||
private int mDataLenght;
|
||||
[SerializeField]
|
||||
private Texture2D m_rawBufferWarper;
|
||||
[SerializeField]
|
||||
private RawImage m_drawCanvas;
|
||||
[SerializeField]
|
||||
private RectTransform m_drawCanvasrect;
|
||||
//int[] mFrameData;
|
||||
IntPtr mFrameDataPtr;
|
||||
|
||||
private TimeSpan lastElapsed;
|
||||
public double videoFPS { get; private set; }
|
||||
public ulong mFrame { get; private set; }
|
||||
bool bInit = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
mFrame = 0;
|
||||
m_drawCanvas = GameObject.Find("GameRawImage").GetComponent<RawImage>();
|
||||
m_drawCanvasrect = m_drawCanvas.GetComponent<RectTransform>();
|
||||
}
|
||||
|
||||
public void Initialize(int width, int height,IntPtr framePtr)
|
||||
{
|
||||
m_drawCanvas.color = Color.white;
|
||||
|
||||
if (m_rawBufferWarper == null || mWidth != width || mHeight != height)
|
||||
{
|
||||
mWidth = width;
|
||||
mHeight = height;
|
||||
mDataLenght = width * height * 4;
|
||||
//mFrameData = new int[mWidth * mHeight];
|
||||
//MAMEÀ´µÄÊÇBGRA32£¬ºÃºÃºÃ BGRA->RGBA
|
||||
m_rawBufferWarper = new Texture2D(mWidth, mHeight, TextureFormat.RGBA32, false);
|
||||
m_rawBufferWarper.filterMode = FilterMode.Point;
|
||||
}
|
||||
|
||||
mFrameDataPtr = framePtr;
|
||||
m_drawCanvas.texture = m_rawBufferWarper;
|
||||
bInit = true;
|
||||
|
||||
float targetWidth = ((float)mWidth / mHeight) * m_drawCanvasrect.rect.height ;
|
||||
m_drawCanvasrect.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, targetWidth);
|
||||
}
|
||||
|
||||
public void StopVideo()
|
||||
{
|
||||
bInit = false;
|
||||
m_drawCanvas.color = new Color(0,0,0,0);
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
if (!bInit) return;
|
||||
m_rawBufferWarper.LoadRawTextureData(mFrameDataPtr, mDataLenght);
|
||||
m_rawBufferWarper.Apply();
|
||||
}
|
||||
|
||||
public void SubmitVideo(int[] data, long frame_number)
|
||||
{
|
||||
mFrame = (ulong)frame_number;
|
||||
UMAME.instance.mTimeSpan.SetTick(mFrame);
|
||||
var current = UMAME.sw.Elapsed;
|
||||
var delta = current - lastElapsed;
|
||||
lastElapsed = current;
|
||||
videoFPS = 1d / delta.TotalSeconds;
|
||||
//mFrameData = data;
|
||||
|
||||
//Debug.Log($"frame_number -> {frame_number}");
|
||||
}
|
||||
|
||||
public byte[] GetScreenImg()
|
||||
{
|
||||
return (m_drawCanvas.texture as Texture2D).EncodeToJPG();
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f675565b1f4ed7744a8ea9788c92429d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -12,9 +12,9 @@ namespace AxibugEmuOnline.Client
|
||||
public class CoreSupporter : ISupporterImpl
|
||||
{
|
||||
private NesControllerMapper m_controllerMapper;
|
||||
public CoreSupporter(NesControllerMapper conMapper)
|
||||
{
|
||||
m_controllerMapper = conMapper;
|
||||
public CoreSupporter(NesControllerMapper conMapper)
|
||||
{
|
||||
m_controllerMapper = conMapper;
|
||||
}
|
||||
|
||||
public Stream OpenRom(string fname)
|
||||
@ -107,9 +107,9 @@ namespace AxibugEmuOnline.Client
|
||||
uint LastTestInput = 0;
|
||||
public void SampleInput(uint frameIndex)
|
||||
{
|
||||
if (InGameUI.Instance.IsNetPlay)
|
||||
if (InGameUI.Instance.IsNetPlay)
|
||||
{
|
||||
int targetFrame; ReplayStep replayData; int frameDiff; bool inputDiff;
|
||||
int targetFrame; ReplayStep replayData; int frameDiff; bool inputDiff;
|
||||
if (App.roomMgr.netReplay.TryGetNextFrame((int)frameIndex, out replayData, out frameDiff, out inputDiff))
|
||||
{
|
||||
if (inputDiff)
|
@ -1,4 +1,4 @@
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -21,8 +21,8 @@ namespace AxibugEmuOnline.Client
|
||||
m_states[0] = m_states[1] = m_states[2] = m_states[3] = 0;
|
||||
|
||||
if (Controller0.ConnectSlot.HasValue) m_states[Controller0.ConnectSlot.Value] = Controller0.GetButtons();
|
||||
else if (Controller0.AnyButtonDown()) Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 0);
|
||||
|
||||
else if (Controller0.AnyButtonDown()) Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 0);
|
||||
|
||||
if (Controller1.ConnectSlot.HasValue) m_states[Controller1.ConnectSlot.Value] = Controller1.GetButtons();
|
||||
else if (Controller1.AnyButtonDown()) Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 1);
|
||||
|
||||
@ -45,73 +45,73 @@ namespace AxibugEmuOnline.Client
|
||||
Controller1.ConnectSlot = con1ToSlot;
|
||||
Controller2.ConnectSlot = con2ToSlot;
|
||||
Controller3.ConnectSlot = con3ToSlot;
|
||||
}
|
||||
|
||||
public int? GetSlotConnectingControllerIndex(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return 0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return 1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return 2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return 3;
|
||||
else return null;
|
||||
}
|
||||
|
||||
public IController GetSlotConnectingController(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return Controller0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return Controller1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return Controller2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return Controller3;
|
||||
else return null;
|
||||
}
|
||||
|
||||
//static HashSet<uint> s_temp = new HashSet<uint>(4);
|
||||
//低版本不能这样初始化
|
||||
static HashSet<uint> s_temp = new HashSet<uint>();
|
||||
public uint? GetFreeSlotIndex()
|
||||
{
|
||||
s_temp.Clear();
|
||||
s_temp.Add(0);
|
||||
s_temp.Add(1);
|
||||
s_temp.Add(2);
|
||||
s_temp.Add(3);
|
||||
|
||||
if (Controller0.ConnectSlot.HasValue) s_temp.Remove(Controller0.ConnectSlot.Value);
|
||||
if (Controller1.ConnectSlot.HasValue) s_temp.Remove(Controller1.ConnectSlot.Value);
|
||||
if (Controller2.ConnectSlot.HasValue) s_temp.Remove(Controller2.ConnectSlot.Value);
|
||||
if (Controller3.ConnectSlot.HasValue) s_temp.Remove(Controller3.ConnectSlot.Value);
|
||||
|
||||
if (s_temp.Count > 0) return s_temp.First();
|
||||
else return null;
|
||||
}
|
||||
|
||||
public void LetControllerConnect(int conIndex, uint slotIndex)
|
||||
{
|
||||
Controller targetController;
|
||||
switch (conIndex)
|
||||
{
|
||||
case 0: targetController = Controller0; break;
|
||||
case 1: targetController = Controller1; break;
|
||||
case 2: targetController = Controller2; break;
|
||||
case 3: targetController = Controller3; break;
|
||||
default:
|
||||
throw new System.Exception($"Not Allowed conIndex Range: {conIndex}");
|
||||
break;
|
||||
}
|
||||
//var targetController = conIndex switch
|
||||
//{
|
||||
// 0 => Controller0,
|
||||
// 1 => Controller1,
|
||||
// 2 => Controller2,
|
||||
// 3 => Controller3,
|
||||
// _ => throw new System.Exception($"Not Allowed conIndex Range: {conIndex}")
|
||||
//};
|
||||
|
||||
if (targetController.ConnectSlot.HasValue) return;
|
||||
|
||||
targetController.ConnectSlot = slotIndex;
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged);
|
||||
}
|
||||
|
||||
public int? GetSlotConnectingControllerIndex(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return 0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return 1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return 2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return 3;
|
||||
else return null;
|
||||
}
|
||||
|
||||
public IController GetSlotConnectingController(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return Controller0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return Controller1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return Controller2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return Controller3;
|
||||
else return null;
|
||||
}
|
||||
|
||||
//static HashSet<uint> s_temp = new HashSet<uint>(4);
|
||||
//低版本不能这样初始化
|
||||
static HashSet<uint> s_temp = new HashSet<uint>();
|
||||
public uint? GetFreeSlotIndex()
|
||||
{
|
||||
s_temp.Clear();
|
||||
s_temp.Add(0);
|
||||
s_temp.Add(1);
|
||||
s_temp.Add(2);
|
||||
s_temp.Add(3);
|
||||
|
||||
if (Controller0.ConnectSlot.HasValue) s_temp.Remove(Controller0.ConnectSlot.Value);
|
||||
if (Controller1.ConnectSlot.HasValue) s_temp.Remove(Controller1.ConnectSlot.Value);
|
||||
if (Controller2.ConnectSlot.HasValue) s_temp.Remove(Controller2.ConnectSlot.Value);
|
||||
if (Controller3.ConnectSlot.HasValue) s_temp.Remove(Controller3.ConnectSlot.Value);
|
||||
|
||||
if (s_temp.Count > 0) return s_temp.First();
|
||||
else return null;
|
||||
}
|
||||
|
||||
public void LetControllerConnect(int conIndex, uint slotIndex)
|
||||
{
|
||||
Controller targetController;
|
||||
switch (conIndex)
|
||||
{
|
||||
case 0: targetController = Controller0; break;
|
||||
case 1: targetController = Controller1; break;
|
||||
case 2: targetController = Controller2; break;
|
||||
case 3: targetController = Controller3; break;
|
||||
default:
|
||||
throw new System.Exception($"Not Allowed conIndex Range: {conIndex}");
|
||||
break;
|
||||
}
|
||||
//var targetController = conIndex switch
|
||||
//{
|
||||
// 0 => Controller0,
|
||||
// 1 => Controller1,
|
||||
// 2 => Controller2,
|
||||
// 3 => Controller3,
|
||||
// _ => throw new System.Exception($"Not Allowed conIndex Range: {conIndex}")
|
||||
//};
|
||||
|
||||
if (targetController.ConnectSlot.HasValue) return;
|
||||
|
||||
targetController.ConnectSlot = slotIndex;
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -174,28 +174,28 @@ namespace AxibugEmuOnline.Client
|
||||
return res;
|
||||
}
|
||||
|
||||
public bool AnyButtonDown()
|
||||
{
|
||||
return
|
||||
UP.IsDown ||
|
||||
DOWN.IsDown ||
|
||||
LEFT.IsDown ||
|
||||
RIGHT.IsDown ||
|
||||
A.IsDown ||
|
||||
B.IsDown ||
|
||||
SELECT.IsDown ||
|
||||
START.IsDown ||
|
||||
MIC.IsDown;
|
||||
public bool AnyButtonDown()
|
||||
{
|
||||
return
|
||||
UP.IsDown ||
|
||||
DOWN.IsDown ||
|
||||
LEFT.IsDown ||
|
||||
RIGHT.IsDown ||
|
||||
A.IsDown ||
|
||||
B.IsDown ||
|
||||
SELECT.IsDown ||
|
||||
START.IsDown ||
|
||||
MIC.IsDown;
|
||||
}
|
||||
|
||||
public static KeyListener GetKey(int controllerInput, EnumButtonType nesConBtnType)
|
||||
{
|
||||
string configKey = $"NES_{controllerInput}_{nesConBtnType}";
|
||||
|
||||
//PSV平台固定键值
|
||||
if (UnityEngine.Application.platform == RuntimePlatform.PSP2)
|
||||
string configKey = $"NES_{controllerInput}_{nesConBtnType}";
|
||||
|
||||
//PSV平台固定键值
|
||||
if (UnityEngine.Application.platform == RuntimePlatform.PSP2)
|
||||
{
|
||||
return KeyListener.GetPSVitaKey(controllerInput, nesConBtnType);
|
||||
return KeyListener.GetPSVitaKey(controllerInput, nesConBtnType);
|
||||
}
|
||||
|
||||
if (PlayerPrefs.HasKey(configKey))
|
||||
@ -251,10 +251,10 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
m_keyListener = Controller.GetKey(m_hostController.ControllerIndex, m_buttonType);
|
||||
}
|
||||
}
|
||||
//low C# readonly
|
||||
//public readonly struct KeyListener
|
||||
|
||||
}
|
||||
//low C# readonly
|
||||
//public readonly struct KeyListener
|
||||
|
||||
public struct KeyListener
|
||||
{
|
||||
private readonly KeyCode m_key;
|
||||
@ -269,7 +269,7 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
m_key = KeyCode.None;
|
||||
|
||||
int result;
|
||||
int result;
|
||||
if (int.TryParse(confStr, out result))
|
||||
m_key = (KeyCode)result;
|
||||
}
|
||||
@ -278,9 +278,9 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
return Input.GetKey(m_key);
|
||||
}
|
||||
public bool IsDown()
|
||||
{
|
||||
return Input.GetKeyDown(m_key);
|
||||
public bool IsDown()
|
||||
{
|
||||
return Input.GetKeyDown(m_key);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
@ -343,9 +343,9 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
|
||||
return default(KeyListener);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static KeyListener GetPSVitaKey(int controllerIndex, EnumButtonType nesConBtnType)
|
||||
{
|
||||
switch (controllerIndex)
|
||||
@ -376,6 +376,6 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
return default(KeyListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,12 +20,12 @@ namespace AxibugEmuOnline.Client
|
||||
public NES NesCore { get; private set; }
|
||||
|
||||
/// <summary> 是否暂停 </summary>
|
||||
public bool IsPause { get; private set; }
|
||||
public bool IsPause { get; private set; }
|
||||
public NesControllerMapper ControllerMapper { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
ControllerMapper = new NesControllerMapper();
|
||||
private void Awake()
|
||||
{
|
||||
ControllerMapper = new NesControllerMapper();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
@ -51,8 +51,8 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
var screenBuffer = NesCore.ppu.GetScreenPtr();
|
||||
VideoProvider.SetDrawData(screenBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VideoProvider.ApplyScreenScaler();
|
||||
VideoProvider.ApplyFilterEffect();
|
||||
}
|
||||
@ -178,17 +178,17 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return ControllerMapper;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
|
||||
|
||||
public IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return ControllerMapper;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
@ -219,7 +219,7 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
UnityEditor.EditorUtility.SetDirty(db);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -83,9 +83,9 @@ namespace AxibugEmuOnline.Client
|
||||
App.settings.Filter.ExecuteFilterRender(rt_gpu, Image);
|
||||
}
|
||||
|
||||
public void ApplyScreenScaler()
|
||||
{
|
||||
App.settings.ScreenScaler.CalcScale(Image, RomPlatformType.Nes);
|
||||
public void ApplyScreenScaler()
|
||||
{
|
||||
App.settings.ScreenScaler.CalcScale(Image, RomPlatformType.Nes);
|
||||
}
|
||||
|
||||
private unsafe void PrepareUI(uint* screenData)
|
8
AxibugEmuOnline.Client/Assets/Script/AppMain/UMame.meta
Normal file
8
AxibugEmuOnline.Client/Assets/Script/AppMain/UMame.meta
Normal file
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ea791d3660bb49a4d94f1d824a488569
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Reference in New Issue
Block a user