Compare commits

...

121 Commits

Author SHA1 Message Date
73e3a744ae Merge pull request 'master' (#27) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#27
2024-08-08 10:00:59 +08:00
ALIENJACK\alien
70b6014fdb 实现APU_N106 2024-08-07 18:31:11 +08:00
ALIENJACK\alien
b812a854aa Merge branch 'master' of http://git.axibug.com/sin365/AxibugEmuOnline
# Conflicts:
#	References/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.c
#	References/virtuanessrc097-master/NES/ApuEX/emu2413/emu2413.h
2024-08-07 17:55:52 +08:00
ALIENJACK\alien
8bbe264f24 Emu2413 库实现 2024-08-07 17:45:38 +08:00
1e914679bb References 2024-08-07 12:07:20 +08:00
06647adda3 md 2024-08-07 11:32:03 +08:00
ALIENJACK\alien
d668f7d8df APU_MMC5移植完成,nes20db.xml移到工程根目录,避免打包 2024-08-07 11:30:18 +08:00
46946d4430 fixed 2024-08-07 11:23:39 +08:00
8af94c51f8 fixed 2024-08-07 11:23:06 +08:00
913ba1a791 归档一次 2024-08-07 11:21:10 +08:00
20f28469b2 Merge pull request 'master' (#26) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#26
2024-08-07 11:19:45 +08:00
ALIENJACK\alien
8952b842b1 APU补全中 2024-08-06 19:50:33 +08:00
ALIENJACK\alien
b8c116aa28 键位配置持久化 2024-08-06 18:52:11 +08:00
ALIENJACK\alien
580de2d245 实现输入 2024-08-06 18:09:32 +08:00
ed93542f48 readme 2024-08-06 17:52:29 +08:00
82e0275b5e Merge branch 'master' of http://git.axibug.com/sin365/AxibugEmuOnline 2024-08-06 17:50:54 +08:00
2eb1cf1e97 merge 2024-08-06 17:50:51 +08:00
44311f075b changed 163 175 176 178 192 2024-08-06 17:49:14 +08:00
ALIENJACK\alien
aad4c1775a 优化音频读取方式 2024-08-06 16:03:17 +08:00
ALIENJACK\alien
66f0cc5bd7 添加忽略,添加PatternViewer的性能開關,当ROMDB转换了一个Mapper时,写日志 2024-08-06 14:24:55 +08:00
ALIENJACK\alien
e4da00136d ROMDB提交,Mapper修復 2024-08-06 13:49:24 +08:00
c7f32874ae Merge pull request '移除RenderTexutre,调整Resources和StreamAssets目录结构,加上"NES"父目录,以区分不同模拟器,加入ROMDB机制,修改ROM Mapper信息' (#25) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#25
2024-08-05 23:27:30 +08:00
16adace210 fixed 2024-08-05 23:25:40 +08:00
250b230914 addon 2024-08-05 23:19:00 +08:00
bb42d3f3bd transfer Mapper 000~015 2024-08-05 23:16:39 +08:00
ALIENJACK\alien
e27c970d45 移除RenderTexutre,调整Resources和StreamAssets目录结构,加上"NES"父目录,以区分不同模拟器,加入ROMDB机制,修改ROM Mapper信息 2024-08-05 18:42:58 +08:00
ba1ac5d5c2 Merge pull request 'dev_4VirtualNes' (#24) from dev_4VirtualNes into master
Reviewed-on: sin365/AxibugEmuOnline#24
2024-08-05 18:01:41 +08:00
dc5f55c003 Merge branch 'dev_4VirtualNes' of http://git.axibug.com/sin365/AxibugEmuOnline into dev_4VirtualNes 2024-08-05 17:59:57 +08:00
8b39e9aa02 readme + references 2024-08-05 17:58:53 +08:00
e4b2d67d5e Merge pull request 'dev_4VirtualNes' (#23) from dev_4VirtualNes into master
Reviewed-on: sin365/AxibugEmuOnline#23
2024-08-05 17:49:41 +08:00
5189cf0053 Merge pull request 'Mapper199修改' (#22) from Alienjack/AxibugEmuOnline:dev_4VirtualNes into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#22
2024-08-05 17:47:46 +08:00
ALIENJACK\alien
81920874cc Mapper199修改 2024-08-05 17:46:33 +08:00
8961831f69 Merge pull request 'Mapper补全' (#21) from Alienjack/AxibugEmuOnline:dev_4VirtualNes into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#21
2024-08-05 11:55:06 +08:00
ALIENJACK\alien
ba8b656914 Mapper补全 2024-08-05 11:52:43 +08:00
4e78287c69 Add Mapper Change case 2024-08-05 10:38:27 +08:00
715e8160e8 Addon Special Lost Mapper 35 111 2024-08-05 10:28:41 +08:00
a6cbe6df74 transfer 016-018 2024-08-05 01:44:13 +08:00
c0e29193f7 transfer Mapper 18-43 2024-08-05 01:33:07 +08:00
f82237b7a5 transfer Mapper 43-68 2024-08-05 00:44:30 +08:00
25c1546ff0 transfer Mapper 69~85 2024-08-05 00:05:15 +08:00
923e41a1ba transfer Mapper 86~113 2024-08-04 23:37:02 +08:00
8617d095b8 readme 2024-08-04 22:38:21 +08:00
d5c8b8dc83 Addon Special Lost Mapper 162,163,175,176,178,192,195,199,216 2024-08-04 22:31:39 +08:00
f39ceedb0f transfer Mapper114~164 2024-08-04 00:32:14 +08:00
cb66081f2c transfer mapper 165-198 2024-08-03 23:15:19 +08:00
f924708dd2 transfer Mapper 200-255.cs 2024-08-03 22:26:53 +08:00
c465f1a66e Merge pull request '优化模拟器提交过来的元素转换为Unity Texture2D数据的代码' (#20) from Alienjack/AxibugEmuOnline:dev_4VirtualNes into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#20
2024-08-02 16:55:26 +08:00
ALIENJACK\alien
0a27237a17 音频 internal 翻译完毕 2024-08-02 16:50:16 +08:00
ALIENJACK\alien
090322a60a 优化模拟器提交过来的元素转换为Unity Texture2D数据的代码 2024-08-02 10:58:04 +08:00
507ef45d3a Merge pull request 'dev_4VirtualNes' (#19) from Alienjack/AxibugEmuOnline:dev_4VirtualNes into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#19
2024-07-31 21:39:54 +08:00
ALIENJACK\alien
8dc535e874 图像出现了 2024-07-31 17:40:32 +08:00
ALIENJACK\alien
4de4291a24 123 2024-07-30 18:53:36 +08:00
ALIENJACK\alien
1a371955f3 提交一个可以在vs2022中编译通过的virtuaNes cpp项目 2024-07-30 12:00:24 +08:00
ALIENJACK\alien
e5fa62d209 迭代中 2024-07-30 11:57:09 +08:00
ALIENJACK\alien
d7846c7182 123 2024-07-29 09:25:19 +08:00
69aa14ca67 Merge pull request 'dev_4VirtualNes' (#18) from Alienjack/AxibugEmuOnline:dev_4VirtualNes into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#18
2024-07-27 00:57:58 +08:00
ALIENJACK\alien
323e8c66a2 迭代 2024-07-26 17:52:33 +08:00
ALIENJACK\alien
88214310d7 迭代 2024-07-25 18:34:52 +08:00
ALIENJACK\alien
652616663c 翻译中 2024-07-25 14:03:52 +08:00
ALIENJACK\alien
51aca30cf7 翻译中 2024-07-25 11:03:58 +08:00
52f5dfa8d8 MyNes Standard2.0 核心归档 2024-07-24 15:03:33 +08:00
625d71c2b9 readme 2024-07-24 14:59:15 +08:00
f4a2d8b876 Merge pull request 'dev_4VirtualNes' (#17) from Alienjack/AxibugEmuOnline:dev_4VirtualNes into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#17
2024-07-24 14:51:31 +08:00
ALIENJACK\alien
0e25114e9c 翻译迭代中 2024-07-24 14:27:10 +08:00
ALIENJACK\alien
2d47b306f4 VirtuaNesCore翻译中 2024-07-23 18:31:59 +08:00
275f2c419f Merge pull request 'master' (#15) from master into dev_4VirtualNes
Reviewed-on: sin365/AxibugEmuOnline#15
2024-07-22 14:23:56 +08:00
9e5114a9aa Merge pull request 'master' (#14) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#14
2024-07-22 14:23:05 +08:00
ALIENJACK\alien
ab1381423e Merge branch 'master' of http://git.axibug.com/sin365/AxibugEmuOnline 2024-07-22 13:10:00 +08:00
ALIENJACK\alien
c3c9d97f7d Il2CppSetOptionAttribute 2024-07-22 13:09:42 +08:00
ALIENJACK\alien
e83beaa813 增加il2cppSetOption 2024-07-22 13:09:27 +08:00
f9f348f77f Merge pull request '123' (#13) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#13
2024-07-19 15:35:41 +08:00
ALIENJACK\alien
f22be7a346 123 2024-07-19 15:17:26 +08:00
1a3294d3a3 Merge pull request 'master' (#12) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#12
2024-07-19 12:59:29 +08:00
ALIENJACK\alien
31f3182e35 LoadGame接口提到AppEmu 2024-07-18 16:24:14 +08:00
ALIENJACK\alien
27479341c7 显示canvas 2024-07-18 15:35:14 +08:00
ALIENJACK\alien
68f687b207 移除多余代码 2024-07-18 15:31:15 +08:00
ALIENJACK\alien
2a20131e00 重构一下,让KeyMapper支持各种输入设备 2024-07-18 15:26:43 +08:00
ALIENJACK\alien
8b3b54f731 控制器输入实现 2024-07-18 15:14:45 +08:00
ALIENJACK\alien
34286f4263 删除不要的代码 2024-07-18 13:59:42 +08:00
215058d9e8 Merge pull request 'master' (#11) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#11
2024-07-17 14:33:17 +08:00
ALIENJACK\alien
1fe5204014 迭代 2024-07-17 13:18:45 +08:00
ALIENJACK\alien
57d75cfdcb Merge branch 'master' of http://git.axibug.com/sin365/AxibugEmuOnline 2024-07-17 12:50:34 +08:00
ALIENJACK\alien
1770e2fc45 核心模拟器做成prefab 2024-07-17 12:50:18 +08:00
ALIENJACK\alien
cad555d7ab 完美音效! 2024-07-17 12:43:43 +08:00
584609eecd Merge pull request 'master' (#10) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: sin365/AxibugEmuOnline#10
2024-07-16 18:00:05 +08:00
ALIENJACK\alien
5f6687d8fc gitignore setting 2024-07-16 17:51:00 +08:00
ALIENJACK\alien
4366ef00f9 android平台兼容性 2024-07-16 17:46:07 +08:00
52cf4e6d65 Merge pull request 'dev_basemynes' (#9) from dev_basemynes into master
Reviewed-on: sin365/AxibugEmuOnline#9
2024-07-16 16:33:39 +08:00
80872bd78c Merge pull request 'dev_basemynes' (#8) from Alienjack/AxibugEmuOnline:dev_basemynes into dev_basemynes
Reviewed-on: sin365/AxibugEmuOnline#8
2024-07-16 16:32:27 +08:00
ALIENJACK\alien
a6a90929e0 改到resources中读取rom 2024-07-16 16:30:20 +08:00
ALIENJACK\alien
d7f57adca2 Merge branch 'dev_basemynes' of http://git.axibug.com/sin365/AxibugEmuOnline into dev_basemynes 2024-07-16 16:29:46 +08:00
67569e7971 Merge branch 'dev_basemynes' of http://git.axibug.com/sin365/AxibugEmuOnline into dev_basemynes 2024-07-16 10:59:07 +08:00
e0223a38b3 nes游戏数据库 2024-07-16 10:59:01 +08:00
ac4315b3cd . 2024-07-15 16:48:11 +08:00
08fec2ef9d Merge pull request 'master' (#7) from master into dev_basemynes
Reviewed-on: sin365/AxibugEmuOnline#7
2024-07-15 16:44:23 +08:00
af972e31dc readme 2024-07-15 16:41:43 +08:00
9b1a5c8f7b Merge pull request 'readme' (#6) from dev_basemynes into master
Reviewed-on: sin365/AxibugEmuOnline#6
2024-07-15 16:37:47 +08:00
bcebfc53ad .gitignore 2024-07-15 16:16:25 +08:00
fe076d5077 Merge pull request 'dev_basemynes' (#5) from dev_basemynes into master
Reviewed-on: sin365/AxibugEmuOnline#5
2024-07-15 16:14:30 +08:00
83fc3878b7 新增WebApi 2024-07-15 16:12:09 +08:00
5bcf6c5dea webapi 2024-07-15 16:07:36 +08:00
ALIENJACK\alien
1fd27d7fb7 优化音频流数据不够时的数据设置 2024-07-10 17:04:55 +08:00
65978580be Merge pull request 'dev_basemynes' (#4) from alienjack/AxibugEmuOnline:dev_basemynes into dev_basemynes
Reviewed-on: sin365/AxibugEmuOnline#4
2024-07-10 15:06:15 +08:00
ALIENJACK\alien
4644b7022f 流式音频采用DSP实现,VideoProvider和audioProvider改为monobehaviour 2024-07-10 15:02:14 +08:00
1c3d5ac6cf readme 2024-07-09 17:27:36 +08:00
b394410ab0 服务端房间功能 2024-07-09 17:22:09 +08:00
ALIENJACK\alien
b8386bb3c9 忽略配置提交 2024-07-05 11:52:56 +08:00
ALIENJACK\alien
7b3142861f 移除不必要的sln文件 2024-07-05 11:49:51 +08:00
ALIENJACK\alien
2c12958eb8 绘制性能优化 2024-07-05 11:48:35 +08:00
90a64b85fe Merge pull request 'dev_basemynes' (#3) from alienjack/AxibugEmuOnline:dev_basemynes into dev_basemynes
Reviewed-on: sin365/AxibugEmuOnline#3
2024-07-05 11:30:21 +08:00
ALIENJACK\alien
e8152500fd Merge branch 'dev_basemynes' of http://git.axibug.com/sin365/AxibugEmuOnline into dev_basemynes 2024-07-05 11:25:16 +08:00
ALIENJACK\alien
2868c02c16 音频解决(缺少追赶机制) 2024-07-05 11:24:59 +08:00
ALIENJACK\alien
28e0071191 迭代 2024-07-04 21:06:41 +08:00
495ac68a84 加协议 2024-07-04 17:39:47 +08:00
ALIENJACK\alien
4a7b6c1458 迭代 2024-07-04 10:41:48 +08:00
37b297dff6 Merge pull request 'dev_basemynes' (#2) from alienjack/AxibugEmuOnline:dev_basemynes into dev_basemynes
Reviewed-on: sin365/AxibugEmuOnline#2
2024-07-03 18:24:03 +08:00
ALIENJACK\alien
63f65b89c9 修复语法错误 2024-07-03 18:22:22 +08:00
ALIENJACK\alien
d84b221e81 Merge branch 'dev_basemynes' of http://git.axibug.com/sin365/AxibugEmuOnline into dev_basemynes 2024-07-03 18:19:30 +08:00
ALIENJACK\alien
ed4af60268 core替换为7.7版本 2024-07-03 18:15:28 +08:00
08830263e3 Merge pull request 'mynes.core dll改代码' (#1) from alienjack/AxibugEmuOnline:dev_basemynes into dev_basemynes
Reviewed-on: sin365/AxibugEmuOnline#1
2024-07-03 15:46:20 +08:00
ALIENJACK\alien
7b2b0f3d20 mynes.core dll改代码 2024-07-03 15:40:13 +08:00
863 changed files with 261928 additions and 1875 deletions

19
.gitignore vendored Normal file
View File

@ -0,0 +1,19 @@
/AxibugEmuOnline.Client/*.vsconfig
/AxibugEmuOnline.Client/Library/
/AxibugEmuOnline.Client/Temp/
/AxibugEmuOnline.Client/UserSettings/
/AxibugEmuOnline.Client/.vs/
/AxibugEmuOnline.Client/*.csproj
/AxibugEmuOnline.Client/*.sln
/AxibugEmuOnline.Client/*.sln
/AxibugEmuOnline.Client/obj/
/AxibugEmuOnline.Client/log/
/AxibugEmuOnline.Client/ProjectSettings/Packages/
/AxibugEmuOnline.Web/config.cfg
/AxibugEmuOnline.Client/ProjectSettings/ProjectVersion.txt
/AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset
/AxibugEmuOnline.Client/Logs
/virtuanessrc097-master/save
/virtuanessrc097-master/.vs
/virtuanessrc097-master/Debug
/virtuanessrc097-master/VirtuaNES.ini

View File

@ -1,33 +0,0 @@
fileFormatVersion: 2
guid: 986b9dc19d701a94abe3e4d4b80a70ae
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 1
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 481b76fe04e7dcd4c9d5c89eab10343d
guid: 8d7ded91aab4c0b42abba5042aaceb39
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -0,0 +1,625 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &1575933574
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1575933575}
- component: {fileID: 1575933577}
- component: {fileID: 1575933576}
m_Layer: 5
m_Name: notify
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &1575933575
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1575933574}
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: 8662582775439058149}
m_RootOrder: 2
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: 160, y: 30}
m_Pivot: {x: 0, y: 0}
--- !u!222 &1575933577
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1575933574}
m_CullTransparentMesh: 1
--- !u!114 &1575933576
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1575933574}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, 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_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 6
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 1
m_VerticalOverflow: 1
m_LineSpacing: 1
m_Text:
--- !u!1 &319390252125274553
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3543948837876491845}
- component: {fileID: 2496653285840897638}
m_Layer: 0
m_Name: Input
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3543948837876491845
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 319390252125274553}
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: 8662582775964487076}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &2496653285840897638
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 319390252125274553}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: d79c33962dea7dc48b2c5fcd45afe1ad, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &8662582774585465456
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8662582774585465455}
- component: {fileID: 8662582774585465453}
- component: {fileID: 8662582774585465454}
m_Layer: 5
m_Name: canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8662582774585465455
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582774585465456}
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: 8662582775439058149}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8662582774585465453
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582774585465456}
m_CullTransparentMesh: 1
--- !u!114 &8662582774585465454
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582774585465456}
m_Enabled: 0
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: 5d4a385f133f9074583d64ab2172a03b, type: 2}
m_UVRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
--- !u!1 &8662582774971523582
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 3209572454846341542}
- component: {fileID: 8662582774971523580}
- component: {fileID: 8662582774971523579}
m_Layer: 5
m_Name: Audio
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &3209572454846341542
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582774971523582}
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: 8662582775964487076}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!82 &8662582774971523580
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582774971523582}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 0}
m_PlayOnAwake: 0
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!114 &8662582774971523579
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582774971523582}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 765129d4fad76714191795975893ea9c, type: 3}
m_Name:
m_EditorClassIdentifier:
m_coreProxy: {fileID: 8662582775964487075}
m_as: {fileID: 8662582774971523580}
--- !u!1 &8662582775350046795
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 7667066390141474019}
- component: {fileID: 8662582775350046791}
- component: {fileID: 8662582775350046790}
m_Layer: 5
m_Name: Video
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &7667066390141474019
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775350046795}
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: 8662582775439058149}
m_Father: {fileID: 8662582775964487076}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!222 &8662582775350046791
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775350046795}
m_CullTransparentMesh: 1
--- !u!114 &8662582775350046790
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775350046795}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f2632911774df3c488ec24b39651c4de, type: 3}
m_Name:
m_EditorClassIdentifier:
m_coreProxy: {fileID: 8662582775964487075}
m_drawCanvas: {fileID: 8662582774585465454}
m_fpsText: {fileID: 8662582775359084754}
m_nofity: {fileID: 1575933576}
--- !u!1 &8662582775359084756
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8662582775359084755}
- component: {fileID: 8662582775359084753}
- component: {fileID: 8662582775359084754}
m_Layer: 5
m_Name: fps
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8662582775359084755
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775359084756}
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: 8662582775439058149}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 0}
m_AnchorMax: {x: 1, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 160, y: 30}
m_Pivot: {x: 1, y: 0}
--- !u!222 &8662582775359084753
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775359084756}
m_CullTransparentMesh: 1
--- !u!114 &8662582775359084754
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775359084756}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, 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_FontData:
m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0}
m_FontSize: 14
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 8
m_AlignByGeometry: 0
m_RichText: 1
m_HorizontalOverflow: 1
m_VerticalOverflow: 1
m_LineSpacing: 1
m_Text:
--- !u!1 &8662582775439058150
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8662582775439058149}
- component: {fileID: 8662582775439058146}
- component: {fileID: 8662582775439058147}
- component: {fileID: 8662582775439058148}
m_Layer: 5
m_Name: Canvas
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!224 &8662582775439058149
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775439058150}
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: 8662582774585465455}
- {fileID: 8662582775359084755}
- {fileID: 1575933575}
m_Father: {fileID: 7667066390141474019}
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 &8662582775439058146
Canvas:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775439058150}
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 &8662582775439058147
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775439058150}
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 &8662582775439058148
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775439058150}
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 &8662582775964487077
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 8662582775964487076}
- component: {fileID: 8662582775964487075}
m_Layer: 0
m_Name: NesCoreProxy
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &8662582775964487076
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775964487077}
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: 7667066390141474019}
- {fileID: 3209572454846341542}
- {fileID: 3543948837876491845}
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &8662582775964487075
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 8662582775964487077}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ac8cd27a180bf3e489b2ca27c821bffe, type: 3}
m_Name:
m_EditorClassIdentifier:
VideoCom: {fileID: 8662582775350046790}
AudioCom: {fileID: 8662582774971523579}
InputManager: {fileID: 2496653285840897638}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d75df7d1f5a2c824ab5013cbd79da7a4
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 6b52033f7628c4346a6dd0b2806e75ee
guid: 319a1a12506a5334ebd963b4fd991c2a
folderAsset: yes
DefaultImporter:
externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 040fea71e1812ce45bd2b72c8ad2e2ae
guid: ccf426abdad56c74682de4e38b3048e3
TextScriptImporter:
externalObjects: {}
userData:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 42cbfafb123e63b45841ae95eb432053
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,7 +0,0 @@
fileFormatVersion: 2
guid: 333f6913aec8b2b41807add4cf643f6a
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,347 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 0
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 2
m_BakeBackend: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 512
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 256
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 1
m_PVRDenoiserTypeDirect: 1
m_PVRDenoiserTypeIndirect: 1
m_PVRDenoiserTypeAO: 1
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 1
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!1 &1232273651
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1232273654}
- component: {fileID: 1232273653}
- component: {fileID: 1232273652}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!81 &1232273652
AudioListener:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1232273651}
m_Enabled: 1
--- !u!20 &1232273653
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1232273651}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 1
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &1232273654
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1232273651}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 1, z: -10}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &1359344831
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1359344834}
- component: {fileID: 1359344833}
- component: {fileID: 1359344832}
m_Layer: 0
m_Name: EventSystem
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &1359344832
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1359344831}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4f231c4fb786f3946a6b90b886c48677, type: 3}
m_Name:
m_EditorClassIdentifier:
m_HorizontalAxis: Horizontal
m_VerticalAxis: Vertical
m_SubmitButton: Submit
m_CancelButton: Cancel
m_InputActionsPerSecond: 10
m_RepeatDelay: 0.5
m_ForceModuleActive: 0
--- !u!114 &1359344833
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1359344831}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 76c392e42b5098c458856cdf6ecaaaa1, type: 3}
m_Name:
m_EditorClassIdentifier:
m_FirstSelected: {fileID: 0}
m_sendNavigationEvents: 1
m_DragThreshold: 10
--- !u!4 &1359344834
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1359344831}
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: 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: 2
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: 4232056521131536012, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
propertyPath: RomName
value: tstd2.nes
objectReference: {fileID: 0}
- target: {fileID: 4232056521131536013, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
propertyPath: m_Name
value: NesEmulator
objectReference: {fileID: 0}
- target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
propertyPath: m_Enabled
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
propertyPath: m_Texture
value:
objectReference: {fileID: 0}
- target: {fileID: 4232056521759880276, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
m_RemovedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 4664d2ef3d138e141b308c242abd4327
guid: 3dba71db67877594a9b5b77059205ec8
DefaultImporter:
externalObjects: {}
userData:

View File

@ -6,19 +6,19 @@ RenderTexture:
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: RenderTexture
m_Name: New Render Texture
m_ImageContentsHash:
serializedVersion: 2
Hash: 00000000000000000000000000000000
m_ForcedFallbackFormat: 4
m_DownscaleFallback: 0
m_IsAlphaChannelOptional: 0
serializedVersion: 5
serializedVersion: 3
m_Width: 256
m_Height: 240
m_AntiAliasing: 1
m_MipCount: -1
m_DepthStencilFormat: 92
m_DepthFormat: 0
m_ColorFormat: 8
m_MipMap: 0
m_GenerateMips: 1
@ -36,4 +36,3 @@ RenderTexture:
m_WrapW: 1
m_Dimension: 2
m_VolumeDepth: 1
m_ShadowSamplingMode: 2

View File

@ -1,8 +1,8 @@
fileFormatVersion: 2
guid: 6645567e4c11d9447b1aee2406f681c5
guid: 5d4a385f133f9074583d64ab2172a03b
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 0
mainObjectFileID: 8400000
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,6 +1,9 @@
{
"name": "AxibugEmuOnline.Client",
"references": [],
"rootNamespace": "AxibugEmuOnline.Client",
"references": [
"GUID:390a2c4058e5c304a87e8be70c84d80b"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": true,

View File

@ -1,100 +0,0 @@
using System.Reflection;
using MyNes.Core;
namespace AxibugEmuOnline.Client
{
public class WINSettings : ISettings
{
public string App_Version = "";
public int Win_Location_X = 10;
public int Win_Location_Y = 10;
public int Win_Size_W = 768;
public int Win_Size_H = 743;
public bool Win_StartInFullscreen;
public string[] Misc_RecentFiles = new string[0];
public bool PauseEmuWhenFocusLost = true;
public bool ShowGettingStarted = true;
public string InterfaceLanguage = "English";
public bool ShutdowOnEscapePress = true;
public bool LoadStateOpenRecent;
public string Database_FilePath = "";
public string[] Database_FoldersSnapshots;
public string[] Database_FoldersCovers;
public string[] Database_FoldersInfos;
public string[] Database_FoldersScanned;
public bool LauncherRememberLastSelection = true;
public int LauncherLatestSelection;
public int LauncherLocationX = 10;
public int LauncherLocationY = 10;
public int LauncherSizeW = 1480;
public int LauncherSizeH = 920;
public int LauncherSpliter1 = 807;
public int LauncherSpliter2 = 420;
public int LauncherSpliter3 = 308;
public int LauncherSpliter4 = 271;
public bool LauncherAutoMinimize = true;
public bool LauncherAutoCycleImagesInGameTab = true;
public bool LauncherShowAyAppStart;
public int SnapsView_ImageMode = 1;
public bool SnapsView_ShowBar = true;
public bool SnapsView_ShowStatus = true;
public bool SnapsView_AutoCycle = true;
public int CoversView_ImageMode = 1;
public bool CoversView_ShowBar = true;
public bool CoversView_ShowStatus = true;
public bool CoversView_AutoCycle = true;
public WINSettings(string path)
: base(path)
{
}
public override void LoadSettings()
{
base.LoadSettings();
if (App_Version != Assembly.GetExecutingAssembly().GetName().Version.ToString())
{
ShowGettingStarted = true;
App_Version = Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
}
}
}

View File

@ -1,155 +1,10 @@
using MyNes.Core;
using Palmmedia.ReportGenerator.Core;
using SevenZip;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.IO;
using UnityEngine;
namespace AxibugEmuOnline.Client.Manager
{
public class AppEmu
{
INes _nes;
public static WINSettings Settings { get; private set; }
private bool isMaxing;
private bool isMoving;
private bool pausedByMainWindow;
private bool isMouseVisible;
private int mouseHiderCounter;
private const int mouseHiderReload = 1;
private bool gameLoaded;
private IContainer components;
public AppEmu()
{
}
public void Init()
{
_nes = new INes();
}
internal void LoadGame(string filePath)
{
bool success = false;
switch (Path.GetExtension(filePath).ToLower())
{
case ".nes":
NesEmu.LoadGame(filePath, out success);
break;
case ".7z":
case ".zip":
case ".rar":
case ".gzip":
case ".tar":
case ".bzip2":
case ".xz":
{
string text = filePath;
string text2 = Path.GetTempPath() + "\\MYNES\\";
SevenZipExtractor sevenZipExtractor;
try
{
sevenZipExtractor = new SevenZipExtractor(text);
}
catch (Exception ex)
{
MessageBox.Show(Resources.Message35 + ": \n" + ex.Message);
return;
}
if (sevenZipExtractor.ArchiveFileData.Count == 1)
{
if (sevenZipExtractor.ArchiveFileData[0].FileName.Substring(sevenZipExtractor.ArchiveFileData[0].FileName.Length - 4, 4).ToLower() == ".nes")
{
sevenZipExtractor.ExtractArchive(text2);
text = text2 + sevenZipExtractor.ArchiveFileData[0].FileName;
}
}
else
{
List<string> list = new List<string>();
foreach (ArchiveFileInfo archiveFileDatum in sevenZipExtractor.ArchiveFileData)
{
list.Add(archiveFileDatum.FileName);
}
FormFilesList formFilesList = new FormFilesList(list.ToArray());
if (formFilesList.ShowDialog(this) != DialogResult.OK)
{
return;
}
string[] fileNames = new string[1] { formFilesList.SelectedRom };
sevenZipExtractor.ExtractFiles(text2, fileNames);
text = text2 + formFilesList.SelectedRom;
}
NesEmu.LoadGame(text, out success);
break;
}
}
if (success)
{
if (Settings.Misc_RecentFiles == null)
{
Settings.Misc_RecentFiles = new string[0];
}
List<string> list2 = new List<string>(Settings.Misc_RecentFiles);
if (list2.Contains(filePath))
{
list2.Remove(filePath);
}
list2.Insert(0, filePath);
if (list2.Count > 19)
{
list2.RemoveAt(list2.Count - 1);
}
Settings.Misc_RecentFiles = list2.ToArray();
gameLoaded = true;
if (Settings.Win_StartInFullscreen)
{
if (base.WindowState != FormWindowState.Maximized)
{
MyNesMain.VideoProvider.ResizeBegin();
Thread.Sleep(100);
MyNesMain.RendererSettings.Vid_Fullscreen = true;
base.FormBorderStyle = FormBorderStyle.None;
menuStrip1.Visible = false;
base.WindowState = FormWindowState.Maximized;
MyNesMain.VideoProvider.ResizeEnd();
}
}
else if (MyNesMain.RendererSettings.Vid_AutoStretch)
{
ApplyStretch(applyRegion: true);
}
}
ApplyWindowTitle();
}
#region Setting
internal void LoadSettings()
{
base.Location = new Point(Program.Settings.Win_Location_X, Program.Settings.Win_Location_Y);
base.Size = new Size(Program.Settings.Win_Size_W, Program.Settings.Win_Size_H);
for (int i = 0; i < Program.SupportedLanguages.Length / 3; i++)
{
ToolStripMenuItem toolStripMenuItem = new ToolStripMenuItem();
toolStripMenuItem.Text = Program.SupportedLanguages[i, 2];
toolStripMenuItem.Checked = Program.SupportedLanguages[i, 0] == Program.Settings.InterfaceLanguage;
interfaceLanguageToolStripMenuItem.DropDownItems.Add(toolStripMenuItem);
}
}
#endregion
public class AppEmu
{
}
}

View File

@ -11,15 +11,19 @@ namespace AxibugEmuOnline.Client.Manager
{
public class AppNetGame
{
int CurrRoomID;
int[] _palette;
public int[] _renderbuffer { private set; get; }
public AppNetGame()
{
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdScreen, OnScreen);
}
Protobuf_Screnn_Frame _Protobuf_Screnn_Frame = new Protobuf_Screnn_Frame();
public void SendScreen(byte[] ScreenData)
public void SendScreen(byte[] RenderBuffer)
{
byte[] comData = CompressByteArray(ScreenData);
byte[] comData = CompressByteArray(RenderBuffer);
_Protobuf_Screnn_Frame.FrameID = 0;
_Protobuf_Screnn_Frame.RawBitmap = ByteString.CopyFrom(comData);
AppAxibugEmuOnline.networkHelper.SendToServer((int)CommandID.CmdScreen, ProtoBufHelper.Serizlize(_Protobuf_Screnn_Frame));
@ -28,14 +32,14 @@ namespace AxibugEmuOnline.Client.Manager
public void OnScreen(byte[] reqData)
{
Protobuf_Screnn_Frame msg = ProtoBufHelper.DeSerizlize<Protobuf_Screnn_Frame>(reqData);
//lock (RawBitmap)
//{
// byte[] data = DecompressByteArray(msg.RawBitmap.ToArray());
// for (int i = 0; i < data.Length; i++)
// {
// RawBitmap[i] = _palette[data[i]];
// }
//}
lock (_renderbuffer)
{
byte[] data = DecompressByteArray(msg.RawBitmap.ToArray());
for (int i = 0; i < data.Length; i++)
{
_renderbuffer[i] = _palette[data[i]];
}
}
}
public static byte[] CompressByteArray(byte[] bytesToCompress)

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5ff32bd86cd0f8245811007dc4e50768
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,51 @@
using UnityEngine;
using VirtualNes.Core;
namespace AxibugEmuOnline.Client
{
public class AudioProvider : MonoBehaviour
{
public NesEmulator NesEmu;
[SerializeField]
private AudioSource m_as;
private SoundBuffer _buffer = new SoundBuffer(4096);
public void Start()
{
var dummy = AudioClip.Create("dummy", 1, 1, AudioSettings.outputSampleRate, false);
dummy.SetData(new float[] { 1 }, 0);
m_as.clip = dummy; //just to let unity play the audiosource
m_as.loop = true;
m_as.spatialBlend = 1;
m_as.Play();
}
void OnAudioFilterRead(float[] data, int channels)
{
int step = channels;
if (NesEmu == null || NesEmu.NesCore == null) return;
ProcessSound(NesEmu.NesCore, (uint)(data.Length / channels));
for (int i = 0; i < data.Length; i += step)
{
float rawFloat = 0;
if (_buffer.TryRead(out byte rawData))
rawFloat = rawData / 255f;
data[i] = rawFloat;
for (int fill = 1; fill < step; fill++)
data[i + fill] = rawFloat;
}
}
void ProcessSound(NES nes, uint feedCount)
{
nes.apu.Process(_buffer, feedCount);
}
}
}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: ed2bba3664d14d840a5ed2847926614c
guid: a6a09b6a4cf4c2d4f994a13fd7e89d6f
MonoImporter:
externalObjects: {}
serializedVersion: 2

View File

@ -0,0 +1,21 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VirtualNes.Core.Debug;
namespace AxibugEmuOnline.Client
{
public class CoreDebuger : IDebugerImpl
{
public void Log(string message)
{
Debug.Log(message);
}
public void LogError(string message)
{
Debug.LogError(message);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 06357866273334741b885e5a1ad23afd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,108 @@
using AxibugEmuOnline.Client.ClientCore;
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using UnityEngine;
using VirtualNes.Core;
namespace AxibugEmuOnline.Client
{
public class CoreSupporter : ISupporterImpl
{
private static string RomDirectoryPath
{
get
{
#if UNITY_EDITOR
return "Assets/StreamingAssets/NES/Roms";
#else
return $"{Application.streamingAssetsPath}/NES/Roms";
#endif
}
}
public Stream OpenRom(string fname)
{
try
{
var stream = File.Open($"{RomDirectoryPath}/{fname}", FileMode.Open);
return stream;
}
catch (Exception ex)
{
Debug.LogError(ex);
return null;
}
}
public void GetRomPathInfo(string fname, out string fullPath, out string directPath)
{
directPath = RomDirectoryPath;
fullPath = $"{directPath}/{fname}";
}
public Stream OpenFile_DISKSYS()
{
return new MemoryStream(Resources.Load<TextAsset>("NES/Disksys.rom").bytes);
}
public void SaveSRAMToFile(byte[] sramContent, string romName)
{
string sramDirectoryPath = $"{Application.persistentDataPath}/sav";
Directory.CreateDirectory(sramDirectoryPath);
romName = Path.GetFileNameWithoutExtension(romName);
File.WriteAllBytes($"{sramDirectoryPath}/{romName}.sav", sramContent);
}
public void SaveDISKToFile(byte[] diskFileContent, string romName)
{
string diskFileDirectoryPath = $"{Application.persistentDataPath}/dsv";
Directory.CreateDirectory(diskFileDirectoryPath);
romName = Path.GetFileNameWithoutExtension(romName);
File.WriteAllBytes($"{diskFileDirectoryPath}/{romName}.dsv", diskFileContent);
}
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;
}
}
public bool TryGetMapperNo(ROM rom, out int mapperNo)
{
var db = Resources.Load<RomDB>("NES/ROMDB");
return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo);
}
public ControllerState GetControllerState()
{
var mapper = NesControllerMapper.Get();
return mapper.CreateState();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8207d923313517f448d7b4d54756e993
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,124 @@
using System;
using System.IO;
using UnityEngine;
using VirtualNes.Core;
namespace AxibugEmuOnline.Client
{
public class NesControllerMapper
{
private static readonly string ConfigFilePath = $"{Application.persistentDataPath}/NES/ControllerMapper.json";
public MapperSetter Player1 = new MapperSetter();
public MapperSetter Player2 = new MapperSetter();
public MapperSetter Player3 = new MapperSetter();
public MapperSetter Player4 = new MapperSetter();
public NesControllerMapper()
{
Player1.UP.keyCode = KeyCode.W;
Player1.DOWN.keyCode = KeyCode.S;
Player1.LEFT.keyCode = KeyCode.A;
Player1.RIGHT.keyCode = KeyCode.D;
Player1.B.keyCode = KeyCode.J;
Player1.A.keyCode = KeyCode.K;
Player1.SELECT.keyCode = KeyCode.V;
Player1.START.keyCode = KeyCode.B;
}
public void Save()
{
var jsonStr = JsonUtility.ToJson(this);
File.WriteAllText(ConfigFilePath, jsonStr);
}
public ControllerState CreateState()
{
var state1 = Player1.GetButtons();
var state2 = Player2.GetButtons();
var state3 = Player3.GetButtons();
var state4 = Player4.GetButtons();
return new ControllerState(state1, state2, state3, state4);
}
private static NesControllerMapper s_setting;
public static NesControllerMapper Get()
{
if (s_setting == null)
{
try
{
var json = File.ReadAllText($"{Application.persistentDataPath}/Nes/ControllerMapper.json");
s_setting = JsonUtility.FromJson<NesControllerMapper>(json);
}
catch
{
s_setting = new NesControllerMapper();
}
}
return s_setting;
}
[Serializable]
public class Mapper
{
public EnumButtonType buttonType;
public KeyCode keyCode;
public Mapper(EnumButtonType buttonType)
{
this.buttonType = buttonType;
}
}
[Serializable]
public class MapperSetter
{
public Mapper UP = new Mapper(EnumButtonType.UP);
public Mapper DOWN = new Mapper(EnumButtonType.DOWN);
public Mapper LEFT = new Mapper(EnumButtonType.LEFT);
public Mapper RIGHT = new Mapper(EnumButtonType.RIGHT);
public Mapper A = new Mapper(EnumButtonType.A);
public Mapper B = new Mapper(EnumButtonType.B);
public Mapper SELECT = new Mapper(EnumButtonType.SELECT);
public Mapper START = new Mapper(EnumButtonType.START);
public Mapper MIC = new Mapper(EnumButtonType.MIC);
public EnumButtonType GetButtons()
{
EnumButtonType res = 0;
if (Input.GetKey(UP.keyCode))
res |= EnumButtonType.UP;
if (Input.GetKey(DOWN.keyCode))
res |= EnumButtonType.DOWN;
if (Input.GetKey(LEFT.keyCode))
res |= EnumButtonType.LEFT;
if (Input.GetKey(RIGHT.keyCode))
res |= EnumButtonType.RIGHT;
if (Input.GetKey(A.keyCode))
res |= EnumButtonType.A;
if (Input.GetKey(B.keyCode))
res |= EnumButtonType.B;
if (Input.GetKey(SELECT.keyCode))
res |= EnumButtonType.SELECT;
if (Input.GetKey(START.keyCode))
res |= EnumButtonType.START;
if (Input.GetKey(MIC.keyCode))
res |= EnumButtonType.MIC;
return res;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 66fc8233a79cd254f8d005452dcd4ac0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,97 @@
using AxibugEmuOnline.Client.ClientCore;
using System;
using System.IO;
using System.Xml.Linq;
using UnityEngine;
using VirtualNes.Core;
using VirtualNes.Core.Debug;
namespace AxibugEmuOnline.Client
{
public class NesEmulator : MonoBehaviour
{
public NES NesCore { get; private set; }
public VideoProvider VideoProvider;
public AudioProvider AudioProvider;
#if UNITY_EDITOR
public string RomName;
#endif
private void Start()
{
Application.targetFrameRate = 60;
VideoProvider.NesEmu = this;
AudioProvider.NesEmu = this;
#if UNITY_EDITOR
StartGame(RomName);
#endif
}
public void StartGame(string romName)
{
StopGame();
Supporter.Setup(new CoreSupporter());
Debuger.Setup(new CoreDebuger());
try
{
NesCore = new NES(romName);
}
catch (Exception ex)
{
NesCore = null;
Debug.LogError(ex);
}
}
public void StopGame()
{
NesCore?.Dispose();
NesCore = null;
}
private void Update()
{
if (NesCore != null)
{
var controlState = Supporter.GetControllerState();
NesCore.pad.Sync(controlState);
NesCore.EmulateFrame(true);
var screenBuffer = NesCore.ppu.GetScreenPtr();
var lineColorMode = NesCore.ppu.GetLineColorMode();
VideoProvider.SetDrawData(screenBuffer, lineColorMode, 256, 240);
}
}
#if UNITY_EDITOR
[ContextMenu("IMPORT")]
public void TTTA()
{
var db = Resources.Load<RomDB>("NES/ROMDB");
db.Clear();
var xmlStr = File.ReadAllText("nes20db.xml");
var xml = XDocument.Parse(xmlStr);
var games = xml.Element("nes20db").Elements("game");
foreach (var game in games)
{
var crcStr = game.Element("rom").Attribute("crc32").Value;
var crc = uint.Parse($"{crcStr}", System.Globalization.NumberStyles.HexNumber);
var mapper = int.Parse($"{game.Element("pcb").Attribute("mapper").Value}");
if (mapper > 255) continue;
db.AddInfo(new RomDB.RomInfo { CRC = crc, Mapper = mapper });
}
UnityEditor.EditorUtility.SetDirty(db);
UnityEditor.AssetDatabase.SaveAssets();
}
#endif
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39557e19783acee499ace6c68549e8f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,528 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &9760340517325694
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 4785916497946256520}
- component: {fileID: 9003897287163669553}
- component: {fileID: 8726979175317618791}
m_Layer: 0
m_Name: AudioProvider
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &4785916497946256520
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9760340517325694}
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: 4232056521131536011}
m_RootOrder: 2
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &9003897287163669553
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9760340517325694}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a6a09b6a4cf4c2d4f994a13fd7e89d6f, type: 3}
m_Name:
m_EditorClassIdentifier:
NesEmu: {fileID: 0}
m_as: {fileID: 8726979175317618791}
--- !u!82 &8726979175317618791
AudioSource:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9760340517325694}
m_Enabled: 1
serializedVersion: 4
OutputAudioMixerGroup: {fileID: 0}
m_audioClip: {fileID: 0}
m_PlayOnAwake: 1
m_Volume: 1
m_Pitch: 1
Loop: 0
Mute: 0
Spatialize: 0
SpatializePostEffects: 0
Priority: 128
DopplerLevel: 1
MinDistance: 1
MaxDistance: 500
Pan2D: 0
rolloffMode: 0
BypassEffects: 0
BypassListenerEffects: 0
BypassReverbZones: 0
rolloffCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
- serializedVersion: 3
time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
panLevelCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
spreadCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
reverbZoneMixCustomCurve:
serializedVersion: 2
m_Curve:
- serializedVersion: 3
time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
weightedMode: 0
inWeight: 0.33333334
outWeight: 0.33333334
m_PreInfinity: 2
m_PostInfinity: 2
m_RotationOrder: 4
--- !u!1 &3545890545112170401
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 1038087993597378172}
- component: {fileID: 3032498056073774270}
- component: {fileID: 634277252673086327}
m_Layer: 5
m_Name: Viewer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!224 &1038087993597378172
RectTransform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3545890545112170401}
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: 1
m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 128, y: 256}
m_Pivot: {x: 0, y: 0}
--- !u!222 &3032498056073774270
CanvasRenderer:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3545890545112170401}
m_CullTransparentMesh: 1
--- !u!114 &634277252673086327
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3545890545112170401}
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
--- !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: []
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:
NesEmu: {fileID: 0}
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}
- {fileID: 1038087993597378172}
m_Father: {fileID: 4232056521131536011}
m_RootOrder: 3
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}
- {fileID: 393435831810118449}
- {fileID: 4785916497946256520}
- {fileID: 4232056520494431727}
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}
AudioProvider: {fileID: 9003897287163669553}
RomName:
--- !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
--- !u!1 &7856060136050839404
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 393435831810118449}
- component: {fileID: 499856625911497759}
m_Layer: 0
m_Name: PatternViewer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
--- !u!4 &393435831810118449
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7856060136050839404}
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: 4232056521131536011}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!114 &499856625911497759
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 7856060136050839404}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: c7a50c189f5be5b4ea54de444f8488a0, type: 3}
m_Name:
m_EditorClassIdentifier:
img: {fileID: 634277252673086327}

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f8bea3f8aa351bb46ada33b2274729ea
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,303 @@
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
{
public static class PaletteDefine
{
public struct RGBQUAD
{
public byte rgbBlue;
public byte rgbGreen;
public byte rgbRed;
public byte rgbReserved;
}
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 256
// Color
public static RGBQUAD[][] m_cpPalette = new RGBQUAD[8][]
{
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
};
// Monochrome
public static RGBQUAD[][] m_mpPalette = new RGBQUAD[8][]
{
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
new RGBQUAD[64*2],
};
#endregion
#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
public static RGBQUAD[] GetPaletteData()
{
RGBQUAD[] rgb = new RGBQUAD[256];
for (int i = 0; i < 64; i++)
{
rgb[i] = m_cpPalette[0][i];
rgb[i + 0x40] = m_mpPalette[0][i];
}
return rgb;
}
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_cpPalette[j][i + 0x00].rgbRed = (byte)Rn;
m_cpPalette[j][i + 0x00].rgbGreen = (byte)Gn;
m_cpPalette[j][i + 0x00].rgbBlue = (byte)Bn;
m_cpPalette[j][i + 0x40].rgbRed = (byte)Rs;
m_cpPalette[j][i + 0x40].rgbGreen = (byte)Gs;
m_cpPalette[j][i + 0x40].rgbBlue = (byte)Bs;
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_mpPalette[j][i + 0x00].rgbRed = (byte)Rn;
m_mpPalette[j][i + 0x00].rgbGreen = (byte)Gn;
m_mpPalette[j][i + 0x00].rgbBlue = (byte)Bn;
m_mpPalette[j][i + 0x40].rgbRed = (byte)Rs;
m_mpPalette[j][i + 0x40].rgbGreen = (byte)Gs;
m_mpPalette[j][i + 0x40].rgbBlue = (byte)Bs;
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;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bbd3f54279eb4ae45831a914b13d1cec
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,85 @@
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using VirtualNes;
using static AxibugEmuOnline.Client.PaletteDefine;
namespace AxibugEmuOnline.Client
{
public class PatternViewer : MonoBehaviour
{
public RawImage img;
private Color32[] m_lpPattern = new Color32[128 * 256];
private Texture2D m_texture;
private Dictionary<byte, RGBQUAD> colors = new Dictionary<byte, RGBQUAD>();
private void Awake()
{
m_texture = new Texture2D(128, 256);
}
private void Update()
{
Paint();
}
private void OnEnable()
{
img.gameObject.SetActive(true);
}
private void OnDisable()
{
img.gameObject.SetActive(false);
}
public void Paint()
{
img.texture = m_texture;
var pal = MMU.SPPAL;
var palette = PaletteDefine.GetPaletteData();
colors[0] = palette[pal[0]];
colors[1] = palette[pal[1]];
colors[2] = palette[pal[2]];
colors[3] = palette[pal[3]];
for (int i = 0; i < 8; i++)
{
var Ptn = MMU.PPU_MEM_BANK[i];
int lpPtn = 0;
for (int p = 0; p < 64; p++)
{
int lpScn = i * 32 * 128 + (p & 15) * 8 + (p / 16) * 8 * 128;
for (int y = 0; y < 8; y++)
{
byte chr_l = Ptn[lpPtn + y];
byte chr_h = Ptn[lpPtn + y + 8];
m_lpPattern[lpScn + 0] = ToColor32(colors, (((chr_h >> 6) & 2) | ((chr_l >> 7) & 1)));
m_lpPattern[lpScn + 4] = ToColor32(colors, (((chr_h >> 2) & 2) | ((chr_l >> 3) & 1)));
m_lpPattern[lpScn + 1] = ToColor32(colors, (((chr_h >> 5) & 2) | ((chr_l >> 6) & 1)));
m_lpPattern[lpScn + 5] = ToColor32(colors, (((chr_h >> 1) & 2) | ((chr_l >> 2) & 1)));
m_lpPattern[lpScn + 2] = ToColor32(colors, (((chr_h >> 4) & 2) | ((chr_l >> 5) & 1)));
m_lpPattern[lpScn + 6] = ToColor32(colors, (((chr_h >> 0) & 2) | ((chr_l >> 1) & 1)));
m_lpPattern[lpScn + 3] = ToColor32(colors, (((chr_h >> 3) & 2) | ((chr_l >> 4) & 1)));
m_lpPattern[lpScn + 7] = ToColor32(colors, (((chr_h << 1) & 2) | ((chr_l >> 0) & 1)));
// Next line
lpScn += 128;
}
// Next pattern
lpPtn += 16;
}
}
m_texture.SetPixels32(m_lpPattern);
m_texture.Apply();
}
private Color32 ToColor32(Dictionary<byte, RGBQUAD> map, int v)
{
var raw = map[(byte)v];
return new Color32(raw.rgbRed, raw.rgbGreen, raw.rgbBlue, 255);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c7a50c189f5be5b4ea54de444f8488a0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace AxibugEmuOnline.Client.ClientCore
{
public class RomDB : ScriptableObject
{
[SerializeField]
private List<RomInfo> romInfos = new List<RomInfo>();
private Dictionary<uint, RomInfo> crc_Info_mapper;
public void AddInfo(RomInfo romInfo)
{
romInfos.Add(romInfo);
}
public void Clear()
{
romInfos.Clear();
}
public bool GetMapperNo(uint crc, out int mapperNo)
{
if (crc_Info_mapper == null)
{
crc_Info_mapper = new Dictionary<uint, RomInfo>();
foreach (var info in romInfos)
{
crc_Info_mapper[info.CRC] = info;
}
}
if (crc_Info_mapper.TryGetValue(crc, out var romInfo))
{
mapperNo = romInfo.Mapper;
return true;
}
else
{
mapperNo = -1;
return false;
}
}
[Serializable]
public class RomInfo
{
public uint CRC;
public int Mapper;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 29131082dba8d234481296f0cf29a1fe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,67 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
namespace AxibugEmuOnline.Client
{
public class VideoProvider : MonoBehaviour
{
public NesEmulator NesEmu;
public RawImage Image;
private UInt32[] wrapTexBuffer;
private IntPtr wrapTexBufferPointer;
private Texture2D wrapTex;
private int TexBufferSize;
private uint[] pPal;
public void SetDrawData(byte[] screenData, byte[] lineColorMode, int screenWidth, int screenHeight)
{
if (wrapTex == null)
{
wrapTex = new Texture2D(screenWidth, screenHeight, TextureFormat.BGRA32, false);
wrapTexBuffer = new UInt32[screenWidth * screenHeight];
// 固定数组,防止垃圾回收器移动它
GCHandle handle = GCHandle.Alloc(wrapTexBuffer, GCHandleType.Pinned);
// 获取数组的指针
wrapTexBufferPointer = handle.AddrOfPinnedObject();
Image.texture = wrapTex;
pPal = PaletteDefine.m_cnPalette[0];
TexBufferSize = wrapTexBuffer.Length * 4;
}
int pScn = 0;
int width;
var Dst = wrapTexBuffer;
var pDst = 0;
for (int line = 0; line < screenHeight; line++)
{
width = screenWidth;
while (width > 0)
{
var edx = screenData[pScn + 8];
int index = edx & 0xFF;
var colorData = pPal[index];
Dst[pDst] = 0xFF000000 | colorData;
pScn += 1;
pDst += 1;
width -= 1;
}
pScn += 16;// PPU.SCREEN_WIDTH - screenWidth;
}
wrapTex.LoadRawTextureData(wrapTexBufferPointer, TexBufferSize);
wrapTex.Apply();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 83fbe375412d1af4482ae76e81c1dda2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,72 @@
using System.Threading;
public class RingBuffer<T>
{
private readonly T[] buffer;
private readonly int capacity;
private int writePos;
private int readPos;
private int count;
public RingBuffer(int capacity)
{
this.capacity = capacity;
this.buffer = new T[capacity];
this.writePos = 0;
this.readPos = 0;
this.count = 0;
}
public void Write(T item)
{
int localWritePos;
int localReadPos;
do
{
localWritePos = Volatile.Read(ref writePos);
localReadPos = Volatile.Read(ref readPos);
int nextWritePos = (localWritePos + 1) % capacity;
if (nextWritePos == localReadPos)
{
// 缓冲区已满,覆盖最旧的未读数据
Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos);
}
}
while (Interlocked.CompareExchange(ref writePos, (localWritePos + 1) % capacity, localWritePos) != localWritePos);
buffer[localWritePos] = item;
Interlocked.Increment(ref count);
}
public bool TryRead(out T item)
{
item = default(T);
int localReadPos;
int localWritePos;
do
{
localReadPos = Volatile.Read(ref readPos);
localWritePos = Volatile.Read(ref writePos);
if (localReadPos == localWritePos)
{
return false; // 缓冲区为空
}
}
while (Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos) != localReadPos);
item = buffer[localReadPos];
Interlocked.Decrement(ref count);
return true;
}
public int Available()
{
return Volatile.Read(ref count);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6bd0f6c1647ed3f49a59e7f06406f49b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,11 @@
using VirtualNes.Core;
public class SoundBuffer : RingBuffer<byte>, ISoundDataBuffer
{
public SoundBuffer(int capacity) : base(capacity) { }
public void WriteByte(byte value)
{
Write(value);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c5f491c577bed63478340426f7698563
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 353264361911f2f43bb2c088c7e73fec
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: fc7102c34a9fa4148b4aa74d54e82b1f
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ac852e7a0b9604940b0f7e0180fd2707
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: dee4e4661b99068439cc932db923d849
guid: 41cd7684d8de61f4499c3aa27a6c5b3a
DefaultImporter:
externalObjects: {}
userData:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 23a003aef20e19f4d8c45acd32012718
guid: 50dfce75937af2a44bafd221a0163501
DefaultImporter:
externalObjects: {}
userData:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 091b4306faaa8fc4084836c5237b76c8
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: a5222bc76eba99e4c9fc92b70f4103bc
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 7abf09a3e3fd84648852e5d972dfd260
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 5df1a0f25b9a1864493e694ce7b40cc4
guid: 0fcf57d6e248ead4a874daa51181ec5f
DefaultImporter:
externalObjects: {}
userData:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2c5bcc6d5df67f04d93e0ab812c36b4e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,559 @@
using Codice.CM.Client.Differences;
using System;
using System.IO;
using System.Security.Principal;
using UnityEngine;
using VirtualNes.Core;
using VirtualNes.Core.Debug;
namespace VirtualNes.Core
{
public class APU
{
public const uint QUEUE_LENGTH = 8192;
// Volume adjust
// Internal sounds
public const uint RECTANGLE_VOL = 0x0F0;
public const uint TRIANGLE_VOL = 0x130;
public const uint NOISE_VOL = 0x0C0;
public const uint DPCM_VOL = 0x0F0;
// Extra sounds
public const uint VRC6_VOL = 0x0F0;
public const uint VRC7_VOL = 0x130;
public const uint FDS_VOL = 0x0F0;
public const uint MMC5_VOL = 0x0F0;
public const uint N106_VOL = 0x088;
public const uint FME7_VOL = 0x130;
private NES nes;
private byte exsound_select;
private APU_INTERNAL @internal = new APU_INTERNAL();
private APU_VRC6 vrc6 = new APU_VRC6();
private APU_VRC7 vrc7 = new APU_VRC7();
private APU_MMC5 mmc5 = new APU_MMC5();
private APU_FDS fds = new APU_FDS();
private APU_N106 n106 = new APU_N106();
private APU_FME7 fme7 = new APU_FME7();
private int last_data;
private int last_diff;
protected short[] m_SoundBuffer = new short[256];
protected int[] lowpass_filter = new int[4];
protected QUEUE queue = new QUEUE();
protected QUEUE exqueue = new QUEUE();
protected bool[] m_bMute = new bool[16];
protected double elapsed_time;
public APU(NES parent)
{
exsound_select = 0;
nes = parent;
@internal.SetParent(parent);
last_data = last_diff = 0;
Array.Clear(m_SoundBuffer, 0, m_SoundBuffer.Length);
Array.Clear(lowpass_filter, 0, lowpass_filter.Length);
for (int i = 0; i < m_bMute.Length; i++)
m_bMute[i] = true;
}
public void Dispose()
{
@internal.Dispose();
vrc6.Dispose();
vrc7.Dispose();
mmc5.Dispose();
fds.Dispose();
n106.Dispose();
fme7.Dispose();
}
private int[] vol = new int[24];
static double cutofftemp = (2.0 * 3.141592653579 * 40.0);
static double tmp = 0.0;
public void Process(ISoundDataBuffer lpBuffer, uint dwSize)
{
int nBits = Supporter.Config.sound.nBits;
uint dwLength = (uint)(dwSize / (nBits / 8));
int output;
QUEUEDATA q = default;
uint writetime;
var pSoundBuf = m_SoundBuffer;
int nCcount = 0;
int nFilterType = Supporter.Config.sound.nFilterType;
if (!Supporter.Config.sound.bEnable)
{
byte empty = (byte)(Supporter.Config.sound.nRate == 8 ? 128 : 0);
for (int i = 0; i < dwSize; i++)
lpBuffer.WriteByte(empty);
return;
}
// Volume setup
// 0:Master
// 1:Rectangle 1
// 2:Rectangle 2
// 3:Triangle
// 4:Noise
// 5:DPCM
// 6:VRC6
// 7:VRC7
// 8:FDS
// 9:MMC5
// 10:N106
// 11:FME7
MemoryUtility.ZEROMEMORY(vol, vol.Length);
var bMute = m_bMute;
var nVolume = Supporter.Config.sound.nVolume;
int nMasterVolume = bMute[0] ? nVolume[0] : 0;
// Internal
vol[0] = (int)(bMute[1] ? (RECTANGLE_VOL * nVolume[1] * nMasterVolume) / (100 * 100) : 0);
vol[1] = (int)(bMute[2] ? (RECTANGLE_VOL * nVolume[2] * nMasterVolume) / (100 * 100) : 0);
vol[2] = (int)(bMute[3] ? (TRIANGLE_VOL * nVolume[3] * nMasterVolume) / (100 * 100) : 0);
vol[3] = (int)(bMute[4] ? (NOISE_VOL * nVolume[4] * nMasterVolume) / (100 * 100) : 0);
vol[4] = (int)(bMute[5] ? (DPCM_VOL * nVolume[5] * nMasterVolume) / (100 * 100) : 0);
// VRC6
vol[5] = (int)(bMute[6] ? (VRC6_VOL * nVolume[6] * nMasterVolume) / (100 * 100) : 0);
vol[6] = (int)(bMute[7] ? (VRC6_VOL * nVolume[6] * nMasterVolume) / (100 * 100) : 0);
vol[7] = (int)(bMute[8] ? (VRC6_VOL * nVolume[6] * nMasterVolume) / (100 * 100) : 0);
// VRC7
vol[8] = (int)(bMute[6] ? (VRC7_VOL * nVolume[7] * nMasterVolume) / (100 * 100) : 0);
// FDS
vol[9] = (int)(bMute[6] ? (FDS_VOL * nVolume[8] * nMasterVolume) / (100 * 100) : 0);
// MMC5
vol[10] = (int)(bMute[6] ? (MMC5_VOL * nVolume[9] * nMasterVolume) / (100 * 100) : 0);
vol[11] = (int)(bMute[7] ? (MMC5_VOL * nVolume[9] * nMasterVolume) / (100 * 100) : 0);
vol[12] = (int)(bMute[8] ? (MMC5_VOL * nVolume[9] * nMasterVolume) / (100 * 100) : 0);
// N106
vol[13] = (int)(bMute[6] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
vol[14] = (int)(bMute[7] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
vol[15] = (int)(bMute[8] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
vol[16] = (int)(bMute[9] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
vol[17] = (int)(bMute[10] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
vol[18] = (int)(bMute[11] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
vol[19] = (int)(bMute[12] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
vol[20] = (int)(bMute[13] ? (N106_VOL * nVolume[10] * nMasterVolume) / (100 * 100) : 0);
// FME7
vol[21] = (int)(bMute[6] ? (FME7_VOL * nVolume[11] * nMasterVolume) / (100 * 100) : 0);
vol[22] = (int)(bMute[7] ? (FME7_VOL * nVolume[11] * nMasterVolume) / (100 * 100) : 0);
vol[23] = (int)(bMute[8] ? (FME7_VOL * nVolume[11] * nMasterVolume) / (100 * 100) : 0);
// double cycle_rate = ((double)FRAME_CYCLES*60.0/12.0)/(double)Config.sound.nRate;
double cycle_rate = (nes.nescfg.FrameCycles * 60.0 / 12.0) / Supporter.Config.sound.nRate;
// CPUサイクル数がループしてしまった時の対策処理
if (elapsed_time > nes.cpu.GetTotalCycles())
{
QueueFlush();
}
while ((dwLength--) != 0)
{
writetime = (uint)elapsed_time;
while (GetQueue((int)writetime, ref q))
{
WriteProcess(q.addr, q.data);
}
while (GetExQueue((int)writetime, ref q))
{
WriteExProcess(q.addr, q.data);
}
// 0-4:internal 5-7:VRC6 8:VRC7 9:FDS 10-12:MMC5 13-20:N106 21-23:FME7
output = 0;
output += @internal.Process(0) * vol[0];
output += @internal.Process(1) * vol[1];
output += @internal.Process(2) * vol[2];
output += @internal.Process(3) * vol[3];
output += @internal.Process(4) * vol[4];
if ((exsound_select & 0x01) != 0)
{
output += vrc6.Process(0) * vol[5];
output += vrc6.Process(1) * vol[6];
output += vrc6.Process(2) * vol[7];
}
if ((exsound_select & 0x02) != 0)
{
output += vrc7.Process(0) * vol[8];
}
if ((exsound_select & 0x04) != 0)
{
output += fds.Process(0) * vol[9];
}
if ((exsound_select & 0x08) != 0)
{
output += mmc5.Process(0) * vol[10];
output += mmc5.Process(1) * vol[11];
output += mmc5.Process(2) * vol[12];
}
if ((exsound_select & 0x10) != 0)
{
output += n106.Process(0) * vol[13];
output += n106.Process(1) * vol[14];
output += n106.Process(2) * vol[15];
output += n106.Process(3) * vol[16];
output += n106.Process(4) * vol[17];
output += n106.Process(5) * vol[18];
output += n106.Process(6) * vol[19];
output += n106.Process(7) * vol[20];
}
if ((exsound_select & 0x20) != 0)
{
fme7.Process(3); // Envelope & Noise
output += fme7.Process(0) * vol[21];
output += fme7.Process(1) * vol[22];
output += fme7.Process(2) * vol[23];
}
output >>= 8;
if (nFilterType == 1)
{
//ローパスフィルターTYPE 1(Simple)
output = (lowpass_filter[0] + output) / 2;
lowpass_filter[0] = output;
}
else if (nFilterType == 2)
{
//ローパスフィルターTYPE 2(Weighted type 1)
output = (lowpass_filter[1] + lowpass_filter[0] + output) / 3;
lowpass_filter[1] = lowpass_filter[0];
lowpass_filter[0] = output;
}
else if (nFilterType == 3)
{
//ローパスフィルターTYPE 3(Weighted type 2)
output = (lowpass_filter[2] + lowpass_filter[1] + lowpass_filter[0] + output) / 4;
lowpass_filter[2] = lowpass_filter[1];
lowpass_filter[1] = lowpass_filter[0];
lowpass_filter[0] = output;
}
else if (nFilterType == 4)
{
//ローパスフィルターTYPE 4(Weighted type 3)
output = (lowpass_filter[1] + lowpass_filter[0] * 2 + output) / 4;
lowpass_filter[1] = lowpass_filter[0];
lowpass_filter[0] = output;
}
// DC成分のカット(HPF TEST)
{
// static double cutoff = (2.0*3.141592653579*40.0/44100.0);
double cutoff = cutofftemp / Supporter.Config.sound.nRate;
double @in, @out;
@in = output;
@out = (@in - tmp);
tmp = tmp + cutoff * @out;
output = (int)@out;
}
// Limit
if (output > 0x7FFF)
{
output = 0x7FFF;
}
else if (output < -0x8000)
{
output = -0x8000;
}
if (nBits != 8)
{
byte highByte = (byte)(output >> 8); // 获取高8位
byte lowByte = (byte)(output & 0xFF); // 获取低8位
lpBuffer.WriteByte(highByte);
lpBuffer.WriteByte(lowByte);
}
else
{
lpBuffer.WriteByte((byte)((output >> 8) ^ 0x80));
}
if (nCcount < 0x0100)
pSoundBuf[nCcount++] = (short)output;
// elapsedtime += cycle_rate;
elapsed_time += cycle_rate;
}
if (elapsed_time > ((nes.nescfg.FrameCycles / 24) + nes.cpu.GetTotalCycles()))
{
elapsed_time = nes.cpu.GetTotalCycles();
}
if ((elapsed_time + (nes.nescfg.FrameCycles / 6)) < nes.cpu.GetTotalCycles())
{
elapsed_time = nes.cpu.GetTotalCycles();
}
}
private bool GetExQueue(int writetime, ref QUEUEDATA ret)
{
if (exqueue.wrptr == exqueue.rdptr)
{
return false;
}
if (exqueue.data[exqueue.rdptr].time <= writetime)
{
ret = exqueue.data[exqueue.rdptr];
exqueue.rdptr++;
exqueue.rdptr = (int)(exqueue.rdptr & (QUEUE_LENGTH - 1));
return true;
}
return false;
}
private void QueueFlush()
{
while (queue.wrptr != queue.rdptr)
{
WriteProcess(queue.data[queue.rdptr].addr, queue.data[queue.rdptr].data);
queue.rdptr++;
queue.rdptr = (int)(queue.rdptr & (QUEUE_LENGTH - 1));
}
while (exqueue.wrptr != exqueue.rdptr)
{
WriteExProcess(exqueue.data[exqueue.rdptr].addr, exqueue.data[exqueue.rdptr].data);
exqueue.rdptr++;
exqueue.rdptr = (int)(exqueue.rdptr & (QUEUE_LENGTH - 1));
}
}
private void WriteExProcess(ushort addr, byte data)
{
if ((exsound_select & 0x01) != 0)
{
vrc6.Write(addr, data);
}
if ((exsound_select & 0x02) != 0)
{
vrc7.Write(addr, data);
}
if ((exsound_select & 0x04) != 0)
{
fds.Write(addr, data);
}
if ((exsound_select & 0x08) != 0)
{
mmc5.Write(addr, data);
}
if ((exsound_select & 0x10) != 0)
{
if (addr == 0x0000)
{
byte dummy = n106.Read(addr);
}
else
{
n106.Write(addr, data);
}
}
if ((exsound_select & 0x20) != 0)
{
fme7.Write(addr, data);
}
}
private void WriteProcess(ushort addr, byte data)
{
// $4018はVirtuaNES固有ポート
if (addr >= 0x4000 && addr <= 0x401F)
{
@internal.Write(addr, data);
}
}
internal void SyncDPCM(int cycles)
{
@internal.Sync(cycles);
}
internal byte Read(ushort addr)
{
return @internal.SyncRead(addr);
}
internal void Write(ushort addr, byte data)
{
// $4018偼VirtuaNES屌桳億乕僩
if (addr >= 0x4000 && addr <= 0x401F)
{
@internal.SyncWrite(addr, data);
SetQueue(nes.cpu.GetTotalCycles(), addr, data);
}
}
private void SetQueue(int writetime, ushort addr, byte data)
{
queue.data[queue.wrptr].time = writetime;
queue.data[queue.wrptr].addr = addr;
queue.data[queue.wrptr].data = data;
queue.wrptr++;
var newwrptr = (int)(queue.wrptr & (QUEUE_LENGTH - 1));
queue.wrptr = newwrptr;
if (queue.wrptr == queue.rdptr)
{
Debuger.LogError("queue overflow.");
}
}
private bool GetQueue(int writetime, ref QUEUEDATA ret)
{
if (queue.wrptr == queue.rdptr)
{
return false;
}
if (queue.data[queue.rdptr].time <= writetime)
{
ret = queue.data[queue.rdptr];
queue.rdptr++;
var newrdptr = (int)(queue.rdptr & (QUEUE_LENGTH - 1));
queue.rdptr = newrdptr;
return true;
}
return false;
}
public void SoundSetup()
{
float fClock = nes.nescfg.CpuClock;
int nRate = Supporter.Config.sound.nRate;
@internal.Setup(fClock, nRate);
vrc6.Setup(fClock, nRate);
vrc7.Setup(fClock, nRate);
mmc5.Setup(fClock, nRate);
fds.Setup(fClock, nRate);
n106.Setup(fClock, nRate);
fme7.Setup(fClock, nRate);
}
internal void SelectExSound(byte data)
{
exsound_select = data;
}
internal void Reset()
{
queue = new QUEUE();
exqueue = new QUEUE();
elapsed_time = 0;
float fClock = nes.nescfg.CpuClock;
int nRate = Supporter.Config.sound.nRate;
@internal.Reset(fClock, nRate);
vrc6.Reset(fClock, nRate);
vrc7.Reset(fClock, nRate);
mmc5.Reset(fClock, nRate);
fds.Reset(fClock, nRate);
n106.Reset(fClock, nRate);
fme7.Reset(fClock, nRate);
SoundSetup();
}
internal void ExWrite(ushort addr, byte data)
{
SetExQueue(nes.cpu.GetTotalCycles(), addr, data);
if ((exsound_select & 0x04) != 0)
{
if (addr >= 0x4040 && addr < 0x4100)
{
fds.SyncWrite(addr, data);
}
}
if ((exsound_select & 0x08) != 0)
{
if (addr >= 0x5000 && addr <= 0x5015)
{
mmc5.SyncWrite(addr, data);
}
}
}
private void SetExQueue(int writetime, ushort addr, byte data)
{
exqueue.data[exqueue.wrptr].time = writetime;
exqueue.data[exqueue.wrptr].addr = addr;
exqueue.data[exqueue.wrptr].data = data;
exqueue.wrptr++;
var temp = QUEUE_LENGTH - 1;
exqueue.wrptr = (int)(exqueue.wrptr & temp);
if (exqueue.wrptr == exqueue.rdptr)
{
Debuger.LogError("exqueue overflow.");
}
}
internal byte ExRead(ushort addr)
{
byte data = 0;
if ((exsound_select & 0x10) != 0)
{
if (addr == 0x4800)
{
SetExQueue(nes.cpu.GetTotalCycles(), 0, 0);
}
}
if ((exsound_select & 0x04) != 0)
{
if (addr >= 0x4040 && addr < 0x4100)
{
data = fds.SyncRead(addr);
}
}
if ((exsound_select & 0x08) != 0)
{
if (addr >= 0x5000 && addr <= 0x5015)
{
data = mmc5.SyncRead(addr);
}
}
return data;
}
}
public struct QUEUEDATA
{
public int time;
public ushort addr;
public byte data;
public byte reserved;
}
public class QUEUE
{
public int rdptr;
public int wrptr;
public QUEUEDATA[] data = new QUEUEDATA[8192];
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cb5a8e579d35b9a4ca7966225235265a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e6179c4bc7e6fa744901b21b63e98aba
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,472 @@
using System;
namespace VirtualNes.Core
{
public class APU_FDS : APU_INTERFACE
{
FDSSOUND fds = new FDSSOUND();
FDSSOUND fds_sync = new FDSSOUND();
int[] output_buf = new int[8];
int sampling_rate;
public APU_FDS()
{
fds.ZeroMemory();
fds_sync.ZeroMemory();
Array.Clear(output_buf, 0, output_buf.Length);
sampling_rate = 22050;
}
public override void Reset(float fClock, int nRate)
{
fds.ZeroMemory();
fds_sync.ZeroMemory();
sampling_rate = 22050;
}
public override void Setup(float fClock, int nRate)
{
sampling_rate = nRate;
}
int[] tbl_writesub = { 30, 20, 15, 12 };
private void WriteSub(ushort addr, byte data, FDSSOUND ch, double rate)
{
if (addr < 0x4040 || addr > 0x40BF)
return;
ch.reg[addr - 0x4040] = data;
if (addr >= 0x4040 && addr <= 0x407F)
{
if (ch.wave_setup != 0)
{
ch.main_wavetable[addr - 0x4040] = 0x20 - (data & 0x3F);
}
}
else
{
switch (addr)
{
case 0x4080: // Volume Envelope
ch.volenv_mode = (byte)(data >> 6);
if ((data & 0x80) != 0)
{
ch.volenv_gain = (byte)(data & 0x3F);
// 即時反映
if (ch.main_addr == 0)
{
ch.now_volume = (ch.volenv_gain < 0x21) ? ch.volenv_gain : 0x20;
}
}
// エンベロープ1段階の演算
ch.volenv_decay = (byte)(data & 0x3F);
ch.volenv_phaseacc = (double)ch.envelope_speed * (double)(ch.volenv_decay + 1) * rate / (232.0 * 960.0);
break;
case 0x4082: // Main Frequency(Low)
ch.main_frequency = (ch.main_frequency & ~0x00FF) | data;
break;
case 0x4083: // Main Frequency(High)
ch.main_enable = (byte)((~data) & (1 << 7));
ch.envelope_enable = (byte)((~data) & (1 << 6));
if (ch.main_enable == 0)
{
ch.main_addr = 0;
ch.now_volume = (ch.volenv_gain < 0x21) ? ch.volenv_gain : 0x20;
}
// ch.main_frequency = (ch.main_frequency&0x00FF)|(((INT)data&0x3F)<<8);
ch.main_frequency = (ch.main_frequency & 0x00FF) | ((data & 0x0F) << 8);
break;
case 0x4084: // Sweep Envelope
ch.swpenv_mode = (byte)(data >> 6);
if ((data & 0x80) != 0)
{
ch.swpenv_gain = (byte)(data & 0x3F);
}
// エンベロープ1段階の演算
ch.swpenv_decay = (byte)(data & 0x3F);
ch.swpenv_phaseacc = (double)ch.envelope_speed * (double)(ch.swpenv_decay + 1) * rate / (232.0 * 960.0);
break;
case 0x4085: // Sweep Bias
if ((data & 0x40) != 0) ch.sweep_bias = (data & 0x3f) - 0x40;
else ch.sweep_bias = data & 0x3f;
ch.lfo_addr = 0;
break;
case 0x4086: // Effector(LFO) Frequency(Low)
ch.lfo_frequency = (ch.lfo_frequency & (~0x00FF)) | data;
break;
case 0x4087: // Effector(LFO) Frequency(High)
ch.lfo_enable = (byte)((~data & 0x80));
ch.lfo_frequency = (ch.lfo_frequency & 0x00FF) | ((data & 0x0F) << 8);
break;
case 0x4088: // Effector(LFO) wavetable
if (ch.lfo_enable == 0)
{
// FIFO?
for (byte i = 0; i < 31; i++)
{
ch.lfo_wavetable[i * 2 + 0] = ch.lfo_wavetable[(i + 1) * 2 + 0];
ch.lfo_wavetable[i * 2 + 1] = ch.lfo_wavetable[(i + 1) * 2 + 1];
}
ch.lfo_wavetable[31 * 2 + 0] = (byte)(data & 0x07);
ch.lfo_wavetable[31 * 2 + 1] = (byte)(data & 0x07);
}
break;
case 0x4089: // Sound control
{
ch.master_volume = tbl_writesub[data & 3];
ch.wave_setup = (byte)(data & 0x80);
}
break;
case 0x408A: // Sound control 2
ch.envelope_speed = data;
break;
default:
break;
}
}
}
public override void Write(ushort addr, byte data)
{
WriteSub(addr, data, fds, sampling_rate);
}
public override byte Read(ushort addr)
{
byte data = (byte)(addr >> 8);
if (addr >= 0x4040 && addr <= 0x407F)
{
data = (byte)(fds.main_wavetable[addr & 0x3F] | 0x40);
}
else
if (addr == 0x4090)
{
data = (byte)((fds.volenv_gain & 0x3F) | 0x40);
}
else
if (addr == 0x4092)
{
data = (byte)((fds.swpenv_gain & 0x3F) | 0x40);
}
return data;
}
int[] tbl_process = { 0, 1, 2, 4, 0, -4, -2, -1 };
public override int Process(int channel)
{
// Envelope unit
if (fds.envelope_enable != 0 && fds.envelope_speed != 0)
{
// Volume envelope
if (fds.volenv_mode < 2)
{
double decay = ((double)fds.envelope_speed * (double)(fds.volenv_decay + 1) * (double)sampling_rate) / (232.0 * 960.0);
fds.volenv_phaseacc -= 1.0;
while (fds.volenv_phaseacc < 0.0)
{
fds.volenv_phaseacc += decay;
if (fds.volenv_mode == 0)
{
// 減少モード
if (fds.volenv_gain != 0)
fds.volenv_gain--;
}
else
if (fds.volenv_mode == 1)
{
if (fds.volenv_gain < 0x20)
fds.volenv_gain++;
}
}
}
// Sweep envelope
if (fds.swpenv_mode < 2)
{
double decay = ((double)fds.envelope_speed * (double)(fds.swpenv_decay + 1) * (double)sampling_rate) / (232.0 * 960.0);
fds.swpenv_phaseacc -= 1.0;
while (fds.swpenv_phaseacc < 0.0)
{
fds.swpenv_phaseacc += decay;
if (fds.swpenv_mode == 0)
{
// 減少モード
if (fds.swpenv_gain != 0)
fds.swpenv_gain--;
}
else
if (fds.swpenv_mode == 1)
{
if (fds.swpenv_gain < 0x20)
fds.swpenv_gain++;
}
}
}
}
// Effector(LFO) unit
int sub_freq = 0;
// if( fds.lfo_enable && fds.envelope_speed && fds.lfo_frequency ) {
if (fds.lfo_enable != 0)
{
if (fds.lfo_frequency != 0)
{
fds.lfo_phaseacc -= (1789772.5 * (double)fds.lfo_frequency) / 65536.0;
while (fds.lfo_phaseacc < 0.0)
{
fds.lfo_phaseacc += (double)sampling_rate;
if (fds.lfo_wavetable[fds.lfo_addr] == 4)
fds.sweep_bias = 0;
else
fds.sweep_bias += tbl_process[fds.lfo_wavetable[fds.lfo_addr]];
fds.lfo_addr = (fds.lfo_addr + 1) & 63;
}
}
if (fds.sweep_bias > 63)
fds.sweep_bias -= 128;
else if (fds.sweep_bias < -64)
fds.sweep_bias += 128;
int sub_multi = fds.sweep_bias * fds.swpenv_gain;
if ((sub_multi & 0x0F) != 0)
{
// 16で割り切れない場合
sub_multi = (sub_multi / 16);
if (fds.sweep_bias >= 0)
sub_multi += 2; // 正の場合
else
sub_multi -= 1; // 負の場合
}
else
{
// 16で割り切れる場合
sub_multi = (sub_multi / 16);
}
// 193を超えると-258する(-64へラップ)
if (sub_multi > 193)
sub_multi -= 258;
// -64を下回ると+256する(192へラップ)
if (sub_multi < -64)
sub_multi += 256;
sub_freq = (fds.main_frequency) * sub_multi / 64;
}
// Main unit
int output = 0;
if (fds.main_enable != 0 && fds.main_frequency != 0 && fds.wave_setup == 0)
{
int freq;
int main_addr_old = fds.main_addr;
freq = (int)((fds.main_frequency + sub_freq) * 1789772.5 / 65536.0);
fds.main_addr = (fds.main_addr + freq + 64 * sampling_rate) % (64 * sampling_rate);
// 1周期を超えたらボリューム更新
if (main_addr_old > fds.main_addr)
fds.now_volume = (fds.volenv_gain < 0x21) ? fds.volenv_gain : 0x20;
output = fds.main_wavetable[(fds.main_addr / sampling_rate) & 0x3f] * 8 * fds.now_volume * fds.master_volume / 30;
if (fds.now_volume != 0)
fds.now_freq = freq * 4;
else
fds.now_freq = 0;
}
else
{
fds.now_freq = 0;
output = 0;
}
// LPF
output = (output_buf[0] * 2 + output) / 3;
output_buf[0] = output;
fds.output = output;
return fds.output;
}
internal void SyncWrite(ushort addr, byte data)
{
WriteSub(addr, data, fds_sync, 1789772.5d);
}
internal byte SyncRead(ushort addr)
{
byte data = (byte)(addr >> 8);
if (addr >= 0x4040 && addr <= 0x407F)
{
data = (byte)(fds_sync.main_wavetable[addr & 0x3F] | 0x40);
}
else
if (addr == 0x4090)
{
data = (byte)((fds_sync.volenv_gain & 0x3F) | 0x40);
}
else
if (addr == 0x4092)
{
data = (byte)((fds_sync.swpenv_gain & 0x3F) | 0x40);
}
return data;
}
public override bool Sync(int cycles)
{
// Envelope unit
if (fds_sync.envelope_enable != 0 && fds_sync.envelope_speed != 0)
{
// Volume envelope
double decay;
if (fds_sync.volenv_mode < 2)
{
decay = ((double)fds_sync.envelope_speed * (double)(fds_sync.volenv_decay + 1) * 1789772.5) / (232.0 * 960.0);
fds_sync.volenv_phaseacc -= (double)cycles;
while (fds_sync.volenv_phaseacc < 0.0)
{
fds_sync.volenv_phaseacc += decay;
if (fds_sync.volenv_mode == 0)
{
// 減少モード
if (fds_sync.volenv_gain != 0)
fds_sync.volenv_gain--;
}
else
if (fds_sync.volenv_mode == 1)
{
// 増加モード
if (fds_sync.volenv_gain < 0x20)
fds_sync.volenv_gain++;
}
}
}
// Sweep envelope
if (fds_sync.swpenv_mode < 2)
{
decay = ((double)fds_sync.envelope_speed * (double)(fds_sync.swpenv_decay + 1) * 1789772.5) / (232.0 * 960.0);
fds_sync.swpenv_phaseacc -= (double)cycles;
while (fds_sync.swpenv_phaseacc < 0.0)
{
fds_sync.swpenv_phaseacc += decay;
if (fds_sync.swpenv_mode == 0)
{
// 減少モード
if (fds_sync.swpenv_gain != 0)
fds_sync.swpenv_gain--;
}
else
if (fds_sync.swpenv_mode == 1)
{
// 増加モード
if (fds_sync.swpenv_gain < 0x20)
fds_sync.swpenv_gain++;
}
}
}
}
return false;
}
public override int GetFreq(int channel)
{
return fds.now_freq;
}
private class FDSSOUND
{
public byte[] reg = new byte[0x80];
public byte volenv_mode; // Volume Envelope
public byte volenv_gain;
public byte volenv_decay;
public double volenv_phaseacc;
public byte swpenv_mode; // Sweep Envelope
public byte swpenv_gain;
public byte swpenv_decay;
public double swpenv_phaseacc;
// For envelope unit
public byte envelope_enable; // $4083 bit6
public byte envelope_speed; // $408A
// For $4089
public byte wave_setup; // bit7
public int master_volume; // bit1-0
// For Main unit
public int[] main_wavetable = new int[64];
public byte main_enable;
public int main_frequency;
public int main_addr;
// For Effector(LFO) unit
public byte[] lfo_wavetable = new byte[64];
public byte lfo_enable; // 0:Enable 1:Wavetable setup
public int lfo_frequency;
public int lfo_addr;
public double lfo_phaseacc;
// For Sweep unit
public int sweep_bias;
// Misc
public int now_volume;
public int now_freq;
public int output;
public void ZeroMemory()
{
Array.Clear(reg, 0, reg.Length);
volenv_mode = 0;
volenv_gain = 0;
volenv_decay = 0;
volenv_phaseacc = 0.0;
swpenv_mode = 0;
swpenv_gain = 0;
swpenv_decay = 0;
swpenv_phaseacc = 0.0;
envelope_enable = 0;
envelope_speed = 0;
wave_setup = 0;
master_volume = 0;
Array.Clear(main_wavetable, 0, main_wavetable.Length);
main_enable = 0;
main_frequency = 0;
main_addr = 0;
Array.Clear(lfo_wavetable, 0, lfo_wavetable.Length);
lfo_enable = 0;
lfo_frequency = 0;
lfo_addr = 0;
lfo_phaseacc = 0.0;
sweep_bias = 0;
now_volume = 0;
now_freq = 0;
output = 0;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5e16912525198924a860e53ab4ef0c81
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,28 @@
using System;
namespace VirtualNes.Core
{
public class APU_FME7 : APU_INTERFACE
{
public override void Reset(float fClock, int nRate)
{
//todo : 实现
}
public override void Setup(float fClock, int nRate)
{
//todo : 实现
}
public override void Write(ushort addr, byte data)
{
//todo : 实现
}
public override int Process(int channel)
{
//todo : 实现
return 0;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 03e0258857a7134438a497aec27ea607
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
namespace VirtualNes.Core
{
public abstract class APU_INTERFACE
{
public const float APU_CLOCK = 1789772.5f;
public virtual void Dispose() { }
public abstract void Reset(float fClock, int nRate);
public abstract void Setup(float fClock, int nRate);
public abstract void Write(ushort addr, byte data);
public abstract int Process(int channel);
public virtual byte Read(ushort addr)
{
return (byte)(addr >> 8);
}
public virtual void WriteSync(ushort addr, byte data) { }
public virtual byte ReadSync(ushort addr) { return 0; }
public virtual void VSync() { }
public virtual bool Sync(int cycles) { return false; }
public virtual int GetFreq(int channel) { return 0; }
public virtual int GetStateSize() { return 0; }
public virtual void SaveState(byte[] p) { }
public virtual void LoadState(byte[] p) { }
public static int INT2FIX(int x)
{
return x << 16;
}
public static int FIX2INT(int x)
{
return x >> 16;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cc44be42b66d6ac4aade437e81960274
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d5f443ad7d5ef1d4394c7fe540f2e3e4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,415 @@
using Codice.CM.Client.Differences;
using System;
namespace VirtualNes.Core
{
public class APU_MMC5 : APU_INTERFACE
{
public const int RECTANGLE_VOL_SHIFT = 8;
public const int DAOUT_VOL_SHIFT = 6;
SYNCRECTANGLE sch0 = new SYNCRECTANGLE();
SYNCRECTANGLE sch1 = new SYNCRECTANGLE();
RECTANGLE ch0 = new RECTANGLE();
RECTANGLE ch1 = new RECTANGLE();
byte reg5010;
byte reg5011;
byte reg5015;
byte sync_reg5015;
int FrameCycle;
float cpu_clock;
int cycle_rate;
// Tables
static int[] vbl_length = new int[32];
static int[] duty_lut = new int[4];
static int[] decay_lut = new int[16];
static int[] vbl_lut = new int[32];
public APU_MMC5()
{
// 仮設定
Reset(APU_INTERFACE.APU_CLOCK, 22050);
}
public override void Reset(float fClock, int nRate)
{
sch0.ZeroMemory();
sch1.ZeroMemory();
reg5010 = reg5011 = reg5015 = 0;
sync_reg5015 = 0;
FrameCycle = 0;
Setup(fClock, nRate);
for (ushort addr = 0x5000; addr <= 0x5015; addr++)
{
Write(addr, 0);
}
}
public override void Setup(float fClock, int nRate)
{
cpu_clock = fClock;
cycle_rate = (int)(fClock * 65536.0f / nRate);
// Create Tables
int i;
int samples = (int)(nRate / 60.0f);
for (i = 0; i < 16; i++)
decay_lut[i] = (i + 1) * samples * 5;
for (i = 0; i < 32; i++)
vbl_lut[i] = vbl_length[i] * samples * 5;
}
public override void Write(ushort addr, byte data)
{
switch (addr)
{
// MMC5 CH0 rectangle
case 0x5000:
ch0.reg[0] = data;
ch0.volume = (byte)(data & 0x0F);
ch0.holdnote = (byte)(data & 0x20);
ch0.fixed_envelope = (byte)(data & 0x10);
ch0.env_decay = decay_lut[data & 0x0F];
ch0.duty_flip = duty_lut[data >> 6];
break;
case 0x5001:
ch0.reg[1] = data;
break;
case 0x5002:
ch0.reg[2] = data;
ch0.freq = INT2FIX(((ch0.reg[3] & 0x07) << 8) + data + 1);
break;
case 0x5003:
ch0.reg[3] = data;
ch0.vbl_length = vbl_lut[data >> 3];
ch0.env_vol = 0;
ch0.freq = INT2FIX(((data & 0x07) << 8) + ch0.reg[2] + 1);
if ((reg5015 & 0x01) != 0)
ch0.enable = 0xFF;
break;
// MMC5 CH1 rectangle
case 0x5004:
ch1.reg[0] = data;
ch1.volume = (byte)(data & 0x0F);
ch1.holdnote = (byte)(data & 0x20);
ch1.fixed_envelope = (byte)(data & 0x10);
ch1.env_decay = decay_lut[data & 0x0F];
ch1.duty_flip = duty_lut[data >> 6];
break;
case 0x5005:
ch1.reg[1] = data;
break;
case 0x5006:
ch1.reg[2] = data;
ch1.freq = INT2FIX(((ch1.reg[3] & 0x07) << 8) + data + 1);
break;
case 0x5007:
ch1.reg[3] = data;
ch1.vbl_length = vbl_lut[data >> 3];
ch1.env_vol = 0;
ch1.freq = INT2FIX(((data & 0x07) << 8) + ch1.reg[2] + 1);
if ((reg5015 & 0x02) != 0)
ch1.enable = 0xFF;
break;
case 0x5010:
reg5010 = data;
break;
case 0x5011:
reg5011 = data;
break;
case 0x5012:
case 0x5013:
case 0x5014:
break;
case 0x5015:
reg5015 = data;
if ((reg5015 & 0x01) != 0)
{
ch0.enable = 0xFF;
}
else
{
ch0.enable = 0;
ch0.vbl_length = 0;
}
if ((reg5015 & 0x02) != 0)
{
ch1.enable = 0xFF;
}
else
{
ch1.enable = 0;
ch1.vbl_length = 0;
}
break;
}
}
internal void SyncWrite(ushort addr, byte data)
{
switch (addr)
{
// MMC5 CH0 rectangle
case 0x5000:
sch0.reg[0] = data;
sch0.holdnote = (byte)(data & 0x20);
break;
case 0x5001:
case 0x5002:
sch0.reg[addr & 3] = data;
break;
case 0x5003:
sch0.reg[3] = data;
sch0.vbl_length = vbl_length[data >> 3];
if ((sync_reg5015 & 0x01) != 0)
sch0.enable = 0xFF;
break;
// MMC5 CH1 rectangle
case 0x5004:
sch1.reg[0] = data;
sch1.holdnote = (byte)(data & 0x20);
break;
case 0x5005:
case 0x5006:
sch1.reg[addr & 3] = data;
break;
case 0x5007:
sch1.reg[3] = data;
sch1.vbl_length = vbl_length[data >> 3];
if ((sync_reg5015 & 0x02) != 0)
sch1.enable = 0xFF;
break;
case 0x5010:
case 0x5011:
case 0x5012:
case 0x5013:
case 0x5014:
break;
case 0x5015:
sync_reg5015 = data;
if ((sync_reg5015 & 0x01) != 0)
{
sch0.enable = 0xFF;
}
else
{
sch0.enable = 0;
sch0.vbl_length = 0;
}
if ((sync_reg5015 & 0x02) != 0)
{
sch1.enable = 0xFF;
}
else
{
sch1.enable = 0;
sch1.vbl_length = 0;
}
break;
}
}
internal byte SyncRead(ushort addr)
{
byte data = 0;
if (addr == 0x5015)
{
if ((sch0.enable != 0) && sch0.vbl_length > 0) data |= (1 << 0);
if ((sch1.enable != 0) && sch1.vbl_length > 0) data |= (1 << 1);
}
return data;
}
public override bool Sync(int cycles)
{
FrameCycle += cycles;
if (FrameCycle >= 7457 * 5 / 2)
{
FrameCycle -= 7457 * 5 / 2;
if (sch0.enable != 0 && sch0.holdnote == 0)
{
if ((sch0.vbl_length) != 0)
{
sch0.vbl_length--;
}
}
if (sch1.enable != 0 && sch1.holdnote == 0)
{
if ((sch1.vbl_length) != 0)
{
sch1.vbl_length--;
}
}
}
return false;
}
public override int Process(int channel)
{
switch (channel)
{
case 0:
return RectangleRender(ch0);
case 1:
return RectangleRender(ch1);
case 2:
return reg5011 << DAOUT_VOL_SHIFT;
}
return 0;
}
public override int GetFreq(int channel)
{
if (channel == 0 || channel == 1)
{
RECTANGLE ch = null;
if (channel == 0) ch = ch0;
else ch = ch1;
if (ch.enable == 0 || ch.vbl_length <= 0)
return 0;
if (ch.freq < INT2FIX(8))
return 0;
if (ch.fixed_envelope != 0)
{
if (ch.volume == 0)
return 0;
}
else
{
if ((0x0F - ch.env_vol) == 0)
return 0;
}
return (int)(256.0f * cpu_clock / (FIX2INT(ch.freq) * 16.0f));
}
return 0;
}
private int RectangleRender(RECTANGLE ch)
{
if (ch.enable == 0 || ch.vbl_length <= 0)
return 0;
// vbl length counter
if (ch.holdnote == 0)
ch.vbl_length -= 5;
// envelope unit
ch.env_phase -= 5 * 4;
while (ch.env_phase < 0)
{
ch.env_phase += ch.env_decay;
if ((ch.holdnote) != 0)
ch.env_vol = (byte)((ch.env_vol + 1) & 0x0F);
else if (ch.env_vol < 0x0F)
ch.env_vol++;
}
if (ch.freq < INT2FIX(8))
return 0;
int volume;
if ((ch.fixed_envelope) != 0)
volume = ch.volume;
else
volume = (0x0F - ch.env_vol);
int output = volume << RECTANGLE_VOL_SHIFT;
ch.phaseacc -= cycle_rate;
if (ch.phaseacc >= 0)
{
if (ch.adder < ch.duty_flip)
ch.output_vol = output;
else
ch.output_vol = -output;
return ch.output_vol;
}
if (ch.freq > cycle_rate)
{
ch.phaseacc += ch.freq;
ch.adder = (ch.adder + 1) & 0x0F;
if (ch.adder < ch.duty_flip)
ch.output_vol = output;
else
ch.output_vol = -output;
}
else
{
// 加重平均
int num_times, total;
num_times = total = 0;
while (ch.phaseacc < 0)
{
ch.phaseacc += ch.freq;
ch.adder = (ch.adder + 1) & 0x0F;
if (ch.adder < ch.duty_flip)
total += output;
else
total -= output;
num_times++;
}
ch.output_vol = total / num_times;
}
return ch.output_vol;
}
public class SYNCRECTANGLE
{
// For sync
public byte[] reg = new byte[4];
public byte enable;
public byte holdnote;
public byte[] dummy = new byte[2];
public int vbl_length;
public void ZeroMemory()
{
Array.Clear(reg, 0, reg.Length);
enable = 0;
holdnote = 0;
Array.Clear(dummy, 0, dummy.Length);
vbl_length = 0;
}
}
public class RECTANGLE
{
public byte[] reg = new byte[4];
public byte enable;
public int vbl_length;
public int phaseacc;
public int freq;
public int output_vol;
public byte fixed_envelope;
public byte holdnote;
public byte volume;
public byte env_vol;
public int env_phase;
public int env_decay;
public int adder;
public int duty_flip;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15b983a12234c3c47baefb9fa2751351
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,245 @@
using RECTANGLE = VirtualNes.Core.APU_VRC6.RECTANGLE;
using SAWTOOTH = VirtualNes.Core.APU_VRC6.SAWTOOTH;
namespace VirtualNes.Core
{
public class APU_N106 : APU_INTERFACE
{
RECTANGLE ch0 = new RECTANGLE();
RECTANGLE ch1 = new RECTANGLE();
SAWTOOTH ch2 = new SAWTOOTH();
float cpu_clock;
int cycle_rate;
public APU_N106()
{
Reset(APU_CLOCK, 22050);
}
public override void Reset(float fClock, int nRate)
{
ch0.ZeroMemory();
ch1.ZeroMemory();
ch2.ZeroMemory();
Setup(fClock, nRate);
}
public override void Setup(float fClock, int nRate)
{
cpu_clock = fClock;
cycle_rate = (int)(fClock * 65536.0f / nRate);
}
public override void Write(ushort addr, byte data)
{
switch (addr)
{
// VRC6 CH0 rectangle
case 0x9000:
ch0.reg[0] = data;
ch0.gate = (byte)(data & 0x80);
ch0.volume = (byte)(data & 0x0F);
ch0.duty_pos = (byte)((data >> 4) & 0x07);
break;
case 0x9001:
ch0.reg[1] = data;
ch0.freq = INT2FIX((((ch0.reg[2] & 0x0F) << 8) | data) + 1);
break;
case 0x9002:
ch0.reg[2] = data;
ch0.enable = (byte)(data & 0x80);
ch0.freq = INT2FIX((((data & 0x0F) << 8) | ch0.reg[1]) + 1);
break;
// VRC6 CH1 rectangle
case 0xA000:
ch1.reg[0] = data;
ch1.gate = (byte)(data & 0x80);
ch1.volume = (byte)(data & 0x0F);
ch1.duty_pos = (byte)((data >> 4) & 0x07);
break;
case 0xA001:
ch1.reg[1] = data;
ch1.freq = INT2FIX((((ch1.reg[2] & 0x0F) << 8) | data) + 1);
break;
case 0xA002:
ch1.reg[2] = data;
ch1.enable = (byte)(data & 0x80);
ch1.freq = INT2FIX((((data & 0x0F) << 8) | ch1.reg[1]) + 1);
break;
// VRC6 CH2 sawtooth
case 0xB000:
ch2.reg[1] = data;
ch2.phaseaccum = (byte)(data & 0x3F);
break;
case 0xB001:
ch2.reg[1] = data;
ch2.freq = INT2FIX((((ch2.reg[2] & 0x0F) << 8) | data) + 1);
break;
case 0xB002:
ch2.reg[2] = data;
ch2.enable = (byte)(data & 0x80);
ch2.freq = INT2FIX((((data & 0x0F) << 8) | ch2.reg[1]) + 1);
// ch2.adder = 0; // クリアするとノイズの原因になる
// ch2.accum = 0; // クリアするとノイズの原因になる
break;
}
}
public override int Process(int channel)
{
switch (channel)
{
case 0:
return RectangleRender(ch0);
case 1:
return RectangleRender(ch1);
case 2:
return SawtoothRender(ch2);
}
return 0;
}
public override int GetFreq(int channel)
{
if (channel == 0 || channel == 1)
{
RECTANGLE ch;
if (channel == 0) ch = ch0;
else ch = ch1;
if (ch.enable == 0 || ch.gate != 0 || ch.volume == 0)
return 0;
if (ch.freq < INT2FIX(8))
return 0;
return (int)((256.0f * cpu_clock / (FIX2INT(ch.freq) * 16.0f)));
}
if (channel == 2)
{
SAWTOOTH ch = ch2;
if (ch.enable == 0 || ch.phaseaccum == 0)
return 0;
if (ch.freq < INT2FIX(8))
return 0;
return (int)(256.0f * cpu_clock / (FIX2INT(ch.freq) * 14.0f));
}
return 0;
}
int RectangleRender(RECTANGLE ch)
{
// Enable?
if (ch.enable == 0)
{
ch.output_vol = 0;
ch.adder = 0;
return ch.output_vol;
}
// Digitized output
if (ch.gate != 0)
{
ch.output_vol = ch.volume << APU_VRC6.RECTANGLE_VOL_SHIFT;
return ch.output_vol;
}
// 一定以上の周波数は処理しない(無駄)
if (ch.freq < INT2FIX(8))
{
ch.output_vol = 0;
return ch.output_vol;
}
ch.phaseacc -= cycle_rate;
if (ch.phaseacc >= 0)
return ch.output_vol;
int output = ch.volume << APU_VRC6.RECTANGLE_VOL_SHIFT;
if (ch.freq > cycle_rate)
{
// add 1 step
ch.phaseacc += ch.freq;
ch.adder = (byte)((ch.adder + 1) & 0x0F);
if (ch.adder <= ch.duty_pos)
ch.output_vol = output;
else
ch.output_vol = -output;
}
else
{
// average calculate
int num_times, total;
num_times = total = 0;
while (ch.phaseacc < 0)
{
ch.phaseacc += ch.freq;
ch.adder = (byte)((ch.adder + 1) & 0x0F);
if (ch.adder <= ch.duty_pos)
total += output;
else
total += -output;
num_times++;
}
ch.output_vol = total / num_times;
}
return ch.output_vol;
}
int SawtoothRender(SAWTOOTH ch)
{
// Digitized output
if (ch.enable == 0)
{
ch.output_vol = 0;
return ch.output_vol;
}
// 一定以上の周波数は処理しない(無駄)
if (ch.freq < INT2FIX(9))
{
return ch.output_vol;
}
ch.phaseacc -= cycle_rate / 2;
if (ch.phaseacc >= 0)
return ch.output_vol;
if (ch.freq > cycle_rate / 2)
{
// add 1 step
ch.phaseacc += ch.freq;
if (++ch.adder >= 7)
{
ch.adder = 0;
ch.accum = 0;
}
ch.accum += ch.phaseaccum;
ch.output_vol = ch.accum << APU_VRC6.SAWTOOTH_VOL_SHIFT;
}
else
{
// average calculate
int num_times, total;
num_times = total = 0;
while (ch.phaseacc < 0)
{
ch.phaseacc += ch.freq;
if (++ch.adder >= 7)
{
ch.adder = 0;
ch.accum = 0;
}
ch.accum += ch.phaseaccum;
total += ch.accum << APU_VRC6.SAWTOOTH_VOL_SHIFT;
num_times++;
}
ch.output_vol = (total / num_times);
}
return ch.output_vol;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a47ed257e942d4478215338d8fe4c35
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,310 @@
using System;
namespace VirtualNes.Core
{
public class APU_VRC6 : APU_INTERFACE
{
public const int RECTANGLE_VOL_SHIFT = 8;
public const int SAWTOOTH_VOL_SHIFT = 6;
private RECTANGLE ch0 = new RECTANGLE();
private RECTANGLE ch1 = new RECTANGLE();
private SAWTOOTH ch2 = new SAWTOOTH();
private int cycle_rate;
private float cpu_clock;
public APU_VRC6()
{
Reset(APU_CLOCK, 22050);
}
public override void Reset(float fClock, int nRate)
{
ch0.ZeroMemory();
ch1.ZeroMemory();
ch2.ZeroMemory();
Setup(fClock, nRate);
}
public override void Setup(float fClock, int nRate)
{
cpu_clock = fClock;
cycle_rate = (int)(fClock * 65536.0f / nRate);
}
public override void Write(ushort addr, byte data)
{
switch (addr)
{
// VRC6 CH0 rectangle
case 0x9000:
ch0.reg[0] = data;
ch0.gate = (byte)(data & 0x80);
ch0.volume = (byte)(data & 0x0F);
ch0.duty_pos = (byte)((data >> 4) & 0x07);
break;
case 0x9001:
ch0.reg[1] = data;
ch0.freq = INT2FIX((((ch0.reg[2] & 0x0F) << 8) | data) + 1);
break;
case 0x9002:
ch0.reg[2] = data;
ch0.enable = (byte)(data & 0x80);
ch0.freq = INT2FIX((((data & 0x0F) << 8) | ch0.reg[1]) + 1);
break;
// VRC6 CH1 rectangle
case 0xA000:
ch1.reg[0] = data;
ch1.gate = (byte)(data & 0x80);
ch1.volume = (byte)(data & 0x0F);
ch1.duty_pos = (byte)((data >> 4) & 0x07);
break;
case 0xA001:
ch1.reg[1] = data;
ch1.freq = INT2FIX((((ch1.reg[2] & 0x0F) << 8) | data) + 1);
break;
case 0xA002:
ch1.reg[2] = data;
ch1.enable = (byte)(data & 0x80);
ch1.freq = INT2FIX((((data & 0x0F) << 8) | ch1.reg[1]) + 1);
break;
// VRC6 CH2 sawtooth
case 0xB000:
ch2.reg[1] = data;
ch2.phaseaccum = (byte)(data & 0x3F);
break;
case 0xB001:
ch2.reg[1] = data;
ch2.freq = INT2FIX((((ch2.reg[2] & 0x0F) << 8) | data) + 1);
break;
case 0xB002:
ch2.reg[2] = data;
ch2.enable = (byte)(data & 0x80);
ch2.freq = INT2FIX((((data & 0x0F) << 8) | ch2.reg[1]) + 1);
// ch2.adder = 0; // 僋儕傾偡傞偲僲僀僘偺尨場偵側傞
// ch2.accum = 0; // 僋儕傾偡傞偲僲僀僘偺尨場偵側傞
break;
}
}
public override int Process(int channel)
{
switch (channel)
{
case 0:
return RectangleRender(ch0);
case 1:
return RectangleRender(ch1);
case 2:
return SawtoothRender(ch2);
}
return 0;
}
public override int GetFreq(int channel)
{
if (channel == 0 || channel == 1)
{
RECTANGLE ch = null;
if (channel == 0) ch = ch0;
else ch = ch1;
if (ch.enable == 0 || ch.gate != 0 || ch.volume == 0)
return 0;
if (ch.freq < INT2FIX(8))
return 0;
return (int)(256.0f * cpu_clock / (FIX2INT(ch.freq) * 16.0f));
}
if (channel == 2)
{
SAWTOOTH ch = ch2;
if (ch.enable == 0 || ch.phaseaccum == 0)
return 0;
if (ch.freq < INT2FIX(8))
return 0;
return (int)(256.0f * cpu_clock / (FIX2INT(ch.freq) * 14.0f));
}
return 0;
}
private int RectangleRender(RECTANGLE ch)
{
// Enable?
if (ch.enable == 0)
{
ch.output_vol = 0;
ch.adder = 0;
return ch.output_vol;
}
// Digitized output
if (ch.gate != 0)
{
ch.output_vol = ch.volume << RECTANGLE_VOL_SHIFT;
return ch.output_vol;
}
// 堦掕埲忋偺廃攇悢偼張棟偟側偄(柍懯)
if (ch.freq < INT2FIX(8))
{
ch.output_vol = 0;
return ch.output_vol;
}
ch.phaseacc -= cycle_rate;
if (ch.phaseacc >= 0)
return ch.output_vol;
int output = ch.volume << RECTANGLE_VOL_SHIFT;
if (ch.freq > cycle_rate)
{
// add 1 step
ch.phaseacc += ch.freq;
ch.adder = (byte)((ch.adder + 1) & 0x0F);
if (ch.adder <= ch.duty_pos)
ch.output_vol = output;
else
ch.output_vol = -output;
}
else
{
// average calculate
int num_times, total;
num_times = total = 0;
while (ch.phaseacc < 0)
{
ch.phaseacc += ch.freq;
ch.adder = (byte)((ch.adder + 1) & 0x0F);
if (ch.adder <= ch.duty_pos)
total += output;
else
total += -output;
num_times++;
}
ch.output_vol = total / num_times;
}
return ch.output_vol;
}
private int SawtoothRender(SAWTOOTH ch)
{
// Digitized output
if (ch.enable == 0)
{
ch.output_vol = 0;
return ch.output_vol;
}
// 堦掕埲忋偺廃攇悢偼張棟偟側偄(柍懯)
if (ch.freq < INT2FIX(9))
{
return ch.output_vol;
}
ch.phaseacc -= cycle_rate / 2;
if (ch.phaseacc >= 0)
return ch.output_vol;
if (ch.freq > cycle_rate / 2)
{
// add 1 step
ch.phaseacc += ch.freq;
if (++ch.adder >= 7)
{
ch.adder = 0;
ch.accum = 0;
}
ch.accum += ch.phaseaccum;
ch.output_vol = ch.accum << SAWTOOTH_VOL_SHIFT;
}
else
{
// average calculate
int num_times, total;
num_times = total = 0;
while (ch.phaseacc < 0)
{
ch.phaseacc += ch.freq;
if (++ch.adder >= 7)
{
ch.adder = 0;
ch.accum = 0;
}
ch.accum += ch.phaseaccum;
total += ch.accum << SAWTOOTH_VOL_SHIFT;
num_times++;
}
ch.output_vol = (total / num_times);
}
return ch.output_vol;
}
public class RECTANGLE
{
public byte[] reg = new byte[3];
public byte enable;
public byte gate;
public byte volume;
public int phaseacc;
public int freq;
public int output_vol;
public byte adder;
public byte duty_pos;
public void ZeroMemory()
{
Array.Clear(reg, 0, reg.Length);
enable = default;
gate = default;
volume = default;
phaseacc = default;
freq = default;
output_vol = default;
adder = default;
duty_pos = default;
}
}
public class SAWTOOTH
{
public byte[] reg = new byte[3];
public byte enable;
public byte volume;
public int phaseacc;
public int freq;
public int output_vol;
public byte adder;
public byte accum;
public byte phaseaccum;
public void ZeroMemory()
{
Array.Clear(reg, 0, reg.Length);
enable = default;
volume = default;
phaseacc = default;
freq = default;
output_vol = default;
adder = default;
accum = default;
phaseaccum = default;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 190f3271accd30f4eb5b13590417d265
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,96 @@
using System;
using VirtualNes.Core.Emu2413;
namespace VirtualNes.Core
{
public class APU_VRC7 : APU_INTERFACE
{
OPLL VRC7_OPLL;
byte address;
public APU_VRC7()
{
Emu2413API.OPLL_init(3579545, 22050); // 仮のサンプリングレート
VRC7_OPLL = Emu2413API.OPLL_new();
if (VRC7_OPLL != null)
{
Emu2413API.OPLL_reset(VRC7_OPLL);
Emu2413API.OPLL_reset_patch(VRC7_OPLL, Emu2413API.OPLL_VRC7_TONE);
VRC7_OPLL.masterVolume = 128;
}
// 仮設定
Reset(APU_CLOCK, 22050);
}
public override void Dispose()
{
if (VRC7_OPLL != null)
{
Emu2413API.OPLL_delete(VRC7_OPLL);
VRC7_OPLL = null;
// OPLL_close(); // 無くても良い(中身無し)
}
}
public override void Reset(float fClock, int nRate)
{
if (VRC7_OPLL != null)
{
Emu2413API.OPLL_reset(VRC7_OPLL);
Emu2413API.OPLL_reset_patch(VRC7_OPLL, Emu2413API.OPLL_VRC7_TONE);
VRC7_OPLL.masterVolume = 128;
}
address = 0;
Setup(fClock, nRate);
}
public override void Setup(float fClock, int nRate)
{
Emu2413API.OPLL_setClock((UInt32)(fClock * 2.0f), (UInt32)nRate);
}
public override void Write(ushort addr, byte data)
{
if (VRC7_OPLL != null)
{
if (addr == 0x9010)
{
address = data;
}
else if (addr == 0x9030)
{
Emu2413API.OPLL_writeReg(VRC7_OPLL, address, data);
}
}
}
public override int Process(int channel)
{
if (VRC7_OPLL != null)
return Emu2413API.OPLL_calc(VRC7_OPLL);
return 0;
}
float[] blkmul = { 0.5f, 1.0f, 2.0f, 4.0f, 8.0f, 16.0f, 32.0f, 64.0f };
public override int GetFreq(int channel)
{
if (VRC7_OPLL != null && channel < 8)
{
int fno = ((VRC7_OPLL.reg[0x20 + channel] & 0x01) << 8) + VRC7_OPLL.reg[0x10 + channel];
int blk = (VRC7_OPLL.reg[0x20 + channel] >> 1) & 0x07;
if ((VRC7_OPLL.reg[0x20 + channel] & 0x10) != 0)
{
return (int)((256.0d * fno * blkmul[blk]) / ((1 << 18) / (3579545.0 / 72.0)));
}
}
return 0;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 180a87918f9d49e4fad978014f1d594f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 055e668755423bf4dabeb6cc007bce76
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,36 @@
namespace VirtualNes.Core
{
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 type;
public byte length;
public ushort address;
public uint data;
public string comment;
}
class GENIECODE
{
public ushort address;
public byte data;
public byte cmp;
};
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5494fe2d7f568c5498880bcb5625e21e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7b37fc906e6cec64eb2608762f7f80bf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,66 @@
using System;
namespace VirtualNes.Core
{
public class ArrayRef<T>
{
private T[] m_rawArray;
private int m_offset;
private int m_length;
public int Offset
{
get => m_offset;
set
{
var gap = value - m_offset;
m_length -= gap;
}
}
public ArrayRef() { }
public ArrayRef(T[] array, int offset, int length)
{
SetArray(array, offset, length);
}
public ArrayRef(T[] array) : this(array, 0, array.Length) { }
public ArrayRef(T[] array, int offset) : this(array, offset, array.Length - offset) { }
public void SetArray(T[] array, int offset, int length)
{
m_rawArray = array;
m_offset = offset;
m_length = length;
}
public void SetArray(T[] array, int offset)
{
m_rawArray = array;
m_offset = offset;
m_length = array.Length - offset;
}
public T this[int index]
{
get
{
return m_rawArray[m_offset + index];
}
set
{
m_rawArray[(m_offset + index)] = value;
}
}
public static implicit operator ArrayRef<T>(T[] array)
{
return new ArrayRef<T>(array);
}
public static implicit operator Span<T>(ArrayRef<T> array)
{
return new Span<T>(array.m_rawArray, array.Offset, array.m_length);
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fe59f85b299db6f498a7e87a5125df58
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,87 @@
using System;
namespace VirtualNes.Core
{
public static class CRC
{
const int CHAR_BIT = 8;
const uint CRCPOLY1 = 0x04C11DB7U;
const uint CRCPOLY2 = 0xEDB88320U;
static bool m_Init;
static bool m_InitRev;
static uint[] m_CrcTable = new uint[byte.MaxValue + 1];
static uint[] m_CrcTableRev = new uint[byte.MaxValue + 1];
public static ulong Crc(int size, Span<byte> c)
{
if (!m_Init)
{
MakeTable();
m_Init = true;
}
ulong r = 0xFFFFFFFFUL;
int step = 0;
while (--size >= 0)
{
r = (r << CHAR_BIT) ^ m_CrcTable[(byte)(r >> (32 - CHAR_BIT)) ^ c[step]];
step++;
}
return ~r & 0xFFFFFFFFUL;
}
public static uint CrcRev(int size, Span<byte> c)
{
if (!m_InitRev)
{
MakeTableRev();
m_InitRev = true;
}
uint r = 0xFFFFFFFFU;
int step = 0;
while (--size >= 0)
{
r = (r >> CHAR_BIT) ^ m_CrcTableRev[(byte)r ^ c[step]];
step++;
}
return r ^ 0xFFFFFFFFU;
}
static void MakeTable()
{
int i, j;
uint r;
for (i = 0; i <= byte.MaxValue; i++)
{
r = (uint)i << (32 - CHAR_BIT);
for (j = 0; j < CHAR_BIT; j++)
{
if ((r & 0x80000000UL) > 0) r = (r << 1) ^ CRCPOLY1;
else r <<= 1;
}
m_CrcTable[i] = r & 0xFFFFFFFFU;
}
}
static void MakeTableRev()
{
int i, j;
uint r;
for (i = 0; i <= byte.MaxValue; i++)
{
r = (uint)i;
for (j = 0; j < CHAR_BIT; j++)
{
if ((r & 1) > 0) r = (r >> 1) ^ CRCPOLY2;
else r >>= 1;
}
m_CrcTableRev[i] = r;
}
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e1939f721bc0cab42add18338dbff333
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d5b90f721bfc1ac4ea985c0f564d1c6e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f5ecddbb6b69204478d799a484d8c47c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,208 @@
using System;
namespace VirtualNes.Core.Emu2413
{
public static class Const
{
internal static sbyte[][] Create_Default_Inst()
{
unchecked
{
sbyte[][] res = new sbyte[Emu2413API.OPLL_TONE_NUM][]
{
new sbyte[]
{
(sbyte)0x00,(sbyte) 0x00, (sbyte)0x00, (sbyte)0x00,(sbyte) 0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x61,(sbyte) 0x61, (sbyte)0x1e, (sbyte)0x17,(sbyte) 0xf0, (sbyte)0x7f, (sbyte)0x07, (sbyte)0x17, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x13,(sbyte) 0x41, (sbyte)0x0f, (sbyte)0x0d,(sbyte) 0xce, (sbyte)0xd2, (sbyte)0x43, (sbyte)0x13, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x03,(sbyte) 0x01, (sbyte)0x99, (sbyte)0x04,(sbyte) 0xff, (sbyte)0xc3, (sbyte)0x03, (sbyte)0x73, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x21,(sbyte) 0x61, (sbyte)0x1b, (sbyte)0x07,(sbyte) 0xaf, (sbyte)0x63, (sbyte)0x40, (sbyte)0x28, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x22,(sbyte) 0x21, (sbyte)0x1e, (sbyte)0x06,(sbyte) 0xf0, (sbyte)0x76, (sbyte)0x08, (sbyte)0x28, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x31,(sbyte) 0x22, (sbyte)0x16, (sbyte)0x05,(sbyte) 0x90, (sbyte)0x71, (sbyte)0x00, (sbyte)0x18, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x21,(sbyte) 0x61, (sbyte)0x1d, (sbyte)0x07,(sbyte) 0x82, (sbyte)0x81, (sbyte)0x10, (sbyte)0x17, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x23,(sbyte) 0x21, (sbyte)0x2d, (sbyte)0x16,(sbyte) 0xc0, (sbyte)0x70, (sbyte)0x07, (sbyte)0x07, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x61,(sbyte) 0x21, (sbyte)0x1b, (sbyte)0x06,(sbyte) 0x64, (sbyte)0x65, (sbyte)0x18, (sbyte)0x18, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x61,(sbyte) 0x61, (sbyte)0x0c, (sbyte)0x18,(sbyte) 0x85, (sbyte)0xa0, (sbyte)0x79, (sbyte)0x07, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x23,(sbyte) 0x21, (sbyte)0x87, (sbyte)0x11,(sbyte) 0xf0, (sbyte)0xa4, (sbyte)0x00, (sbyte)0xf7, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x97,(sbyte) 0xe1, (sbyte)0x28, (sbyte)0x07,(sbyte) 0xff, (sbyte)0xf3, (sbyte)0x02, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x61,(sbyte) 0x10, (sbyte)0x0c, (sbyte)0x05,(sbyte) 0xf2, (sbyte)0xc4, (sbyte)0x40, (sbyte)0xc8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x01,(sbyte) 0x01, (sbyte)0x56, (sbyte)0x03,(sbyte) 0xb4, (sbyte)0xb2, (sbyte)0x23, (sbyte)0x58, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x61,(sbyte) 0x41, (sbyte)0x89, (sbyte)0x03,(sbyte) 0xf1, (sbyte)0xf4, (sbyte)0xf0, (sbyte)0x13, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x04,(sbyte) 0x21, (sbyte)0x28, (sbyte)0x00,(sbyte) 0xdf, (sbyte)0xf8, (sbyte)0xff, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x23,(sbyte) 0x22, (sbyte)0x00, (sbyte)0x00,(sbyte) 0xd8, (sbyte)0xf8, (sbyte)0xf8, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x25,(sbyte) 0x18, (sbyte)0x00, (sbyte)0x00,(sbyte) 0xf8, (sbyte)0xda, (sbyte)0xf8, (sbyte)0x55, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
},
new sbyte[]
{
(sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x33, (sbyte)0x01, (sbyte)0x09, (sbyte)0x0e, (sbyte)0x94, (sbyte)0x90, (sbyte)0x40, (sbyte)0x01, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x13, (sbyte)0x41, (sbyte)0x0f, (sbyte)0x0d, (sbyte)0xce, (sbyte)0xd3, (sbyte)0x43, (sbyte)0x13, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x01, (sbyte)0x12, (sbyte)0x1b, (sbyte)0x06, (sbyte)0xff, (sbyte)0xd2, (sbyte)0x00, (sbyte)0x32, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x61, (sbyte)0x61, (sbyte)0x1b, (sbyte)0x07, (sbyte)0xaf, (sbyte)0x63, (sbyte)0x20, (sbyte)0x28, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x22, (sbyte)0x21, (sbyte)0x1e, (sbyte)0x06, (sbyte)0xf0, (sbyte)0x76, (sbyte)0x08, (sbyte)0x28, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x66, (sbyte)0x21, (sbyte)0x15, (sbyte)0x00, (sbyte)0x93, (sbyte)0x94, (sbyte)0x20, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x21, (sbyte)0x61, (sbyte)0x1c, (sbyte)0x07, (sbyte)0x82, (sbyte)0x81, (sbyte)0x10, (sbyte)0x17, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x23, (sbyte)0x21, (sbyte)0x20, (sbyte)0x1f, (sbyte)0xc0, (sbyte)0x71, (sbyte)0x07, (sbyte)0x47, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x25, (sbyte)0x31, (sbyte)0x26, (sbyte)0x05, (sbyte)0x64, (sbyte)0x41, (sbyte)0x18, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x17, (sbyte)0x21, (sbyte)0x28, (sbyte)0x07, (sbyte)0xff, (sbyte)0x83, (sbyte)0x02, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x97, (sbyte)0x81, (sbyte)0x25, (sbyte)0x07, (sbyte)0xcf, (sbyte)0xc8, (sbyte)0x02, (sbyte)0x14, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x21, (sbyte)0x21, (sbyte)0x54, (sbyte)0x0f, (sbyte)0x80, (sbyte)0x7f, (sbyte)0x07, (sbyte)0x07, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x01, (sbyte)0x01, (sbyte)0x56, (sbyte)0x03, (sbyte)0xd3, (sbyte)0xb2, (sbyte)0x43, (sbyte)0x58, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x31, (sbyte)0x21, (sbyte)0x0c, (sbyte)0x03, (sbyte)0x82, (sbyte)0xc0, (sbyte)0x40, (sbyte)0x07, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x21, (sbyte)0x01, (sbyte)0x0c, (sbyte)0x03, (sbyte)0xd4, (sbyte)0xd3, (sbyte)0x40, (sbyte)0x84, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x04, (sbyte)0x21, (sbyte)0x28, (sbyte)0x00, (sbyte)0xdf, (sbyte)0xf8, (sbyte)0xff, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x23, (sbyte)0x22, (sbyte)0x00, (sbyte)0x00, (sbyte)0xa8, (sbyte)0xf8, (sbyte)0xf8, (sbyte)0xf8, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
(sbyte)0x25, (sbyte)0x18, (sbyte)0x00, (sbyte)0x00, (sbyte)0xf8, (sbyte)0xa9, (sbyte)0xf8, (sbyte)0x55, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00, (sbyte)0x00,
}
};
return res;
}
}
internal static OPLL_PATCH[][] Create_Default_Patch()
{
OPLL_PATCH[][] res = new OPLL_PATCH[Emu2413API.OPLL_TONE_NUM][]
{
new OPLL_PATCH[(16 + 3) * 2],
new OPLL_PATCH[(16 + 3) * 2],
};
for (int x = 0; x < Emu2413API.OPLL_TONE_NUM; x++)
for (int y = 0; y < (16 + 3) * 2; y++)
res[x][y] = new OPLL_PATCH();
return res;
}
internal static uint[,,,] Create_tllTable()
{
var res = new uint[16, 8, 1 << Emu2413API.TL_BITS, 4];
return res;
}
internal static Int32[,,] Create_rksTable()
{
return new int[2, 8, 2];
}
internal static UInt32[,,] Create_dphaseTable()
{
return new uint[512, 8, 16];
}
}
public class OPLL_PATCH
{
public uint TL, FB, EG, ML, AR, DR, SL, RR, KR, KL, AM, PM, WF;
public void Copy(OPLL_PATCH other)
{
TL = other.TL;
FB = other.FB;
EG = other.EG;
ML = other.ML;
AR = other.AR;
DR = other.DR;
SL = other.SL;
RR = other.RR;
KR = other.KR;
KL = other.KL;
AM = other.AM;
PM = other.PM;
WF = other.WF;
}
}
public class OPLL_SLOT
{
public OPLL_PATCH patch;
public int type; /* 0 : modulator 1 : carrier */
/* OUTPUT */
public Int32 feedback;
public Int32[] output = new Int32[5]; /* Output value of slot */
/* for Phase Generator (PG) */
public UInt32[] sintbl; /* Wavetable */
public UInt32 phase; /* Phase */
public UInt32 dphase; /* Phase increment amount */
public UInt32 pgout; /* output */
/* for Envelope Generator (EG) */
public int fnum; /* F-Number */
public int block; /* Block */
public int volume; /* Current volume */
public int sustine; /* Sustine 1 = ON, 0 = OFF */
public UInt32 tll; /* Total Level + Key scale level*/
public UInt32 rks; /* Key scale offset (Rks) */
public int eg_mode; /* Current state */
public UInt32 eg_phase; /* Phase */
public UInt32 eg_dphase; /* Phase increment amount */
public UInt32 egout; /* output */
/* refer to opll-> */
public int plfo_pm => m_host.lfo_pm;
public int plfo_am => m_host.lfo_am;
private OPLL m_host;
public void SetHost(OPLL host)
{
m_host = host;
}
}
public class OPLL_CH
{
public int patch_number;
public int key_status;
public OPLL_SLOT mod;
public OPLL_SLOT car;
}
public class OPLL
{
public UInt32 adr;
public Int32[] output = new Int32[2];
/* Register */
public byte[] reg = new byte[0x40];
public int[] slot_on_flag = new int[18];
/* Rythm Mode : 0 = OFF, 1 = ON */
public int rythm_mode;
/* Pitch Modulator */
public UInt32 pm_phase;
public Int32 lfo_pm;
/* Amp Modulator */
public Int32 am_phase;
public Int32 lfo_am;
/* Noise Generator */
public UInt32 noise_seed;
public UInt32 whitenoise;
public UInt32 noiseA;
public UInt32 noiseB;
public UInt32 noiseA_phase;
public UInt32 noiseB_phase;
public UInt32 noiseA_idx;
public UInt32 noiseB_idx;
public UInt32 noiseA_dphase;
public UInt32 noiseB_dphase;
/* Channel & Slot */
public OPLL_CH[] ch = new OPLL_CH[9];
public OPLL_SLOT[] slot = new OPLL_SLOT[18];
/* Voice Data */
public OPLL_PATCH[] patch = new OPLL_PATCH[19 * 2];
public int[] patch_update = new int[2]; /* flag for check patch update */
public UInt32 mask;
public int masterVolume; /* 0min -- 64 -- 127 max (Liner) */
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c1aaa5374091a64a88e750483fe6f6b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,12 @@
namespace VirtualNes.Core
{
// 昤夋曽幃
public enum EnumRenderMethod
{
POST_ALL_RENDER = 0, // 僗僉儍儞儔僀儞暘偺柦椷幚峴屻丆儗儞僟儕儞僌
PRE_ALL_RENDER = 1, // 儗儞僟儕儞僌偺幚峴屻丆僗僉儍儞儔僀儞暘偺柦椷幚峴
POST_RENDER = 2, // 昞帵婜娫暘偺柦椷幚峴屻丆儗儞僟儕儞僌
PRE_RENDER = 3, // 儗儞僟儕儞僌幚峴屻丆昞帵婜娫暘偺柦椷幚峴
TILE_RENDER = 4 // 僞僀儖儀乕僗儗儞僟儕儞僌
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c379fb6535bd23449474dee5018652c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace VirtualNes.Core
{
public interface ISoundDataBuffer
{
void WriteByte(byte value);
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4585a754599519b48bfe50294600818f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More