sound system refactored

This commit is contained in:
Jairinho 2022-03-01 21:01:20 -03:00
parent 18d4d7f843
commit a9399f2d17
No known key found for this signature in database
GPG Key ID: 954589B18A21D5B6
5 changed files with 59 additions and 52 deletions

BIN
chip8/beep.wav Normal file

Binary file not shown.

View File

@ -4,10 +4,11 @@ import (
_ "embed" _ "embed"
"encoding/binary" "encoding/binary"
"image" "image"
"math"
) )
//go:embed sound.wav //go:embed beep.wav
var Sound []byte var Beep []byte
const ( const (
MemorySize = 4096 // 4KB of memory MemorySize = 4096 // 4KB of memory
@ -19,13 +20,14 @@ const (
) )
const ( const (
Width = 64 Width = 64
Height = 32 Height = 32
FPS = 60 FPS = 60
SampleRate = 44100
) )
type KeyPressed func(key uint8) bool type KeyPressed func(key uint8) bool
type PlaySound func(sound []byte) func() type SoundPlayer func(sound []byte) (func(), func())
type ROM struct { type ROM struct {
Name string Name string
@ -43,14 +45,14 @@ type Emulator struct {
ROM ROM // game rom ROM ROM // game rom
Display *image.RGBA // display buffer Display *image.RGBA // display buffer
KeyPressed KeyPressed // input function KeyPressed KeyPressed // input function
PlaySound PlaySound PlaySound func() // play sound effect
StopSound func() StopSound func() // stop sound effect
} }
func NewEmulator(keyPressed KeyPressed, playSound PlaySound) *Emulator { func NewEmulator(keyPressed KeyPressed, soundPlayer SoundPlayer) *Emulator {
emulator := new(Emulator) emulator := new(Emulator)
emulator.KeyPressed = keyPressed emulator.KeyPressed = keyPressed
emulator.PlaySound = playSound emulator.PlaySound, emulator.StopSound = soundPlayer(Beep)
emulator.Stack = NewStack() emulator.Stack = NewStack()
emulator.Display = image.NewRGBA(image.Rect(0, 0, Width, Height)) emulator.Display = image.NewRGBA(image.Rect(0, 0, Width, Height))
emulator.Reset() emulator.Reset()
@ -97,20 +99,13 @@ func (emulator *Emulator) LoadFont() {
} }
func (emulator *Emulator) UpdateTimers() { func (emulator *Emulator) UpdateTimers() {
if emulator.DT > 0 { if emulator.ST != 0 {
emulator.DT -= 1 emulator.PlaySound()
}
if emulator.ST > 0 {
emulator.ST -= 1
if emulator.StopSound == nil {
emulator.StopSound = emulator.PlaySound(Sound)
}
} else { } else {
if emulator.StopSound != nil { emulator.StopSound()
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() { func (emulator *Emulator) Cycle() {

View File

@ -8,7 +8,9 @@ import (
) )
func TestEmulator_Reset(t *testing.T) { 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[0x03] = 0xFF
emulator.V[0x0F] = 0xBB emulator.V[0x0F] = 0xBB

Binary file not shown.

68
main.go
View File

@ -50,71 +50,81 @@ var KeyMapping = []ebiten.Key{
ebiten.KeyV, ebiten.KeyV,
} }
type UI struct { type GUI struct {
Emulator *chip8.Emulator State State
State State Emulator *chip8.Emulator
AudioContext *audio.Context
} }
func (ui *UI) Run() { func (gui *GUI) Run() {
for { for {
ui.Emulator.Cycle() gui.Emulator.Cycle()
time.Sleep(time.Millisecond * 2) time.Sleep(time.Millisecond * 2)
} }
} }
func (ui *UI) Update() error { func (gui *GUI) Update() error {
if ebiten.IsKeyPressed(ebiten.KeyEscape) { if ebiten.IsKeyPressed(ebiten.KeyEscape) {
ui.Emulator.Reset() gui.Emulator.Reset()
} }
switch gui.State {
switch ui.State {
case LoadingState: case LoadingState:
go ui.Run() go gui.Run()
ui.State = RunningState gui.State = RunningState
case RunningState: case RunningState:
ui.Emulator.UpdateTimers() gui.Emulator.UpdateTimers()
} }
return nil return nil
} }
func (ui *UI) Draw(screen *ebiten.Image) { func (gui *GUI) Draw(screen *ebiten.Image) {
frame := ebiten.NewImageFromImage(ui.Emulator.Display) frame := ebiten.NewImageFromImage(gui.Emulator.Display)
operation := new(ebiten.DrawImageOptions) operation := new(ebiten.DrawImageOptions)
operation.GeoM.Scale(ScreenScale, ScreenScale) operation.GeoM.Scale(ScreenScale, ScreenScale)
screen.DrawImage(frame, operation) screen.DrawImage(frame, operation)
} }
func (ui *UI) Layout(int, int) (int, int) { func (gui *GUI) Layout(int, int) (int, int) {
return Width, Height return Width, Height
} }
func (ui *UI) KeyPressed(key uint8) bool { func KeyPressed(key uint8) bool {
return ebiten.IsKeyPressed(KeyMapping[key]) return ebiten.IsKeyPressed(KeyMapping[key])
} }
func (ui *UI) PlaySound(sound []byte) func() { func SoundPlayer(sound []byte) (func(), func()) {
player := ui.AudioContext.NewPlayerFromBytes(sound) player := audio.NewContext(chip8.SampleRate).NewPlayerFromBytes(sound)
player.SetVolume(0.3) player.SetVolume(0.3)
player.Play() return PlaySound(player), StopSound(player)
return func() { _ = player.Close() } }
func PlaySound(player *audio.Player) func() {
return func() {
if player.IsPlaying() {
return
}
player.Play()
}
}
func StopSound(player *audio.Player) func() {
return func() {
player.Pause()
player.Seek(0)
}
} }
func main() { func main() {
rom := LoadROM() rom := LoadROM()
ui := UI{} gui := GUI{}
ui.Emulator = chip8.NewEmulator(ui.KeyPressed, ui.PlaySound) gui.State = LoadingState
ui.State = LoadingState gui.Emulator = chip8.NewEmulator(KeyPressed, SoundPlayer)
ui.AudioContext = audio.NewContext(44100) gui.Emulator.LoadROM(rom)
ui.Emulator.LoadROM(rom)
ebiten.SetWindowSize(Width, Height) ebiten.SetWindowSize(Width, Height)
ebiten.SetWindowTitle("CHIP-8 : " + rom.Name) ebiten.SetWindowTitle("CHIP-8 : " + rom.Name)
if err := ebiten.RunGame(&ui); err != nil { if err := ebiten.RunGame(&gui); err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }