master #71
@ -1,4 +1,4 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
@ -15,6 +15,8 @@ namespace AxibugEmuOnline.Client
|
||||
void SetupScheme();
|
||||
void StartGame(RomFile romFile);
|
||||
void DoReset();
|
||||
IControllerSetuper GetControllerSetuper();
|
||||
|
||||
EnumPlatform Platform { get; }
|
||||
uint Frame { get; }
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
/// </summary>
|
||||
private IEmuCore m_emuCore;
|
||||
|
||||
private VirtualNes.Core.IControllerSetuper m_controllerSetuper;
|
||||
private IControllerSetuper m_controllerSetuper;
|
||||
|
||||
/// <summary>
|
||||
/// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
|
||||
@ -63,7 +63,7 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
|
||||
m_emuCore.SetupScheme();
|
||||
|
||||
m_controllerSetuper = Supporter.GetControllerSetuper();
|
||||
m_controllerSetuper = m_emuCore.GetControllerSetuper();
|
||||
|
||||
//自动分配0号手柄到0号手柄位
|
||||
m_controllerSetuper.SetConnect(con0ToSlot: 0);
|
||||
|
@ -0,0 +1,39 @@
|
||||
/// <summary>
|
||||
/// 负责管理本地控制器与具体游戏之间的槽位分配
|
||||
/// </summary>
|
||||
public interface IControllerSetuper
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置本地手柄与游戏手柄槽位的映射,这个方法是一个全量更新手柄插入设置的方法
|
||||
/// </summary>
|
||||
void SetConnect(
|
||||
uint? con0ToSlot = null,
|
||||
uint? con1ToSlot = null,
|
||||
uint? con2ToSlot = null,
|
||||
uint? con3ToSlot = null);
|
||||
|
||||
/// <summary>
|
||||
/// 指定手柄插槽位,获取当前槽位连接的本地手柄序号
|
||||
/// </summary>
|
||||
/// <param name="slotIndex"></param>
|
||||
/// <returns></returns>
|
||||
int? GetSlotConnectingControllerIndex(int slotIndex);
|
||||
IController GetSlotConnectingController(int slotIndex);
|
||||
|
||||
/// <summary>
|
||||
/// 获得一个空的槽位
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
uint? GetFreeSlotIndex();
|
||||
|
||||
/// <summary>
|
||||
/// 增量式的修改一个手柄和一个槽位的连接关系
|
||||
/// </summary>
|
||||
/// <param name="conIndex"></param>
|
||||
/// <param name="slotIndex"></param>
|
||||
void LetControllerConnect(int conIndex, uint slotIndex);
|
||||
}
|
||||
public interface IController
|
||||
{
|
||||
bool AnyButtonDown();
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f567cb126b157854e9f9b2c71f8cda8e
|
@ -1,4 +1,4 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using System.IO;
|
||||
@ -10,6 +10,12 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CoreSupporter : ISupporterImpl
|
||||
{
|
||||
private NesControllerMapper m_controllerMapper;
|
||||
public CoreSupporter(NesControllerMapper conMapper)
|
||||
{
|
||||
m_controllerMapper = conMapper;
|
||||
}
|
||||
|
||||
public Stream OpenRom(string fname)
|
||||
{
|
||||
try
|
||||
@ -57,7 +63,6 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
|
||||
public EmulatorConfig Config { get; private set; } = new EmulatorConfig();
|
||||
public NesControllerMapper ControllerMapper { get; private set; } = new NesControllerMapper();
|
||||
public void PrepareDirectory(string directPath)
|
||||
{
|
||||
Directory.CreateDirectory($"{App.PersistentDataPath}/{directPath}");
|
||||
@ -116,7 +121,7 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
else m_sampledState = default(ControllerState);
|
||||
|
||||
var localState = ControllerMapper.CreateState();
|
||||
var localState = m_controllerMapper.CreateState();
|
||||
var rawData = ToNet(localState);
|
||||
if (LastTestInput != rawData)
|
||||
{
|
||||
@ -127,15 +132,10 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
else
|
||||
{
|
||||
m_sampledState = ControllerMapper.CreateState();
|
||||
m_sampledState = m_controllerMapper.CreateState();
|
||||
}
|
||||
}
|
||||
|
||||
public IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return ControllerMapper;
|
||||
}
|
||||
|
||||
public ControllerState FromNet(AxiReplay.ReplayStep step)
|
||||
{
|
||||
var temp = new ServerInputSnapShot();
|
||||
|
@ -46,7 +46,7 @@ namespace AxibugEmuOnline.Client
|
||||
Controller3.ConnectSlot = con3ToSlot;
|
||||
}
|
||||
|
||||
public int? GetSlotConnectingController(int slotIndex)
|
||||
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;
|
||||
@ -55,6 +55,15 @@ namespace AxibugEmuOnline.Client
|
||||
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);
|
||||
public uint? GetFreeSlotIndex()
|
||||
{
|
||||
@ -94,7 +103,7 @@ namespace AxibugEmuOnline.Client
|
||||
/// <summary>
|
||||
/// Nes控制器
|
||||
/// </summary>
|
||||
public class Controller
|
||||
public class Controller : IController
|
||||
{
|
||||
/// <summary>
|
||||
/// 控制器编号
|
||||
|
@ -22,6 +22,12 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
/// <summary> 是否暂停 </summary>
|
||||
public bool IsPause { get; private set; }
|
||||
public NesControllerMapper ControllerMapper { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
ControllerMapper = new NesControllerMapper();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
@ -48,12 +54,11 @@ namespace AxibugEmuOnline.Client
|
||||
VideoProvider.SetDrawData(screenBuffer);
|
||||
}
|
||||
|
||||
|
||||
VideoProvider.ApplyFilterEffect();
|
||||
}
|
||||
|
||||
public EnumPlatform Platform => EnumPlatform.NES;
|
||||
|
||||
private CoreSupporter m_coreSupporter;
|
||||
/// <summary>
|
||||
/// 指定ROM开始游戏
|
||||
/// </summary>
|
||||
@ -61,7 +66,8 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
StopGame();
|
||||
|
||||
Supporter.Setup(new CoreSupporter());
|
||||
m_coreSupporter = new CoreSupporter(ControllerMapper);
|
||||
Supporter.Setup(m_coreSupporter);
|
||||
Debuger.Setup(new CoreDebuger());
|
||||
|
||||
App.nesRomLib.AddRomFile(rom);
|
||||
@ -159,8 +165,8 @@ namespace AxibugEmuOnline.Client
|
||||
//推进帧
|
||||
private bool PushEmulatorFrame()
|
||||
{
|
||||
Supporter.SampleInput(NesCore.FrameCount);
|
||||
var controlState = Supporter.GetControllerState();
|
||||
m_coreSupporter.SampleInput(NesCore.FrameCount);
|
||||
var controlState = m_coreSupporter.GetControllerState();
|
||||
|
||||
//如果未收到Input数据,核心帧不推进
|
||||
if (!controlState.valid) return false;
|
||||
@ -207,6 +213,11 @@ namespace AxibugEmuOnline.Client
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
public IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return ControllerMapper;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
|
||||
// スキャンラインカラー
|
||||
private static int m_nScanlineColor => Supporter.Config.graphics.nScanlineColor;
|
||||
private static int m_nScanlineColor => 75; //patternViewer调试器用的,参照EmulatorConfig.graphics.nScanlineColor的值
|
||||
|
||||
public static float[][] PalConvTbl = new float[8][]
|
||||
{
|
||||
|
@ -117,10 +117,10 @@ namespace AxibugEmuOnline.Client
|
||||
m_delayCreateRoom = false;
|
||||
//延迟创建房间成功后,同步本地手柄连接状态
|
||||
Dictionary<uint, uint> temp = new Dictionary<uint, uint>();
|
||||
var setuper = Supporter.GetControllerSetuper();
|
||||
var setuper = App.emu.Core.GetControllerSetuper();
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
var joyIndex = setuper.GetSlotConnectingController(i);
|
||||
var joyIndex = setuper.GetSlotConnectingControllerIndex(i);
|
||||
if (joyIndex != null) temp[(uint)i] = (uint)joyIndex.Value;
|
||||
}
|
||||
App.roomMgr.SendChangePlaySlotIdxWithJoyIdx(temp);
|
||||
|
@ -1,6 +1,7 @@
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using DG.Tweening;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@ -18,9 +19,7 @@ public class ControllerInfo : MonoBehaviour
|
||||
Image m_indexIcon;
|
||||
[SerializeField]
|
||||
Text m_playerName;
|
||||
|
||||
int m_localJoyIndex;
|
||||
bool m_isLocal;
|
||||
private bool m_islocal;
|
||||
|
||||
public int SlotIndex
|
||||
{
|
||||
@ -60,6 +59,18 @@ public class ControllerInfo : MonoBehaviour
|
||||
Eventer.Instance.UnregisterEvent(EEvent.OnControllerConnectChanged, OnControlConnectChanged);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (m_islocal)
|
||||
{
|
||||
var controller = App.emu.Core.GetControllerSetuper().GetSlotConnectingController(m_slotIndex);
|
||||
if (controller == null) return;
|
||||
if (!controller.AnyButtonDown()) return;
|
||||
|
||||
m_indexIcon.rectTransform.DOShakePosition(0.1f);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMineRoomCreated() => UpdateConnectInfo();
|
||||
private void OnJoinRoom() => UpdateConnectInfo();
|
||||
private void OnLeaveRoom() => UpdateConnectInfo();
|
||||
@ -79,14 +90,15 @@ public class ControllerInfo : MonoBehaviour
|
||||
}
|
||||
else
|
||||
{
|
||||
var connecter = Supporter.GetControllerSetuper();
|
||||
if (connecter == null)
|
||||
if (App.emu.Core.IsNull())
|
||||
{
|
||||
SetDisconnect();
|
||||
return;
|
||||
}
|
||||
|
||||
var localControlIndex = connecter.GetSlotConnectingController(SlotIndex);
|
||||
}
|
||||
var connecter = App.emu.Core.GetControllerSetuper();
|
||||
|
||||
var localControlIndex = connecter.GetSlotConnectingControllerIndex(SlotIndex);
|
||||
if (localControlIndex == null)
|
||||
SetDisconnect();
|
||||
else
|
||||
@ -101,8 +113,7 @@ public class ControllerInfo : MonoBehaviour
|
||||
|
||||
private void UpdateStateView(bool isLocal, string playerName, int slotIndex)
|
||||
{
|
||||
m_localJoyIndex = slotIndex;
|
||||
m_isLocal = isLocal;
|
||||
m_islocal = isLocal;
|
||||
|
||||
m_connectInfoNode.SetActiveEx(true);
|
||||
m_playerName.text = playerName;
|
||||
@ -110,11 +121,9 @@ public class ControllerInfo : MonoBehaviour
|
||||
|
||||
private void SetDisconnect()
|
||||
{
|
||||
m_localJoyIndex = -1;
|
||||
m_isLocal = false;
|
||||
|
||||
m_connectInfoNode.SetActiveEx(false);
|
||||
m_playerName.text = null;
|
||||
m_islocal = false;
|
||||
}
|
||||
|
||||
private void UpdateIndexIcon()
|
||||
|
@ -1,4 +1,5 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Manager;
|
||||
using System;
|
||||
@ -31,7 +32,8 @@ public class ControllerInfoPanel : MonoBehaviour
|
||||
}
|
||||
else //不在房间中,直接设置
|
||||
{
|
||||
var setuper = Supporter.GetControllerSetuper();
|
||||
if (App.emu.Core.IsNull()) return;
|
||||
var setuper = App.emu.Core.GetControllerSetuper();
|
||||
if (setuper == null) return;
|
||||
|
||||
var freeSlotIndex = setuper.GetFreeSlotIndex();
|
||||
|
@ -73,7 +73,7 @@ namespace VirtualNes.Core
|
||||
|
||||
public void Process(ISoundDataBuffer lpBuffer, uint dwSize)
|
||||
{
|
||||
int nBits = Supporter.Config.sound.nBits;
|
||||
int nBits = Supporter.S.Config.sound.nBits;
|
||||
uint dwLength = (uint)(dwSize / (nBits / 8));
|
||||
int output;
|
||||
QUEUEDATA q = new QUEUEDATA();
|
||||
@ -82,11 +82,11 @@ namespace VirtualNes.Core
|
||||
var pSoundBuf = m_SoundBuffer;
|
||||
int nCcount = 0;
|
||||
|
||||
int nFilterType = Supporter.Config.sound.nFilterType;
|
||||
int nFilterType = Supporter.S.Config.sound.nFilterType;
|
||||
|
||||
if (!Supporter.Config.sound.bEnable)
|
||||
if (!Supporter.S.Config.sound.bEnable)
|
||||
{
|
||||
byte empty = (byte)(Supporter.Config.sound.nRate == 8 ? 128 : 0);
|
||||
byte empty = (byte)(Supporter.S.Config.sound.nRate == 8 ? 128 : 0);
|
||||
for (int i = 0; i < dwSize; i++)
|
||||
lpBuffer.WriteByte(empty);
|
||||
return;
|
||||
@ -108,7 +108,7 @@ namespace VirtualNes.Core
|
||||
MemoryUtility.ZEROMEMORY(vol, vol.Length);
|
||||
|
||||
var bMute = m_bMute;
|
||||
var nVolume = Supporter.Config.sound.nVolume;
|
||||
var nVolume = Supporter.S.Config.sound.nVolume;
|
||||
|
||||
int nMasterVolume = bMute[0] ? nVolume[0] : 0;
|
||||
|
||||
@ -151,7 +151,7 @@ namespace VirtualNes.Core
|
||||
vol[23] = (int)(bMute[8] ? (FME7_VOL * nVolume[11] * nMasterVolume) / (100 * 100) : 0);
|
||||
|
||||
// double cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
|
||||
double cycle_rate = (nes.nescfg.FrameCycles * 60.0 / 12.0) / Supporter.Config.sound.nRate;
|
||||
double cycle_rate = (nes.nescfg.FrameCycles * 60.0 / 12.0) / Supporter.S.Config.sound.nRate;
|
||||
|
||||
// CPUサイクル数がループしてしまった時の対策処理
|
||||
if (elapsed_time > nes.cpu.GetTotalCycles())
|
||||
@ -253,7 +253,7 @@ namespace VirtualNes.Core
|
||||
// DC成分のカット(HPF TEST)
|
||||
{
|
||||
// static double cutoff = (2.0*3.141592653579*40.0/44100.0);
|
||||
double cutoff = cutofftemp / Supporter.Config.sound.nRate;
|
||||
double cutoff = cutofftemp / Supporter.S.Config.sound.nRate;
|
||||
double @in, @out;
|
||||
|
||||
@in = output;
|
||||
@ -436,7 +436,7 @@ namespace VirtualNes.Core
|
||||
public void SoundSetup()
|
||||
{
|
||||
float fClock = nes.nescfg.CpuClock;
|
||||
int nRate = Supporter.Config.sound.nRate;
|
||||
int nRate = Supporter.S.Config.sound.nRate;
|
||||
|
||||
@internal.Setup(fClock, nRate);
|
||||
vrc6.Setup(fClock, nRate);
|
||||
@ -460,7 +460,7 @@ namespace VirtualNes.Core
|
||||
elapsed_time = 0;
|
||||
|
||||
float fClock = nes.nescfg.CpuClock;
|
||||
int nRate = Supporter.Config.sound.nRate;
|
||||
int nRate = Supporter.S.Config.sound.nRate;
|
||||
|
||||
@internal.Reset(fClock, nRate);
|
||||
vrc6.Reset(fClock, nRate);
|
||||
|
@ -1,4 +1,4 @@
|
||||
|
||||
|
||||
using System;
|
||||
|
||||
namespace VirtualNes.Core
|
||||
@ -184,15 +184,15 @@ namespace VirtualNes.Core
|
||||
|
||||
Setup(fClock, nRate);
|
||||
|
||||
// $4011反場ヽ趙仄卅中
|
||||
// $4011は初期化しない
|
||||
ushort addr;
|
||||
for (addr = 0x4000; addr <= 0x4010; addr++)
|
||||
{
|
||||
Write(addr, 0x00);
|
||||
SyncWrite(addr, 0x00);
|
||||
}
|
||||
// Write( 0x4001, 0x08 ); // Reset媆反inc乒奈玉卞卅月?
|
||||
// Write( 0x4005, 0x08 ); // Reset媆反inc乒奈玉卞卅月?
|
||||
// Write( 0x4001, 0x08 ); // Reset時はincモードになる?
|
||||
// Write( 0x4005, 0x08 ); // Reset時はincモードになる?
|
||||
Write(0x4012, 0x00);
|
||||
Write(0x4013, 0x00);
|
||||
Write(0x4015, 0x00);
|
||||
@ -200,7 +200,7 @@ namespace VirtualNes.Core
|
||||
SyncWrite(0x4013, 0x00);
|
||||
SyncWrite(0x4015, 0x00);
|
||||
|
||||
// $4017反𤩸五煋心匹場ヽ趙仄卅中(場ヽ乒奈玉互0匹丐月及毛ヽ渾仄凶末白玄互丐月鮋)
|
||||
// $4017は書き込みで初期化しない(初期モードが0であるのを期待したソフトがある為)
|
||||
FrameIRQ = 0xC0;
|
||||
FrameCycle = 0;
|
||||
FrameIRQoccur = 0;
|
||||
@ -301,7 +301,7 @@ namespace VirtualNes.Core
|
||||
case 0x4017:
|
||||
break;
|
||||
|
||||
// VirtuaNES嘐衄禾奈玄
|
||||
// VirtuaNES固有ポート
|
||||
case 0x4018:
|
||||
UpdateRectangle(ch0, data);
|
||||
UpdateRectangle(ch1, data);
|
||||
@ -635,7 +635,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
}
|
||||
|
||||
// 奶件民平堪中皿民用奶朮市永玄(TEST)
|
||||
// インチキ臭いプチノイズカット(TEST)
|
||||
ch4.dpcm_output_real = ((ch4.reg[1] & 0x01) + ch4.dpcm_value * 2) - 0x40;
|
||||
if (Math.Abs(ch4.dpcm_output_real - ch4.dpcm_output_fake) <= 8)
|
||||
{
|
||||
@ -712,7 +712,7 @@ namespace VirtualNes.Core
|
||||
private int RenderTriangle()
|
||||
{
|
||||
int vol;
|
||||
if (Supporter.Config.sound.bDisableVolumeEffect)
|
||||
if (Supporter.S.Config.sound.bDisableVolumeEffect)
|
||||
{
|
||||
vol = 256;
|
||||
}
|
||||
@ -731,7 +731,7 @@ namespace VirtualNes.Core
|
||||
return ch2.nowvolume * vol / 256;
|
||||
}
|
||||
|
||||
if (!(Supporter.Config.sound.bChangeTone && ChannelTone[2, 0] != 0))
|
||||
if (!(Supporter.S.Config.sound.bChangeTone && ChannelTone[2, 0] != 0))
|
||||
{
|
||||
ch2.phaseacc -= cycle_rate;
|
||||
if (ch2.phaseacc >= 0)
|
||||
@ -756,7 +756,7 @@ namespace VirtualNes.Core
|
||||
return ch2.nowvolume * vol / 256;
|
||||
}
|
||||
|
||||
// 樓笭ⅸ歙
|
||||
// 加重平均
|
||||
int num_times, total;
|
||||
num_times = total = 0;
|
||||
while (ch2.phaseacc < 0)
|
||||
@ -799,7 +799,7 @@ namespace VirtualNes.Core
|
||||
return ch2.nowvolume * vol / 256;
|
||||
}
|
||||
|
||||
// 樓笭ⅸ歙
|
||||
// 加重平均
|
||||
int num_times, total;
|
||||
num_times = total = 0;
|
||||
while (ch2.phaseacc < 0)
|
||||
@ -832,9 +832,9 @@ namespace VirtualNes.Core
|
||||
}
|
||||
int volume = ch.nowvolume;
|
||||
|
||||
if (!(Supporter.Config.sound.bChangeTone && (ChannelTone[(ch.complement == 0) ? 0 : 1, ch.reg[0] >> 6]) != 0))
|
||||
if (!(Supporter.S.Config.sound.bChangeTone && (ChannelTone[(ch.complement == 0) ? 0 : 1, ch.reg[0] >> 6]) != 0))
|
||||
{
|
||||
// 娗嶲<EFBFBD>燴
|
||||
// 補間処理
|
||||
double total;
|
||||
double sample_weight = ch.phaseacc;
|
||||
if (sample_weight > cycle_rate)
|
||||
@ -864,7 +864,7 @@ namespace VirtualNes.Core
|
||||
int x = ChannelTone[(ch.complement == 0) ? 0 : 1, ch.reg[0] >> 6] - 1;
|
||||
int pTone = 0;
|
||||
|
||||
// 載陔剠仄
|
||||
// 更新無し
|
||||
ch.phaseacc -= cycle_rate * 2;
|
||||
if (ch.phaseacc >= 0)
|
||||
{
|
||||
@ -872,7 +872,7 @@ namespace VirtualNes.Core
|
||||
return temp * volume / ((1 << RECTANGLE_VOL_SHIFT) / 2);
|
||||
}
|
||||
|
||||
// 1旦氾永皿分仃載陔
|
||||
// 1ステップだけ更新
|
||||
int freq = INT2FIX(ch.freq + 1);
|
||||
if (freq > cycle_rate * 2)
|
||||
{
|
||||
@ -882,7 +882,7 @@ namespace VirtualNes.Core
|
||||
return temp * volume / ((1 << RECTANGLE_VOL_SHIFT) / 2);
|
||||
}
|
||||
|
||||
// 樓笭ⅸ歙
|
||||
// 加重平均
|
||||
int num_times, total;
|
||||
num_times = total = 0;
|
||||
while (ch.phaseacc < 0)
|
||||
@ -1015,7 +1015,7 @@ namespace VirtualNes.Core
|
||||
SyncWrite4017(data);
|
||||
break;
|
||||
|
||||
// VirtuaNES娚葲<EFBFBD><EFBFBD><EFBFBD>
|
||||
// VirtuaNES屌桳億乕僩
|
||||
case 0x4018:
|
||||
SyncUpdateRectangle(ch0, data);
|
||||
SyncUpdateRectangle(ch1, data);
|
||||
|
@ -1110,7 +1110,7 @@ namespace VirtualNes.Core
|
||||
case 0xD2: /* JAM */
|
||||
case 0xF2: /* JAM */
|
||||
default:
|
||||
if (!Supporter.Config.emulator.bIllegalOp)
|
||||
if (!Supporter.S.Config.emulator.bIllegalOp)
|
||||
{
|
||||
throw new Exception("IllegalOp");
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ namespace VirtualNes.Core
|
||||
Debuger.Log($"SOUND CODE:{addr & 0x1F:X2}");
|
||||
|
||||
// OSDにするべきか…
|
||||
if (Supporter.Config.sound.bExtraSoundEnable)
|
||||
if (Supporter.S.Config.sound.bExtraSoundEnable)
|
||||
{
|
||||
//TODO : 似乎VirtuaNES有直接播放某个音频文件的功能
|
||||
//DirectSound.EsfAllStop();
|
||||
|
@ -43,7 +43,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
|
||||
// OSDにするべきか…
|
||||
if (Supporter.Config.sound.bExtraSoundEnable)
|
||||
if (Supporter.S.Config.sound.bExtraSoundEnable)
|
||||
{
|
||||
//TODO : 似乎VirtuaNES有直接播放某个音频文件的功能
|
||||
//DirectSound.EsfAllStop();
|
||||
|
@ -57,7 +57,7 @@ namespace VirtualNes.Core
|
||||
9,10, 8,11,13,12,14,15 };
|
||||
|
||||
// OSDにするべきか…
|
||||
if (Supporter.Config.sound.bExtraSoundEnable)
|
||||
if (Supporter.S.Config.sound.bExtraSoundEnable)
|
||||
{
|
||||
//TODO : 似乎VirtuaNES有直接播放某个音频文件的功能
|
||||
Debuger.Log($"CODE {data:X2}");
|
||||
|
@ -326,7 +326,7 @@ namespace VirtualNes.Core
|
||||
if (pad.GetExController() != (int)EXCONTROLLER.EXCONTROLLER_TURBOFILE)
|
||||
return;
|
||||
|
||||
var fp = Supporter.OpenFile(Supporter.Config.path.szSavePath, "TurboFile.vtf");
|
||||
var fp = Supporter.S.OpenFile(Supporter.S.Config.path.szSavePath, "TurboFile.vtf");
|
||||
try
|
||||
{
|
||||
if (fp == null)
|
||||
@ -367,10 +367,10 @@ namespace VirtualNes.Core
|
||||
if (!rom.IsSAVERAM())
|
||||
return;
|
||||
|
||||
var saveFileDir = Supporter.Config.path.szSavePath;
|
||||
var saveFileDir = Supporter.S.Config.path.szSavePath;
|
||||
var saveFileName = $"{rom.GetRomName()}.sav";
|
||||
|
||||
var fp = Supporter.OpenFile(saveFileDir, saveFileName);
|
||||
var fp = Supporter.S.OpenFile(saveFileDir, saveFileName);
|
||||
|
||||
try
|
||||
{
|
||||
@ -502,13 +502,13 @@ namespace VirtualNes.Core
|
||||
EmulationCPU(nescfg.ScanlineCycles);
|
||||
if (bDraw)
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pad.IsZapperMode() && scanline == ZapperY)
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -518,7 +518,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -535,13 +535,13 @@ namespace VirtualNes.Core
|
||||
EmulationCPU(nescfg.HDrawCycles);
|
||||
if (bDraw)
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pad.IsZapperMode() && scanline == ZapperY)
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -551,7 +551,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -658,7 +658,7 @@ namespace VirtualNes.Core
|
||||
// 僗僋儕乕儞昤夋(Scanline 1乣239)
|
||||
if (bDraw)
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
ppu.ScanlineNext();
|
||||
EmulationCPU(FETCH_CYCLES * 10);
|
||||
mapper.HSync(scanline);
|
||||
@ -670,7 +670,7 @@ namespace VirtualNes.Core
|
||||
{
|
||||
if (pad.IsZapperMode() && scanline == ZapperY)
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
ppu.ScanlineNext();
|
||||
EmulationCPU(FETCH_CYCLES * 10);
|
||||
mapper.HSync(scanline);
|
||||
@ -694,7 +694,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
ppu.Scanline(scanline, Supporter.Config.graphics.bAllSprite, Supporter.Config.graphics.bLeftClip);
|
||||
ppu.Scanline(scanline, Supporter.S.Config.graphics.bAllSprite, Supporter.S.Config.graphics.bLeftClip);
|
||||
ppu.ScanlineNext();
|
||||
EmulationCPU(FETCH_CYCLES * 10);
|
||||
mapper.HSync(scanline);
|
||||
@ -1095,7 +1095,7 @@ namespace VirtualNes.Core
|
||||
|
||||
Debuger.Log($"Saving SAVERAM...[{romName}]");
|
||||
|
||||
Supporter.SaveSRAMToFile(MMU.WRAM, romName);
|
||||
Supporter.S.SaveSRAMToFile(MMU.WRAM, romName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1143,7 +1143,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
}
|
||||
|
||||
Supporter.SaveDISKToFile(contents.ToArray(), rom.GetRomName());
|
||||
Supporter.S.SaveDISKToFile(contents.ToArray(), rom.GetRomName());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -1168,7 +1168,7 @@ namespace VirtualNes.Core
|
||||
{
|
||||
Debuger.Log("Saving TURBOFILE...");
|
||||
|
||||
Supporter.SaveFile(MMU.ERAM, Supporter.Config.path.szSavePath, "TurboFile.vtf");
|
||||
Supporter.S.SaveFile(MMU.ERAM, Supporter.S.Config.path.szSavePath, "TurboFile.vtf");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ namespace VirtualNes.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Supporter.Config.emulator.bFourPlayer)
|
||||
if (Supporter.S.Config.emulator.bFourPlayer)
|
||||
{
|
||||
// NES type
|
||||
pad1bit = padbitsync[0] | ((uint)padbitsync[2] << 8) | 0x00080000;
|
||||
|
@ -50,7 +50,7 @@ namespace VirtualNes.Core
|
||||
|
||||
try
|
||||
{
|
||||
fp = Supporter.OpenRom(fname);
|
||||
fp = Supporter.S.OpenRom(fname);
|
||||
if (fp == null)
|
||||
{
|
||||
throw new System.Exception($"Open Rom Failed:[{fname}]");
|
||||
@ -167,7 +167,7 @@ namespace VirtualNes.Core
|
||||
lpPRG[3] = 0x1A;
|
||||
lpPRG[4] = (byte)diskno;
|
||||
|
||||
fp = Supporter.OpenFile_DISKSYS();
|
||||
fp = Supporter.S.OpenFile_DISKSYS();
|
||||
if (fp == null)
|
||||
{
|
||||
throw new Exception($"Not found DISKSYS.ROM for [{fname}]");
|
||||
@ -217,7 +217,7 @@ namespace VirtualNes.Core
|
||||
throw new Exception($"Unsupport format:[{fname}]");
|
||||
}
|
||||
|
||||
Supporter.GetFilePathInfo(fname, out fullpath, out path);
|
||||
Supporter.S.GetRomPathInfo(fname, out fullpath, out path);
|
||||
name = Path.GetFileNameWithoutExtension(fullpath);
|
||||
if (!bNSF)
|
||||
{
|
||||
@ -244,7 +244,7 @@ namespace VirtualNes.Core
|
||||
|
||||
FileNameCheck(fname);
|
||||
|
||||
if (Supporter.TryGetMapperNo(this, out int mapperNo))
|
||||
if (Supporter.S.TryGetMapperNo(this, out int mapperNo))
|
||||
{
|
||||
Debuger.Log($"ROMDB Set Mapper #{mapper:000} to #{mapperNo:000}");
|
||||
mapper = mapperNo;
|
||||
|
@ -5,73 +5,12 @@ namespace VirtualNes.Core
|
||||
public static class Supporter
|
||||
{
|
||||
private static ISupporterImpl s_support;
|
||||
internal static ISupporterImpl S => s_support;
|
||||
|
||||
public static void Setup(ISupporterImpl supporter)
|
||||
{
|
||||
s_support = supporter;
|
||||
}
|
||||
|
||||
public static Stream OpenRom(string fname)
|
||||
{
|
||||
return s_support.OpenRom(fname);
|
||||
}
|
||||
|
||||
public static void GetFilePathInfo(string fname, out string fullPath, out string directPath)
|
||||
{
|
||||
s_support.GetRomPathInfo(fname, out fullPath, out directPath);
|
||||
}
|
||||
|
||||
public static Stream OpenFile_DISKSYS()
|
||||
{
|
||||
return s_support.OpenFile_DISKSYS();
|
||||
}
|
||||
|
||||
public static void SaveSRAMToFile(byte[] sramContent, string romName)
|
||||
{
|
||||
s_support.SaveSRAMToFile(sramContent, romName);
|
||||
}
|
||||
|
||||
public static void SaveDISKToFile(byte[] diskFileContent, string romName)
|
||||
{
|
||||
s_support.SaveDISKToFile(diskFileContent, romName);
|
||||
}
|
||||
|
||||
public static void PrepareDirectory(string directPath)
|
||||
{
|
||||
s_support.PrepareDirectory(directPath);
|
||||
}
|
||||
|
||||
public static void SaveFile(byte[] fileData, string directPath, string fileName)
|
||||
{
|
||||
s_support.SaveFile(fileData, directPath, fileName);
|
||||
}
|
||||
|
||||
public static Stream OpenFile(string directPath, string fileName)
|
||||
{
|
||||
return s_support.OpenFile(directPath, fileName);
|
||||
}
|
||||
|
||||
public static bool TryGetMapperNo(ROM rom, out int mapperNo)
|
||||
{
|
||||
return s_support.TryGetMapperNo(rom, out mapperNo);
|
||||
}
|
||||
|
||||
public static ControllerState GetControllerState()
|
||||
{
|
||||
return s_support.GetControllerState();
|
||||
}
|
||||
|
||||
public static void SampleInput(uint frameCount)
|
||||
{
|
||||
s_support.SampleInput(frameCount);
|
||||
}
|
||||
|
||||
public static IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return s_support?.GetControllerSetuper();
|
||||
}
|
||||
|
||||
public static EmulatorConfig Config => s_support.Config;
|
||||
}
|
||||
|
||||
public interface ISupporterImpl
|
||||
@ -82,48 +21,11 @@ namespace VirtualNes.Core
|
||||
void SaveSRAMToFile(byte[] sramContent, string romName);
|
||||
void SaveDISKToFile(byte[] diskFileContent, string romName);
|
||||
EmulatorConfig Config { get; }
|
||||
|
||||
void PrepareDirectory(string directPath);
|
||||
void SaveFile(byte[] fileData, string directPath, string fileName);
|
||||
Stream OpenFile(string directPath, string fileName);
|
||||
bool TryGetMapperNo(ROM rom, out int mapperNo);
|
||||
ControllerState GetControllerState();
|
||||
void SampleInput(uint frameCount);
|
||||
IControllerSetuper GetControllerSetuper();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 负责管理本地控制器与具体游戏之间的槽位分配
|
||||
/// </summary>
|
||||
public interface IControllerSetuper
|
||||
{
|
||||
/// <summary>
|
||||
/// 设置本地手柄与游戏手柄槽位的映射,这个方法是一个全量更新手柄插入设置的方法
|
||||
/// </summary>
|
||||
void SetConnect(
|
||||
uint? con0ToSlot = null,
|
||||
uint? con1ToSlot = null,
|
||||
uint? con2ToSlot = null,
|
||||
uint? con3ToSlot = null);
|
||||
|
||||
/// <summary>
|
||||
/// 指定手柄插槽位,获取当前槽位连接的本地手柄序号
|
||||
/// </summary>
|
||||
/// <param name="slotIndex"></param>
|
||||
/// <returns></returns>
|
||||
int? GetSlotConnectingController(int slotIndex);
|
||||
|
||||
/// <summary>
|
||||
/// 获得一个空的槽位
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
uint? GetFreeSlotIndex();
|
||||
|
||||
/// <summary>
|
||||
/// 增量式的修改一个手柄和一个槽位的连接关系
|
||||
/// </summary>
|
||||
/// <param name="conIndex"></param>
|
||||
/// <param name="slotIndex"></param>
|
||||
void LetControllerConnect(int conIndex, uint slotIndex);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user