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"
"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() {

View File

@ -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

Binary file not shown.

64
main.go
View File

@ -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)
}
}