sound system refactored
This commit is contained in:
parent
18d4d7f843
commit
a9399f2d17
BIN
chip8/beep.wav
Normal file
BIN
chip8/beep.wav
Normal file
Binary file not shown.
|
@ -4,10 +4,11 @@ import (
|
|||
_ "embed"
|
||||
"encoding/binary"
|
||||
"image"
|
||||
"math"
|
||||
)
|
||||
|
||||
//go:embed sound.wav
|
||||
var Sound []byte
|
||||
//go:embed beep.wav
|
||||
var Beep []byte
|
||||
|
||||
const (
|
||||
MemorySize = 4096 // 4KB of memory
|
||||
|
@ -22,10 +23,11 @@ const (
|
|||
Width = 64
|
||||
Height = 32
|
||||
FPS = 60
|
||||
SampleRate = 44100
|
||||
)
|
||||
|
||||
type KeyPressed func(key uint8) bool
|
||||
type PlaySound func(sound []byte) func()
|
||||
type SoundPlayer func(sound []byte) (func(), func())
|
||||
|
||||
type ROM struct {
|
||||
Name string
|
||||
|
@ -43,14 +45,14 @@ type Emulator struct {
|
|||
ROM ROM // game rom
|
||||
Display *image.RGBA // display buffer
|
||||
KeyPressed KeyPressed // input function
|
||||
PlaySound PlaySound
|
||||
StopSound func()
|
||||
PlaySound func() // play sound effect
|
||||
StopSound func() // stop sound effect
|
||||
}
|
||||
|
||||
func NewEmulator(keyPressed KeyPressed, playSound PlaySound) *Emulator {
|
||||
func NewEmulator(keyPressed KeyPressed, soundPlayer SoundPlayer) *Emulator {
|
||||
emulator := new(Emulator)
|
||||
emulator.KeyPressed = keyPressed
|
||||
emulator.PlaySound = playSound
|
||||
emulator.PlaySound, emulator.StopSound = soundPlayer(Beep)
|
||||
emulator.Stack = NewStack()
|
||||
emulator.Display = image.NewRGBA(image.Rect(0, 0, Width, Height))
|
||||
emulator.Reset()
|
||||
|
@ -97,20 +99,13 @@ func (emulator *Emulator) LoadFont() {
|
|||
}
|
||||
|
||||
func (emulator *Emulator) UpdateTimers() {
|
||||
if emulator.DT > 0 {
|
||||
emulator.DT -= 1
|
||||
}
|
||||
if emulator.ST > 0 {
|
||||
emulator.ST -= 1
|
||||
if emulator.StopSound == nil {
|
||||
emulator.StopSound = emulator.PlaySound(Sound)
|
||||
}
|
||||
if emulator.ST != 0 {
|
||||
emulator.PlaySound()
|
||||
} else {
|
||||
if emulator.StopSound != nil {
|
||||
emulator.StopSound()
|
||||
emulator.StopSound = nil
|
||||
}
|
||||
}
|
||||
emulator.ST = uint8(math.Max(0, float64(emulator.ST)-1))
|
||||
emulator.DT = uint8(math.Max(0, float64(emulator.DT)-1))
|
||||
}
|
||||
|
||||
func (emulator *Emulator) Cycle() {
|
||||
|
|
|
@ -8,7 +8,9 @@ import (
|
|||
)
|
||||
|
||||
func TestEmulator_Reset(t *testing.T) {
|
||||
emulator := chip8.NewEmulator(nil, nil)
|
||||
soundPlayer := func(sound []byte) (func(), func()) { return nil, nil }
|
||||
|
||||
emulator := chip8.NewEmulator(nil, soundPlayer)
|
||||
emulator.V[0x03] = 0xFF
|
||||
emulator.V[0x0F] = 0xBB
|
||||
|
||||
|
|
BIN
chip8/sound.wav
BIN
chip8/sound.wav
Binary file not shown.
64
main.go
64
main.go
|
@ -50,71 +50,81 @@ var KeyMapping = []ebiten.Key{
|
|||
ebiten.KeyV,
|
||||
}
|
||||
|
||||
type UI struct {
|
||||
Emulator *chip8.Emulator
|
||||
type GUI struct {
|
||||
State State
|
||||
AudioContext *audio.Context
|
||||
Emulator *chip8.Emulator
|
||||
}
|
||||
|
||||
func (ui *UI) Run() {
|
||||
func (gui *GUI) Run() {
|
||||
for {
|
||||
ui.Emulator.Cycle()
|
||||
gui.Emulator.Cycle()
|
||||
time.Sleep(time.Millisecond * 2)
|
||||
}
|
||||
}
|
||||
|
||||
func (ui *UI) Update() error {
|
||||
func (gui *GUI) Update() error {
|
||||
if ebiten.IsKeyPressed(ebiten.KeyEscape) {
|
||||
ui.Emulator.Reset()
|
||||
gui.Emulator.Reset()
|
||||
}
|
||||
|
||||
switch ui.State {
|
||||
switch gui.State {
|
||||
case LoadingState:
|
||||
go ui.Run()
|
||||
ui.State = RunningState
|
||||
go gui.Run()
|
||||
gui.State = RunningState
|
||||
case RunningState:
|
||||
ui.Emulator.UpdateTimers()
|
||||
gui.Emulator.UpdateTimers()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ui *UI) Draw(screen *ebiten.Image) {
|
||||
frame := ebiten.NewImageFromImage(ui.Emulator.Display)
|
||||
|
||||
func (gui *GUI) Draw(screen *ebiten.Image) {
|
||||
frame := ebiten.NewImageFromImage(gui.Emulator.Display)
|
||||
operation := new(ebiten.DrawImageOptions)
|
||||
operation.GeoM.Scale(ScreenScale, ScreenScale)
|
||||
|
||||
screen.DrawImage(frame, operation)
|
||||
}
|
||||
|
||||
func (ui *UI) Layout(int, int) (int, int) {
|
||||
func (gui *GUI) Layout(int, int) (int, int) {
|
||||
return Width, Height
|
||||
}
|
||||
|
||||
func (ui *UI) KeyPressed(key uint8) bool {
|
||||
func KeyPressed(key uint8) bool {
|
||||
return ebiten.IsKeyPressed(KeyMapping[key])
|
||||
}
|
||||
|
||||
func (ui *UI) PlaySound(sound []byte) func() {
|
||||
player := ui.AudioContext.NewPlayerFromBytes(sound)
|
||||
func SoundPlayer(sound []byte) (func(), func()) {
|
||||
player := audio.NewContext(chip8.SampleRate).NewPlayerFromBytes(sound)
|
||||
player.SetVolume(0.3)
|
||||
return PlaySound(player), StopSound(player)
|
||||
}
|
||||
|
||||
func PlaySound(player *audio.Player) func() {
|
||||
return func() {
|
||||
if player.IsPlaying() {
|
||||
return
|
||||
}
|
||||
player.Play()
|
||||
return func() { _ = player.Close() }
|
||||
}
|
||||
}
|
||||
|
||||
func StopSound(player *audio.Player) func() {
|
||||
return func() {
|
||||
player.Pause()
|
||||
player.Seek(0)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
rom := LoadROM()
|
||||
|
||||
ui := UI{}
|
||||
ui.Emulator = chip8.NewEmulator(ui.KeyPressed, ui.PlaySound)
|
||||
ui.State = LoadingState
|
||||
ui.AudioContext = audio.NewContext(44100)
|
||||
ui.Emulator.LoadROM(rom)
|
||||
gui := GUI{}
|
||||
gui.State = LoadingState
|
||||
gui.Emulator = chip8.NewEmulator(KeyPressed, SoundPlayer)
|
||||
gui.Emulator.LoadROM(rom)
|
||||
|
||||
ebiten.SetWindowSize(Width, Height)
|
||||
ebiten.SetWindowTitle("CHIP-8 : " + rom.Name)
|
||||
|
||||
if err := ebiten.RunGame(&ui); err != nil {
|
||||
if err := ebiten.RunGame(&gui); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user