diff --git a/chip8/chip8.go b/chip8/chip8.go index 37c21ba..051a986 100644 --- a/chip8/chip8.go +++ b/chip8/chip8.go @@ -1,10 +1,14 @@ package chip8 import ( + _ "embed" "encoding/binary" "image" ) +//go:embed sound.wav +var Sound []byte + const ( MemorySize = 4096 // 4KB of memory InstructionSize = 2 // 2 bytes long instructions @@ -21,6 +25,7 @@ const ( ) type KeyPressed func(key uint8) bool +type PlaySound func(sound []byte) func() type ROM struct { Name string @@ -38,11 +43,14 @@ type Emulator struct { ROM ROM // game rom Display *image.RGBA // display buffer KeyPressed KeyPressed // input function + PlaySound PlaySound + StopSound func() } -func NewEmulator(keyPressed KeyPressed) *Emulator { +func NewEmulator(keyPressed KeyPressed, playSound PlaySound) *Emulator { emulator := new(Emulator) emulator.KeyPressed = keyPressed + emulator.PlaySound = playSound emulator.Stack = NewStack() emulator.Display = image.NewRGBA(image.Rect(0, 0, Width, Height)) emulator.Reset() @@ -93,7 +101,17 @@ func (emulator *Emulator) UpdateTimers() { emulator.DT -= 1 } if emulator.ST > 0 { + if emulator.StopSound == nil { + _ = 1 + emulator.StopSound = emulator.PlaySound(Sound) + } + emulator.ST -= 1 + } else { + if emulator.StopSound != nil { + emulator.StopSound() + emulator.StopSound = nil + } } } diff --git a/chip8/sound.wav b/chip8/sound.wav new file mode 100644 index 0000000..657aa25 Binary files /dev/null and b/chip8/sound.wav differ diff --git a/go.mod b/go.mod index 8c4f655..0c5531d 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( require ( github.com/davecgh/go-spew v1.1.0 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20210727001814-0db043d8d5be // indirect + github.com/hajimehoshi/oto/v2 v2.1.0-alpha.2 // indirect github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240 // indirect github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/pmezard/go-difflib v1.0.0 // indirect diff --git a/go.sum b/go.sum index 8d674c1..896e23a 100644 --- a/go.sum +++ b/go.sum @@ -8,7 +8,9 @@ github.com/hajimehoshi/ebiten/v2 v2.2.5 h1:i6NdS6pEi5kgfTh+4XAVCVtCXxjTyxzU1cj1o github.com/hajimehoshi/ebiten/v2 v2.2.5/go.mod h1:olKl/qqhMBBAm2oI7Zy292nCtE+nitlmYKNF3UpbFn0= github.com/hajimehoshi/file2byteslice v0.0.0-20210813153925-5340248a8f41/go.mod h1:CqqAHp7Dk/AqQiwuhV1yT2334qbA/tFWQW0MD2dGqUE= github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= +github.com/hajimehoshi/oto v0.6.1 h1:7cJz/zRQV4aJvMSSRqzN2TImoVVMpE0BCY4nrNJaDOM= github.com/hajimehoshi/oto v0.6.1/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI= +github.com/hajimehoshi/oto/v2 v2.1.0-alpha.2 h1:DV2DcbY3YLuLB9gI9R1GT9TPOo92lUeWveV8ci1sBLk= github.com/hajimehoshi/oto/v2 v2.1.0-alpha.2/go.mod h1:rUKQmwMkqmRxe+IAof9+tuYA2ofm8cAWXFmSfzDN8vQ= github.com/jakecoffman/cp v1.1.0/go.mod h1:JjY/Fp6d8E1CHnu74gWNnU0+b9VzEdUVPoJxg2PsTQg= github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240 h1:dy+DS31tGEGCsZzB45HmJJNHjur8GDgtRNX9U7HnSX4= diff --git a/main.go b/main.go index 96d6b70..a121cc5 100644 --- a/main.go +++ b/main.go @@ -6,6 +6,7 @@ import ( "time" "github.com/hajimehoshi/ebiten/v2" + "github.com/hajimehoshi/ebiten/v2/audio" "github.com/tangzero/chip8-emulator/chip8" ) @@ -50,8 +51,9 @@ var KeyMapping = []ebiten.Key{ } type UI struct { - Emulator *chip8.Emulator - State State + Emulator *chip8.Emulator + State State + AudioContext *audio.Context } func (ui *UI) Run() { @@ -85,17 +87,27 @@ func (ui *UI) Layout(outsideWidth, outsideHeight int) (int, int) { return Width, Height } -func KeyPressed(key uint8) bool { +func (ui *UI) KeyPressed(key uint8) bool { return ebiten.IsKeyPressed(KeyMapping[key]) } +func (ui *UI) PlaySound(sound []byte) func() { + player := ui.AudioContext.NewPlayerFromBytes(sound) + player.SetVolume(0.3) + player.Play() + return func() { + player.Pause() + _ = player.Close() + } +} + func main() { rom := LoadROM() - ui := UI{ - Emulator: chip8.NewEmulator(KeyPressed), - State: LoadingState, - } + ui := UI{} + ui.Emulator = chip8.NewEmulator(ui.KeyPressed, ui.PlaySound) + ui.State = LoadingState + ui.AudioContext = audio.NewContext(44100) ui.Emulator.LoadROM(rom) ebiten.SetWindowSize(Width, Height)