1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-06-19 13:45:23 +00:00

Removed audio singleton (#482)

This commit is contained in:
Tim Sarbin 2020-06-28 19:31:10 -04:00 committed by GitHub
parent 1b614ddb3a
commit 3f575cf1d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 115 additions and 136 deletions

View File

@ -0,0 +1,7 @@
package d2interface
type AudioProvider interface {
PlayBGM(song string)
LoadSoundEffect(sfx string) (SoundEffect, error)
SetVolumes(bgmVolume, sfxVolume float64)
}

View File

@ -0,0 +1,6 @@
package d2interface
type SoundEffect interface {
Play()
Stop()
}

View File

@ -1,59 +0,0 @@
package d2audio
import (
"errors"
)
var singleton AudioProvider
var (
ErrWasInit = errors.New("audio system is already initialized")
ErrNotInit = errors.New("audio system has not been initialized")
)
type SoundEffect interface {
Play()
Stop()
}
type AudioProvider interface {
PlayBGM(song string)
LoadSoundEffect(sfx string) (SoundEffect, error)
SetVolumes(bgmVolume, sfxVolume float64)
}
// CreateManager creates a sound provider
func Initialize(audioProvider AudioProvider) error {
verifyNotInit()
singleton = audioProvider
return nil
}
// PlayBGM plays an infinitely looping background track
func PlayBGM(song string) error {
verifyWasInit()
singleton.PlayBGM(song)
return nil
}
func LoadSoundEffect(sfx string) (SoundEffect, error) {
verifyWasInit()
return singleton.LoadSoundEffect(sfx)
}
func SetVolumes(bgmVolume, sfxVolume float64) {
verifyWasInit()
singleton.SetVolumes(bgmVolume, sfxVolume)
}
func verifyWasInit() {
if singleton == nil {
panic(ErrNotInit)
}
}
func verifyNotInit() {
if singleton != nil {
panic(ErrWasInit)
}
}

View File

@ -3,8 +3,9 @@ package ebiten
import ( import (
"log" "log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/hajimehoshi/ebiten/audio/wav" "github.com/hajimehoshi/ebiten/audio/wav"
"github.com/hajimehoshi/ebiten/audio" "github.com/hajimehoshi/ebiten/audio"
@ -70,7 +71,7 @@ func (eap *AudioProvider) PlayBGM(song string) {
} }
} }
func (eap *AudioProvider) LoadSoundEffect(sfx string) (d2audio.SoundEffect, error) { func (eap *AudioProvider) LoadSoundEffect(sfx string) (d2interface.SoundEffect, error) {
result := CreateSoundEffect(sfx, eap.audioContext, eap.sfxVolume) // TODO: Split result := CreateSoundEffect(sfx, eap.audioContext, eap.sfxVolume) // TODO: Split
return result, nil return result, nil
} }

View File

@ -3,8 +3,9 @@ package d2ui
import ( import (
"log" "log"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
) )
@ -28,10 +29,10 @@ type UI struct {
} }
var singleton UI var singleton UI
var clickSfx d2audio.SoundEffect var clickSfx d2interface.SoundEffect
func Initialize() { func Initialize(audioProvider d2interface.AudioProvider) {
sfx, err := d2audio.LoadSoundEffect(d2resource.SFXButtonClick) sfx, err := audioProvider.LoadSoundEffect(d2resource.SFXButtonClick)
if err != nil { if err != nil {
log.Fatalf("failed to initialize ui: %v", err) log.Fatalf("failed to initialize ui: %v", err)
} }

View File

@ -6,12 +6,13 @@ import (
"os" "os"
"strings" "strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2common" "github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2inventory" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2inventory"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
@ -45,18 +46,21 @@ type CharacterSelect struct {
showDeleteConfirmation bool showDeleteConfirmation bool
connectionType d2clientconnectiontype.ClientConnectionType connectionType d2clientconnectiontype.ClientConnectionType
connectionHost string connectionHost string
audioProvider d2interface.AudioProvider
} }
func CreateCharacterSelect(connectionType d2clientconnectiontype.ClientConnectionType, connectionHost string) *CharacterSelect { func CreateCharacterSelect(audioProvider d2interface.AudioProvider,
connectionType d2clientconnectiontype.ClientConnectionType, connectionHost string) *CharacterSelect {
return &CharacterSelect{ return &CharacterSelect{
selectedCharacter: -1, selectedCharacter: -1,
connectionType: connectionType, connectionType: connectionType,
connectionHost: connectionHost, connectionHost: connectionHost,
audioProvider: audioProvider,
} }
} }
func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) { func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
d2audio.PlayBGM(d2resource.BGMTitle) v.audioProvider.PlayBGM(d2resource.BGMTitle)
d2input.BindHandler(v) d2input.BindHandler(v)
loading.Progress(0.1) loading.Progress(0.1)
@ -172,11 +176,11 @@ func (v *CharacterSelect) updateCharacterBoxes() {
} }
func (v *CharacterSelect) onNewCharButtonClicked() { func (v *CharacterSelect) onNewCharButtonClicked() {
d2screen.SetNextScreen(CreateSelectHeroClass(v.connectionType, v.connectionHost)) d2screen.SetNextScreen(CreateSelectHeroClass(v.audioProvider, v.connectionType, v.connectionHost))
} }
func (v *CharacterSelect) onExitButtonClicked() { func (v *CharacterSelect) onExitButtonClicked() {
mainMenu := CreateMainMenu() mainMenu := CreateMainMenu(v.audioProvider)
mainMenu.SetScreenMode(ScreenModeMainMenu) mainMenu.SetScreenMode(ScreenModeMainMenu)
d2screen.SetNextScreen(mainMenu) d2screen.SetNextScreen(mainMenu)
} }
@ -307,5 +311,5 @@ func (v *CharacterSelect) onOkButtonClicked() {
gameClient.Open("", v.gameStates[v.selectedCharacter].FilePath) gameClient.Open("", v.gameStates[v.selectedCharacter].FilePath)
} }
d2screen.SetNextScreen(CreateGame(gameClient)) d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient))
} }

View File

@ -8,6 +8,8 @@ import (
"path" "path"
"strings" "strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common" "github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
@ -32,15 +34,17 @@ type Credits struct {
cycleTime float64 cycleTime float64
cyclesTillNextLine int cyclesTillNextLine int
doneWithCredits bool doneWithCredits bool
audioProvider d2interface.AudioProvider
} }
// CreateCredits creates an instance of the credits screen // CreateCredits creates an instance of the credits screen
func CreateCredits() *Credits { func CreateCredits(audioProvider d2interface.AudioProvider) *Credits {
result := &Credits{ result := &Credits{
labels: make([]*labelItem, 0), labels: make([]*labelItem, 0),
cycleTime: 0, cycleTime: 0,
doneWithCredits: false, doneWithCredits: false,
cyclesTillNextLine: 0, cyclesTillNextLine: 0,
audioProvider: audioProvider,
} }
return result return result
} }
@ -134,7 +138,7 @@ func (v *Credits) Advance(tickTime float64) error {
} }
func (v *Credits) onExitButtonClicked() { func (v *Credits) onExitButtonClicked() {
mainMenu := CreateMainMenu() mainMenu := CreateMainMenu(v.audioProvider)
mainMenu.SetScreenMode(ScreenModeMainMenu) mainMenu.SetScreenMode(ScreenModeMainMenu)
d2screen.SetNextScreen(mainMenu) d2screen.SetNextScreen(mainMenu)
} }

View File

@ -3,8 +3,9 @@ package d2gamescreen
import ( import (
"fmt" "fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
@ -56,13 +57,14 @@ const (
type EscapeMenu struct { type EscapeMenu struct {
isOpen bool isOpen bool
selectSound d2audio.SoundEffect selectSound d2interface.SoundEffect
currentLayout layoutID currentLayout layoutID
// leftPent and rightPent are generated once and shared between the layouts // leftPent and rightPent are generated once and shared between the layouts
leftPent *d2gui.AnimatedSprite leftPent *d2gui.AnimatedSprite
rightPent *d2gui.AnimatedSprite rightPent *d2gui.AnimatedSprite
layouts []*layout layouts []*layout
audioProvider d2interface.AudioProvider
} }
type layout struct { type layout struct {
@ -110,8 +112,11 @@ type actionableElement interface {
Trigger() Trigger()
} }
func NewEscapeMenu() *EscapeMenu { func NewEscapeMenu(audioProvider d2interface.AudioProvider) *EscapeMenu {
m := &EscapeMenu{} m := &EscapeMenu{
audioProvider: audioProvider,
}
m.layouts = []*layout{ m.layouts = []*layout{
mainLayoutID: m.newMainLayout(), mainLayoutID: m.newMainLayout(),
optionsLayoutID: m.newOptionsLayout(), optionsLayoutID: m.newOptionsLayout(),
@ -283,7 +288,7 @@ func (m *EscapeMenu) addEnumLabel(l *layout, optID optionID, text string, values
} }
func (m *EscapeMenu) OnLoad() { func (m *EscapeMenu) OnLoad() {
m.selectSound, _ = d2audio.LoadSoundEffect(d2resource.SFXCursorSelect) m.selectSound, _ = m.audioProvider.LoadSoundEffect(d2resource.SFXCursorSelect)
} }
func (m *EscapeMenu) OnEscKey() { func (m *EscapeMenu) OnEscKey() {
@ -334,7 +339,7 @@ func (m *EscapeMenu) showLayout(id layoutID) {
} }
if id == saveLayoutID { if id == saveLayoutID {
mainMenu := CreateMainMenu() mainMenu := CreateMainMenu(m.audioProvider)
mainMenu.SetScreenMode(ScreenModeMainMenu) mainMenu.SetScreenMode(ScreenModeMainMenu)
d2screen.SetNextScreen(mainMenu) d2screen.SetNextScreen(mainMenu)
return return

View File

@ -2,14 +2,15 @@ package d2gamescreen
import ( import (
"fmt" "fmt"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"image/color" "image/color"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapentity"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2maprenderer"
@ -25,11 +26,12 @@ type Game struct {
gameControls *d2player.GameControls // TODO: Hack gameControls *d2player.GameControls // TODO: Hack
localPlayer *d2mapentity.Player localPlayer *d2mapentity.Player
lastRegionType d2enum.RegionIdType lastRegionType d2enum.RegionIdType
audioProvider d2interface.AudioProvider
ticksSinceLevelCheck float64 ticksSinceLevelCheck float64
escapeMenu *EscapeMenu escapeMenu *EscapeMenu
} }
func CreateGame(gameClient *d2client.GameClient) *Game { func CreateGame(audioProvider d2interface.AudioProvider, gameClient *d2client.GameClient) *Game {
result := &Game{ result := &Game{
gameClient: gameClient, gameClient: gameClient,
gameControls: nil, gameControls: nil,
@ -37,7 +39,8 @@ func CreateGame(gameClient *d2client.GameClient) *Game {
lastRegionType: d2enum.RegionNone, lastRegionType: d2enum.RegionNone,
ticksSinceLevelCheck: 0, ticksSinceLevelCheck: 0,
mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine), mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine),
escapeMenu: NewEscapeMenu(), escapeMenu: NewEscapeMenu(audioProvider),
audioProvider: audioProvider,
} }
result.escapeMenu.OnLoad() result.escapeMenu.OnLoad()
d2input.BindHandler(result.escapeMenu) d2input.BindHandler(result.escapeMenu)
@ -45,7 +48,7 @@ func CreateGame(gameClient *d2client.GameClient) *Game {
} }
func (v *Game) OnLoad(loading d2screen.LoadingState) { func (v *Game) OnLoad(loading d2screen.LoadingState) {
d2audio.PlayBGM("") v.audioProvider.PlayBGM("")
} }
func (v *Game) OnUnload() error { func (v *Game) OnUnload() error {
@ -88,7 +91,7 @@ func (v *Game) Advance(tickTime float64) error {
tile := v.gameClient.MapEngine.TileAt(v.localPlayer.TileX, v.localPlayer.TileY) tile := v.gameClient.MapEngine.TileAt(v.localPlayer.TileX, v.localPlayer.TileY)
if tile != nil { if tile != nil {
musicInfo := d2common.GetMusicDef(tile.RegionType) musicInfo := d2common.GetMusicDef(tile.RegionType)
d2audio.PlayBGM(musicInfo.MusicFile) v.audioProvider.PlayBGM(musicInfo.MusicFile)
// skip showing zone change text the first time we enter the world // skip showing zone change text the first time we enter the world
if v.lastRegionType != d2enum.RegionNone && v.lastRegionType != tile.RegionType { if v.lastRegionType != d2enum.RegionNone && v.lastRegionType != tile.RegionType {

View File

@ -8,6 +8,8 @@ import (
"os/exec" "os/exec"
"runtime" "runtime"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player" "github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
@ -18,7 +20,6 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
@ -69,19 +70,21 @@ type MainMenu struct {
tcpJoinGameEntry d2ui.TextBox tcpJoinGameEntry d2ui.TextBox
screenMode MainMenuScreenMode screenMode MainMenuScreenMode
leftButtonHeld bool leftButtonHeld bool
audioProvider d2interface.AudioProvider
} }
// CreateMainMenu creates an instance of MainMenu // CreateMainMenu creates an instance of MainMenu
func CreateMainMenu() *MainMenu { func CreateMainMenu(audioProvider d2interface.AudioProvider) *MainMenu {
return &MainMenu{ return &MainMenu{
screenMode: ScreenModeUnknown, screenMode: ScreenModeUnknown,
leftButtonHeld: true, leftButtonHeld: true,
audioProvider: audioProvider,
} }
} }
// Load is called to load the resources for the main menu // Load is called to load the resources for the main menu
func (v *MainMenu) OnLoad(loading d2screen.LoadingState) { func (v *MainMenu) OnLoad(loading d2screen.LoadingState) {
d2audio.PlayBGM(d2resource.BGMTitle) v.audioProvider.PlayBGM(d2resource.BGMTitle)
loading.Progress(0.2) loading.Progress(0.2)
v.versionLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic) v.versionLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
@ -277,10 +280,10 @@ func openbrowser(url string) {
func (v *MainMenu) onSinglePlayerClicked() { func (v *MainMenu) onSinglePlayerClicked() {
// Go here only if existing characters are available to select // Go here only if existing characters are available to select
if d2player.HasGameStates() { if d2player.HasGameStates() {
d2screen.SetNextScreen(CreateCharacterSelect(d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText())) d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText()))
return return
} }
d2screen.SetNextScreen(CreateSelectHeroClass(d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText())) d2screen.SetNextScreen(CreateSelectHeroClass(v.audioProvider, d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText()))
} }
func (v *MainMenu) onGithubButtonClicked() { func (v *MainMenu) onGithubButtonClicked() {
@ -292,7 +295,7 @@ func (v *MainMenu) onExitButtonClicked() {
} }
func (v *MainMenu) onCreditsButtonClicked() { func (v *MainMenu) onCreditsButtonClicked() {
d2screen.SetNextScreen(CreateCredits()) d2screen.SetNextScreen(CreateCredits(v.audioProvider))
} }
// Render renders the main menu // Render renders the main menu
@ -407,7 +410,7 @@ func (v *MainMenu) onTcpIpCancelClicked() {
} }
func (v *MainMenu) onTcpIpHostGameClicked() { func (v *MainMenu) onTcpIpHostGameClicked() {
d2screen.SetNextScreen(CreateCharacterSelect(d2clientconnectiontype.LANServer, "")) d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANServer, ""))
} }
func (v *MainMenu) onTcpIpJoinGameClicked() { func (v *MainMenu) onTcpIpJoinGameClicked() {
@ -419,5 +422,5 @@ func (v *MainMenu) onBtnTcpIpCancelClicked() {
} }
func (v *MainMenu) onBtnTcpIpOkClicked() { func (v *MainMenu) onBtnTcpIpOkClicked() {
d2screen.SetNextScreen(CreateCharacterSelect(d2clientconnectiontype.LANClient, v.tcpJoinGameEntry.GetText())) d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANClient, v.tcpJoinGameEntry.GetText()))
} }

View File

@ -4,6 +4,8 @@ import (
"image" "image"
"image/color" "image/color"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player" "github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
"github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client" "github.com/OpenDiablo2/OpenDiablo2/d2networking/d2client"
@ -15,7 +17,6 @@ import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
@ -32,8 +33,8 @@ type HeroRenderInfo struct {
BackWalkSprite *d2ui.Sprite BackWalkSprite *d2ui.Sprite
BackWalkSpriteOverlay *d2ui.Sprite BackWalkSpriteOverlay *d2ui.Sprite
SelectionBounds image.Rectangle SelectionBounds image.Rectangle
SelectSfx d2audio.SoundEffect SelectSfx d2interface.SoundEffect
DeselectSfx d2audio.SoundEffect DeselectSfx d2interface.SoundEffect
} }
func (hri *HeroRenderInfo) Advance(elapsed float64) { func (hri *HeroRenderInfo) Advance(elapsed float64) {
@ -67,20 +68,23 @@ type SelectHeroClass struct {
hardcoreCharLabel d2ui.Label hardcoreCharLabel d2ui.Label
connectionType d2clientconnectiontype.ClientConnectionType connectionType d2clientconnectiontype.ClientConnectionType
connectionHost string connectionHost string
audioProvider d2interface.AudioProvider
} }
func CreateSelectHeroClass(connectionType d2clientconnectiontype.ClientConnectionType, connectionHost string) *SelectHeroClass { func CreateSelectHeroClass(audioProvider d2interface.AudioProvider,
connectionType d2clientconnectiontype.ClientConnectionType, connectionHost string) *SelectHeroClass {
result := &SelectHeroClass{ result := &SelectHeroClass{
heroRenderInfo: make(map[d2enum.Hero]*HeroRenderInfo), heroRenderInfo: make(map[d2enum.Hero]*HeroRenderInfo),
selectedHero: d2enum.HeroNone, selectedHero: d2enum.HeroNone,
connectionType: connectionType, connectionType: connectionType,
connectionHost: connectionHost, connectionHost: connectionHost,
audioProvider: audioProvider,
} }
return result return result
} }
func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) { func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
d2audio.PlayBGM(d2resource.BGMTitle) v.audioProvider.PlayBGM(d2resource.BGMTitle)
loading.Progress(0.1) loading.Progress(0.1)
v.bgImage = loadSprite(d2resource.CharacterSelectBackground, d2resource.PaletteFechar) v.bgImage = loadSprite(d2resource.CharacterSelectBackground, d2resource.PaletteFechar)
@ -172,8 +176,8 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
loadSprite(d2resource.CharacterSelectBarbarianBackWalk, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelectBarbarianBackWalk, d2resource.PaletteFechar),
nil, nil,
image.Rectangle{Min: image.Point{X: 364, Y: 201}, Max: image.Point{X: 90, Y: 170}}, image.Rectangle{Min: image.Point{X: 364, Y: 201}, Max: image.Point{X: 90, Y: 170}},
loadSoundEffect(d2resource.SFXBarbarianSelect), v.loadSoundEffect(d2resource.SFXBarbarianSelect),
loadSoundEffect(d2resource.SFXBarbarianDeselect), v.loadSoundEffect(d2resource.SFXBarbarianDeselect),
} }
v.heroRenderInfo[d2enum.HeroBarbarian].IdleSprite.SetPosition(400, 330) v.heroRenderInfo[d2enum.HeroBarbarian].IdleSprite.SetPosition(400, 330)
v.heroRenderInfo[d2enum.HeroBarbarian].IdleSprite.PlayForward() v.heroRenderInfo[d2enum.HeroBarbarian].IdleSprite.PlayForward()
@ -205,8 +209,8 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
loadSprite(d2resource.CharacterSelecSorceressBackWalk, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelecSorceressBackWalk, d2resource.PaletteFechar),
loadSprite(d2resource.CharacterSelecSorceressBackWalkOverlay, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelecSorceressBackWalkOverlay, d2resource.PaletteFechar),
image.Rectangle{Min: image.Point{X: 580, Y: 240}, Max: image.Point{X: 65, Y: 160}}, image.Rectangle{Min: image.Point{X: 580, Y: 240}, Max: image.Point{X: 65, Y: 160}},
loadSoundEffect(d2resource.SFXSorceressSelect), v.loadSoundEffect(d2resource.SFXSorceressSelect),
loadSoundEffect(d2resource.SFXSorceressDeselect), v.loadSoundEffect(d2resource.SFXSorceressDeselect),
} }
v.heroRenderInfo[d2enum.HeroSorceress].IdleSprite.SetPosition(626, 352) v.heroRenderInfo[d2enum.HeroSorceress].IdleSprite.SetPosition(626, 352)
v.heroRenderInfo[d2enum.HeroSorceress].IdleSprite.PlayForward() v.heroRenderInfo[d2enum.HeroSorceress].IdleSprite.PlayForward()
@ -252,8 +256,8 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
loadSprite(d2resource.CharacterSelecNecromancerBackWalk, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelecNecromancerBackWalk, d2resource.PaletteFechar),
loadSprite(d2resource.CharacterSelecNecromancerBackWalkOverlay, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelecNecromancerBackWalkOverlay, d2resource.PaletteFechar),
image.Rectangle{Min: image.Point{X: 265, Y: 220}, Max: image.Point{X: 55, Y: 175}}, image.Rectangle{Min: image.Point{X: 265, Y: 220}, Max: image.Point{X: 55, Y: 175}},
loadSoundEffect(d2resource.SFXNecromancerSelect), v.loadSoundEffect(d2resource.SFXNecromancerSelect),
loadSoundEffect(d2resource.SFXNecromancerDeselect), v.loadSoundEffect(d2resource.SFXNecromancerDeselect),
} }
v.heroRenderInfo[d2enum.HeroNecromancer].IdleSprite.SetPosition(300, 335) v.heroRenderInfo[d2enum.HeroNecromancer].IdleSprite.SetPosition(300, 335)
v.heroRenderInfo[d2enum.HeroNecromancer].IdleSprite.PlayForward() v.heroRenderInfo[d2enum.HeroNecromancer].IdleSprite.PlayForward()
@ -296,8 +300,8 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
loadSprite(d2resource.CharacterSelecPaladinBackWalk, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelecPaladinBackWalk, d2resource.PaletteFechar),
nil, nil,
image.Rectangle{Min: image.Point{X: 490, Y: 210}, Max: image.Point{X: 65, Y: 180}}, image.Rectangle{Min: image.Point{X: 490, Y: 210}, Max: image.Point{X: 65, Y: 180}},
loadSoundEffect(d2resource.SFXPaladinSelect), v.loadSoundEffect(d2resource.SFXPaladinSelect),
loadSoundEffect(d2resource.SFXPaladinDeselect), v.loadSoundEffect(d2resource.SFXPaladinDeselect),
} }
v.heroRenderInfo[d2enum.HeroPaladin].IdleSprite.SetPosition(521, 338) v.heroRenderInfo[d2enum.HeroPaladin].IdleSprite.SetPosition(521, 338)
v.heroRenderInfo[d2enum.HeroPaladin].IdleSprite.PlayForward() v.heroRenderInfo[d2enum.HeroPaladin].IdleSprite.PlayForward()
@ -333,8 +337,8 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
loadSprite(d2resource.CharacterSelecAmazonBackWalk, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelecAmazonBackWalk, d2resource.PaletteFechar),
nil, nil,
image.Rectangle{Min: image.Point{X: 70, Y: 220}, Max: image.Point{X: 55, Y: 200}}, image.Rectangle{Min: image.Point{X: 70, Y: 220}, Max: image.Point{X: 55, Y: 200}},
loadSoundEffect(d2resource.SFXAmazonSelect), v.loadSoundEffect(d2resource.SFXAmazonSelect),
loadSoundEffect(d2resource.SFXAmazonDeselect), v.loadSoundEffect(d2resource.SFXAmazonDeselect),
} }
v.heroRenderInfo[d2enum.HeroAmazon].IdleSprite.SetPosition(100, 339) v.heroRenderInfo[d2enum.HeroAmazon].IdleSprite.SetPosition(100, 339)
v.heroRenderInfo[d2enum.HeroAmazon].IdleSprite.PlayForward() v.heroRenderInfo[d2enum.HeroAmazon].IdleSprite.PlayForward()
@ -365,8 +369,8 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
loadSprite(d2resource.CharacterSelectAssassinBackWalk, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelectAssassinBackWalk, d2resource.PaletteFechar),
nil, nil,
image.Rectangle{Min: image.Point{X: 175, Y: 235}, Max: image.Point{X: 50, Y: 180}}, image.Rectangle{Min: image.Point{X: 175, Y: 235}, Max: image.Point{X: 50, Y: 180}},
loadSoundEffect(d2resource.SFXAssassinSelect), v.loadSoundEffect(d2resource.SFXAssassinSelect),
loadSoundEffect(d2resource.SFXAssassinDeselect), v.loadSoundEffect(d2resource.SFXAssassinDeselect),
} }
v.heroRenderInfo[d2enum.HeroAssassin].IdleSprite.SetPosition(231, 365) v.heroRenderInfo[d2enum.HeroAssassin].IdleSprite.SetPosition(231, 365)
v.heroRenderInfo[d2enum.HeroAssassin].IdleSprite.PlayForward() v.heroRenderInfo[d2enum.HeroAssassin].IdleSprite.PlayForward()
@ -398,8 +402,8 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
loadSprite(d2resource.CharacterSelectDruidBackWalk, d2resource.PaletteFechar), loadSprite(d2resource.CharacterSelectDruidBackWalk, d2resource.PaletteFechar),
nil, nil,
image.Rectangle{Min: image.Point{X: 680, Y: 220}, Max: image.Point{X: 70, Y: 195}}, image.Rectangle{Min: image.Point{X: 680, Y: 220}, Max: image.Point{X: 70, Y: 195}},
loadSoundEffect(d2resource.SFXDruidSelect), v.loadSoundEffect(d2resource.SFXDruidSelect),
loadSoundEffect(d2resource.SFXDruidDeselect), v.loadSoundEffect(d2resource.SFXDruidDeselect),
} }
v.heroRenderInfo[d2enum.HeroDruid].IdleSprite.SetPosition(720, 370) v.heroRenderInfo[d2enum.HeroDruid].IdleSprite.SetPosition(720, 370)
v.heroRenderInfo[d2enum.HeroDruid].IdleSprite.PlayForward() v.heroRenderInfo[d2enum.HeroDruid].IdleSprite.PlayForward()
@ -429,15 +433,15 @@ func (v *SelectHeroClass) OnUnload() error {
return nil return nil
} }
func (v SelectHeroClass) onExitButtonClicked() { func (v *SelectHeroClass) onExitButtonClicked() {
d2screen.SetNextScreen(CreateCharacterSelect(v.connectionType, v.connectionHost)) d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, v.connectionType, v.connectionHost))
} }
func (v SelectHeroClass) onOkButtonClicked() { func (v *SelectHeroClass) onOkButtonClicked() {
gameState := d2player.CreatePlayerState(v.heroNameTextbox.GetText(), v.selectedHero, *d2datadict.CharStats[v.selectedHero], v.hardcoreCheckbox.GetCheckState()) gameState := d2player.CreatePlayerState(v.heroNameTextbox.GetText(), v.selectedHero, *d2datadict.CharStats[v.selectedHero], v.hardcoreCheckbox.GetCheckState())
gameClient, _ := d2client.Create(d2clientconnectiontype.Local) gameClient, _ := d2client.Create(d2clientconnectiontype.Local)
gameClient.Open(v.connectionHost, gameState.FilePath) gameClient.Open(v.connectionHost, gameState.FilePath)
d2screen.SetNextScreen(CreateGame(gameClient)) d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient))
} }
func (v *SelectHeroClass) Render(screen d2render.Surface) error { func (v *SelectHeroClass) Render(screen d2render.Surface) error {
@ -658,7 +662,7 @@ func loadSprite(animationPath, palettePath string) *d2ui.Sprite {
return sprite return sprite
} }
func loadSoundEffect(sfx string) d2audio.SoundEffect { func (v *SelectHeroClass) loadSoundEffect(sfx string) d2interface.SoundEffect {
result, _ := d2audio.LoadSoundEffect(sfx) result, _ := v.audioProvider.LoadSoundEffect(sfx)
return result return result
} }

30
main.go
View File

@ -15,13 +15,15 @@ import (
"strings" "strings"
"sync" "sync"
ebiten2 "github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio/ebiten"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
"github.com/OpenDiablo2/OpenDiablo2/d2common" "github.com/OpenDiablo2/OpenDiablo2/d2common"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource" "github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
ebiten2 "github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio/ebiten"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input" "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
@ -73,7 +75,13 @@ func main() {
log.SetFlags(log.Lshortfile) log.SetFlags(log.Lshortfile)
log.Println("OpenDiablo2 - Open source Diablo 2 engine") log.Println("OpenDiablo2 - Open source Diablo 2 engine")
if err := initialize(); err != nil { // Initialize our providers
audioProvider, err := ebiten2.CreateAudio()
if err != nil {
panic(err)
}
if err := initialize(audioProvider); err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
run(updateInitError) run(updateInitError)
} }
@ -88,7 +96,7 @@ func main() {
} }
if *region == 0 { if *region == 0 {
d2screen.SetNextScreen(d2gamescreen.CreateMainMenu()) d2screen.SetNextScreen(d2gamescreen.CreateMainMenu(audioProvider))
} else { } else {
d2screen.SetNextScreen(d2gamescreen.CreateMapEngineTest(*region, *preset)) d2screen.SetNextScreen(d2gamescreen.CreateMapEngineTest(*region, *preset))
} }
@ -96,7 +104,7 @@ func main() {
run(update) run(update)
} }
func initialize() error { func initialize(audioProvider d2interface.AudioProvider) error {
singleton.timeScale = 1.0 singleton.timeScale = 1.0
singleton.lastTime = d2common.Now() singleton.lastTime = d2common.Now()
singleton.lastScreenAdvance = singleton.lastTime singleton.lastScreenAdvance = singleton.lastTime
@ -181,15 +189,7 @@ func initialize() error {
return err return err
} }
audioProvider, err := ebiten2.CreateAudio() audioProvider.SetVolumes(config.BgmVolume, config.SfxVolume)
if err != nil {
return err
}
if err := d2audio.Initialize(audioProvider); err != nil {
return err
}
d2audio.SetVolumes(config.BgmVolume, config.SfxVolume)
if err := loadDataDict(); err != nil { if err := loadDataDict(); err != nil {
return err return err
@ -201,7 +201,7 @@ func initialize() error {
d2inventory.LoadHeroObjects() d2inventory.LoadHeroObjects()
d2ui.Initialize() d2ui.Initialize(audioProvider)
d2script.CreateScriptEngine() d2script.CreateScriptEngine()