forked from sin365/AxibugEmuOnline
Merge pull request 'dev_4VirtualNes' (#19) from Alienjack/AxibugEmuOnline:dev_4VirtualNes into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#19
This commit is contained in:
commit
507ef45d3a
1
.gitignore
vendored
1
.gitignore
vendored
@ -13,3 +13,4 @@
|
|||||||
/AxibugEmuOnline.Client/ProjectSettings/ProjectVersion.txt
|
/AxibugEmuOnline.Client/ProjectSettings/ProjectVersion.txt
|
||||||
/AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset
|
/AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset
|
||||||
/AxibugEmuOnline.Client/Logs
|
/AxibugEmuOnline.Client/Logs
|
||||||
|
/virtuanessrc097-master/save
|
||||||
|
@ -123,49 +123,6 @@ NavMeshSettings:
|
|||||||
debug:
|
debug:
|
||||||
m_Flags: 0
|
m_Flags: 0
|
||||||
m_NavMeshData: {fileID: 0}
|
m_NavMeshData: {fileID: 0}
|
||||||
--- !u!1 &149545946
|
|
||||||
GameObject:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
serializedVersion: 6
|
|
||||||
m_Component:
|
|
||||||
- component: {fileID: 149545948}
|
|
||||||
- component: {fileID: 149545947}
|
|
||||||
m_Layer: 0
|
|
||||||
m_Name: NesEmulator
|
|
||||||
m_TagString: Untagged
|
|
||||||
m_Icon: {fileID: 0}
|
|
||||||
m_NavMeshLayer: 0
|
|
||||||
m_StaticEditorFlags: 0
|
|
||||||
m_IsActive: 1
|
|
||||||
--- !u!114 &149545947
|
|
||||||
MonoBehaviour:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 149545946}
|
|
||||||
m_Enabled: 1
|
|
||||||
m_EditorHideFlags: 0
|
|
||||||
m_Script: {fileID: 11500000, guid: 39557e19783acee499ace6c68549e8f8, type: 3}
|
|
||||||
m_Name:
|
|
||||||
m_EditorClassIdentifier:
|
|
||||||
--- !u!4 &149545948
|
|
||||||
Transform:
|
|
||||||
m_ObjectHideFlags: 0
|
|
||||||
m_CorrespondingSourceObject: {fileID: 0}
|
|
||||||
m_PrefabInstance: {fileID: 0}
|
|
||||||
m_PrefabAsset: {fileID: 0}
|
|
||||||
m_GameObject: {fileID: 149545946}
|
|
||||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
|
||||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
|
||||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
|
||||||
m_Children: []
|
|
||||||
m_Father: {fileID: 0}
|
|
||||||
m_RootOrder: 3
|
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
|
||||||
--- !u!1 &708549044
|
--- !u!1 &708549044
|
||||||
GameObject:
|
GameObject:
|
||||||
m_ObjectHideFlags: 0
|
m_ObjectHideFlags: 0
|
||||||
@ -408,3 +365,60 @@ Transform:
|
|||||||
m_Father: {fileID: 0}
|
m_Father: {fileID: 0}
|
||||||
m_RootOrder: 1
|
m_RootOrder: 1
|
||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!1001 &4232056520998800727
|
||||||
|
PrefabInstance:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Modification:
|
||||||
|
m_TransformParent: {fileID: 0}
|
||||||
|
m_Modifications:
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_RootOrder
|
||||||
|
value: 3
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalPosition.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.w
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalRotation.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536011, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536013, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_Name
|
||||||
|
value: NesEmulator
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
m_RemovedComponents: []
|
||||||
|
m_SourcePrefab: {fileID: 100100000, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
@ -7,6 +7,7 @@ namespace AxibugEmuOnline.Client
|
|||||||
{
|
{
|
||||||
public class CoreDebuger : IDebugerImpl
|
public class CoreDebuger : IDebugerImpl
|
||||||
{
|
{
|
||||||
|
|
||||||
public void Log(string message)
|
public void Log(string message)
|
||||||
{
|
{
|
||||||
Debug.Log(message);
|
Debug.Log(message);
|
||||||
|
@ -64,5 +64,33 @@ namespace AxibugEmuOnline.Client
|
|||||||
}
|
}
|
||||||
|
|
||||||
public EmulatorConfig Config { get; private set; } = new EmulatorConfig();
|
public EmulatorConfig Config { get; private set; } = new EmulatorConfig();
|
||||||
|
|
||||||
|
public void PrepareDirectory(string directPath)
|
||||||
|
{
|
||||||
|
Directory.CreateDirectory($"{Application.persistentDataPath}/{directPath}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SaveFile(byte[] fileData, string directPath, string fileName)
|
||||||
|
{
|
||||||
|
PrepareDirectory(directPath);
|
||||||
|
|
||||||
|
var fileFullpath = $"{Application.persistentDataPath}/{directPath}/{fileName}";
|
||||||
|
File.WriteAllBytes(fileFullpath, fileData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream OpenFile(string directPath, string fileName)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var data = File.ReadAllBytes($"{Application.persistentDataPath}/{directPath}/{fileName}");
|
||||||
|
if (data == null) return null;
|
||||||
|
return new MemoryStream(data);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using VirtualNes.Core;
|
using VirtualNes.Core;
|
||||||
using VirtualNes.Core.Debug;
|
using VirtualNes.Core.Debug;
|
||||||
@ -8,6 +10,8 @@ namespace AxibugEmuOnline.Client
|
|||||||
{
|
{
|
||||||
private NES m_nesIns;
|
private NES m_nesIns;
|
||||||
|
|
||||||
|
public VideoProvider VideoProvider;
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
StartGame("Kirby.nes");
|
StartGame("Kirby.nes");
|
||||||
@ -19,8 +23,16 @@ namespace AxibugEmuOnline.Client
|
|||||||
|
|
||||||
Supporter.Setup(new CoreSupporter());
|
Supporter.Setup(new CoreSupporter());
|
||||||
Debuger.Setup(new CoreDebuger());
|
Debuger.Setup(new CoreDebuger());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
m_nesIns = new NES(romName);
|
m_nesIns = new NES(romName);
|
||||||
m_nesIns.Command(NESCOMMAND.NESCMD_HWRESET);
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
m_nesIns = null;
|
||||||
|
Debug.LogError(ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopGame()
|
public void StopGame()
|
||||||
@ -29,9 +41,18 @@ namespace AxibugEmuOnline.Client
|
|||||||
m_nesIns = null;
|
m_nesIns = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
m_nesIns?.EmulateFrame(true);
|
if (m_nesIns != null)
|
||||||
|
{
|
||||||
|
m_nesIns.EmulateFrame(true);
|
||||||
|
|
||||||
|
var screenBuffer = m_nesIns.ppu.GetScreenPtr();
|
||||||
|
var lineColorMode = m_nesIns.ppu.GetLineColorMode();
|
||||||
|
|
||||||
|
VideoProvider.SetDrawData(screenBuffer, lineColorMode, 256, 240);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,264 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!1 &4232056520112715746
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4232056520112715745}
|
||||||
|
- component: {fileID: 4232056520112715744}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: VideoProvider
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4232056520112715745
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056520112715746}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 4232056520494431727}
|
||||||
|
m_Father: {fileID: 4232056521131536011}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &4232056520112715744
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056520112715746}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 83fbe375412d1af4482ae76e81c1dda2, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
Image: {fileID: 4232056521759880274}
|
||||||
|
--- !u!1 &4232056520494431712
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4232056520494431727}
|
||||||
|
- component: {fileID: 4232056520494431724}
|
||||||
|
- component: {fileID: 4232056520494431725}
|
||||||
|
- component: {fileID: 4232056520494431726}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: Canvas
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &4232056520494431727
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056520494431712}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 0, y: 0, z: 0}
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 4232056521759880275}
|
||||||
|
m_Father: {fileID: 4232056520112715745}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0, y: 0}
|
||||||
|
m_AnchorMax: {x: 0, y: 0}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 0, y: 0}
|
||||||
|
m_Pivot: {x: 0, y: 0}
|
||||||
|
--- !u!223 &4232056520494431724
|
||||||
|
Canvas:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056520494431712}
|
||||||
|
m_Enabled: 1
|
||||||
|
serializedVersion: 3
|
||||||
|
m_RenderMode: 0
|
||||||
|
m_Camera: {fileID: 0}
|
||||||
|
m_PlaneDistance: 100
|
||||||
|
m_PixelPerfect: 0
|
||||||
|
m_ReceivesEvents: 1
|
||||||
|
m_OverrideSorting: 0
|
||||||
|
m_OverridePixelPerfect: 0
|
||||||
|
m_SortingBucketNormalizedSize: 0
|
||||||
|
m_AdditionalShaderChannelsFlag: 0
|
||||||
|
m_SortingLayerID: 0
|
||||||
|
m_SortingOrder: 0
|
||||||
|
m_TargetDisplay: 0
|
||||||
|
--- !u!114 &4232056520494431725
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056520494431712}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_UiScaleMode: 0
|
||||||
|
m_ReferencePixelsPerUnit: 100
|
||||||
|
m_ScaleFactor: 1
|
||||||
|
m_ReferenceResolution: {x: 800, y: 600}
|
||||||
|
m_ScreenMatchMode: 0
|
||||||
|
m_MatchWidthOrHeight: 0
|
||||||
|
m_PhysicalUnit: 3
|
||||||
|
m_FallbackScreenDPI: 96
|
||||||
|
m_DefaultSpriteDPI: 96
|
||||||
|
m_DynamicPixelsPerUnit: 1
|
||||||
|
m_PresetInfoIsWorld: 0
|
||||||
|
--- !u!114 &4232056520494431726
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056520494431712}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_IgnoreReversedGraphics: 1
|
||||||
|
m_BlockingObjects: 0
|
||||||
|
m_BlockingMask:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_Bits: 4294967295
|
||||||
|
--- !u!1 &4232056521131536013
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4232056521131536011}
|
||||||
|
- component: {fileID: 4232056521131536012}
|
||||||
|
m_Layer: 0
|
||||||
|
m_Name: NesEmulator
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!4 &4232056521131536011
|
||||||
|
Transform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056521131536013}
|
||||||
|
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_Children:
|
||||||
|
- {fileID: 4232056520112715745}
|
||||||
|
m_Father: {fileID: 0}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
|
--- !u!114 &4232056521131536012
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056521131536013}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 39557e19783acee499ace6c68549e8f8, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
VideoProvider: {fileID: 4232056520112715744}
|
||||||
|
--- !u!1 &4232056521759880276
|
||||||
|
GameObject:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
serializedVersion: 6
|
||||||
|
m_Component:
|
||||||
|
- component: {fileID: 4232056521759880275}
|
||||||
|
- component: {fileID: 4232056521759880273}
|
||||||
|
- component: {fileID: 4232056521759880274}
|
||||||
|
m_Layer: 5
|
||||||
|
m_Name: RawImage
|
||||||
|
m_TagString: Untagged
|
||||||
|
m_Icon: {fileID: 0}
|
||||||
|
m_NavMeshLayer: 0
|
||||||
|
m_StaticEditorFlags: 0
|
||||||
|
m_IsActive: 1
|
||||||
|
--- !u!224 &4232056521759880275
|
||||||
|
RectTransform:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056521759880276}
|
||||||
|
m_LocalRotation: {x: 1, y: 0, z: 0, w: 0}
|
||||||
|
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||||
|
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||||
|
m_Children: []
|
||||||
|
m_Father: {fileID: 4232056520494431727}
|
||||||
|
m_RootOrder: 0
|
||||||
|
m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0}
|
||||||
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
|
m_SizeDelta: {x: 272, y: 240}
|
||||||
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
|
--- !u!222 &4232056521759880273
|
||||||
|
CanvasRenderer:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056521759880276}
|
||||||
|
m_CullTransparentMesh: 1
|
||||||
|
--- !u!114 &4232056521759880274
|
||||||
|
MonoBehaviour:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_GameObject: {fileID: 4232056521759880276}
|
||||||
|
m_Enabled: 1
|
||||||
|
m_EditorHideFlags: 0
|
||||||
|
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
|
||||||
|
m_Name:
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
m_Material: {fileID: 0}
|
||||||
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
|
m_RaycastTarget: 1
|
||||||
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
|
m_Maskable: 1
|
||||||
|
m_OnCullStateChanged:
|
||||||
|
m_PersistentCalls:
|
||||||
|
m_Calls: []
|
||||||
|
m_Texture: {fileID: 8400000, guid: ffe34aaf87e4b9942b4c2ac05943d444, type: 2}
|
||||||
|
m_UVRect:
|
||||||
|
serializedVersion: 2
|
||||||
|
x: 0
|
||||||
|
y: 0
|
||||||
|
width: 1
|
||||||
|
height: 1
|
@ -0,0 +1,7 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f8bea3f8aa351bb46ada33b2274729ea
|
||||||
|
PrefabImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,38 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!84 &8400000
|
||||||
|
RenderTexture:
|
||||||
|
m_ObjectHideFlags: 0
|
||||||
|
m_CorrespondingSourceObject: {fileID: 0}
|
||||||
|
m_PrefabInstance: {fileID: 0}
|
||||||
|
m_PrefabAsset: {fileID: 0}
|
||||||
|
m_Name: New Render Texture
|
||||||
|
m_ImageContentsHash:
|
||||||
|
serializedVersion: 2
|
||||||
|
Hash: 00000000000000000000000000000000
|
||||||
|
m_ForcedFallbackFormat: 4
|
||||||
|
m_DownscaleFallback: 0
|
||||||
|
m_IsAlphaChannelOptional: 0
|
||||||
|
serializedVersion: 3
|
||||||
|
m_Width: 272
|
||||||
|
m_Height: 240
|
||||||
|
m_AntiAliasing: 1
|
||||||
|
m_MipCount: -1
|
||||||
|
m_DepthFormat: 2
|
||||||
|
m_ColorFormat: 8
|
||||||
|
m_MipMap: 0
|
||||||
|
m_GenerateMips: 1
|
||||||
|
m_SRGB: 0
|
||||||
|
m_UseDynamicScale: 0
|
||||||
|
m_BindMS: 0
|
||||||
|
m_EnableCompatibleFormat: 1
|
||||||
|
m_TextureSettings:
|
||||||
|
serializedVersion: 2
|
||||||
|
m_FilterMode: 1
|
||||||
|
m_Aniso: 0
|
||||||
|
m_MipBias: 0
|
||||||
|
m_WrapU: 1
|
||||||
|
m_WrapV: 1
|
||||||
|
m_WrapW: 1
|
||||||
|
m_Dimension: 2
|
||||||
|
m_VolumeDepth: 1
|
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ffe34aaf87e4b9942b4c2ac05943d444
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 8400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,242 @@
|
|||||||
|
using Codice.CM.Client.Differences;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
using VirtualNes.Core;
|
||||||
|
|
||||||
|
namespace AxibugEmuOnline.Client.Assets.Script.NesEmulator
|
||||||
|
{
|
||||||
|
public static class PaletteDefine
|
||||||
|
{
|
||||||
|
public class PALBUF
|
||||||
|
{
|
||||||
|
public byte r;
|
||||||
|
public byte g;
|
||||||
|
public byte b;
|
||||||
|
|
||||||
|
public PALBUF(byte r, byte g, byte b)
|
||||||
|
{
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// スキャンラインカラー
|
||||||
|
private static int m_nScanlineColor => Supporter.Config.graphics.nScanlineColor;
|
||||||
|
|
||||||
|
public static float[][] PalConvTbl = new float[8][]
|
||||||
|
{
|
||||||
|
new float[3]{1.00f, 1.00f, 1.00f},
|
||||||
|
new float[3]{1.00f, 0.80f, 0.73f},
|
||||||
|
new float[3]{0.73f, 1.00f, 0.70f},
|
||||||
|
new float[3]{0.76f, 0.78f, 0.58f},
|
||||||
|
new float[3]{0.86f, 0.80f, 1.00f},
|
||||||
|
new float[3]{0.83f, 0.68f, 0.85f},
|
||||||
|
new float[3]{0.67f, 0.77f, 0.83f},
|
||||||
|
new float[3]{0.68f, 0.68f, 0.68f},
|
||||||
|
};
|
||||||
|
|
||||||
|
public static PALBUF[] m_PaletteBuf = new PALBUF[64]
|
||||||
|
{
|
||||||
|
new PALBUF(0x7F, 0x7F, 0x7F),
|
||||||
|
new PALBUF(0x20, 0x00, 0xB0),
|
||||||
|
new PALBUF(0x28, 0x00, 0xB8),
|
||||||
|
new PALBUF(0x60, 0x10, 0xA0),
|
||||||
|
new PALBUF(0x98, 0x20, 0x78),
|
||||||
|
new PALBUF(0xB0, 0x10, 0x30),
|
||||||
|
new PALBUF(0xA0, 0x30, 0x00),
|
||||||
|
new PALBUF(0x78, 0x40, 0x00),
|
||||||
|
new PALBUF(0x48, 0x58, 0x00),
|
||||||
|
new PALBUF(0x38, 0x68, 0x00),
|
||||||
|
new PALBUF(0x38, 0x6C, 0x00),
|
||||||
|
new PALBUF(0x30, 0x60, 0x40),
|
||||||
|
new PALBUF(0x30, 0x50, 0x80),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0xBC, 0xBC, 0xBC),
|
||||||
|
new PALBUF(0x40, 0x60, 0xF8),
|
||||||
|
new PALBUF(0x40, 0x40, 0xFF),
|
||||||
|
new PALBUF(0x90, 0x40, 0xF0),
|
||||||
|
new PALBUF(0xD8, 0x40, 0xC0),
|
||||||
|
new PALBUF(0xD8, 0x40, 0x60),
|
||||||
|
new PALBUF(0xE0, 0x50, 0x00),
|
||||||
|
new PALBUF(0xC0, 0x70, 0x00),
|
||||||
|
new PALBUF(0x88, 0x88, 0x00),
|
||||||
|
new PALBUF(0x50, 0xA0, 0x00),
|
||||||
|
new PALBUF(0x48, 0xA8, 0x10),
|
||||||
|
new PALBUF(0x48, 0xA0, 0x68),
|
||||||
|
new PALBUF(0x40, 0x90, 0xC0),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0xFF, 0xFF, 0xFF),
|
||||||
|
new PALBUF(0x60, 0xA0, 0xFF),
|
||||||
|
new PALBUF(0x50, 0x80, 0xFF),
|
||||||
|
new PALBUF(0xA0, 0x70, 0xFF),
|
||||||
|
new PALBUF(0xF0, 0x60, 0xFF),
|
||||||
|
new PALBUF(0xFF, 0x60, 0xB0),
|
||||||
|
new PALBUF(0xFF, 0x78, 0x30),
|
||||||
|
new PALBUF(0xFF, 0xA0, 0x00),
|
||||||
|
new PALBUF(0xE8, 0xD0, 0x20),
|
||||||
|
new PALBUF(0x98, 0xE8, 0x00),
|
||||||
|
new PALBUF(0x70, 0xF0, 0x40),
|
||||||
|
new PALBUF(0x70, 0xE0, 0x90),
|
||||||
|
new PALBUF(0x60, 0xD0, 0xE0),
|
||||||
|
new PALBUF(0x60, 0x60, 0x60),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0xFF, 0xFF, 0xFF),
|
||||||
|
new PALBUF(0x90, 0xD0, 0xFF),
|
||||||
|
new PALBUF(0xA0, 0xB8, 0xFF),
|
||||||
|
new PALBUF(0xC0, 0xB0, 0xFF),
|
||||||
|
new PALBUF(0xE0, 0xB0, 0xFF),
|
||||||
|
new PALBUF(0xFF, 0xB8, 0xE8),
|
||||||
|
new PALBUF(0xFF, 0xC8, 0xB8),
|
||||||
|
new PALBUF(0xFF, 0xD8, 0xA0),
|
||||||
|
new PALBUF(0xFF, 0xF0, 0x90),
|
||||||
|
new PALBUF(0xC8, 0xF0, 0x80),
|
||||||
|
new PALBUF(0xA0, 0xF0, 0xA0),
|
||||||
|
new PALBUF(0xA0, 0xFF, 0xC8),
|
||||||
|
new PALBUF(0xA0, 0xFF, 0xF0),
|
||||||
|
new PALBUF(0xA0, 0xA0, 0xA0),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
new PALBUF(0x00, 0x00, 0x00),
|
||||||
|
};
|
||||||
|
|
||||||
|
#region ピクセルフォーマットに変換したパレット
|
||||||
|
// Color
|
||||||
|
public static uint[][] m_cnPalette = new uint[8][]
|
||||||
|
{
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
};
|
||||||
|
// Color/Scanline
|
||||||
|
public static uint[][] m_csPalette = new uint[8][]
|
||||||
|
{
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Monochrome
|
||||||
|
public static uint[][] m_mnPalette = new uint[8][]
|
||||||
|
{
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
};
|
||||||
|
|
||||||
|
// Monochrome/Scanline
|
||||||
|
public static uint[][] m_msPalette = new uint[8][]
|
||||||
|
{
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
new uint[256],
|
||||||
|
};
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
static PaletteDefine()
|
||||||
|
{
|
||||||
|
int Rbit = 0, Gbit = 0, Bbit = 0;
|
||||||
|
int Rsft = 0, Gsft = 0, Bsft = 0;
|
||||||
|
|
||||||
|
GetBitMask(0xFF0000, ref Rsft, ref Rbit);
|
||||||
|
GetBitMask(0x00FF00, ref Gsft, ref Gbit);
|
||||||
|
GetBitMask(0x0000FF, ref Bsft, ref Bbit);
|
||||||
|
|
||||||
|
for (int j = 0; j < 8; j++)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 64; i++)
|
||||||
|
{
|
||||||
|
uint Rn, Gn, Bn;
|
||||||
|
uint Rs, Gs, Bs;
|
||||||
|
|
||||||
|
// Normal
|
||||||
|
Rn = (uint)(PalConvTbl[j][0] * m_PaletteBuf[i].r);
|
||||||
|
Gn = (uint)(PalConvTbl[j][1] * m_PaletteBuf[i].g);
|
||||||
|
Bn = (uint)(PalConvTbl[j][2] * m_PaletteBuf[i].b);
|
||||||
|
// Scanline
|
||||||
|
Rs = (uint)(PalConvTbl[j][0] * m_PaletteBuf[i].r * m_nScanlineColor / 100.0f);
|
||||||
|
Gs = (uint)(PalConvTbl[j][1] * m_PaletteBuf[i].g * m_nScanlineColor / 100.0f);
|
||||||
|
Bs = (uint)(PalConvTbl[j][2] * m_PaletteBuf[i].b * m_nScanlineColor / 100.0f);
|
||||||
|
|
||||||
|
m_cnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft);
|
||||||
|
m_csPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft);
|
||||||
|
|
||||||
|
// Monochrome
|
||||||
|
Rn = (uint)(m_PaletteBuf[i & 0x30].r);
|
||||||
|
Gn = (uint)(m_PaletteBuf[i & 0x30].g);
|
||||||
|
Bn = (uint)(m_PaletteBuf[i & 0x30].b);
|
||||||
|
Rn =
|
||||||
|
Gn =
|
||||||
|
Bn = (uint)(0.299f * Rn + 0.587f * Gn + 0.114f * Bn);
|
||||||
|
Rn = (uint)(PalConvTbl[j][0] * Rn);
|
||||||
|
Gn = (uint)(PalConvTbl[j][1] * Gn);
|
||||||
|
Bn = (uint)(PalConvTbl[j][2] * Bn);
|
||||||
|
if (Rn > 0xFF) Rs = 0xFF;
|
||||||
|
if (Gn > 0xFF) Gs = 0xFF;
|
||||||
|
if (Bn > 0xFF) Bs = 0xFF;
|
||||||
|
// Scanline
|
||||||
|
Rs = (uint)(m_PaletteBuf[i & 0x30].r * m_nScanlineColor / 100.0f);
|
||||||
|
Gs = (uint)(m_PaletteBuf[i & 0x30].g * m_nScanlineColor / 100.0f);
|
||||||
|
Bs = (uint)(m_PaletteBuf[i & 0x30].b * m_nScanlineColor / 100.0f);
|
||||||
|
Rs =
|
||||||
|
Gs =
|
||||||
|
Bs = (uint)(0.299f * Rs + 0.587f * Gs + 0.114f * Bs);
|
||||||
|
Rs = (uint)(PalConvTbl[j][0] * Rs);
|
||||||
|
Gs = (uint)(PalConvTbl[j][1] * Gs);
|
||||||
|
Bs = (uint)(PalConvTbl[j][2] * Bs);
|
||||||
|
if (Rs > 0xFF) Rs = 0xFF;
|
||||||
|
if (Gs > 0xFF) Gs = 0xFF;
|
||||||
|
if (Bs > 0xFF) Bs = 0xFF;
|
||||||
|
|
||||||
|
m_mnPalette[j][i] = ((Rn >> (8 - Rbit)) << Rsft) | ((Gn >> (8 - Gbit)) << Gsft) | ((Bn >> (8 - Bbit)) << Bsft);
|
||||||
|
m_msPalette[j][i] = ((Rs >> (8 - Rbit)) << Rsft) | ((Gs >> (8 - Gbit)) << Gsft) | ((Bs >> (8 - Bbit)) << Bsft);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ビット位置の取得
|
||||||
|
static void GetBitMask(uint val, ref int shift, ref int bits)
|
||||||
|
{
|
||||||
|
shift = 0;
|
||||||
|
while (((val & (1 << shift)) == 0) && (shift < 32))
|
||||||
|
{
|
||||||
|
shift++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bits = 32;
|
||||||
|
while (((val & (1 << (bits - 1))) == 0) && (bits > 0))
|
||||||
|
{
|
||||||
|
bits--;
|
||||||
|
}
|
||||||
|
bits = bits - shift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bbd3f54279eb4ae45831a914b13d1cec
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,82 @@
|
|||||||
|
using AxibugEmuOnline.Client.Assets.Script.NesEmulator;
|
||||||
|
using Codice.CM.Client.Differences;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
|
using UnityEngine.Playables;
|
||||||
|
using UnityEngine.UI;
|
||||||
|
using VirtualNes.Core;
|
||||||
|
|
||||||
|
namespace AxibugEmuOnline.Client
|
||||||
|
{
|
||||||
|
public class VideoProvider : MonoBehaviour
|
||||||
|
{
|
||||||
|
public RawImage Image;
|
||||||
|
|
||||||
|
private Color32[] wrapTexBuffer;
|
||||||
|
private IntPtr wrapTexBufferPointer;
|
||||||
|
private Texture2D wrapTex;
|
||||||
|
|
||||||
|
public void SetDrawData(byte[] screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
|
||||||
|
{
|
||||||
|
if (wrapTex == null)
|
||||||
|
{
|
||||||
|
wrapTex = new Texture2D(screenWidth, screenHeight, TextureFormat.BGRA32, false);
|
||||||
|
wrapTexBuffer = new Color32[screenWidth * screenHeight];
|
||||||
|
// 固定数组,防止垃圾回收器移动它
|
||||||
|
GCHandle handle = GCHandle.Alloc(wrapTexBuffer, GCHandleType.Pinned);
|
||||||
|
// 获取数组的指针
|
||||||
|
wrapTexBufferPointer = handle.AddrOfPinnedObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint[] pPal;
|
||||||
|
int pScn = 0;
|
||||||
|
int width;
|
||||||
|
|
||||||
|
var Dst = wrapTexBuffer;
|
||||||
|
var pDst = 0;
|
||||||
|
|
||||||
|
for (int line = 0; line < screenHeight; line++)
|
||||||
|
{
|
||||||
|
if ((lineColorMode[line] & 0x80) == 0)
|
||||||
|
{
|
||||||
|
pPal = PaletteDefine.m_cnPalette[lineColorMode[line] & 0x07];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pPal = PaletteDefine.m_mnPalette[lineColorMode[line] & 0x07];
|
||||||
|
}
|
||||||
|
|
||||||
|
width = screenWidth;
|
||||||
|
|
||||||
|
while (width > 0)
|
||||||
|
{
|
||||||
|
var edx = screenData[pScn + 8];
|
||||||
|
|
||||||
|
byte index = (byte)(edx & 0xFF);
|
||||||
|
var colorData = pPal[index];
|
||||||
|
var rawData = BitConverter.GetBytes(colorData);
|
||||||
|
Dst[pDst] = new Color32(rawData[0], rawData[1], rawData[2], 255);
|
||||||
|
|
||||||
|
pScn += 1;
|
||||||
|
pDst += 1;
|
||||||
|
width -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pScn += PPU.SCREEN_WIDTH - screenWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
//wrapTex.SetPixels32(wrapTexBuffer);
|
||||||
|
wrapTex.LoadRawTextureData(wrapTexBufferPointer, screenWidth * screenHeight * 4);
|
||||||
|
wrapTex.Apply();
|
||||||
|
|
||||||
|
Graphics.Blit(wrapTex, Image.mainTexture as RenderTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 83fbe375412d1af4482ae76e81c1dda2
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -9,22 +9,23 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
public override void Reset(float fClock, int nRate)
|
public override void Reset(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(float fClock, int nRate)
|
public override void Setup(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(ushort addr, byte data)
|
public override void Write(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Process(int channel)
|
public override int Process(int channel)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SyncWrite(ushort addr, byte data)
|
internal void SyncWrite(ushort addr, byte data)
|
||||||
@ -34,7 +35,7 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
private void WriteSub(ushort addr, byte data, FDSSOUND ch, double rate)
|
private void WriteSub(ushort addr, byte data, FDSSOUND ch, double rate)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
private class FDSSOUND
|
private class FDSSOUND
|
||||||
|
@ -6,22 +6,23 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
public override void Reset(float fClock, int nRate)
|
public override void Reset(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(float fClock, int nRate)
|
public override void Setup(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(ushort addr, byte data)
|
public override void Write(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Process(int channel)
|
public override int Process(int channel)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//todo : 实现
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,22 +127,23 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
public override void Reset(float fClock, int nRate)
|
public override void Reset(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(float fClock, int nRate)
|
public override void Setup(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(ushort addr, byte data)
|
public override void Write(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Process(int channel)
|
public override int Process(int channel)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal byte SyncRead(ushort addr)
|
internal byte SyncRead(ushort addr)
|
||||||
|
@ -6,27 +6,28 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
public override void Reset(float fClock, int nRate)
|
public override void Reset(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(float fClock, int nRate)
|
public override void Setup(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(ushort addr, byte data)
|
public override void Write(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Process(int channel)
|
public override int Process(int channel)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SyncWrite(ushort addr, byte data)
|
internal void SyncWrite(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,23 @@
|
|||||||
{
|
{
|
||||||
public override void Reset(float fClock, int nRate)
|
public override void Reset(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(float fClock, int nRate)
|
public override void Setup(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(ushort addr, byte data)
|
public override void Write(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Process(int channel)
|
public override int Process(int channel)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,22 +4,23 @@
|
|||||||
{
|
{
|
||||||
public override void Reset(float fClock, int nRate)
|
public override void Reset(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Setup(float fClock, int nRate)
|
public override void Setup(float fClock, int nRate)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Write(ushort addr, byte data)
|
public override void Write(ushort addr, byte data)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Process(int channel)
|
public override int Process(int channel)
|
||||||
{
|
{
|
||||||
throw new System.NotImplementedException();
|
//todo : 实现
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#undef DPCM_SYNCCLOCK
|
#undef DPCM_SYNCCLOCK
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using VirtualNes.Core.Debug;
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -42,7 +43,7 @@ namespace VirtualNes.Core
|
|||||||
private int DMA_cycles;
|
private int DMA_cycles;
|
||||||
private Mapper mapper;
|
private Mapper mapper;
|
||||||
private APU apu;
|
private APU apu;
|
||||||
private R6502 R = new R6502();
|
internal R6502 R = new R6502();
|
||||||
private byte[] ZN_Table = new byte[256];
|
private byte[] ZN_Table = new byte[256];
|
||||||
private Memory<byte> STACK;
|
private Memory<byte> STACK;
|
||||||
|
|
||||||
@ -132,75 +133,77 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
switch (opcode)
|
switch (opcode)
|
||||||
{
|
{
|
||||||
case 0x69:
|
case 0x69: // ADC #$??
|
||||||
MR_IM(); ADC();
|
MR_IM(); ADC();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
break;
|
break;
|
||||||
case 0x65:
|
case 0x65: // ADC $??
|
||||||
MR_ZP(); ADC();
|
MR_ZP(); ADC();
|
||||||
ADD_CYCLE(3);
|
ADD_CYCLE(3);
|
||||||
break;
|
break;
|
||||||
case 0x75:
|
case 0x75: // ADC $??,X
|
||||||
MR_ZX(); ADC();
|
MR_ZX(); ADC();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0x6D:
|
case 0x6D: // ADC $????
|
||||||
MR_AB(); ADC();
|
MR_AB(); ADC();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0x7D:
|
case 0x7D: // ADC $????,X
|
||||||
MR_AX(); ADC(); CHECK_EA();
|
MR_AX(); ADC(); CHECK_EA();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0x79:
|
case 0x79: // ADC $????,Y
|
||||||
MR_AY(); ADC(); CHECK_EA();
|
MR_AY(); ADC(); CHECK_EA();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0x61:
|
case 0x61: // ADC ($??,X)
|
||||||
MR_IX(); ADC();
|
MR_IX(); ADC();
|
||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
case 0x71:
|
case 0x71: // ADC ($??),Y
|
||||||
MR_IY(); ADC(); CHECK_EA();
|
MR_IY(); ADC(); CHECK_EA();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0xE9:
|
|
||||||
|
case 0xE9: // SBC #$??
|
||||||
MR_IM(); SBC();
|
MR_IM(); SBC();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
break;
|
break;
|
||||||
case 0xE5:
|
case 0xE5: // SBC $??
|
||||||
MR_ZP(); SBC();
|
MR_ZP(); SBC();
|
||||||
ADD_CYCLE(3);
|
ADD_CYCLE(3);
|
||||||
break;
|
break;
|
||||||
case 0xF5:
|
case 0xF5: // SBC $??,X
|
||||||
MR_ZX(); SBC();
|
MR_ZX(); SBC();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0xED:
|
case 0xED: // SBC $????
|
||||||
MR_AB(); SBC();
|
MR_AB(); SBC();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0xFD:
|
case 0xFD: // SBC $????,X
|
||||||
MR_AX(); SBC(); CHECK_EA();
|
MR_AX(); SBC(); CHECK_EA();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0xF9: // SBC $????Y
|
case 0xF9: // SBC $????,Y
|
||||||
MR_AY(); SBC(); CHECK_EA();
|
MR_AY(); SBC(); CHECK_EA();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0xE1: // SBC ($??X)
|
case 0xE1: // SBC ($??,X)
|
||||||
MR_IX(); SBC();
|
MR_IX(); SBC();
|
||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
case 0xF1: // SBC ($??)Y
|
case 0xF1: // SBC ($??),Y
|
||||||
MR_IY(); SBC(); CHECK_EA();
|
MR_IY(); SBC(); CHECK_EA();
|
||||||
ADD_CYCLE(5);
|
ADD_CYCLE(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xC6: // DEC $??
|
case 0xC6: // DEC $??
|
||||||
MR_ZP(); DEC(); MW_ZP();
|
MR_ZP(); DEC(); MW_ZP();
|
||||||
ADD_CYCLE(5);
|
ADD_CYCLE(5);
|
||||||
break;
|
break;
|
||||||
case 0xD6: // DEC $??X
|
case 0xD6: // DEC $??,X
|
||||||
MR_ZX(); DEC(); MW_ZP();
|
MR_ZX(); DEC(); MW_ZP();
|
||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
@ -208,10 +211,11 @@ namespace VirtualNes.Core
|
|||||||
MR_AB(); DEC(); MW_EA();
|
MR_AB(); DEC(); MW_EA();
|
||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
case 0xDE: // DEC $????X
|
case 0xDE: // DEC $????,X
|
||||||
MR_AX(); DEC(); MW_EA();
|
MR_AX(); DEC(); MW_EA();
|
||||||
ADD_CYCLE(7);
|
ADD_CYCLE(7);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xCA: // DEX
|
case 0xCA: // DEX
|
||||||
DEX();
|
DEX();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
@ -220,11 +224,12 @@ namespace VirtualNes.Core
|
|||||||
DEY();
|
DEY();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xE6: // INC $??
|
case 0xE6: // INC $??
|
||||||
MR_ZP(); INC(); MW_ZP();
|
MR_ZP(); INC(); MW_ZP();
|
||||||
ADD_CYCLE(5);
|
ADD_CYCLE(5);
|
||||||
break;
|
break;
|
||||||
case 0xF6: // INC $??X
|
case 0xF6: // INC $??,X
|
||||||
MR_ZX(); INC(); MW_ZP();
|
MR_ZX(); INC(); MW_ZP();
|
||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
@ -232,10 +237,11 @@ namespace VirtualNes.Core
|
|||||||
MR_AB(); INC(); MW_EA();
|
MR_AB(); INC(); MW_EA();
|
||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
case 0xFE: // INC $????X
|
case 0xFE: // INC $????,X
|
||||||
MR_AX(); INC(); MW_EA();
|
MR_AX(); INC(); MW_EA();
|
||||||
ADD_CYCLE(7);
|
ADD_CYCLE(7);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xE8: // INX
|
case 0xE8: // INX
|
||||||
INX();
|
INX();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
@ -244,6 +250,7 @@ namespace VirtualNes.Core
|
|||||||
INY();
|
INY();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x29: // AND #$??
|
case 0x29: // AND #$??
|
||||||
MR_IM(); AND();
|
MR_IM(); AND();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
@ -252,7 +259,7 @@ namespace VirtualNes.Core
|
|||||||
MR_ZP(); AND();
|
MR_ZP(); AND();
|
||||||
ADD_CYCLE(3);
|
ADD_CYCLE(3);
|
||||||
break;
|
break;
|
||||||
case 0x35: // AND $??X
|
case 0x35: // AND $??,X
|
||||||
MR_ZX(); AND();
|
MR_ZX(); AND();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
@ -260,22 +267,23 @@ namespace VirtualNes.Core
|
|||||||
MR_AB(); AND();
|
MR_AB(); AND();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0x3D: // AND $????X
|
case 0x3D: // AND $????,X
|
||||||
MR_AX(); AND(); CHECK_EA();
|
MR_AX(); AND(); CHECK_EA();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0x39: // AND $????Y
|
case 0x39: // AND $????,Y
|
||||||
MR_AY(); AND(); CHECK_EA();
|
MR_AY(); AND(); CHECK_EA();
|
||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
case 0x21: // AND ($??X)
|
case 0x21: // AND ($??,X)
|
||||||
MR_IX(); AND();
|
MR_IX(); AND();
|
||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
case 0x31: // AND ($??)Y
|
case 0x31: // AND ($??),Y
|
||||||
MR_IY(); AND(); CHECK_EA();
|
MR_IY(); AND(); CHECK_EA();
|
||||||
ADD_CYCLE(5);
|
ADD_CYCLE(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0A: // ASL A
|
case 0x0A: // ASL A
|
||||||
ASL_A();
|
ASL_A();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
@ -705,7 +713,7 @@ namespace VirtualNes.Core
|
|||||||
ADD_CYCLE(6);
|
ADD_CYCLE(6);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 僼儔僌惂屼宯
|
// フラグ制御系
|
||||||
case 0x18: // CLC
|
case 0x18: // CLC
|
||||||
CLC();
|
CLC();
|
||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
@ -736,7 +744,7 @@ namespace VirtualNes.Core
|
|||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 僗僞僢僋宯
|
// スタック系
|
||||||
case 0x48: // PHA
|
case 0x48: // PHA
|
||||||
PUSH(R.A);
|
PUSH(R.A);
|
||||||
ADD_CYCLE(3);
|
ADD_CYCLE(3);
|
||||||
@ -755,7 +763,7 @@ namespace VirtualNes.Core
|
|||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 偦偺懠
|
// その他
|
||||||
case 0x00: // BRK
|
case 0x00: // BRK
|
||||||
BRK();
|
BRK();
|
||||||
ADD_CYCLE(7);
|
ADD_CYCLE(7);
|
||||||
@ -765,7 +773,7 @@ namespace VirtualNes.Core
|
|||||||
ADD_CYCLE(2);
|
ADD_CYCLE(2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// 枹岞奐柦椷孮
|
// 未公開命令群
|
||||||
case 0x0B: // ANC #$??
|
case 0x0B: // ANC #$??
|
||||||
case 0x2B: // ANC #$??
|
case 0x2B: // ANC #$??
|
||||||
MR_IM(); ANC();
|
MR_IM(); ANC();
|
||||||
@ -1105,7 +1113,7 @@ namespace VirtualNes.Core
|
|||||||
default:
|
default:
|
||||||
if (!Supporter.Config.emulator.bIllegalOp)
|
if (!Supporter.Config.emulator.bIllegalOp)
|
||||||
{
|
{
|
||||||
throw new Exception("Illegal Opcode");
|
throw new Exception("IllegalOp");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1113,6 +1121,8 @@ namespace VirtualNes.Core
|
|||||||
ADD_CYCLE(4);
|
ADD_CYCLE(4);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// default:
|
||||||
|
// __assume(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nmi_request != 0)
|
if (nmi_request != 0)
|
||||||
@ -1143,7 +1153,6 @@ namespace VirtualNes.Core
|
|||||||
#endif
|
#endif
|
||||||
return TOTAL_cycles - OLD_cycles;
|
return TOTAL_cycles - OLD_cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void _IRQ()
|
private void _IRQ()
|
||||||
{
|
{
|
||||||
PUSH((byte)(R.PC >> 8));
|
PUSH((byte)(R.PC >> 8));
|
||||||
@ -1169,7 +1178,7 @@ namespace VirtualNes.Core
|
|||||||
return (ushort)(nes.Read(addr) + nes.Read((ushort)(addr + 1)) * 0x100);
|
return (ushort)(nes.Read(addr) + nes.Read((ushort)(addr + 1)) * 0x100);
|
||||||
}
|
}
|
||||||
|
|
||||||
var temp = MMU.CPU_MEM_BANK[addr >> 13].Span;
|
var temp = MMU.CPU_MEM_BANK[addr >> 13];
|
||||||
shortTemp[0] = temp[addr & 0x1FFF];
|
shortTemp[0] = temp[addr & 0x1FFF];
|
||||||
shortTemp[1] = temp[(addr & 0x1FFF) + 1];
|
shortTemp[1] = temp[(addr & 0x1FFF) + 1];
|
||||||
return BitConverter.ToUInt16(shortTemp, 0);
|
return BitConverter.ToUInt16(shortTemp, 0);
|
||||||
@ -1716,14 +1725,14 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
internal byte OP6502(ushort addr)
|
internal byte OP6502(ushort addr)
|
||||||
{
|
{
|
||||||
return MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF];
|
return MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] shortTemp = new byte[2];
|
private byte[] shortTemp = new byte[2];
|
||||||
internal ushort OP6502W(ushort addr)
|
internal ushort OP6502W(ushort addr)
|
||||||
{
|
{
|
||||||
var bytePage = MMU.CPU_MEM_BANK[addr >> 13];
|
var bytePage = MMU.CPU_MEM_BANK[addr >> 13];
|
||||||
var spanByte = bytePage.Span;
|
var spanByte = bytePage;
|
||||||
shortTemp[0] = spanByte[addr & 0x1FFF];
|
shortTemp[0] = spanByte[addr & 0x1FFF];
|
||||||
shortTemp[1] = spanByte[(addr & 0x1FFF) + 1];
|
shortTemp[1] = spanByte[(addr & 0x1FFF) + 1];
|
||||||
return BitConverter.ToUInt16(shortTemp, 0);
|
return BitConverter.ToUInt16(shortTemp, 0);
|
||||||
@ -1744,11 +1753,11 @@ namespace VirtualNes.Core
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Dummy access
|
// Dummy access
|
||||||
mapper.Read(addr, MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF]);
|
mapper.Read(addr, MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Quick bank read
|
// Quick bank read
|
||||||
return MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF];
|
return MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AND()
|
private void AND()
|
||||||
@ -1836,7 +1845,7 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
ET = OP6502W(R.PC);
|
ET = OP6502W(R.PC);
|
||||||
R.PC += 2;
|
R.PC += 2;
|
||||||
EA = (byte)(ET + R.X);
|
EA = (ushort)(ET + R.X);
|
||||||
DT = RD6502(EA);
|
DT = RD6502(EA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,22 @@
|
|||||||
{
|
{
|
||||||
public class CHEATCODE
|
public class CHEATCODE
|
||||||
{
|
{
|
||||||
|
// 埲壓偺俀偮偼OR儅僗僋
|
||||||
|
public const int CHEAT_ENABLE = 1 << 0;
|
||||||
|
public const int CHEAT_KEYDISABLE = 1 << 1;
|
||||||
|
|
||||||
|
// 彂偒崬傒庬椶
|
||||||
|
public const int CHEAT_TYPE_ALWAYS = 0; // 忢偵彂偒崬傒
|
||||||
|
public const int CHEAT_TYPE_ONCE = 1; // 侾夞偩偗彂偒崬傒
|
||||||
|
public const int CHEAT_TYPE_GREATER = 2; // 僨乕僞傛傝戝偒偄帪
|
||||||
|
public const int CHEAT_TYPE_LESS = 3; // 僨乕僞傛傝彫偝偄帪
|
||||||
|
|
||||||
|
// 僨乕僞挿
|
||||||
|
public const int CHEAT_LENGTH_1BYTE = 0;
|
||||||
|
public const int CHEAT_LENGTH_2BYTE = 1;
|
||||||
|
public const int CHEAT_LENGTH_3BYTE = 2;
|
||||||
|
public const int CHEAT_LENGTH_4BYTE = 3;
|
||||||
|
|
||||||
public byte enable;
|
public byte enable;
|
||||||
public byte type;
|
public byte type;
|
||||||
public byte length;
|
public byte length;
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class ByteArrayRef
|
||||||
|
{
|
||||||
|
private byte[] m_rawArray;
|
||||||
|
private int m_offset;
|
||||||
|
private int m_length;
|
||||||
|
|
||||||
|
public ByteArrayRef(byte[] array, int offset, int length)
|
||||||
|
{
|
||||||
|
m_rawArray = array;
|
||||||
|
m_offset = offset;
|
||||||
|
m_length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_rawArray[m_offset + index];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
m_rawArray[(m_offset + index)] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: fe59f85b299db6f498a7e87a5125df58
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,17 +1,26 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public static class MemoryUtility
|
public static class MemoryUtility
|
||||||
{
|
{
|
||||||
public static void ZEROMEMORY(byte[] array, uint length)
|
public static void ZEROMEMORY(byte[] array, int length)
|
||||||
{
|
{
|
||||||
memset(array, 0, length);
|
Array.Clear(array, 0, array.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void memset(byte[] array, byte value, uint length)
|
public static void memset(byte[] array, byte value, int length)
|
||||||
{
|
{
|
||||||
Unsafe.InitBlock(ref array[0], value, length);
|
memset(array, 0, value, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void memset(byte[] array, int offset, byte value, int length)
|
||||||
|
{
|
||||||
|
for (int i = offset; i < length; i++)
|
||||||
|
{
|
||||||
|
array[i] = value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
namespace VirtualNes.Core.Debug
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core.Debug
|
||||||
{
|
{
|
||||||
public static class Debuger
|
public static class Debuger
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using VirtualNes.Core;
|
||||||
|
|
||||||
namespace VirtualNes
|
namespace VirtualNes
|
||||||
{
|
{
|
||||||
public static class MMU
|
public static class MMU
|
||||||
{
|
{
|
||||||
// CPU 儊儌儕僶儞僋
|
// CPU 儊儌儕僶儞僋
|
||||||
public static Memory<byte>[] CPU_MEM_BANK = new Memory<byte>[8]; // 8K扨埵
|
public static ByteArrayRef[] CPU_MEM_BANK = new ByteArrayRef[8]; // 8K扨埵
|
||||||
public static byte[] CPU_MEM_TYPE = new byte[8];
|
public static byte[] CPU_MEM_TYPE = new byte[8];
|
||||||
public static int[] CPU_MEM_PAGE = new int[8]; // 僗僥乕僩僙乕僽梡
|
public static int[] CPU_MEM_PAGE = new int[8]; // 僗僥乕僩僙乕僽梡
|
||||||
// PPU 儊儌儕僶儞僋
|
// PPU 儊儌儕僶儞僋
|
||||||
public static Memory<byte>[] PPU_MEM_BANK = new Memory<byte>[12]; // 1K扨埵
|
public static ByteArrayRef[] PPU_MEM_BANK = new ByteArrayRef[12]; // 1K扨埵
|
||||||
public static byte[] PPU_MEM_TYPE = new byte[12];
|
public static byte[] PPU_MEM_TYPE = new byte[12];
|
||||||
public static int[] PPU_MEM_PAGE = new int[12]; // 僗僥乕僩僙乕僽梡
|
public static int[] PPU_MEM_PAGE = new int[12]; // 僗僥乕僩僙乕僽梡
|
||||||
public static byte[] CRAM_USED = new byte[16]; // 僗僥乕僩僙乕僽梡
|
public static byte[] CRAM_USED = new byte[16]; // 僗僥乕僩僙乕僽梡
|
||||||
@ -67,9 +68,12 @@ namespace VirtualNes
|
|||||||
public const byte VRAM_MIRROR4L = 0x03; // PA10 L屌掕 $2000-$23FF偺儈儔乕
|
public const byte VRAM_MIRROR4L = 0x03; // PA10 L屌掕 $2000-$23FF偺儈儔乕
|
||||||
public const byte VRAM_MIRROR4H = 0x04; // PA10 H屌掕 $2400-$27FF偺儈儔乕
|
public const byte VRAM_MIRROR4H = 0x04; // PA10 H屌掕 $2400-$27FF偺儈儔乕
|
||||||
|
|
||||||
internal static void SetPROM_Bank(byte page, Memory<byte> ptr, byte type)
|
// Frame-IRQ儗僕僗僞($4017)
|
||||||
|
public static int FrameIRQ;
|
||||||
|
|
||||||
|
internal static void SetPROM_Bank(byte page, byte[] ptr, byte type)
|
||||||
{
|
{
|
||||||
CPU_MEM_BANK[page] = ptr;
|
CPU_MEM_BANK[page] = new ByteArrayRef(ptr, 0, ptr.Length);
|
||||||
CPU_MEM_TYPE[page] = type;
|
CPU_MEM_TYPE[page] = type;
|
||||||
CPU_MEM_PAGE[page] = 0;
|
CPU_MEM_PAGE[page] = 0;
|
||||||
}
|
}
|
||||||
@ -77,7 +81,7 @@ namespace VirtualNes
|
|||||||
internal static void SetPROM_8K_Bank(byte page, int bank)
|
internal static void SetPROM_8K_Bank(byte page, int bank)
|
||||||
{
|
{
|
||||||
bank %= PROM_8K_SIZE;
|
bank %= PROM_8K_SIZE;
|
||||||
CPU_MEM_BANK[page] = new Memory<byte>(MMU.PROM, 0x2000 * bank, MMU.PROM.Length - 0x2000 * bank);
|
CPU_MEM_BANK[page] = new ByteArrayRef(MMU.PROM, 0x2000 * bank, MMU.PROM.Length - 0x2000 * bank);
|
||||||
CPU_MEM_TYPE[page] = BANKTYPE_ROM;
|
CPU_MEM_TYPE[page] = BANKTYPE_ROM;
|
||||||
CPU_MEM_PAGE[page] = bank;
|
CPU_MEM_PAGE[page] = bank;
|
||||||
}
|
}
|
||||||
@ -105,7 +109,7 @@ namespace VirtualNes
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PPU VROM bank
|
// PPU VROM bank
|
||||||
internal static void SetVROM_Bank(byte page, Memory<byte> ptr, byte type)
|
internal static void SetVROM_Bank(byte page, ByteArrayRef ptr, byte type)
|
||||||
{
|
{
|
||||||
PPU_MEM_BANK[page] = ptr;
|
PPU_MEM_BANK[page] = ptr;
|
||||||
PPU_MEM_TYPE[page] = type;
|
PPU_MEM_TYPE[page] = type;
|
||||||
@ -115,7 +119,7 @@ namespace VirtualNes
|
|||||||
internal static void SetVROM_1K_Bank(byte page, int bank)
|
internal static void SetVROM_1K_Bank(byte page, int bank)
|
||||||
{
|
{
|
||||||
bank %= VROM_1K_SIZE;
|
bank %= VROM_1K_SIZE;
|
||||||
PPU_MEM_BANK[page] = new Memory<byte>(VROM, 0x0400 * bank, VROM.Length - (0x0400 * bank));
|
PPU_MEM_BANK[page] = new ByteArrayRef(VROM, 0x0400 * bank, VROM.Length - (0x0400 * bank));
|
||||||
PPU_MEM_TYPE[page] = BANKTYPE_VROM;
|
PPU_MEM_TYPE[page] = BANKTYPE_VROM;
|
||||||
PPU_MEM_PAGE[page] = bank;
|
PPU_MEM_PAGE[page] = bank;
|
||||||
}
|
}
|
||||||
@ -158,7 +162,7 @@ namespace VirtualNes
|
|||||||
internal static void SetCRAM_1K_Bank(byte page, int bank)
|
internal static void SetCRAM_1K_Bank(byte page, int bank)
|
||||||
{
|
{
|
||||||
bank &= 0x1F;
|
bank &= 0x1F;
|
||||||
PPU_MEM_BANK[page] = new Memory<byte>(MMU.CRAM, 0x0400 * bank, MMU.CRAM.Length - 0x0400 * bank);
|
PPU_MEM_BANK[page] = new ByteArrayRef(MMU.CRAM, 0x0400 * bank, MMU.CRAM.Length - 0x0400 * bank);
|
||||||
PPU_MEM_TYPE[page] = BANKTYPE_CRAM;
|
PPU_MEM_TYPE[page] = BANKTYPE_CRAM;
|
||||||
PPU_MEM_PAGE[page] = bank;
|
PPU_MEM_PAGE[page] = bank;
|
||||||
|
|
||||||
@ -190,7 +194,7 @@ namespace VirtualNes
|
|||||||
internal static void SetVRAM_1K_Bank(byte page, int bank)
|
internal static void SetVRAM_1K_Bank(byte page, int bank)
|
||||||
{
|
{
|
||||||
bank &= 3;
|
bank &= 3;
|
||||||
PPU_MEM_BANK[page] = new Memory<byte>(VRAM, 0x0400 * bank, VRAM.Length - 0x0400 * bank);
|
PPU_MEM_BANK[page] = new ByteArrayRef(VRAM, 0x0400 * bank, VRAM.Length - 0x0400 * bank);
|
||||||
PPU_MEM_TYPE[page] = BANKTYPE_VRAM;
|
PPU_MEM_TYPE[page] = BANKTYPE_VRAM;
|
||||||
PPU_MEM_PAGE[page] = bank;
|
PPU_MEM_PAGE[page] = bank;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ namespace VirtualNes.Core
|
|||||||
public abstract class Mapper
|
public abstract class Mapper
|
||||||
{
|
{
|
||||||
protected NES nes;
|
protected NES nes;
|
||||||
|
|
||||||
public Mapper(NES parent)
|
public Mapper(NES parent)
|
||||||
{
|
{
|
||||||
nes = parent;
|
nes = parent;
|
||||||
@ -25,7 +26,7 @@ namespace VirtualNes.Core
|
|||||||
// $6000-$7FFF WRAM
|
// $6000-$7FFF WRAM
|
||||||
if (addr >= 0x6000 && addr <= 0x7FFF)
|
if (addr >= 0x6000 && addr <= 0x7FFF)
|
||||||
{
|
{
|
||||||
return MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF];
|
return MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (byte)(addr >> 8);
|
return (byte)(addr >> 8);
|
||||||
@ -34,7 +35,7 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
if (addr >= 0x6000 && addr <= 0x7FFF)
|
if (addr >= 0x6000 && addr <= 0x7FFF)
|
||||||
{
|
{
|
||||||
MMU.CPU_MEM_BANK[addr >> 13].Span[addr & 0x1FFF] = data;
|
MMU.CPU_MEM_BANK[addr >> 13][addr & 0x1FFF] = data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,10 +79,13 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
public static Mapper CreateMapper(NES parent, int no)
|
public static Mapper CreateMapper(NES parent, int no)
|
||||||
{
|
{
|
||||||
|
//todo : 实现加载mapper
|
||||||
switch (no)
|
switch (no)
|
||||||
{
|
{
|
||||||
|
case 4:
|
||||||
|
return new Mapper004(parent);
|
||||||
default:
|
default:
|
||||||
throw new NotImplementedException($"Mapper#{no} is not Impl");
|
throw new NotImplementedException($"Mapper#{no:000} is not Impl");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,576 @@
|
|||||||
|
using Codice.CM.Client.Differences;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class Mapper004 : Mapper
|
||||||
|
{
|
||||||
|
private const int MMC3_IRQ_KLAX = 1;
|
||||||
|
private const int MMC3_IRQ_SHOUGIMEIKAN = 2;
|
||||||
|
private const int MMC3_IRQ_DAI2JISUPER = 3;
|
||||||
|
private const int MMC3_IRQ_DBZ2 = 4;
|
||||||
|
private const int MMC3_IRQ_ROCKMAN3 = 5;
|
||||||
|
|
||||||
|
protected byte[] reg = new byte[8];
|
||||||
|
protected byte prg0, prg1;
|
||||||
|
protected byte chr01, chr23, chr4, chr5, chr6, chr7;
|
||||||
|
protected byte we_sram;
|
||||||
|
|
||||||
|
protected byte irq_type;
|
||||||
|
protected byte irq_enable;
|
||||||
|
protected byte irq_counter;
|
||||||
|
protected byte irq_latch;
|
||||||
|
protected byte irq_request;
|
||||||
|
protected byte irq_preset;
|
||||||
|
protected byte irq_preset_vbl;
|
||||||
|
|
||||||
|
protected byte vs_patch;
|
||||||
|
protected byte vs_index;
|
||||||
|
|
||||||
|
private byte[] VS_TKO_Security = new byte[32]
|
||||||
|
{
|
||||||
|
0xff, 0xbf, 0xb7, 0x97, 0x97, 0x17, 0x57, 0x4f,
|
||||||
|
0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90, 0x94, 0x14,
|
||||||
|
0x56, 0x4e, 0x6f, 0x6b, 0xeb, 0xa9, 0xb1, 0x90,
|
||||||
|
0xd4, 0x5c, 0x3e, 0x26, 0x87, 0x83, 0x13, 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
public Mapper004(NES parent) : base(parent) { }
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
reg[i] = 0x00;
|
||||||
|
}
|
||||||
|
|
||||||
|
prg0 = 0;
|
||||||
|
prg1 = 1;
|
||||||
|
SetBank_CPU();
|
||||||
|
|
||||||
|
chr01 = 0;
|
||||||
|
chr23 = 2;
|
||||||
|
chr4 = 4;
|
||||||
|
chr5 = 5;
|
||||||
|
chr6 = 6;
|
||||||
|
chr7 = 7;
|
||||||
|
SetBank_PPU();
|
||||||
|
|
||||||
|
we_sram = 0; // Disable
|
||||||
|
irq_enable = 0; // Disable
|
||||||
|
irq_counter = 0;
|
||||||
|
irq_latch = 0xFF;
|
||||||
|
irq_request = 0;
|
||||||
|
irq_preset = 0;
|
||||||
|
irq_preset_vbl = 0;
|
||||||
|
|
||||||
|
// IRQ僞僀僾愝掕
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_CLOCK);
|
||||||
|
irq_type = 0;
|
||||||
|
|
||||||
|
uint crc = nes.rom.GetPROM_CRC();
|
||||||
|
|
||||||
|
if (crc == 0x5c707ac4)
|
||||||
|
{ // Mother(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0xcb106f49)
|
||||||
|
{ // F-1 Sensation(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x1170392a)
|
||||||
|
{ // Karakuri Kengou Den - Musashi Road - Karakuri Nin Hashiru!(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0x14a01c70)
|
||||||
|
{ // Gun-Dec(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0xeffeea40)
|
||||||
|
{ // For Klax(J)
|
||||||
|
irq_type = MMC3_IRQ_KLAX;
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0xc17ae2dc)
|
||||||
|
{ // God Slayer - Haruka Tenkuu no Sonata(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x126ea4a0)
|
||||||
|
{ // Summer Carnival '92 - Recca(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0x1f2f4861)
|
||||||
|
{ // J League Fighting Soccer - The King of Ace Strikers(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0x5a6860f1)
|
||||||
|
{ // Shougi Meikan '92(J)
|
||||||
|
irq_type = MMC3_IRQ_SHOUGIMEIKAN;
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0xae280e20)
|
||||||
|
{ // Shougi Meikan '93(J)
|
||||||
|
irq_type = MMC3_IRQ_SHOUGIMEIKAN;
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0xe19a2473)
|
||||||
|
{ // Sugoro Quest - Dice no Senshi Tachi(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x702d9b33)
|
||||||
|
{ // Star Wars - The Empire Strikes Back(Victor)(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0xa9a0d729)
|
||||||
|
{ // Dai Kaijuu - Deburas(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0xc5fea9f2)
|
||||||
|
{ // Dai 2 Ji - Super Robot Taisen(J)
|
||||||
|
irq_type = MMC3_IRQ_DAI2JISUPER;
|
||||||
|
}
|
||||||
|
if (crc == 0xd852c2f7)
|
||||||
|
{ // Time Zone(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0xecfd3c69)
|
||||||
|
{ // Taito Chase H.Q.(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x7a748058)
|
||||||
|
{ // Tom & Jerry (and Tuffy)(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0xaafe699c)
|
||||||
|
{ // Ninja Ryukenden 3 - Yomi no Hakobune(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x6cc62c06)
|
||||||
|
{ // Hoshi no Kirby - Yume no Izumi no Monogatari(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x877dba77)
|
||||||
|
{ // My Life My Love - Boku no Yume - Watashi no Negai(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0x6f96ed15)
|
||||||
|
{ // Max Warrior - Wakusei Kaigenrei(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0x8685f366)
|
||||||
|
{ // Matendouji(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x8635fed1)
|
||||||
|
{ // Mickey Mouse 3 - Yume Fuusen(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x26ff3ea2)
|
||||||
|
{ // Yume Penguin Monogatari(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0x7671bc51)
|
||||||
|
{ // Red Ariimaa 2(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0xade11141)
|
||||||
|
{ // Wanpaku Kokkun no Gourmet World(J)
|
||||||
|
nes.SetIrqType(NES.IRQMETHOD.IRQ_HSYNC);
|
||||||
|
}
|
||||||
|
if (crc == 0x7c7ab58e)
|
||||||
|
{ // Walkuere no Bouken - Toki no Kagi Densetsu(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.POST_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x26ff3ea2)
|
||||||
|
{ // Yume Penguin Monogatari(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
if (crc == 0x126ea4a0)
|
||||||
|
{ // Summer Carnival '92 Recca(J)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crc == 0x1d2e5018 // Rockman 3(J)
|
||||||
|
|| crc == 0x6b999aaf)
|
||||||
|
{ // Megaman 3(U)
|
||||||
|
irq_type = MMC3_IRQ_ROCKMAN3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crc == 0xd88d48d7)
|
||||||
|
{ // Kick Master(U)
|
||||||
|
irq_type = MMC3_IRQ_ROCKMAN3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crc == 0xA67EA466)
|
||||||
|
{ // Alien 3(U)
|
||||||
|
nes.SetRenderMethod(EnumRenderMethod.TILE_RENDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crc == 0xe763891b)
|
||||||
|
{ // DBZ2
|
||||||
|
irq_type = MMC3_IRQ_DBZ2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// VS-Unisystem
|
||||||
|
vs_patch = 0;
|
||||||
|
vs_index = 0;
|
||||||
|
|
||||||
|
if (crc == 0xeb2dba63 // VS TKO Boxing
|
||||||
|
|| crc == 0x98cfe016)
|
||||||
|
{ // VS TKO Boxing (Alt)
|
||||||
|
vs_patch = 1;
|
||||||
|
}
|
||||||
|
if (crc == 0x135adf7c)
|
||||||
|
{ // VS Atari RBI Baseball
|
||||||
|
vs_patch = 2;
|
||||||
|
}
|
||||||
|
if (crc == 0xf9d3b0a3 // VS Super Xevious
|
||||||
|
|| crc == 0x9924980a // VS Super Xevious (b1)
|
||||||
|
|| crc == 0x66bb838f)
|
||||||
|
{ // VS Super Xevious (b2)
|
||||||
|
vs_patch = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetBank_PPU()
|
||||||
|
{
|
||||||
|
if (MMU.VROM_1K_SIZE != 0)
|
||||||
|
{
|
||||||
|
if ((reg[0] & 0x80) != 0)
|
||||||
|
{
|
||||||
|
MMU.SetVROM_8K_Bank(chr4, chr5, chr6, chr7,
|
||||||
|
chr01, chr01 + 1, chr23, chr23 + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.SetVROM_8K_Bank(chr01, chr01 + 1, chr23, chr23 + 1,
|
||||||
|
chr4, chr5, chr6, chr7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((reg[0] & 0x80) != 0)
|
||||||
|
{
|
||||||
|
MMU.SetCRAM_1K_Bank(4, (chr01 + 0) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(5, (chr01 + 1) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(6, (chr23 + 0) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(7, (chr23 + 1) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(0, chr4 & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(1, chr5 & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(2, chr6 & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(3, chr7 & 0x07);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.SetCRAM_1K_Bank(0, (chr01 + 0) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(1, (chr01 + 1) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(2, (chr23 + 0) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(3, (chr23 + 1) & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(4, chr4 & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(5, chr5 & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(6, chr6 & 0x07);
|
||||||
|
MMU.SetCRAM_1K_Bank(7, chr7 & 0x07);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override byte ReadLow(ushort addr)
|
||||||
|
{
|
||||||
|
if (vs_patch == 0)
|
||||||
|
{
|
||||||
|
if (addr >= 0x5000 && addr <= 0x5FFF)
|
||||||
|
{
|
||||||
|
return MMU.XRAM[addr - 0x4000];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vs_patch == 1)
|
||||||
|
{
|
||||||
|
// VS TKO Boxing Security
|
||||||
|
if (addr == 0x5E00)
|
||||||
|
{
|
||||||
|
vs_index = 0;
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
else if (addr == 0x5E01)
|
||||||
|
{
|
||||||
|
return VS_TKO_Security[(vs_index++) & 0x1F];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vs_patch == 2)
|
||||||
|
{
|
||||||
|
// VS Atari RBI Baseball Security
|
||||||
|
if (addr == 0x5E00)
|
||||||
|
{
|
||||||
|
vs_index = 0;
|
||||||
|
return 0x00;
|
||||||
|
}
|
||||||
|
else if (addr == 0x5E01)
|
||||||
|
{
|
||||||
|
if (vs_index++ == 9)
|
||||||
|
return 0x6F;
|
||||||
|
else
|
||||||
|
return 0xB4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (vs_patch == 3)
|
||||||
|
{
|
||||||
|
// VS Super Xevious
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x54FF:
|
||||||
|
return 0x05;
|
||||||
|
case 0x5678:
|
||||||
|
if (vs_index != 0)
|
||||||
|
return 0x00;
|
||||||
|
else
|
||||||
|
return 0x01;
|
||||||
|
case 0x578f:
|
||||||
|
if (vs_index != 0)
|
||||||
|
return 0xD1;
|
||||||
|
else
|
||||||
|
return 0x89;
|
||||||
|
case 0x5567:
|
||||||
|
if (vs_index != 0)
|
||||||
|
{
|
||||||
|
vs_index = 0;
|
||||||
|
return 0x3E;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vs_index = 1;
|
||||||
|
return 0x37;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.ReadLow(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void WriteLow(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
if (addr >= 0x5000 && addr <= 0x5FFF)
|
||||||
|
{
|
||||||
|
MMU.XRAM[addr - 0x4000] = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
base.WriteLow(addr, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Write(ushort addr, byte data)
|
||||||
|
{
|
||||||
|
switch (addr & 0xE001)
|
||||||
|
{
|
||||||
|
case 0x8000:
|
||||||
|
reg[0] = data;
|
||||||
|
SetBank_CPU();
|
||||||
|
SetBank_PPU();
|
||||||
|
break;
|
||||||
|
case 0x8001:
|
||||||
|
reg[1] = data;
|
||||||
|
|
||||||
|
switch (reg[0] & 0x07)
|
||||||
|
{
|
||||||
|
case 0x00:
|
||||||
|
chr01 = (byte)(data & 0xFE);
|
||||||
|
SetBank_PPU();
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
chr23 = (byte)(data & 0xFE);
|
||||||
|
SetBank_PPU();
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
chr4 = data;
|
||||||
|
SetBank_PPU();
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
chr5 = data;
|
||||||
|
SetBank_PPU();
|
||||||
|
break;
|
||||||
|
case 0x04:
|
||||||
|
chr6 = data;
|
||||||
|
SetBank_PPU();
|
||||||
|
break;
|
||||||
|
case 0x05:
|
||||||
|
chr7 = data;
|
||||||
|
SetBank_PPU();
|
||||||
|
break;
|
||||||
|
case 0x06:
|
||||||
|
prg0 = data;
|
||||||
|
SetBank_CPU();
|
||||||
|
break;
|
||||||
|
case 0x07:
|
||||||
|
prg1 = data;
|
||||||
|
SetBank_CPU();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xA000:
|
||||||
|
reg[2] = data;
|
||||||
|
if (!nes.rom.Is4SCREEN())
|
||||||
|
{
|
||||||
|
if ((data & 0x01) != 0) MMU.SetVRAM_Mirror(MMU.VRAM_HMIRROR);
|
||||||
|
else MMU.SetVRAM_Mirror(MMU.VRAM_VMIRROR);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xA001:
|
||||||
|
reg[3] = data;
|
||||||
|
//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() );
|
||||||
|
break;
|
||||||
|
case 0xC000:
|
||||||
|
//DEBUGOUT( "MPRWR A=%04X D=%02X L=%3d CYC=%d\n", addr&0xFFFF, data&0xFF, nes->GetScanline(), nes->cpu->GetTotalCycles() );
|
||||||
|
reg[4] = data;
|
||||||
|
if (irq_type == MMC3_IRQ_KLAX || irq_type == MMC3_IRQ_ROCKMAN3)
|
||||||
|
{
|
||||||
|
irq_counter = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
irq_latch = data;
|
||||||
|
}
|
||||||
|
if (irq_type == MMC3_IRQ_DBZ2)
|
||||||
|
{
|
||||||
|
irq_latch = 0x07;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xC001:
|
||||||
|
reg[5] = data;
|
||||||
|
if (irq_type == MMC3_IRQ_KLAX || irq_type == MMC3_IRQ_ROCKMAN3)
|
||||||
|
{
|
||||||
|
irq_latch = data;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((nes.GetScanline() < 240) || (irq_type == MMC3_IRQ_SHOUGIMEIKAN))
|
||||||
|
{
|
||||||
|
irq_counter |= 0x80;
|
||||||
|
irq_preset = 0xFF;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
irq_counter |= 0x80;
|
||||||
|
irq_preset_vbl = 0xFF;
|
||||||
|
irq_preset = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xE000:
|
||||||
|
reg[6] = data;
|
||||||
|
irq_enable = 0;
|
||||||
|
irq_request = 0;
|
||||||
|
|
||||||
|
nes.cpu.ClrIRQ(CPU.IRQ_MAPPER);
|
||||||
|
break;
|
||||||
|
case 0xE001:
|
||||||
|
reg[7] = data;
|
||||||
|
irq_enable = 1;
|
||||||
|
irq_request = 0;
|
||||||
|
|
||||||
|
// nes->cpu->ClrIRQ( IRQ_MAPPER );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Clock(int cycles)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void HSync(int scanline)
|
||||||
|
{
|
||||||
|
if (irq_type == MMC3_IRQ_KLAX)
|
||||||
|
{
|
||||||
|
if ((scanline >= 0 && scanline <= 239) && nes.ppu.IsDispON())
|
||||||
|
{
|
||||||
|
if (irq_enable != 0)
|
||||||
|
{
|
||||||
|
if (irq_counter == 0)
|
||||||
|
{
|
||||||
|
irq_counter = irq_latch;
|
||||||
|
irq_request = 0xFF;
|
||||||
|
}
|
||||||
|
if (irq_counter > 0)
|
||||||
|
{
|
||||||
|
irq_counter--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (irq_request != 0)
|
||||||
|
{
|
||||||
|
nes.cpu.SetIRQ(CPU.IRQ_MAPPER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (irq_type == MMC3_IRQ_ROCKMAN3)
|
||||||
|
{
|
||||||
|
if ((scanline >= 0 && scanline <= 239) && nes.ppu.IsDispON())
|
||||||
|
{
|
||||||
|
if (irq_enable != 0)
|
||||||
|
{
|
||||||
|
if ((--irq_counter) == 0)
|
||||||
|
{
|
||||||
|
irq_request = 0xFF;
|
||||||
|
irq_counter = irq_latch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (irq_request != 0)
|
||||||
|
{
|
||||||
|
nes.cpu.SetIRQ(CPU.IRQ_MAPPER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((scanline >= 0 && scanline <= 239) && nes.ppu.IsDispON())
|
||||||
|
{
|
||||||
|
if (irq_preset_vbl != 0)
|
||||||
|
{
|
||||||
|
irq_counter = irq_latch;
|
||||||
|
irq_preset_vbl = 0;
|
||||||
|
}
|
||||||
|
if (irq_preset != 0)
|
||||||
|
{
|
||||||
|
irq_counter = irq_latch;
|
||||||
|
irq_preset = 0;
|
||||||
|
if (irq_type == MMC3_IRQ_DAI2JISUPER && scanline == 0)
|
||||||
|
{
|
||||||
|
irq_counter--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (irq_counter > 0)
|
||||||
|
{
|
||||||
|
irq_counter--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (irq_counter == 0)
|
||||||
|
{
|
||||||
|
if (irq_enable != 0)
|
||||||
|
{
|
||||||
|
irq_request = 0xFF;
|
||||||
|
|
||||||
|
nes.cpu.SetIRQ(CPU.IRQ_MAPPER);
|
||||||
|
}
|
||||||
|
irq_preset = 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetBank_CPU()
|
||||||
|
{
|
||||||
|
if ((reg[0] & 0x40) != 0)
|
||||||
|
{
|
||||||
|
MMU.SetPROM_32K_Bank(MMU.PROM_8K_SIZE - 2, prg1, prg0, MMU.PROM_8K_SIZE - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.SetPROM_32K_Bank(prg0, prg1, MMU.PROM_8K_SIZE - 2, MMU.PROM_8K_SIZE - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 1be6fcc00c619e84cbf0d5d92701b2e3
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
File diff suppressed because it is too large
Load Diff
@ -330,7 +330,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetExController(EXCONTROLLER type)
|
internal void SetExController(EXCONTROLLER type)
|
||||||
{
|
{
|
||||||
excontroller_select = (int)type;
|
excontroller_select = (int)type;
|
||||||
|
|
||||||
@ -404,6 +404,42 @@ namespace VirtualNes.Core
|
|||||||
expad.Reset();
|
expad.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal bool IsZapperMode()
|
||||||
|
{
|
||||||
|
return bZapperMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void VSync()
|
||||||
|
{
|
||||||
|
padbitsync[0] = padbit[0];
|
||||||
|
padbitsync[1] = padbit[1];
|
||||||
|
padbitsync[2] = padbit[2];
|
||||||
|
padbitsync[3] = padbit[3];
|
||||||
|
micbitsync = micbit;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal uint GetSyncData()
|
||||||
|
{
|
||||||
|
uint ret;
|
||||||
|
ret = (uint)(padbit[0] | (padbit[1] << 8) | (padbit[2] << 16) | (padbit[3] << 24));
|
||||||
|
ret |= (uint)(micbit << 8);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetSyncData(uint data)
|
||||||
|
{
|
||||||
|
micbit = (byte)((data & 0x00000400) >> 8);
|
||||||
|
padbit[0] = (byte)data;
|
||||||
|
padbit[1] = (byte)(data >> 8);
|
||||||
|
padbit[2] = (byte)(data >> 16);
|
||||||
|
padbit[3] = (byte)(data >> 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal int GetExController()
|
||||||
|
{
|
||||||
|
return excontroller_select;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum VSType
|
public enum VSType
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using Codice.CM.Client.Differences;
|
namespace VirtualNes.Core
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
|
||||||
{
|
{
|
||||||
public class PPU
|
public class PPU
|
||||||
{
|
{
|
||||||
|
public const int SCREEN_WIDTH = 256 + 16;
|
||||||
|
public const int SCREEN_HEIGHT = 240;
|
||||||
|
|
||||||
private static byte[][] CreateCOLORMAP()
|
private static byte[][] CreateCOLORMAP()
|
||||||
{
|
{
|
||||||
byte[][] res = new byte[5][];
|
byte[][] res = new byte[5][];
|
||||||
@ -187,7 +187,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
addr &= 0xEFFF;
|
addr &= 0xEFFF;
|
||||||
}
|
}
|
||||||
MMU.PPU7_Temp = MMU.PPU_MEM_BANK[addr >> 10].Span[addr & 0x03FF];
|
MMU.PPU7_Temp = MMU.PPU_MEM_BANK[addr >> 10][addr & 0x03FF];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +199,7 @@ namespace VirtualNes.Core
|
|||||||
ScanlineNo = scanline;
|
ScanlineNo = scanline;
|
||||||
if (scanline < 240)
|
if (scanline < 240)
|
||||||
{
|
{
|
||||||
lpScanline = (int)(Screen.SCREEN_WIDTH) * scanline;
|
lpScanline = (SCREEN_WIDTH) * scanline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
if (MMU.PPU_MEM_TYPE[vaddr >> 10] != MMU.BANKTYPE_VROM)
|
if (MMU.PPU_MEM_TYPE[vaddr >> 10] != MMU.BANKTYPE_VROM)
|
||||||
{
|
{
|
||||||
MMU.PPU_MEM_BANK[vaddr >> 10].Span[vaddr & 0x03FF] = data;
|
MMU.PPU_MEM_BANK[vaddr >> 10][vaddr & 0x03FF] = data;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -358,15 +358,810 @@ namespace VirtualNes.Core
|
|||||||
loopy_shift = 0;
|
loopy_shift = 0;
|
||||||
|
|
||||||
if (lpScreen != null)
|
if (lpScreen != null)
|
||||||
MemoryUtility.memset(lpScreen, 0x3F, (int)(Screen.SCREEN_WIDTH) * (int)(Screen.SCREEN_HEIGHT));
|
MemoryUtility.memset(lpScreen, 0x3F, SCREEN_WIDTH * SCREEN_HEIGHT);
|
||||||
if (lpColormode != null)
|
if (lpColormode != null)
|
||||||
MemoryUtility.memset(lpColormode, 0, (int)(Screen.SCREEN_HEIGHT));
|
MemoryUtility.memset(lpColormode, 0, SCREEN_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Screen
|
internal void FrameStart()
|
||||||
{
|
{
|
||||||
SCREEN_WIDTH = 256 + 16,
|
if ((MMU.PPUREG[1] & (PPU_SPDISP_BIT | PPU_BGDISP_BIT)) != 0)
|
||||||
SCREEN_HEIGHT = 240
|
{
|
||||||
|
MMU.loopy_v = MMU.loopy_t;
|
||||||
|
loopy_shift = MMU.loopy_x;
|
||||||
|
loopy_y = (ushort)((MMU.loopy_v & 0x7000) >> 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lpScreen != null)
|
||||||
|
{
|
||||||
|
MemoryUtility.memset(lpScreen, 0x3F, SCREEN_WIDTH);
|
||||||
|
}
|
||||||
|
if (lpColormode != null)
|
||||||
|
{
|
||||||
|
lpColormode[0] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ScanlineNext()
|
||||||
|
{
|
||||||
|
if ((MMU.PPUREG[1] & (PPU_BGDISP_BIT | PPU_SPDISP_BIT)) != 0)
|
||||||
|
{
|
||||||
|
if ((MMU.loopy_v & 0x7000) == 0x7000)
|
||||||
|
{
|
||||||
|
MMU.loopy_v &= 0x8FFF;
|
||||||
|
if ((MMU.loopy_v & 0x03E0) == 0x03A0)
|
||||||
|
{
|
||||||
|
MMU.loopy_v ^= 0x0800;
|
||||||
|
MMU.loopy_v &= 0xFC1F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((MMU.loopy_v & 0x03E0) == 0x03E0)
|
||||||
|
{
|
||||||
|
MMU.loopy_v &= 0xFC1F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.loopy_v += 0x0020;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.loopy_v += 0x1000;
|
||||||
|
}
|
||||||
|
loopy_y = (ushort)((MMU.loopy_v & 0x7000) >> 12);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ScanlineStart()
|
||||||
|
{
|
||||||
|
if ((MMU.PPUREG[1] & (PPU_BGDISP_BIT | PPU_SPDISP_BIT)) != 0)
|
||||||
|
{
|
||||||
|
MMU.loopy_v = (ushort)((MMU.loopy_v & 0xFBE0) | (MMU.loopy_t & 0x041F));
|
||||||
|
loopy_shift = MMU.loopy_x;
|
||||||
|
loopy_y = (ushort)((MMU.loopy_v & 0x7000) >> 12);
|
||||||
|
nes.mapper.PPU_Latch((ushort)(0x2000 + (MMU.loopy_v & 0x0FFF)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] BGwrite = new byte[33 + 1];
|
||||||
|
private byte[] BGmono = new byte[33 + 1];
|
||||||
|
private byte[] SPwrite = new byte[33 + 1];
|
||||||
|
|
||||||
|
internal void Scanline(int scanline, bool bMax, bool bLeftClip)
|
||||||
|
{
|
||||||
|
int pScn = 0;
|
||||||
|
int pBGw = 0;
|
||||||
|
byte chr_h = 0, chr_l = 0, attr = 0;
|
||||||
|
|
||||||
|
MemoryUtility.ZEROMEMORY(BGwrite, BGwrite.Length);
|
||||||
|
MemoryUtility.ZEROMEMORY(BGmono, BGmono.Length);
|
||||||
|
|
||||||
|
// Linecolor mode
|
||||||
|
lpColormode[scanline] = (byte)(((MMU.PPUREG[1] & PPU_BGCOLOR_BIT) >> 5) | ((MMU.PPUREG[1] & PPU_COLORMODE_BIT) << 7));
|
||||||
|
|
||||||
|
// Render BG
|
||||||
|
if ((MMU.PPUREG[1] & PPU_BGDISP_BIT) == 0)
|
||||||
|
{
|
||||||
|
MemoryUtility.memset(lpScreen, lpScanline, MMU.BGPAL[0], SCREEN_WIDTH);
|
||||||
|
if (nes.GetRenderMethod() == EnumRenderMethod.TILE_RENDER)
|
||||||
|
{
|
||||||
|
nes.EmulationCPU(NES.FETCH_CYCLES * 4 * 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (nes.GetRenderMethod() != EnumRenderMethod.TILE_RENDER)
|
||||||
|
{
|
||||||
|
if (!bExtLatch)
|
||||||
|
{
|
||||||
|
// Without Extension Latch
|
||||||
|
pScn = lpScanline + (8 - loopy_shift);
|
||||||
|
pBGw = 0;
|
||||||
|
|
||||||
|
int tileofs = (MMU.PPUREG[0] & PPU_BGTBL_BIT) << 8;
|
||||||
|
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||||
|
int attradr = 0x23C0 + (MMU.loopy_v & 0x0C00) + ((MMU.loopy_v & 0x0380) >> 4);
|
||||||
|
int ntbl_x = ntbladr & 0x001F;
|
||||||
|
int attrsft = (ntbladr & 0x0040) >> 4;
|
||||||
|
var pNTBL = MMU.PPU_MEM_BANK[ntbladr >> 10];
|
||||||
|
|
||||||
|
int tileadr;
|
||||||
|
int cache_tile = unchecked((int)(0xFFFF0000));
|
||||||
|
byte cache_attr = 0xFF;
|
||||||
|
|
||||||
|
chr_h = chr_l = attr = 0;
|
||||||
|
|
||||||
|
attradr &= 0x3FF;
|
||||||
|
|
||||||
|
|
||||||
|
for (int i = 0; i < 33; i++)
|
||||||
|
{
|
||||||
|
tileadr = tileofs + pNTBL[ntbladr & 0x03FF] * 0x10 + loopy_y;
|
||||||
|
attr = (byte)(((pNTBL[attradr + (ntbl_x >> 2)] >> ((ntbl_x & 2) + attrsft)) & 3) << 2);
|
||||||
|
|
||||||
|
if (cache_tile == tileadr && cache_attr == attr)
|
||||||
|
{
|
||||||
|
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||||
|
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||||
|
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||||
|
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||||
|
|
||||||
|
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||||
|
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||||
|
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||||
|
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||||
|
|
||||||
|
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache_tile = tileadr;
|
||||||
|
cache_attr = attr;
|
||||||
|
chr_l = MMU.PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||||
|
chr_h = MMU.PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||||
|
BGwrite[pBGw] = (byte)(chr_h | chr_l);
|
||||||
|
|
||||||
|
int pBGPAL = attr;
|
||||||
|
{
|
||||||
|
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||||
|
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||||
|
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||||
|
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + ((c1 >> 6))];
|
||||||
|
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||||
|
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pScn += 8;
|
||||||
|
pBGw++;
|
||||||
|
|
||||||
|
// Character latch(For MMC2/MMC4)
|
||||||
|
if (bChrLatch)
|
||||||
|
{
|
||||||
|
nes.mapper.PPU_ChrLatch((ushort)(tileadr));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++ntbl_x == 32)
|
||||||
|
{
|
||||||
|
ntbl_x = 0;
|
||||||
|
ntbladr ^= 0x41F;
|
||||||
|
attradr = 0x03C0 + ((ntbladr & 0x0380) >> 4);
|
||||||
|
pNTBL = MMU.PPU_MEM_BANK[ntbladr >> 10];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ntbladr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// With Extension Latch(For MMC5)
|
||||||
|
pScn = lpScanline + (8 - loopy_shift);
|
||||||
|
pBGw = 0;
|
||||||
|
|
||||||
|
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||||
|
int ntbl_x = ntbladr & 0x1F;
|
||||||
|
|
||||||
|
int cache_tile = unchecked((int)(0xFFFF0000));
|
||||||
|
byte cache_attr = 0xFF;
|
||||||
|
|
||||||
|
byte exattr = 0;
|
||||||
|
chr_h = chr_l = attr = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 33; i++)
|
||||||
|
{
|
||||||
|
nes.mapper.PPU_ExtLatchX(i);
|
||||||
|
nes.mapper.PPU_ExtLatch((ushort)ntbladr, ref chr_l, ref chr_h, ref exattr);
|
||||||
|
attr = (byte)(exattr & 0x0C);
|
||||||
|
|
||||||
|
if (cache_tile != ((chr_h << 8) + chr_l) || cache_attr != attr)
|
||||||
|
{
|
||||||
|
cache_tile = ((chr_h << 8) + chr_l);
|
||||||
|
cache_attr = attr;
|
||||||
|
BGwrite[pBGw] = (byte)(chr_h | chr_l);
|
||||||
|
|
||||||
|
int pBGPAL = attr;
|
||||||
|
{
|
||||||
|
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||||
|
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||||
|
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||||
|
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + (c2 >> 6)];
|
||||||
|
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||||
|
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||||
|
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||||
|
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||||
|
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||||
|
|
||||||
|
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||||
|
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||||
|
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||||
|
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||||
|
|
||||||
|
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||||
|
}
|
||||||
|
pScn += 8;
|
||||||
|
pBGw++;
|
||||||
|
|
||||||
|
if (++ntbl_x == 32)
|
||||||
|
{
|
||||||
|
ntbl_x = 0;
|
||||||
|
ntbladr ^= 0x41F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ntbladr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!bExtLatch)
|
||||||
|
{
|
||||||
|
// Without Extension Latch
|
||||||
|
if (!bExtNameTable)
|
||||||
|
{
|
||||||
|
pScn = lpScanline + (8 - loopy_shift);
|
||||||
|
pBGw = 0;
|
||||||
|
|
||||||
|
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||||
|
int attradr = 0x03C0 + ((MMU.loopy_v & 0x0380) >> 4);
|
||||||
|
int ntbl_x = ntbladr & 0x001F;
|
||||||
|
int attrsft = (ntbladr & 0x0040) >> 4;
|
||||||
|
var pNTBL = MMU.PPU_MEM_BANK[ntbladr >> 10];
|
||||||
|
|
||||||
|
int tileadr = 0;
|
||||||
|
int cache_tile = unchecked((int)(0xFFFF0000));
|
||||||
|
byte cache_attr = 0xFF;
|
||||||
|
|
||||||
|
chr_h = chr_l = attr = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 33; i++)
|
||||||
|
{
|
||||||
|
tileadr = ((MMU.PPUREG[0] & PPU_BGTBL_BIT) << 8) + pNTBL[ntbladr & 0x03FF] * 0x10 + loopy_y;
|
||||||
|
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
nes.EmulationCPU(NES.FETCH_CYCLES * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
attr = (byte)(((pNTBL[attradr + (ntbl_x >> 2)] >> ((ntbl_x & 2) + attrsft)) & 3) << 2);
|
||||||
|
|
||||||
|
if (cache_tile != tileadr || cache_attr != attr)
|
||||||
|
{
|
||||||
|
cache_tile = tileadr;
|
||||||
|
cache_attr = attr;
|
||||||
|
|
||||||
|
chr_l = MMU.PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||||
|
chr_h = MMU.PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||||
|
lpScreen[pBGw] = (byte)(chr_l | chr_h);
|
||||||
|
|
||||||
|
int pBGPAL = attr;
|
||||||
|
{
|
||||||
|
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||||
|
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||||
|
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||||
|
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + ((c2 >> 6))];
|
||||||
|
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||||
|
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||||
|
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||||
|
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||||
|
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||||
|
|
||||||
|
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||||
|
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||||
|
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||||
|
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||||
|
|
||||||
|
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||||
|
}
|
||||||
|
pScn += 8;
|
||||||
|
pBGw++;
|
||||||
|
|
||||||
|
// Character latch(For MMC2/MMC4)
|
||||||
|
if (bChrLatch)
|
||||||
|
{
|
||||||
|
nes.mapper.PPU_ChrLatch((ushort)(tileadr));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++ntbl_x == 32)
|
||||||
|
{
|
||||||
|
ntbl_x = 0;
|
||||||
|
ntbladr ^= 0x41F;
|
||||||
|
attradr = 0x03C0 + ((ntbladr & 0x0380) >> 4);
|
||||||
|
pNTBL = MMU.PPU_MEM_BANK[ntbladr >> 10];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ntbladr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pScn = lpScanline + (8 - loopy_shift);
|
||||||
|
pBGw = 0;
|
||||||
|
|
||||||
|
int ntbladr;
|
||||||
|
int tileadr;
|
||||||
|
int cache_tile = unchecked((int)(0xFFFF0000));
|
||||||
|
byte cache_attr = 0xFF;
|
||||||
|
|
||||||
|
chr_h = chr_l = attr = 0;
|
||||||
|
|
||||||
|
ushort loopy_v_tmp = MMU.loopy_v;
|
||||||
|
|
||||||
|
for (int i = 0; i < 33; i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
nes.EmulationCPU(NES.FETCH_CYCLES * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||||
|
tileadr = ((MMU.PPUREG[0] & PPU_BGTBL_BIT) << 8) + MMU.PPU_MEM_BANK[ntbladr >> 10][ntbladr & 0x03FF] * 0x10 + ((MMU.loopy_v & 0x7000) >> 12);
|
||||||
|
attr = (byte)(((MMU.PPU_MEM_BANK[ntbladr >> 10][0x03C0 + ((ntbladr & 0x0380) >> 4) + ((ntbladr & 0x001C) >> 2)] >> (((ntbladr & 0x40) >> 4) + (ntbladr & 0x02))) & 3) << 2);
|
||||||
|
|
||||||
|
if (cache_tile != tileadr || cache_attr != attr)
|
||||||
|
{
|
||||||
|
cache_tile = tileadr;
|
||||||
|
cache_attr = attr;
|
||||||
|
|
||||||
|
chr_l = MMU.PPU_MEM_BANK[tileadr >> 10][tileadr & 0x03FF];
|
||||||
|
chr_h = MMU.PPU_MEM_BANK[tileadr >> 10][(tileadr & 0x03FF) + 8];
|
||||||
|
BGwrite[pBGw] = (byte)(chr_l | chr_h);
|
||||||
|
|
||||||
|
int pBGPAL = attr;
|
||||||
|
{
|
||||||
|
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||||
|
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||||
|
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + (c1 >> 6)];
|
||||||
|
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + (c2 >> 6)];
|
||||||
|
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||||
|
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||||
|
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||||
|
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||||
|
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||||
|
|
||||||
|
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||||
|
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||||
|
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||||
|
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||||
|
|
||||||
|
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||||
|
}
|
||||||
|
pScn += 8;
|
||||||
|
pBGw++;
|
||||||
|
|
||||||
|
// Character latch(For MMC2/MMC4)
|
||||||
|
if (bChrLatch)
|
||||||
|
{
|
||||||
|
nes.mapper.PPU_ChrLatch((ushort)tileadr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((MMU.loopy_v & 0x1F) == 0x1F)
|
||||||
|
{
|
||||||
|
MMU.loopy_v ^= 0x041F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MMU.loopy_v++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MMU.loopy_v = loopy_v_tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// With Extension Latch(For MMC5)
|
||||||
|
pScn = lpScanline + (8 - loopy_shift);
|
||||||
|
pBGw = 0;
|
||||||
|
|
||||||
|
int ntbladr = 0x2000 + (MMU.loopy_v & 0x0FFF);
|
||||||
|
int ntbl_x = ntbladr & 0x1F;
|
||||||
|
|
||||||
|
int cache_tile = unchecked((int)0xFFFF0000);
|
||||||
|
byte cache_attr = 0xFF;
|
||||||
|
|
||||||
|
byte exattr = 0;
|
||||||
|
chr_h = chr_l = attr = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < 33; i++)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
nes.EmulationCPU(NES.FETCH_CYCLES * 4);
|
||||||
|
}
|
||||||
|
nes.mapper.PPU_ExtLatchX(i);
|
||||||
|
nes.mapper.PPU_ExtLatch((ushort)ntbladr, ref chr_l, ref chr_h, ref exattr);
|
||||||
|
attr = (byte)(exattr & 0x0C);
|
||||||
|
|
||||||
|
if (cache_tile != ((chr_h << 8) + chr_l) || cache_attr != attr)
|
||||||
|
{
|
||||||
|
cache_tile = ((chr_h << 8) + chr_l);
|
||||||
|
cache_attr = attr;
|
||||||
|
BGwrite[pBGw] = (byte)(chr_l | chr_h);
|
||||||
|
|
||||||
|
int pBGPAL = attr;
|
||||||
|
{
|
||||||
|
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||||
|
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||||
|
lpScreen[pScn + 0] = MMU.BGPAL[pBGPAL + ((c1 >> 6))];
|
||||||
|
lpScreen[pScn + 4] = MMU.BGPAL[pBGPAL + ((c1 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 1] = MMU.BGPAL[pBGPAL + ((c2 >> 6))];
|
||||||
|
lpScreen[pScn + 5] = MMU.BGPAL[pBGPAL + ((c2 >> 2) & 3)];
|
||||||
|
lpScreen[pScn + 2] = MMU.BGPAL[pBGPAL + ((c1 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 6] = MMU.BGPAL[pBGPAL + (c1 & 3)];
|
||||||
|
lpScreen[pScn + 3] = MMU.BGPAL[pBGPAL + ((c2 >> 4) & 3)];
|
||||||
|
lpScreen[pScn + 7] = MMU.BGPAL[pBGPAL + (c2 & 3)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lpScreen[pScn + 0] = lpScreen[pScn - 8];
|
||||||
|
lpScreen[pScn + 0 + 1] = lpScreen[pScn - 8 + 1];
|
||||||
|
lpScreen[pScn + 0 + 2] = lpScreen[pScn - 8 + 2];
|
||||||
|
lpScreen[pScn + 0 + 3] = lpScreen[pScn - 8 + 3];
|
||||||
|
|
||||||
|
lpScreen[pScn + 4] = lpScreen[pScn - 4];
|
||||||
|
lpScreen[pScn + 4 + 1] = lpScreen[pScn - 4 + 1];
|
||||||
|
lpScreen[pScn + 4 + 2] = lpScreen[pScn - 4 + 2];
|
||||||
|
lpScreen[pScn + 4 + 3] = lpScreen[pScn - 4 + 3];
|
||||||
|
|
||||||
|
BGwrite[pBGw + 0] = BGwrite[pBGw - 1];
|
||||||
|
}
|
||||||
|
pScn += 8;
|
||||||
|
pBGw++;
|
||||||
|
|
||||||
|
if (++ntbl_x == 32)
|
||||||
|
{
|
||||||
|
ntbl_x = 0;
|
||||||
|
ntbladr ^= 0x41F;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ntbladr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((MMU.PPUREG[1] & PPU_BGCLIP_BIT) == 0 && bLeftClip)
|
||||||
|
{
|
||||||
|
pScn = lpScanline + 8;
|
||||||
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
lpScreen[i] = MMU.BGPAL[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render sprites
|
||||||
|
var temp = ~PPU_SPMAX_FLAG;
|
||||||
|
MMU.PPUREG[2] = (byte)(MMU.PPUREG[2] & temp);
|
||||||
|
|
||||||
|
// 昞帵婜娫奜偱偁傟偽僉儍儞僙儖
|
||||||
|
if (scanline > 239)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((MMU.PPUREG[1] & PPU_SPDISP_BIT) == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spmax = 0;
|
||||||
|
int spraddr = 0, sp_y = 0, sp_h = 0;
|
||||||
|
chr_h = chr_l = 0;
|
||||||
|
|
||||||
|
|
||||||
|
pBGw = 0;
|
||||||
|
int pSPw = 0;
|
||||||
|
int pBit2Rev = 0;
|
||||||
|
|
||||||
|
MemoryUtility.ZEROMEMORY(SPwrite, SPwrite.Length);
|
||||||
|
|
||||||
|
spmax = 0;
|
||||||
|
Sprite sp = new Sprite(MMU.SPRAM, 0);
|
||||||
|
sp_h = (MMU.PPUREG[0] & PPU_SP16_BIT) != 0 ? 15 : 7;
|
||||||
|
|
||||||
|
// Left clip
|
||||||
|
if (bLeftClip && ((MMU.PPUREG[1] & PPU_SPCLIP_BIT) == 0))
|
||||||
|
{
|
||||||
|
SPwrite[0] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 64; i++, sp.AddOffset(1))
|
||||||
|
{
|
||||||
|
sp_y = scanline - (sp.y + 1);
|
||||||
|
// 僗僉儍儞儔僀儞撪偵SPRITE偑懚嵼偡傞偐傪僠僃僢僋
|
||||||
|
if (sp_y != (sp_y & sp_h))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((MMU.PPUREG[0] & PPU_SP16_BIT) == 0)
|
||||||
|
{
|
||||||
|
// 8x8 Sprite
|
||||||
|
spraddr = ((MMU.PPUREG[0] & PPU_SPTBL_BIT) << 9) + (sp.tile << 4);
|
||||||
|
if ((sp.attr & SP_VMIRROR_BIT) == 0)
|
||||||
|
spraddr += sp_y;
|
||||||
|
else
|
||||||
|
spraddr += 7 - sp_y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 8x16 Sprite
|
||||||
|
spraddr = ((sp.tile & 1) << 12) + ((sp.tile & 0xFE) << 4);
|
||||||
|
if ((sp.attr & SP_VMIRROR_BIT) == 0)
|
||||||
|
spraddr += ((sp_y & 8) << 1) + (sp_y & 7);
|
||||||
|
else
|
||||||
|
spraddr += ((~sp_y & 8) << 1) + (7 - (sp_y & 7));
|
||||||
|
}
|
||||||
|
// Character pattern
|
||||||
|
chr_l = MMU.PPU_MEM_BANK[spraddr >> 10][spraddr & 0x3FF];
|
||||||
|
chr_h = MMU.PPU_MEM_BANK[spraddr >> 10][(spraddr & 0x3FF) + 8];
|
||||||
|
|
||||||
|
// Character latch(For MMC2/MMC4)
|
||||||
|
if (bChrLatch)
|
||||||
|
{
|
||||||
|
nes.mapper.PPU_ChrLatch((ushort)spraddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// pattern mask
|
||||||
|
if ((sp.attr & SP_HMIRROR_BIT) != 0)
|
||||||
|
{
|
||||||
|
chr_l = Bit2Rev[pBit2Rev + chr_l];
|
||||||
|
chr_h = Bit2Rev[pBit2Rev + chr_h];
|
||||||
|
}
|
||||||
|
byte SPpat = (byte)(chr_l | chr_h);
|
||||||
|
|
||||||
|
// Sprite hitcheck
|
||||||
|
if (i == 0 && (MMU.PPUREG[2] & PPU_SPHIT_FLAG) == 0)
|
||||||
|
{
|
||||||
|
int BGpos = ((sp.x & 0xF8) + ((loopy_shift + (sp.x & 7)) & 8)) >> 3;
|
||||||
|
int BGsft = 8 - ((loopy_shift + sp.x) & 7);
|
||||||
|
|
||||||
|
var temp1 = BGwrite[pBGw + BGpos + 0] << 8;
|
||||||
|
var temp2 = BGwrite[pBGw + BGpos + 1];
|
||||||
|
byte BGmsk = (byte)((temp1 | temp2) >> BGsft);
|
||||||
|
|
||||||
|
if ((SPpat & BGmsk) != 0)
|
||||||
|
{
|
||||||
|
MMU.PPUREG[2] |= PPU_SPHIT_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite mask
|
||||||
|
int SPpos = sp.x / 8;
|
||||||
|
int SPsft = 8 - (sp.x & 7);
|
||||||
|
byte SPmsk = (byte)((SPwrite[pSPw + SPpos + 0] << 8 | SPwrite[pSPw + SPpos + 1]) >> SPsft);
|
||||||
|
ushort SPwrt = (ushort)(SPpat << SPsft);
|
||||||
|
SPwrite[pSPw + SPpos + 0] = (byte)(SPwrite[pSPw + SPpos + 0] | SPwrt >> 8);
|
||||||
|
SPwrite[pSPw + SPpos + 1] = (byte)(SPwrite[pSPw + SPpos + 1] | SPwrt & 0xFF);
|
||||||
|
SPpat = (byte)(SPpat & ~SPmsk);
|
||||||
|
|
||||||
|
if ((sp.attr & SP_PRIORITY_BIT) != 0)
|
||||||
|
{
|
||||||
|
// BG > SP priority
|
||||||
|
int BGpos = ((sp.x & 0xF8) + ((loopy_shift + (sp.x & 7)) & 8)) >> 3;
|
||||||
|
int BGsft = 8 - ((loopy_shift + sp.x) & 7);
|
||||||
|
byte BGmsk = (byte)(((BGwrite[pBGw + BGpos + 0] << 8) | BGwrite[pBGw + BGpos + 1]) >> BGsft);
|
||||||
|
|
||||||
|
SPpat = (byte)(SPpat & ~BGmsk);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Attribute
|
||||||
|
int pSPPAL = (sp.attr & SP_COLOR_BIT) << 2;
|
||||||
|
// Ptr
|
||||||
|
pScn = lpScanline + sp.x + 8;
|
||||||
|
|
||||||
|
if (!bExtMono)
|
||||||
|
{
|
||||||
|
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||||
|
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||||
|
if ((SPpat & 0x80) != 0) lpScreen[pScn + 0] = MMU.SPPAL[pSPPAL + (c1 >> 6)];
|
||||||
|
if ((SPpat & 0x08) != 0) lpScreen[pScn + 4] = MMU.SPPAL[pSPPAL + ((c1 >> 2) & 3)];
|
||||||
|
if ((SPpat & 0x40) != 0) lpScreen[pScn + 1] = MMU.SPPAL[pSPPAL + ((c2 >> 6))];
|
||||||
|
if ((SPpat & 0x04) != 0) lpScreen[pScn + 5] = MMU.SPPAL[pSPPAL + ((c2 >> 2) & 3)];
|
||||||
|
if ((SPpat & 0x20) != 0) lpScreen[pScn + 2] = MMU.SPPAL[pSPPAL + ((c1 >> 4) & 3)];
|
||||||
|
if ((SPpat & 0x02) != 0) lpScreen[pScn + 6] = MMU.SPPAL[pSPPAL + (c1 & 3)];
|
||||||
|
if ((SPpat & 0x10) != 0) lpScreen[pScn + 3] = MMU.SPPAL[pSPPAL + ((c2 >> 4) & 3)];
|
||||||
|
if ((SPpat & 0x01) != 0) lpScreen[pScn + 7] = MMU.SPPAL[pSPPAL + (c2 & 3)];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Monocrome effect (for Final Fantasy)
|
||||||
|
byte mono = BGmono[((sp.x & 0xF8) + ((loopy_shift + (sp.x & 7)) & 8)) >> 3];
|
||||||
|
|
||||||
|
int c1 = ((chr_l >> 1) & 0x55) | (chr_h & 0xAA);
|
||||||
|
int c2 = (chr_l & 0x55) | ((chr_h << 1) & 0xAA);
|
||||||
|
if ((SPpat & 0x80) != 0) lpScreen[pScn + 0] = (byte)(MMU.SPPAL[pSPPAL + (c1 >> 6)] | mono);
|
||||||
|
if ((SPpat & 0x08) != 0) lpScreen[pScn + 4] = (byte)(MMU.SPPAL[pSPPAL + ((c1 >> 2) & 3)] | mono);
|
||||||
|
if ((SPpat & 0x40) != 0) lpScreen[pScn + 1] = (byte)(MMU.SPPAL[pSPPAL + (c2 >> 6)] | mono);
|
||||||
|
if ((SPpat & 0x04) != 0) lpScreen[pScn + 5] = (byte)(MMU.SPPAL[pSPPAL + ((c2 >> 2) & 3)] | mono);
|
||||||
|
if ((SPpat & 0x20) != 0) lpScreen[pScn + 2] = (byte)(MMU.SPPAL[pSPPAL + ((c1 >> 4) & 3)] | mono);
|
||||||
|
if ((SPpat & 0x02) != 0) lpScreen[pScn + 6] = (byte)(MMU.SPPAL[pSPPAL + (c1 & 3)] | mono);
|
||||||
|
if ((SPpat & 0x10) != 0) lpScreen[pScn + 3] = (byte)(MMU.SPPAL[pSPPAL + ((c2 >> 4) & 3)] | mono);
|
||||||
|
if ((SPpat & 0x01) != 0) lpScreen[pScn + 7] = (byte)(MMU.SPPAL[pSPPAL + (c2 & 3)] | mono);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++spmax > 8 - 1)
|
||||||
|
{
|
||||||
|
if (!bMax)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (spmax > 8 - 1)
|
||||||
|
{
|
||||||
|
MMU.PPUREG[2] |= PPU_SPMAX_FLAG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool IsSprite0(int scanline)
|
||||||
|
{
|
||||||
|
// 僗僾儔僀僩orBG旕昞帵偼僉儍儞僙儖(僸僢僩偟側偄)
|
||||||
|
if ((MMU.PPUREG[1] & (PPU_SPDISP_BIT | PPU_BGDISP_BIT)) != (PPU_SPDISP_BIT | PPU_BGDISP_BIT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 婛偵僸僢僩偟偰偄偨傜僉儍儞僙儖
|
||||||
|
if ((MMU.PPUREG[2] & PPU_SPHIT_FLAG) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ((MMU.PPUREG[0] & PPU_SP16_BIT) == 0)
|
||||||
|
{
|
||||||
|
// 8x8
|
||||||
|
if ((scanline < MMU.SPRAM[0] + 1) || (scanline > (MMU.SPRAM[0] + 7 + 1)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 8x16
|
||||||
|
if ((scanline < MMU.SPRAM[0] + 1) || (scanline > (MMU.SPRAM[0] + 15 + 1)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void DummyScanline(int scanline)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int spmax;
|
||||||
|
int sp_h;
|
||||||
|
|
||||||
|
MMU.PPUREG[2] = (byte)(MMU.PPUREG[2] & ~PPU_SPMAX_FLAG);
|
||||||
|
|
||||||
|
// 僗僾儔僀僩旕昞帵偼僉儍儞僙儖
|
||||||
|
if ((MMU.PPUREG[1] & PPU_SPDISP_BIT) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// 昞帵婜娫奜偱偁傟偽僉儍儞僙儖
|
||||||
|
if (scanline < 0 || scanline > 239)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Sprite sp = new Sprite(MMU.SPRAM, 0);
|
||||||
|
sp_h = (MMU.PPUREG[0] & PPU_SP16_BIT) != 0 ? 15 : 7;
|
||||||
|
|
||||||
|
spmax = 0;
|
||||||
|
// Sprite Max check
|
||||||
|
for (i = 0; i < 64; i++, sp.AddOffset(1))
|
||||||
|
{
|
||||||
|
// 僗僉儍儞儔僀儞撪偵SPRITE偑懚嵼偡傞偐傪僠僃僢僋
|
||||||
|
if ((scanline < sp.y + 1) || (scanline > (sp.y + sp_h + 1)))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (++spmax > 8 - 1)
|
||||||
|
{
|
||||||
|
MMU.PPUREG[2] |= PPU_SPMAX_FLAG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void VBlankEnd()
|
||||||
|
{
|
||||||
|
MMU.PPUREG[2] = (byte)(MMU.PPUREG[2] & ~PPU_VBLANK_FLAG);
|
||||||
|
// VBlank扙弌帪偵僋儕傾偝傟傞
|
||||||
|
// 僄僉僒僀僩僶僀僋偱廳梫
|
||||||
|
MMU.PPUREG[2] = (byte)(MMU.PPUREG[2] & ~PPU_SPHIT_FLAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void VBlankStart()
|
||||||
|
{
|
||||||
|
MMU.PPUREG[2] |= PPU_VBLANK_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] GetScreenPtr()
|
||||||
|
{
|
||||||
|
return lpScreen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] GetLineColorMode()
|
||||||
|
{
|
||||||
|
return lpColormode;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetScreenPtr(byte[] screenBuffer, byte[] colormode)
|
||||||
|
{
|
||||||
|
lpScreen = screenBuffer;
|
||||||
|
lpColormode = colormode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal bool IsDispON()
|
||||||
|
{
|
||||||
|
return (MMU.PPUREG[1] & (PPU_BGDISP_BIT | PPU_SPDISP_BIT)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct Sprite
|
||||||
|
{
|
||||||
|
public byte y
|
||||||
|
{
|
||||||
|
get => raw[offset + 0];
|
||||||
|
set => raw[offset + 0] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte tile
|
||||||
|
{
|
||||||
|
get => raw[offset + 1];
|
||||||
|
set => raw[offset + 1] = value;
|
||||||
|
}
|
||||||
|
public byte attr
|
||||||
|
{
|
||||||
|
get => raw[offset + 2];
|
||||||
|
set => raw[offset + 2] = value;
|
||||||
|
}
|
||||||
|
public byte x
|
||||||
|
{
|
||||||
|
get => raw[offset + 3];
|
||||||
|
set => raw[offset + 3] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] raw;
|
||||||
|
private int offset;
|
||||||
|
|
||||||
|
public Sprite(byte[] raw, int offset)
|
||||||
|
{
|
||||||
|
this.raw = raw;
|
||||||
|
this.offset = offset * 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddOffset(int offset)
|
||||||
|
{
|
||||||
|
this.offset += offset * 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,7 +218,7 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
|
|
||||||
Supporter.GetFilePathInfo(fname, out fullpath, out path);
|
Supporter.GetFilePathInfo(fname, out fullpath, out path);
|
||||||
|
name = Path.GetFileNameWithoutExtension(fullpath);
|
||||||
if (!bNSF)
|
if (!bNSF)
|
||||||
{
|
{
|
||||||
mapper = (header.control1 >> 4) | (header.control2 & 0xF0);
|
mapper = (header.control1 >> 4) | (header.control2 & 0xF0);
|
||||||
@ -347,12 +347,12 @@ namespace VirtualNes.Core
|
|||||||
return diskno;
|
return diskno;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ulong GetGameID()
|
internal uint GetGameID()
|
||||||
{
|
{
|
||||||
return fdsgameID;
|
return fdsgameID;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ulong GetMakerID()
|
internal uint GetMakerID()
|
||||||
{
|
{
|
||||||
return fdsmakerID;
|
return fdsmakerID;
|
||||||
}
|
}
|
||||||
@ -396,6 +396,11 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
return nsfheader;
|
return nsfheader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal string GetRomPath()
|
||||||
|
{
|
||||||
|
return path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,5 +2,38 @@
|
|||||||
{
|
{
|
||||||
public class CfgGraphics
|
public class CfgGraphics
|
||||||
{
|
{
|
||||||
|
public bool bAspect = false;
|
||||||
|
public bool bAllSprite = true;
|
||||||
|
public bool bAllLine = false;
|
||||||
|
public bool bFPSDisp = false;
|
||||||
|
public bool bTVFrame = false;
|
||||||
|
public bool bScanline = false;
|
||||||
|
public int nScanlineColor = 75;
|
||||||
|
public bool bSyncDraw = false;
|
||||||
|
public bool bFitZoom = false;
|
||||||
|
|
||||||
|
public bool bLeftClip = true;
|
||||||
|
|
||||||
|
public bool bWindowVSync = false;
|
||||||
|
|
||||||
|
public bool bSyncNoSleep = false;
|
||||||
|
|
||||||
|
public bool bDiskAccessLamp = false;
|
||||||
|
|
||||||
|
public bool bDoubleSize = false;
|
||||||
|
public bool bSystemMemory = false;
|
||||||
|
public bool bUseHEL = false;
|
||||||
|
|
||||||
|
public bool bNoSquareList = false;
|
||||||
|
|
||||||
|
public int nGraphicsFilter = 0;
|
||||||
|
|
||||||
|
public uint dwDisplayWidth = 640;
|
||||||
|
public uint dwDisplayHeight = 480;
|
||||||
|
public uint dwDisplayDepth = 16;
|
||||||
|
public uint dwDisplayRate = 0;
|
||||||
|
|
||||||
|
public bool bPaletteFile = false;
|
||||||
|
public char[] szPaletteFile = new char[260];
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,14 @@
|
|||||||
namespace VirtualNes.Core
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public class CfgMovie
|
public class CfgMovie
|
||||||
{
|
{
|
||||||
|
public byte[] bUsePlayer = new byte[4] { 0xFF, 0x00, 0x00, 0x00 };
|
||||||
|
public bool bRerecord = true;
|
||||||
|
public bool bLoopPlay = false;
|
||||||
|
public bool bResetRec = false;
|
||||||
|
public bool bPadDisplay = false;
|
||||||
|
public bool bTimeDisplay = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,25 @@
|
|||||||
namespace VirtualNes.Core
|
using System;
|
||||||
|
|
||||||
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
public class CfgPath
|
public class CfgPath
|
||||||
{
|
{
|
||||||
|
public bool bRomPath = true;
|
||||||
|
public bool bSavePath = true;
|
||||||
|
public bool bStatePath = true;
|
||||||
|
public bool bSnapshotPath = true;
|
||||||
|
public bool bMoviePath = true;
|
||||||
|
public bool bWavePath = true;
|
||||||
|
public bool bCheatPath = true;
|
||||||
|
public bool bIpsPath = true;
|
||||||
|
|
||||||
|
public string szRomPath = "roms";
|
||||||
|
public string szSavePath = "save";
|
||||||
|
public string szStatePath = "state";
|
||||||
|
public string szSnapshotPath = "snapshot";
|
||||||
|
public string szMoviePath = "movie";
|
||||||
|
public string szWavePath = "wave";
|
||||||
|
public string szCheatPath = "cheatcode";
|
||||||
|
public string szIpsPath = "ips";
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -17,4 +17,35 @@
|
|||||||
public CfgExtraSound extsound { get; private set; } = new CfgExtraSound();
|
public CfgExtraSound extsound { get; private set; } = new CfgExtraSound();
|
||||||
public CfgNetPlay netplay { get; private set; } = new CfgNetPlay();
|
public CfgNetPlay netplay { get; private set; } = new CfgNetPlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class GameOption
|
||||||
|
{
|
||||||
|
// Default保存
|
||||||
|
public static int defRenderMethod;
|
||||||
|
public static int defIRQtype;
|
||||||
|
public static bool defFrameIRQ;
|
||||||
|
public static bool defVideoMode;
|
||||||
|
|
||||||
|
// データ
|
||||||
|
public static int nRenderMethod;
|
||||||
|
public static int nIRQtype;
|
||||||
|
public static bool bFrameIRQ;
|
||||||
|
public static bool bVideoMode;
|
||||||
|
|
||||||
|
public static void Load(uint crc)
|
||||||
|
{
|
||||||
|
nRenderMethod = defRenderMethod;
|
||||||
|
nIRQtype = defIRQtype;
|
||||||
|
bFrameIRQ = defFrameIRQ;
|
||||||
|
bVideoMode = defVideoMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Load(uint gid, uint mid)
|
||||||
|
{
|
||||||
|
nRenderMethod = defRenderMethod;
|
||||||
|
nIRQtype = defIRQtype;
|
||||||
|
bFrameIRQ = defFrameIRQ;
|
||||||
|
bVideoMode = defVideoMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,20 @@ namespace VirtualNes.Core
|
|||||||
s_support.SaveDISKToFile(diskFileContent, 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 EmulatorConfig Config => s_support.Config;
|
public static EmulatorConfig Config => s_support.Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,5 +60,9 @@ namespace VirtualNes.Core
|
|||||||
void SaveSRAMToFile(byte[] sramContent, string romName);
|
void SaveSRAMToFile(byte[] sramContent, string romName);
|
||||||
void SaveDISKToFile(byte[] diskFileContent, string romName);
|
void SaveDISKToFile(byte[] diskFileContent, string romName);
|
||||||
EmulatorConfig Config { get; }
|
EmulatorConfig Config { get; }
|
||||||
|
|
||||||
|
void PrepareDirectory(string directPath);
|
||||||
|
void SaveFile(byte[] fileData, string directPath, string fileName);
|
||||||
|
Stream OpenFile(string directPath, string fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
AxibugEmuOnline.Client/Assets/VirtualNes.Core/VsUnisystem.cs
Normal file
49
AxibugEmuOnline.Client/Assets/VirtualNes.Core/VsUnisystem.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
namespace VirtualNes.Core
|
||||||
|
{
|
||||||
|
public class VSDIPSWITCH
|
||||||
|
{
|
||||||
|
public string name;
|
||||||
|
public ushort value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class VsUnisystem
|
||||||
|
{
|
||||||
|
public static VSDIPSWITCH[] vsdip_default = new VSDIPSWITCH[]
|
||||||
|
{
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x0100},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x01},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x0200},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x02},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x0400},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x04},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x0800},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x08},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x1000},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x10},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x2000},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x20},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x4000},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x40},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name="Unknown", value= 0x8000},
|
||||||
|
new VSDIPSWITCH{name="Off", value= 0x00},
|
||||||
|
new VSDIPSWITCH{name="On", value= 0x80},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0xFF},
|
||||||
|
new VSDIPSWITCH{name=null, value= 0 },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: db82d3b2d60f2c14fa3c5582acc439c6
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
167
virtuanessrc097-master/.gitignore
vendored
Normal file
167
virtuanessrc097-master/.gitignore
vendored
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
VirtuaNES.exe
|
||||||
|
VirtuaNES.ini
|
||||||
|
|
||||||
|
#################
|
||||||
|
## Eclipse
|
||||||
|
#################
|
||||||
|
.vs/
|
||||||
|
debug/
|
||||||
|
*.pydevproject
|
||||||
|
.project
|
||||||
|
.metadata
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# CDT-specific
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
|
||||||
|
#################
|
||||||
|
## Visual Studio
|
||||||
|
#################
|
||||||
|
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.vspscc
|
||||||
|
.builds
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
## TODO: If you have NuGet Package Restore enabled, uncomment this
|
||||||
|
#packages/
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish
|
||||||
|
|
||||||
|
# Others
|
||||||
|
[Bb]in
|
||||||
|
[Oo]bj
|
||||||
|
sql
|
||||||
|
TestResults
|
||||||
|
*.Cache
|
||||||
|
ClientBin
|
||||||
|
stylecop.*
|
||||||
|
~$*
|
||||||
|
*.dbmdl
|
||||||
|
Generated_Code #added for RIA/Silverlight projects
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file to a newer
|
||||||
|
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
############
|
||||||
|
## Windows
|
||||||
|
############
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
|
||||||
|
#############
|
||||||
|
## Python
|
||||||
|
#############
|
||||||
|
|
||||||
|
*.py[co]
|
||||||
|
|
||||||
|
# Packages
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
eggs
|
||||||
|
parts
|
||||||
|
bin
|
||||||
|
var
|
||||||
|
sdist
|
||||||
|
develop-eggs
|
||||||
|
.installed.cfg
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
.coverage
|
||||||
|
.tox
|
||||||
|
|
||||||
|
#Translations
|
||||||
|
*.mo
|
||||||
|
|
||||||
|
#Mr Developer
|
||||||
|
.mr.developer.cfg
|
||||||
|
|
||||||
|
# Mac crap
|
||||||
|
.DS_Store
|
BIN
virtuanessrc097-master/AboutDlg.cpp
Normal file
BIN
virtuanessrc097-master/AboutDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/AboutDlg.h
Normal file
BIN
virtuanessrc097-master/AboutDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/App.cpp
Normal file
BIN
virtuanessrc097-master/App.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/App.h
Normal file
BIN
virtuanessrc097-master/App.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Archive.cpp
Normal file
BIN
virtuanessrc097-master/Archive.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Archive.h
Normal file
BIN
virtuanessrc097-master/Archive.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/AviConvDlg.cpp
Normal file
BIN
virtuanessrc097-master/AviConvDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/AviConvDlg.h
Normal file
BIN
virtuanessrc097-master/AviConvDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/AviWriter.cpp
Normal file
BIN
virtuanessrc097-master/AviWriter.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/AviWriter.h
Normal file
BIN
virtuanessrc097-master/AviWriter.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/CHyperLink.h
Normal file
BIN
virtuanessrc097-master/CHyperLink.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/ChatDlg.cpp
Normal file
BIN
virtuanessrc097-master/ChatDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/ChatDlg.h
Normal file
BIN
virtuanessrc097-master/ChatDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/CheatDlg.cpp
Normal file
BIN
virtuanessrc097-master/CheatDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/CheatDlg.h
Normal file
BIN
virtuanessrc097-master/CheatDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Com.cpp
Normal file
BIN
virtuanessrc097-master/Com.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Com.h
Normal file
BIN
virtuanessrc097-master/Com.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Config.cpp
Normal file
BIN
virtuanessrc097-master/Config.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Config.h
Normal file
BIN
virtuanessrc097-master/Config.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/ControllerDlg.cpp
Normal file
BIN
virtuanessrc097-master/ControllerDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/ControllerDlg.h
Normal file
BIN
virtuanessrc097-master/ControllerDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Crclib.cpp
Normal file
BIN
virtuanessrc097-master/Crclib.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Crclib.h
Normal file
BIN
virtuanessrc097-master/Crclib.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DatachBarcodeDlg.cpp
Normal file
BIN
virtuanessrc097-master/DatachBarcodeDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DatachBarcodeDlg.h
Normal file
BIN
virtuanessrc097-master/DatachBarcodeDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DebugOut.cpp
Normal file
BIN
virtuanessrc097-master/DebugOut.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DebugOut.h
Normal file
BIN
virtuanessrc097-master/DebugOut.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DipSwitchDlg.cpp
Normal file
BIN
virtuanessrc097-master/DipSwitchDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DipSwitchDlg.h
Normal file
BIN
virtuanessrc097-master/DipSwitchDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DirectDraw.cpp
Normal file
BIN
virtuanessrc097-master/DirectDraw.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DirectDraw.h
Normal file
BIN
virtuanessrc097-master/DirectDraw.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DirectInput.cpp
Normal file
BIN
virtuanessrc097-master/DirectInput.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DirectInput.h
Normal file
BIN
virtuanessrc097-master/DirectInput.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DirectSound.cpp
Normal file
BIN
virtuanessrc097-master/DirectSound.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/DirectSound.h
Normal file
BIN
virtuanessrc097-master/DirectSound.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Doc/Copying.txt
Normal file
BIN
virtuanessrc097-master/Doc/Copying.txt
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Doc/ReadmeSrc.txt
Normal file
BIN
virtuanessrc097-master/Doc/ReadmeSrc.txt
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/EmuThread.cpp
Normal file
BIN
virtuanessrc097-master/EmuThread.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/EmuThread.h
Normal file
BIN
virtuanessrc097-master/EmuThread.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/EmulatorDlg.cpp
Normal file
BIN
virtuanessrc097-master/EmulatorDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/EmulatorDlg.h
Normal file
BIN
virtuanessrc097-master/EmulatorDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/English.vlp
Normal file
BIN
virtuanessrc097-master/English.vlp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/ExtSoundFile.h
Normal file
BIN
virtuanessrc097-master/ExtSoundFile.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/FolderDlg.cpp
Normal file
BIN
virtuanessrc097-master/FolderDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/FolderDlg.h
Normal file
BIN
virtuanessrc097-master/FolderDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/GameOptionDlg.cpp
Normal file
BIN
virtuanessrc097-master/GameOptionDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/GameOptionDlg.h
Normal file
BIN
virtuanessrc097-master/GameOptionDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/GraphicsDlg.cpp
Normal file
BIN
virtuanessrc097-master/GraphicsDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/GraphicsDlg.h
Normal file
BIN
virtuanessrc097-master/GraphicsDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/JoyAxisDlg.cpp
Normal file
BIN
virtuanessrc097-master/JoyAxisDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/JoyAxisDlg.h
Normal file
BIN
virtuanessrc097-master/JoyAxisDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/LanguageDlg.cpp
Normal file
BIN
virtuanessrc097-master/LanguageDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/LanguageDlg.h
Normal file
BIN
virtuanessrc097-master/LanguageDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/LauncherDlg.cpp
Normal file
BIN
virtuanessrc097-master/LauncherDlg.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/LauncherDlg.h
Normal file
BIN
virtuanessrc097-master/LauncherDlg.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/MMTimer.cpp
Normal file
BIN
virtuanessrc097-master/MMTimer.cpp
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/MMTimer.h
Normal file
BIN
virtuanessrc097-master/MMTimer.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/Macro.h
Normal file
BIN
virtuanessrc097-master/Macro.h
Normal file
Binary file not shown.
BIN
virtuanessrc097-master/MainFrame.cpp
Normal file
BIN
virtuanessrc097-master/MainFrame.cpp
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user