Compare commits
No commits in common. "1a1e5026f8a58ed67a5477d553aaba137cd2a9e3" and "0eccfd3e6db770380325d9d78dd9be8e488cb092" have entirely different histories.
1a1e5026f8
...
0eccfd3e6d
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +0,0 @@
|
|||||||
[submodule "AxibugEmuOnline.Client/Assets/AlienUICore"]
|
|
||||||
path = AxibugEmuOnline.Client/Assets/AlienUICore
|
|
||||||
url = https://github.com/AlienJack/AlienUICore.git
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit 66425c710fc5fee9206fb82e6f0e60da31fa2733
|
|
||||||
Binary file not shown.
BIN
AxibugEmuOnline.Client/Assets/Plugins/SevenZipSharp.dll
Normal file
BIN
AxibugEmuOnline.Client/Assets/Plugins/SevenZipSharp.dll
Normal file
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 0f9e31e301641e94eb97c78b5c04d45b
|
guid: cda51a5b513e24a4db500829511ef182
|
||||||
PluginImporter:
|
PluginImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@ -1,7 +1,6 @@
|
|||||||
using AxibugEmuOnline.Client.Manager;
|
using AxibugEmuOnline.Client.Manager;
|
||||||
using AxibugEmuOnline.Client.Network;
|
using AxibugEmuOnline.Client.Network;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using static AxibugEmuOnline.Client.Manager.LogManager;
|
using static AxibugEmuOnline.Client.Manager.LogManager;
|
||||||
|
|
||||||
@ -20,13 +19,8 @@ namespace AxibugEmuOnline.Client.ClientCore
|
|||||||
public static UserDataManager user;
|
public static UserDataManager user;
|
||||||
public static AppNetGame netgame;
|
public static AppNetGame netgame;
|
||||||
public static AppEmu emu;
|
public static AppEmu emu;
|
||||||
public static RomLib romLib;
|
|
||||||
public static HttpAPI httpAPI;
|
|
||||||
|
|
||||||
private static CoroutineRunner coRunner;
|
public static void Init()
|
||||||
|
|
||||||
[RuntimeInitializeOnLoadMethod]
|
|
||||||
static void Init()
|
|
||||||
{
|
{
|
||||||
log = new LogManager();
|
log = new LogManager();
|
||||||
LogManager.OnLog += OnNoSugarNetLog;
|
LogManager.OnLog += OnNoSugarNetLog;
|
||||||
@ -36,22 +30,6 @@ namespace AxibugEmuOnline.Client.ClientCore
|
|||||||
user = new UserDataManager();
|
user = new UserDataManager();
|
||||||
emu = new AppEmu();
|
emu = new AppEmu();
|
||||||
netgame = new AppNetGame();
|
netgame = new AppNetGame();
|
||||||
romLib = new RomLib();
|
|
||||||
httpAPI = new HttpAPI();
|
|
||||||
|
|
||||||
var go = new GameObject("[AppAxibugEmuOnline]");
|
|
||||||
GameObject.DontDestroyOnLoad(go);
|
|
||||||
coRunner = go.AddComponent<CoroutineRunner>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Coroutine StartCoroutine(IEnumerator itor)
|
|
||||||
{
|
|
||||||
return coRunner.StartCoroutine(itor);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void StopCoroutine(Coroutine cor)
|
|
||||||
{
|
|
||||||
coRunner.StopCoroutine(cor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Connect(string IP, int port)
|
public static bool Connect(string IP, int port)
|
||||||
@ -65,7 +43,7 @@ namespace AxibugEmuOnline.Client.ClientCore
|
|||||||
}
|
}
|
||||||
static void OnNoSugarNetLog(int LogLevel, string msg)
|
static void OnNoSugarNetLog(int LogLevel, string msg)
|
||||||
{
|
{
|
||||||
Debug.Log("[AxibugEmuOnline]:" + msg);
|
Debug.Log("[AxibugEmuOnline]:"+msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,8 +0,0 @@
|
|||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
|
||||||
{
|
|
||||||
public class CoroutineRunner : MonoBehaviour
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 26e0101eb56737b4f97fcaa3bd319d43
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,79 +0,0 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Networking;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
|
||||||
{
|
|
||||||
public class HttpAPI
|
|
||||||
{
|
|
||||||
public string WebSite = "http://emu.axibug.com/api";
|
|
||||||
public string DownSite = "http://emu.axibug.com";
|
|
||||||
|
|
||||||
public void GetNesRomList(Action<Resp_GameList> callback, int page, int pageSize = 10)
|
|
||||||
{
|
|
||||||
AppAxibugEmuOnline.StartCoroutine(GetNesRomListFlow(page, pageSize, callback));
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator GetNesRomListFlow(int page, int pageSize, Action<Resp_GameList> callback)
|
|
||||||
{
|
|
||||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSite}/NesRomList?Page={page}&PageSize={pageSize}");
|
|
||||||
yield return request.SendWebRequest();
|
|
||||||
|
|
||||||
if (request.result != UnityWebRequest.Result.Success)
|
|
||||||
{
|
|
||||||
callback.Invoke(null);
|
|
||||||
yield break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
|
||||||
callback.Invoke(resp);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum GameType : byte
|
|
||||||
{
|
|
||||||
NONE = 0,
|
|
||||||
ACT,
|
|
||||||
ARPG,
|
|
||||||
AVG,
|
|
||||||
ETC,
|
|
||||||
FTG,
|
|
||||||
PUZ,
|
|
||||||
RAC,
|
|
||||||
RPG,
|
|
||||||
SLG,
|
|
||||||
SPG,
|
|
||||||
SRPG,
|
|
||||||
STG,
|
|
||||||
TAB,
|
|
||||||
/// <summary>
|
|
||||||
/// 合卡
|
|
||||||
/// </summary>
|
|
||||||
ALLINONE,
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class Resp_GameList
|
|
||||||
{
|
|
||||||
public int page;
|
|
||||||
public int maxPage;
|
|
||||||
public int resultAllCount;
|
|
||||||
public List<Resp_RomInfo> gameList;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable]
|
|
||||||
public class Resp_RomInfo
|
|
||||||
{
|
|
||||||
public int id;
|
|
||||||
public string romName;
|
|
||||||
public string gType;
|
|
||||||
public string desc;
|
|
||||||
public string url;
|
|
||||||
public string imgUrl;
|
|
||||||
public string hash;
|
|
||||||
public int stars;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 81bb136dc2c85304db4715953f751aa6
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 006d5604a1d73de4e8d057974313dbaf
|
|
||||||
folderAsset: yes
|
|
||||||
DefaultImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
|
||||||
{
|
|
||||||
public enum EnumPlatform
|
|
||||||
{
|
|
||||||
NES
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 355fa00c125158f4ba90003b0fd5d788
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,124 +0,0 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using UnityEngine;
|
|
||||||
using UnityEngine.Networking;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
|
||||||
{
|
|
||||||
public class RomFile
|
|
||||||
{
|
|
||||||
private HttpAPI.Resp_RomInfo webData;
|
|
||||||
private bool hasLocalFile;
|
|
||||||
private string fileName;
|
|
||||||
private EnumPlatform platform;
|
|
||||||
|
|
||||||
public string LocalFilePath => $"{Application.persistentDataPath}/RemoteRoms/{platform}/{fileName}";
|
|
||||||
public bool FileReady => hasLocalFile;
|
|
||||||
public int ID => webData != null ? webData.id : -1;
|
|
||||||
public bool IsDownloading { get; private set; }
|
|
||||||
public string Alias => webData.romName;
|
|
||||||
public string FileName => fileName;
|
|
||||||
|
|
||||||
public event Action OnDownloadOver;
|
|
||||||
|
|
||||||
public RomFile(EnumPlatform platform)
|
|
||||||
{
|
|
||||||
this.platform = platform;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BeginDownload()
|
|
||||||
{
|
|
||||||
if (FileReady) return;
|
|
||||||
if (IsDownloading) return;
|
|
||||||
|
|
||||||
IsDownloading = true;
|
|
||||||
AppAxibugEmuOnline.StartCoroutine(DownloadRemoteRom((bytes) =>
|
|
||||||
{
|
|
||||||
IsDownloading = false;
|
|
||||||
|
|
||||||
if (bytes != null)
|
|
||||||
{
|
|
||||||
var directPath = Path.GetDirectoryName(LocalFilePath);
|
|
||||||
Directory.CreateDirectory(directPath);
|
|
||||||
|
|
||||||
File.WriteAllBytes(LocalFilePath, bytes);
|
|
||||||
hasLocalFile = true;
|
|
||||||
}
|
|
||||||
OnDownloadOver?.Invoke();
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] GetRomFileData()
|
|
||||||
{
|
|
||||||
if (webData == null) throw new Exception("Not Valid Rom");
|
|
||||||
if (!FileReady) throw new Exception("Rom File Not Downloaded");
|
|
||||||
|
|
||||||
var bytes = File.ReadAllBytes(LocalFilePath);
|
|
||||||
if (Path.GetExtension(LocalFilePath).ToLower() == ".zip")
|
|
||||||
{
|
|
||||||
var zip = new ZipInputStream(new MemoryStream(bytes));
|
|
||||||
while (zip.GetNextEntry() is ZipEntry entry)
|
|
||||||
{
|
|
||||||
if (!entry.Name.ToLower().EndsWith(".nes")) continue;
|
|
||||||
|
|
||||||
var buffer = new byte[1024];
|
|
||||||
MemoryStream output = new MemoryStream();
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
var size = zip.Read(buffer, 0, buffer.Length);
|
|
||||||
if (size == 0) break;
|
|
||||||
else output.Write(buffer, 0, size);
|
|
||||||
}
|
|
||||||
output.Flush();
|
|
||||||
return output.ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception("Not Valid Rom Data");
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerator DownloadRemoteRom(Action<byte[]> callback)
|
|
||||||
{
|
|
||||||
UnityWebRequest uwr = UnityWebRequest.Get($"{AppAxibugEmuOnline.httpAPI.DownSite}/{webData.url}");
|
|
||||||
yield return uwr.SendWebRequest();
|
|
||||||
|
|
||||||
if (uwr.result != UnityWebRequest.Result.Success)
|
|
||||||
{
|
|
||||||
callback(null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
callback(uwr.downloadHandler.data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SetWebData(HttpAPI.Resp_RomInfo resp_RomInfo)
|
|
||||||
{
|
|
||||||
webData = resp_RomInfo;
|
|
||||||
fileName = Path.GetFileName(webData.url);
|
|
||||||
fileName = System.Net.WebUtility.UrlDecode(fileName);
|
|
||||||
|
|
||||||
if (File.Exists(LocalFilePath))
|
|
||||||
{
|
|
||||||
var fileBytes = File.ReadAllBytes(LocalFilePath);
|
|
||||||
var localHash = RomLib.CalcHash(fileBytes);
|
|
||||||
|
|
||||||
hasLocalFile = localHash == webData.hash;
|
|
||||||
if (!hasLocalFile)
|
|
||||||
File.Delete(LocalFilePath);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hasLocalFile = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 3a876afb939308548a7b4bdc53a3f6df
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,64 +0,0 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
|
||||||
{
|
|
||||||
public class RomLib
|
|
||||||
{
|
|
||||||
private Dictionary<int, RomFile> nesRomFileIdMapper = new Dictionary<int, RomFile>();
|
|
||||||
private Dictionary<string, RomFile> nesRomFileNameMapper = new Dictionary<string, RomFile>();
|
|
||||||
|
|
||||||
public RomFile GetNesRomFile(string romFileName)
|
|
||||||
{
|
|
||||||
nesRomFileNameMapper.TryGetValue(romFileName, out RomFile romFile);
|
|
||||||
return romFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void GetNesRomFile(int page, int pageSize, Action<List<RomFile>> callback)
|
|
||||||
{
|
|
||||||
AppAxibugEmuOnline.httpAPI.GetNesRomList((romList) =>
|
|
||||||
{
|
|
||||||
if (romList == null)
|
|
||||||
{
|
|
||||||
callback.Invoke(null);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
List<RomFile> result = new List<RomFile>();
|
|
||||||
for (int i = 0; i < romList.gameList.Count; i++)
|
|
||||||
{
|
|
||||||
var webData = romList.gameList[i];
|
|
||||||
|
|
||||||
nesRomFileIdMapper.TryGetValue(webData.id, out var targetRomFile);
|
|
||||||
if (targetRomFile == null)
|
|
||||||
{
|
|
||||||
targetRomFile = new RomFile(EnumPlatform.NES);
|
|
||||||
targetRomFile.SetWebData(webData);
|
|
||||||
nesRomFileIdMapper[webData.id] = targetRomFile;
|
|
||||||
|
|
||||||
nesRomFileNameMapper[targetRomFile.FileName] = targetRomFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.Add(targetRomFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
callback(result);
|
|
||||||
}
|
|
||||||
}, page, pageSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string CalcHash(byte[] data)
|
|
||||||
{
|
|
||||||
return string.Empty; //todo : 等待远程仓库敲定hash算法
|
|
||||||
//var hashBytes = MD5.Create().ComputeHash(data);
|
|
||||||
//StringBuilder sb = new StringBuilder();
|
|
||||||
//foreach (byte b in hashBytes)
|
|
||||||
//{
|
|
||||||
// sb.Append(b.ToString("x2"));
|
|
||||||
//}
|
|
||||||
|
|
||||||
//return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 8b1860dd3aacece40a93ae8273fc71b1
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -26,10 +26,8 @@ namespace AxibugEmuOnline.Client
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var romFile = AppAxibugEmuOnline.romLib.GetNesRomFile(fname);
|
var stream = File.Open($"{RomDirectoryPath}/{fname}", FileMode.Open);
|
||||||
var bytes = romFile.GetRomFileData();
|
return stream;
|
||||||
Debug.Log($"Open {romFile.Alias}");
|
|
||||||
return new MemoryStream(bytes);
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
using AxibugEmuOnline.Client.ClientCore;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using VirtualNes.Core;
|
using VirtualNes.Core;
|
||||||
@ -16,14 +15,22 @@ namespace AxibugEmuOnline.Client
|
|||||||
public VideoProvider VideoProvider;
|
public VideoProvider VideoProvider;
|
||||||
public AudioProvider AudioProvider;
|
public AudioProvider AudioProvider;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
public string RomName;
|
||||||
|
#endif
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
Application.targetFrameRate = 60;
|
Application.targetFrameRate = 60;
|
||||||
VideoProvider.NesEmu = this;
|
VideoProvider.NesEmu = this;
|
||||||
AudioProvider.NesEmu = this;
|
AudioProvider.NesEmu = this;
|
||||||
|
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
StartGame(RomName);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartGame(RomFile rom)
|
public void StartGame(string romName)
|
||||||
{
|
{
|
||||||
StopGame();
|
StopGame();
|
||||||
|
|
||||||
@ -32,7 +39,7 @@ namespace AxibugEmuOnline.Client
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
NesCore = new NES(rom.FileName);
|
NesCore = new NES(romName);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -85,38 +92,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
UnityEditor.EditorUtility.SetDirty(db);
|
UnityEditor.EditorUtility.SetDirty(db);
|
||||||
UnityEditor.AssetDatabase.SaveAssets();
|
UnityEditor.AssetDatabase.SaveAssets();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ContextMenu("LoadRom")]
|
|
||||||
public void LoadRom()
|
|
||||||
{
|
|
||||||
AppAxibugEmuOnline.romLib.GetNesRomFile(0, 10, (romFiles) =>
|
|
||||||
{
|
|
||||||
if (romFiles == null) return;
|
|
||||||
|
|
||||||
var file = romFiles[2];
|
|
||||||
|
|
||||||
if (file.FileReady)
|
|
||||||
{
|
|
||||||
StartGame(file);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
file.BeginDownload();
|
|
||||||
Action action = null;
|
|
||||||
action = () =>
|
|
||||||
{
|
|
||||||
file.OnDownloadOver -= action;
|
|
||||||
if (!file.FileReady)
|
|
||||||
{
|
|
||||||
throw new Exception("Download Failed");
|
|
||||||
}
|
|
||||||
StartGame(file);
|
|
||||||
};
|
|
||||||
file.OnDownloadOver += action;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
|
using VirtualNes.Core;
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
namespace AxibugEmuOnline.Client
|
||||||
{
|
{
|
||||||
@ -30,7 +31,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
// »ñÈ¡Êý×éµÄÖ¸Õë
|
// »ñÈ¡Êý×éµÄÖ¸Õë
|
||||||
wrapTexBufferPointer = handle.AddrOfPinnedObject();
|
wrapTexBufferPointer = handle.AddrOfPinnedObject();
|
||||||
|
|
||||||
Image.texture = wrapTex;
|
|
||||||
Image.material.SetTexture("_MainTex", wrapTex);
|
Image.material.SetTexture("_MainTex", wrapTex);
|
||||||
|
|
||||||
TexBufferSize = wrapTexBuffer.Length * 4;
|
TexBufferSize = wrapTexBuffer.Length * 4;
|
||||||
@ -43,9 +43,9 @@ namespace AxibugEmuOnline.Client
|
|||||||
uint colorRaw = palRaw[i];
|
uint colorRaw = palRaw[i];
|
||||||
var argbColor = BitConverter.GetBytes(colorRaw);
|
var argbColor = BitConverter.GetBytes(colorRaw);
|
||||||
Color temp = Color.white;
|
Color temp = Color.white;
|
||||||
temp.r = argbColor[2] / 255f;
|
temp.r = argbColor[2]/255f;
|
||||||
temp.g = argbColor[1] / 255f;
|
temp.g = argbColor[1]/255f;
|
||||||
temp.b = argbColor[0] / 255f;
|
temp.b = argbColor[0]/255f;
|
||||||
temp.a = 1;
|
temp.a = 1;
|
||||||
pPal.SetPixel(i, 0, temp);
|
pPal.SetPixel(i, 0, temp);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -105,7 +105,7 @@
|
|||||||
float start= 8.0/272.0;
|
float start= 8.0/272.0;
|
||||||
float end = (272.0-8.0)/272.0;
|
float end = (272.0-8.0)/272.0;
|
||||||
|
|
||||||
mapUV.x = lerp(start,end, mapUV.x);
|
//mapUV.x = lerp(start,end, mapUV.x);
|
||||||
|
|
||||||
half4 color = tex2D(_MainTex,mapUV);
|
half4 color = tex2D(_MainTex,mapUV);
|
||||||
|
|
||||||
|
|||||||
@ -1,401 +1,28 @@
|
|||||||
using System;
|
using System;
|
||||||
using static VirtualNes.Core.APU_INTERNAL;
|
|
||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public class APU_FME7 : APU_INTERFACE
|
public class APU_FME7 : APU_INTERFACE
|
||||||
{
|
{
|
||||||
// Envelope tables
|
|
||||||
byte[] envelope_pulse0 = {
|
|
||||||
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
|
|
||||||
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
|
|
||||||
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
|
|
||||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
|
|
||||||
};
|
|
||||||
byte[] envelope_pulse1 = {
|
|
||||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
||||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
|
||||||
0x00
|
|
||||||
};
|
|
||||||
byte[] envelope_pulse2 = {
|
|
||||||
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
|
|
||||||
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
|
|
||||||
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
|
|
||||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x1F
|
|
||||||
};
|
|
||||||
byte[] envelope_pulse3 = {
|
|
||||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
||||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
|
||||||
0x1F
|
|
||||||
};
|
|
||||||
sbyte[] envstep_pulse = {
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 0
|
|
||||||
};
|
|
||||||
|
|
||||||
byte[] envelope_sawtooth0 = {
|
|
||||||
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
|
|
||||||
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
|
|
||||||
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
|
|
||||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
|
|
||||||
};
|
|
||||||
byte[] envelope_sawtooth1 = {
|
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
||||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
|
||||||
};
|
|
||||||
sbyte[] envstep_sawtooth = {
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, -15
|
|
||||||
};
|
|
||||||
|
|
||||||
byte[] envelope_triangle0 = {
|
|
||||||
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
|
|
||||||
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
|
|
||||||
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
|
|
||||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
|
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
||||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
|
|
||||||
};
|
|
||||||
byte[] envelope_triangle1 = {
|
|
||||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
|
||||||
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
|
|
||||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
|
||||||
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
|
|
||||||
0x1F, 0x1E, 0x1D, 0x1C, 0x1B, 0x1A, 0x19, 0x18,
|
|
||||||
0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 0x10,
|
|
||||||
0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,
|
|
||||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
|
|
||||||
};
|
|
||||||
sbyte[] envstep_triangle = {
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, -31
|
|
||||||
};
|
|
||||||
|
|
||||||
byte[][] envelope_table;
|
|
||||||
sbyte[][] envstep_table;
|
|
||||||
|
|
||||||
ENVELOPE envelope = new ENVELOPE();
|
|
||||||
NOISE noise = new NOISE();
|
|
||||||
CHANNEL[] op = new CHANNEL[3] { new CHANNEL(), new CHANNEL(), new CHANNEL() };
|
|
||||||
byte address;
|
|
||||||
int[] vol_table = new int[0x20];
|
|
||||||
int cycle_rate;
|
|
||||||
|
|
||||||
float cpu_clock;
|
|
||||||
|
|
||||||
public APU_FME7()
|
|
||||||
{
|
|
||||||
envelope_table = new byte[16][]
|
|
||||||
{
|
|
||||||
envelope_pulse0, envelope_pulse0, envelope_pulse0, envelope_pulse0,
|
|
||||||
envelope_pulse1, envelope_pulse1, envelope_pulse1, envelope_pulse1,
|
|
||||||
envelope_sawtooth0, envelope_pulse0, envelope_triangle0, envelope_pulse2,
|
|
||||||
envelope_sawtooth1, envelope_pulse3, envelope_triangle1, envelope_pulse1
|
|
||||||
};
|
|
||||||
|
|
||||||
envstep_table = new sbyte[16][]
|
|
||||||
{
|
|
||||||
envstep_pulse, envstep_pulse, envstep_pulse, envstep_pulse,
|
|
||||||
envstep_pulse, envstep_pulse, envstep_pulse, envstep_pulse,
|
|
||||||
envstep_sawtooth, envstep_pulse, envstep_triangle, envstep_pulse,
|
|
||||||
envstep_sawtooth, envstep_pulse, envstep_triangle, envstep_pulse
|
|
||||||
};
|
|
||||||
|
|
||||||
Reset(APU_CLOCK, 22050);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Reset(float fClock, int nRate)
|
public override void Reset(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
int i;
|
//todo : 实现
|
||||||
|
|
||||||
envelope.ZeroMemory();
|
|
||||||
noise.ZeroMemory();
|
|
||||||
|
|
||||||
foreach (var item in op)
|
|
||||||
{
|
|
||||||
item.ZeroMemory();
|
|
||||||
}
|
|
||||||
|
|
||||||
envelope.envtbl = envelope_table[0];
|
|
||||||
envelope.envstep = envstep_table[0];
|
|
||||||
|
|
||||||
noise.noiserange = 1;
|
|
||||||
noise.noiseout = 0xFF;
|
|
||||||
|
|
||||||
address = 0;
|
|
||||||
|
|
||||||
// Volume to voltage
|
|
||||||
double @out = 0x1FFF;
|
|
||||||
for (i = 31; i > 1; i--)
|
|
||||||
{
|
|
||||||
vol_table[i] = (int)(@out + 0.5);
|
|
||||||
@out /= 1.188502227; /* = 10 ^ (1.5/20) = 1.5dB */
|
|
||||||
}
|
|
||||||
vol_table[1] = 0;
|
|
||||||
vol_table[0] = 0;
|
|
||||||
|
|
||||||
Setup(fClock, nRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(float fClock, int nRate)
|
public override void Setup(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
cpu_clock = fClock;
|
//todo : 实现
|
||||||
cycle_rate = (int)((fClock / 16.0f) * (1 << 16) / nRate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(ushort addr, byte data)
|
public override void Write(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
if (addr == 0xC000)
|
//todo : 实现
|
||||||
{
|
|
||||||
address = data;
|
|
||||||
}
|
|
||||||
else if (addr == 0xE000)
|
|
||||||
{
|
|
||||||
byte chaddr = address;
|
|
||||||
switch (chaddr)
|
|
||||||
{
|
|
||||||
case 0x00:
|
|
||||||
case 0x01:
|
|
||||||
case 0x02:
|
|
||||||
case 0x03:
|
|
||||||
case 0x04:
|
|
||||||
case 0x05:
|
|
||||||
{
|
|
||||||
CHANNEL ch = op[chaddr >> 1];
|
|
||||||
ch.reg[chaddr & 0x01] = data;
|
|
||||||
ch.freq = INT2FIX(((ch.reg[1] & 0x0F) << 8) + ch.reg[0] + 1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
noise.freq = INT2FIX((data & 0x1F) + 1);
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
{
|
|
||||||
for (byte i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
op[i].enable = (byte)(data & (1 << i));
|
|
||||||
op[i].noise_on = (byte)(data & (8 << i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x08:
|
|
||||||
case 0x09:
|
|
||||||
case 0x0A:
|
|
||||||
{
|
|
||||||
CHANNEL ch = op[chaddr & 3];
|
|
||||||
ch.reg[2] = data;
|
|
||||||
ch.env_on = (byte)(data & 0x10);
|
|
||||||
ch.volume = (byte)((data & 0x0F) * 2);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x0B:
|
|
||||||
case 0x0C:
|
|
||||||
envelope.reg[chaddr - 0x0B] = data;
|
|
||||||
envelope.freq = INT2FIX(((envelope.reg[1] & 0x0F) << 8) + envelope.reg[0] + 1);
|
|
||||||
break;
|
|
||||||
case 0x0D:
|
|
||||||
envelope.envtbl = envelope_table[data & 0x0F];
|
|
||||||
envelope.envstep = envstep_table[data & 0x0F];
|
|
||||||
envelope.envadr = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Process(int channel)
|
public override int Process(int channel)
|
||||||
{
|
{
|
||||||
if (channel < 3)
|
//todo : 实现
|
||||||
{
|
|
||||||
return ChannelRender(op[channel]);
|
|
||||||
}
|
|
||||||
else if (channel == 3)
|
|
||||||
{
|
|
||||||
// 必ずch3を1回呼んでからch0-2を呼ぶ事
|
|
||||||
EnvelopeRender();
|
|
||||||
NoiseRender();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetFreq(int channel)
|
|
||||||
{
|
|
||||||
if (channel < 3)
|
|
||||||
{
|
|
||||||
CHANNEL ch = op[channel];
|
|
||||||
|
|
||||||
if (ch.enable != 0 || ch.freq == 0)
|
|
||||||
return 0;
|
|
||||||
if (ch.env_on != 0)
|
|
||||||
{
|
|
||||||
if (envelope.volume == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ch.volume == 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int)(256.0f * cpu_clock / (FIX2INT(ch.freq) * 16.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EnvelopeRender()
|
|
||||||
{
|
|
||||||
if (envelope.freq == 0)
|
|
||||||
return;
|
|
||||||
envelope.phaseacc -= cycle_rate;
|
|
||||||
if (envelope.phaseacc >= 0)
|
|
||||||
return;
|
|
||||||
while (envelope.phaseacc < 0)
|
|
||||||
{
|
|
||||||
envelope.phaseacc += envelope.freq;
|
|
||||||
envelope.envadr += envelope.envstep[envelope.envadr];
|
|
||||||
}
|
|
||||||
envelope.volume = envelope.envtbl[envelope.envadr];
|
|
||||||
}
|
|
||||||
void NoiseRender()
|
|
||||||
{
|
|
||||||
if (noise.freq == 0)
|
|
||||||
return;
|
|
||||||
noise.phaseacc -= cycle_rate;
|
|
||||||
if (noise.phaseacc >= 0)
|
|
||||||
return;
|
|
||||||
while (noise.phaseacc < 0)
|
|
||||||
{
|
|
||||||
noise.phaseacc += noise.freq;
|
|
||||||
if (((noise.noiserange + 1) & 0x02) != 0)
|
|
||||||
noise.noiseout = (byte)(~noise.noiseout);
|
|
||||||
if ((noise.noiserange & 0x01) != 0)
|
|
||||||
noise.noiserange ^= 0x28000;
|
|
||||||
noise.noiserange >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int ChannelRender(CHANNEL ch)
|
|
||||||
{
|
|
||||||
int output, volume;
|
|
||||||
|
|
||||||
if (ch.enable != 0)
|
|
||||||
return 0;
|
|
||||||
if (ch.freq == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ch.phaseacc -= cycle_rate;
|
|
||||||
while (ch.phaseacc < 0)
|
|
||||||
{
|
|
||||||
ch.phaseacc += ch.freq;
|
|
||||||
ch.adder++;
|
|
||||||
}
|
|
||||||
|
|
||||||
output = volume = 0;
|
|
||||||
volume = ch.env_on != 0 ? vol_table[envelope.volume] : vol_table[ch.volume + 1];
|
|
||||||
|
|
||||||
if ((ch.adder & 0x01) != 0)
|
|
||||||
{
|
|
||||||
output += volume;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
output -= volume;
|
|
||||||
}
|
|
||||||
if (ch.noise_on == 0)
|
|
||||||
{
|
|
||||||
if (noise.noiseout != 0)
|
|
||||||
output += volume;
|
|
||||||
else
|
|
||||||
output -= volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
ch.output_vol = output;
|
|
||||||
|
|
||||||
return ch.output_vol;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ENVELOPE
|
|
||||||
{
|
|
||||||
public byte[] reg = new byte[3];
|
|
||||||
public byte volume;
|
|
||||||
|
|
||||||
public int freq;
|
|
||||||
public int phaseacc;
|
|
||||||
public int envadr;
|
|
||||||
|
|
||||||
public byte[] envtbl;
|
|
||||||
public sbyte[] envstep;
|
|
||||||
|
|
||||||
public void ZeroMemory()
|
|
||||||
{
|
|
||||||
Array.Clear(reg, 0, 3);
|
|
||||||
volume = 0;
|
|
||||||
freq = 0;
|
|
||||||
phaseacc = 0;
|
|
||||||
envadr = 0;
|
|
||||||
envtbl = null;
|
|
||||||
envstep = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class NOISE
|
|
||||||
{
|
|
||||||
public int freq;
|
|
||||||
public int phaseacc;
|
|
||||||
public int noiserange;
|
|
||||||
public byte noiseout;
|
|
||||||
|
|
||||||
public void ZeroMemory()
|
|
||||||
{
|
|
||||||
freq = 0; phaseacc = 0; noiserange = 0; noiseout = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class CHANNEL
|
|
||||||
{
|
|
||||||
public byte[] reg = new byte[3];
|
|
||||||
public byte enable;
|
|
||||||
public byte env_on;
|
|
||||||
public byte noise_on;
|
|
||||||
public byte adder;
|
|
||||||
public byte volume;
|
|
||||||
|
|
||||||
public int freq;
|
|
||||||
public int phaseacc;
|
|
||||||
|
|
||||||
public int output_vol;
|
|
||||||
|
|
||||||
public void ZeroMemory()
|
|
||||||
{
|
|
||||||
Array.Clear(reg, 0, reg.Length);
|
|
||||||
enable = 0;
|
|
||||||
env_on = 0;
|
|
||||||
noise_on = 0;
|
|
||||||
adder = 0;
|
|
||||||
volume = 0; freq = 0;
|
|
||||||
phaseacc = 0;
|
|
||||||
output_vol = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -470,6 +470,49 @@ namespace VirtualNes.Core
|
|||||||
// Start
|
// Start
|
||||||
if (state.HasButton(no, EnumButtonType.START)) bit |= 1 << 3;
|
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);
|
return (byte)(bit & 0xFF);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user