Chip8iEmulationCore
是一个 Swift 包,用于模拟 Chip8 系统并运行其程序。此包提供了一个模拟核心,允许您启动模拟、处理 Chip8 程序操作、处理输入以及订阅 Chip8 屏幕输出和声音更新。
模拟核心包可以在 macOS 和 iOS 上的前端应用程序中使用,您只需将用户输入传播到核心并订阅其输出即可。
要将 Chip8iEmulationCore
包含在您的项目中,请将其添加为 Swift Package Dependency(Swift 包依赖项)。
File
-> Add Packages...
(文件 -> 添加包...)在要使用模拟器的 Swift 文件中
import Chip8iEmulationCore
let emulationCore = Chip8EmulationCore()
首先,从文件系统或其他方式以只读(ROM)数据 [UByte]
形式加载 chip8 程序二进制文件,并将其保存在 Chip8Program
结构中,以供模拟使用。
let programROM = Chip8Program(name: "My Pong Game", contentROM: myPongGameROMData)
emulate
函数在一个无限循环中运行(Chip8 程序没有退出命令),因此请确保它在适当的异步上下文中运行。
Task {
await emulationCore.emulate(program: programROM)
}
Chip8 有 16 个系统键,从 0 到 F。
1 2 3 C
4 5 6 D
7 8 9 E
A 0 B F
要处理按键按下和释放事件
emulationCore.onKeyDown(key: .Zero) // Example: Press down Chip8 key '0'
emulationCore.onKeyDown(key: .One) // Example: Press down Chip8 key '1'
emulationCore.onKeyUp(key: .F) // Example: Release Chip8 key 'F'
使用 onKeyDown
和 onKeyUp
方法将输入键 enum
发送到模拟器。有关键盘绑定的更多详细信息和示例,请参阅 EmulationControls
模块。
注意:键盘/控制器/触摸屏按钮可以自定义映射到 Chip8 键,这应该在前端应用程序中完成,模拟核心仅接受
EmulationControls.Chip8Key
枚举。
outputScreen
和 outputSoundTimer
属性都标记为 @Published
,因此您可以订阅它们,并在 SwiftUI
、UIKit
或 AppKit
中更新视图和播放声音。
Publisher Buffer outputScreen
是一个 64x32 的布尔值网格,表示像素状态。
从 outputScreen
publisher buffer 反应式地显示屏幕更新的一种方法是使用 CGImage
扩展方法 fromMonochromeBitmap
,它包含在 Chip8iEmulationCore
包中。
这是一个 macOS 前端应用程序中使用此方法的示例,它使用了此包。示例中还包括核心的初始化,启动游戏和订阅声音定时器更改。
@StateObject var emulationCore = Chip8EmulationCore()
private let singlePingSound = NSSound(named: NSSound.Name("Ping"))
var body: some View {
VStack {
Image(CGImage.fromMonochromeBitmap(emulationCore.outputScreen,
width: 64, height: 32)!,
scale: 5, label: Text("Output"))
.interpolation(.none)
.resizable()
.scaledToFit()
}
.padding()
.onAppear(perform: {
Task {
let program = readProgramFromFile(fileName: "Pong.ch8")
await emulationCore.emulate(program: program)
}
})
.focusable()
.focusEffectDisabled()
.onKeyPress(phases: .down, action: onKeyDown)
.onKeyPress(phases: .up, action: onKeyUp)
.onChange(of: emulationCore.outputSoundTimer) { oldValue, newValue in
handleSoundTimerChange(soundTimer: newValue)
}
}
Publisher outputSoundTimer
是 Chip8 系统声音定时器的 UByte 值。 如果该值大于 0,则每次值更改时应播放短声音效果。
func handleSoundTimerChange(soundTimer: UByte) {
if soundTimer > 0 && !(singlePingSound?.isPlaying == true) {
singlePingSound?.play()
} else if soundTimer == 0 && singlePingSound?.isPlaying == true {
singlePingSound?.stop()
}
}
这是集成 chip8 模拟核心并从简单的 macOS 模拟器前端运行它的示例,该前端将游戏二进制文件和按键输入提供给核心,并显示核心的输出。
此包已获得 MIT 许可证的许可。 有关更多信息,请参阅 LICENSE
文件。