mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-11-17 18:06:03 -05:00
Minor changes to support localized versions.
This commit is contained in:
parent
bf0412554f
commit
da5baec685
98
Common/Sounds.go
Normal file
98
Common/Sounds.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package Common
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/essial/OpenDiablo2/ResourcePaths"
|
||||||
|
)
|
||||||
|
|
||||||
|
// SoundEntry represents a sound entry
|
||||||
|
type SoundEntry struct {
|
||||||
|
Handle string
|
||||||
|
Index int
|
||||||
|
FileName string
|
||||||
|
Volume byte
|
||||||
|
GroupSize uint8
|
||||||
|
Loop bool
|
||||||
|
FadeIn uint8
|
||||||
|
FadeOut uint8
|
||||||
|
DeferInst uint8
|
||||||
|
StopInst uint8
|
||||||
|
Duration uint8
|
||||||
|
Compound int8
|
||||||
|
Reverb bool
|
||||||
|
Falloff uint8
|
||||||
|
Cache uint8
|
||||||
|
AsyncOnly bool
|
||||||
|
Priority uint8
|
||||||
|
Stream uint8
|
||||||
|
Stereo uint8
|
||||||
|
Tracking uint8
|
||||||
|
Solo uint8
|
||||||
|
MusicVol uint8
|
||||||
|
Block1 int
|
||||||
|
Block2 int
|
||||||
|
Block3 int
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateSoundEntry creates a sound entry based on a sound row on sounds.txt
|
||||||
|
func createSoundEntry(soundLine string) SoundEntry {
|
||||||
|
props := strings.Split(soundLine, "\t")
|
||||||
|
result := SoundEntry{
|
||||||
|
Handle: props[0],
|
||||||
|
Index: StringToInt(props[1]),
|
||||||
|
FileName: props[2],
|
||||||
|
Volume: StringToUint8(props[3]),
|
||||||
|
GroupSize: StringToUint8(props[4]),
|
||||||
|
Loop: StringToUint8(props[5]) == 1,
|
||||||
|
FadeIn: StringToUint8(props[6]),
|
||||||
|
FadeOut: StringToUint8(props[7]),
|
||||||
|
DeferInst: StringToUint8(props[8]),
|
||||||
|
StopInst: StringToUint8(props[9]),
|
||||||
|
Duration: StringToUint8(props[10]),
|
||||||
|
Compound: StringToInt8(props[11]),
|
||||||
|
Reverb: StringToUint8(props[12]) == 1,
|
||||||
|
Falloff: StringToUint8(props[13]),
|
||||||
|
Cache: StringToUint8(props[14]),
|
||||||
|
AsyncOnly: StringToUint8(props[15]) == 1,
|
||||||
|
Priority: StringToUint8(props[16]),
|
||||||
|
Stream: StringToUint8(props[17]),
|
||||||
|
Stereo: StringToUint8(props[18]),
|
||||||
|
Tracking: StringToUint8(props[19]),
|
||||||
|
Solo: StringToUint8(props[20]),
|
||||||
|
MusicVol: StringToUint8(props[21]),
|
||||||
|
Block1: StringToInt(props[22]),
|
||||||
|
Block2: StringToInt(props[23]),
|
||||||
|
Block3: StringToInt(props[24]),
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
var Sounds map[string]SoundEntry
|
||||||
|
|
||||||
|
func LoadSounds(fileProvider FileProvider) {
|
||||||
|
Sounds = make(map[string]SoundEntry)
|
||||||
|
soundData := strings.Split(string(fileProvider.LoadFile(ResourcePaths.SoundSettings)), "\r\n")[1:]
|
||||||
|
for _, line := range soundData {
|
||||||
|
if len(line) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
soundEntry := createSoundEntry(line)
|
||||||
|
soundEntry.FileName = "/data/global/sfx/" + strings.ReplaceAll(soundEntry.FileName, `\`, "/")
|
||||||
|
Sounds[soundEntry.Handle] = soundEntry
|
||||||
|
/*
|
||||||
|
// Use the following code to write out the values
|
||||||
|
f, err := os.OpenFile(`C:\Users\lunat\Desktop\D2\sounds.txt`,
|
||||||
|
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
if _, err := f.WriteString("\n[" + soundEntry.Handle + "] " + soundEntry.FileName); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
log.Println("Loaded %d sound definitions", len(Sounds))
|
||||||
|
}
|
@ -25,6 +25,7 @@ import (
|
|||||||
|
|
||||||
// EngineConfig defines the configuration for the engine, loaded from config.json
|
// EngineConfig defines the configuration for the engine, loaded from config.json
|
||||||
type EngineConfig struct {
|
type EngineConfig struct {
|
||||||
|
Language string
|
||||||
FullScreen bool
|
FullScreen bool
|
||||||
Scale float64
|
Scale float64
|
||||||
RunInBackground bool
|
RunInBackground bool
|
||||||
@ -36,12 +37,17 @@ type EngineConfig struct {
|
|||||||
BgmVolume float64
|
BgmVolume float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MpqFileRecord struct {
|
||||||
|
MpqFile string
|
||||||
|
IsPatch bool
|
||||||
|
UnpatchedMpqFile string
|
||||||
|
}
|
||||||
|
|
||||||
// Engine is the core OpenDiablo2 engine
|
// Engine is the core OpenDiablo2 engine
|
||||||
type Engine struct {
|
type Engine struct {
|
||||||
Settings *EngineConfig // Engine configuration settings from json file
|
Settings *EngineConfig // Engine configuration settings from json file
|
||||||
Files map[string]string // Map that defines which files are in which MPQs
|
Files map[string]*MpqFileRecord // Map that defines which files are in which MPQs
|
||||||
Palettes map[Palettes.Palette]Common.Palette // Color palettes
|
Palettes map[Palettes.Palette]Common.Palette // Color palettes
|
||||||
SoundEntries map[string]Sound.SoundEntry // Sound configurations
|
|
||||||
LoadingSprite *Common.Sprite // The sprite shown when loading stuff
|
LoadingSprite *Common.Sprite // The sprite shown when loading stuff
|
||||||
loadingProgress float64 // LoadingProcess is a range between 0.0 and 1.0. If set, loading screen displays.
|
loadingProgress float64 // LoadingProcess is a range between 0.0 and 1.0. If set, loading screen displays.
|
||||||
stepLoadingSize float64 // The size for each loading step
|
stepLoadingSize float64 // The size for each loading step
|
||||||
@ -59,12 +65,13 @@ func CreateEngine() *Engine {
|
|||||||
nextScene: nil,
|
nextScene: nil,
|
||||||
}
|
}
|
||||||
result.loadConfigurationFile()
|
result.loadConfigurationFile()
|
||||||
|
ResourcePaths.LanguageCode = result.Settings.Language
|
||||||
result.mapMpqFiles()
|
result.mapMpqFiles()
|
||||||
result.loadPalettes()
|
result.loadPalettes()
|
||||||
result.loadSoundEntries()
|
|
||||||
Common.LoadTextDictionary(result)
|
Common.LoadTextDictionary(result)
|
||||||
Common.LoadLevelTypes(result)
|
Common.LoadLevelTypes(result)
|
||||||
Common.LoadLevelPresets(result)
|
Common.LoadLevelPresets(result)
|
||||||
|
Common.LoadSounds(result)
|
||||||
result.SoundManager = Sound.CreateManager(result)
|
result.SoundManager = Sound.CreateManager(result)
|
||||||
result.SoundManager.SetVolumes(result.Settings.BgmVolume, result.Settings.SfxVolume)
|
result.SoundManager.SetVolumes(result.Settings.BgmVolume, result.Settings.SfxVolume)
|
||||||
result.UIManager = UI.CreateManager(result, *result.SoundManager)
|
result.UIManager = UI.CreateManager(result, *result.SoundManager)
|
||||||
@ -106,8 +113,7 @@ func (v *Engine) loadConfigurationFile() {
|
|||||||
|
|
||||||
func (v *Engine) mapMpqFiles() {
|
func (v *Engine) mapMpqFiles() {
|
||||||
log.Println("mapping mpq file structure")
|
log.Println("mapping mpq file structure")
|
||||||
v.Files = make(map[string]string)
|
v.Files = make(map[string]*MpqFileRecord)
|
||||||
lock := sync.RWMutex{}
|
|
||||||
for _, mpqFileName := range v.Settings.MpqLoadOrder {
|
for _, mpqFileName := range v.Settings.MpqLoadOrder {
|
||||||
mpqPath := path.Join(v.Settings.MpqPath, mpqFileName)
|
mpqPath := path.Join(v.Settings.MpqPath, mpqFileName)
|
||||||
mpq, err := MPQ.Load(mpqPath)
|
mpq, err := MPQ.Load(mpqPath)
|
||||||
@ -115,16 +121,20 @@ func (v *Engine) mapMpqFiles() {
|
|||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
fileListText, err := mpq.ReadFile("(listfile)")
|
fileListText, err := mpq.ReadFile("(listfile)")
|
||||||
if err != nil {
|
if err != nil || fileListText == nil {
|
||||||
log.Fatal(err)
|
// Super secret patch file activate!
|
||||||
}
|
|
||||||
fileList := strings.Split(string(fileListText), "\r\n")
|
|
||||||
for _, filePath := range fileList {
|
|
||||||
if _, exists := v.Files[strings.ToLower(filePath)]; exists {
|
|
||||||
lock.RUnlock()
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
v.Files[`/`+strings.ReplaceAll(strings.ToLower(filePath), `\`, `/`)] = mpqPath
|
fileList := strings.Split(string(fileListText), "\r\n")
|
||||||
|
|
||||||
|
for _, filePath := range fileList {
|
||||||
|
if _, exists := v.Files[strings.ToLower(filePath)]; exists {
|
||||||
|
if v.Files[strings.ToLower(filePath)].IsPatch {
|
||||||
|
v.Files[strings.ToLower(filePath)].UnpatchedMpqFile = mpqPath
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
v.Files[`/`+strings.ReplaceAll(strings.ToLower(filePath), `\`, `/`)] = &MpqFileRecord{mpqPath, false, ""}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -133,14 +143,38 @@ var mutex sync.Mutex
|
|||||||
|
|
||||||
// LoadFile loads a file from the specified mpq and returns the data as a byte array
|
// LoadFile loads a file from the specified mpq and returns the data as a byte array
|
||||||
func (v *Engine) LoadFile(fileName string) []byte {
|
func (v *Engine) LoadFile(fileName string) []byte {
|
||||||
|
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
||||||
mutex.Lock()
|
mutex.Lock()
|
||||||
// TODO: May want to cache some things if performance becomes an issue
|
// TODO: May want to cache some things if performance becomes an issue
|
||||||
mpqFile := v.Files[strings.ToLower(fileName)]
|
mpqFile := v.Files[strings.ToLower(fileName)]
|
||||||
mpq, err := MPQ.Load(mpqFile)
|
var mpq MPQ.MPQ
|
||||||
|
var err error
|
||||||
|
if mpqFile == nil {
|
||||||
|
// Super secret non-listed file?
|
||||||
|
for _, mpqFile := range v.Settings.MpqLoadOrder {
|
||||||
|
mpqFilePath := path.Join(v.Settings.MpqPath, mpqFile)
|
||||||
|
mpq, err = MPQ.Load(mpqFilePath)
|
||||||
|
newFileName := strings.ReplaceAll(fileName, `/`, `\`)[1:]
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !mpq.FileExists(newFileName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// We found the super-secret file!
|
||||||
|
v.Files[strings.ToLower(fileName)] = &MpqFileRecord{mpqFilePath, false, ""}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else if mpqFile.IsPatch {
|
||||||
|
log.Fatal("Tried to load a patchfile")
|
||||||
|
} else {
|
||||||
|
mpq, err = MPQ.Load(mpqFile.MpqFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error loading file '%s'", fileName)
|
log.Printf("Error loading file '%s'", fileName)
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fileName = strings.ReplaceAll(fileName, `/`, `\`)[1:]
|
fileName = strings.ReplaceAll(fileName, `/`, `\`)[1:]
|
||||||
blockTableEntry, err := mpq.GetFileBlockData(fileName)
|
blockTableEntry, err := mpq.GetFileBlockData(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -173,19 +207,6 @@ func (v *Engine) loadPalettes() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Engine) loadSoundEntries() {
|
|
||||||
log.Println("loading sound configurations")
|
|
||||||
v.SoundEntries = make(map[string]Sound.SoundEntry)
|
|
||||||
soundData := strings.Split(string(v.LoadFile(ResourcePaths.SoundSettings)), "\r\n")[1:]
|
|
||||||
for _, line := range soundData {
|
|
||||||
if len(line) == 0 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
soundEntry := Sound.CreateSoundEntry(line)
|
|
||||||
v.SoundEntries[soundEntry.Handle] = soundEntry
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// LoadSprite loads a sprite from the game's data files
|
// LoadSprite loads a sprite from the game's data files
|
||||||
func (v *Engine) LoadSprite(fileName string, palette Palettes.Palette) *Common.Sprite {
|
func (v *Engine) LoadSprite(fileName string, palette Palettes.Palette) *Common.Sprite {
|
||||||
data := v.LoadFile(fileName)
|
data := v.LoadFile(fileName)
|
||||||
|
21
MPQ/MPQ.go
21
MPQ/MPQ.go
@ -7,6 +7,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/essial/OpenDiablo2/ResourcePaths"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MPQ represents an MPQ archive
|
// MPQ represents an MPQ archive
|
||||||
@ -40,6 +42,13 @@ type HashTableEntry struct { // 16 bytes
|
|||||||
BlockIndex uint32
|
BlockIndex uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PatchInfo struct {
|
||||||
|
Length uint32 // Length of patch info header, in bytes
|
||||||
|
Flags uint32 // Flags. 0x80000000 = MD5 (?)
|
||||||
|
DataSize uint32 // Uncompressed size of the patch file
|
||||||
|
Md5 [16]byte // MD5 of the entire patch file after decompression
|
||||||
|
}
|
||||||
|
|
||||||
// FileFlag represents flags for a file record in the MPQ archive
|
// FileFlag represents flags for a file record in the MPQ archive
|
||||||
type FileFlag uint32
|
type FileFlag uint32
|
||||||
|
|
||||||
@ -216,6 +225,7 @@ func (v MPQ) getFileHashEntry(fileName string) (HashTableEntry, error) {
|
|||||||
|
|
||||||
// GetFileBlockData gets a block table entry
|
// GetFileBlockData gets a block table entry
|
||||||
func (v MPQ) GetFileBlockData(fileName string) (BlockTableEntry, error) {
|
func (v MPQ) GetFileBlockData(fileName string) (BlockTableEntry, error) {
|
||||||
|
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
||||||
fileEntry, err := v.getFileHashEntry(fileName)
|
fileEntry, err := v.getFileHashEntry(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return BlockTableEntry{}, err
|
return BlockTableEntry{}, err
|
||||||
@ -231,11 +241,18 @@ func (v *MPQ) Close() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v MPQ) FileExists(fileName string) bool {
|
||||||
|
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
||||||
|
_, err := v.getFileHashEntry(fileName)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
// ReadFile reads a file from the MPQ and returns a memory stream
|
// ReadFile reads a file from the MPQ and returns a memory stream
|
||||||
func (v MPQ) ReadFile(fileName string) ([]byte, error) {
|
func (v MPQ) ReadFile(fileName string) ([]byte, error) {
|
||||||
|
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
||||||
fileBlockData, err := v.GetFileBlockData(fileName)
|
fileBlockData, err := v.GetFileBlockData(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
fileBlockData.FileName = strings.ToLower(fileName)
|
fileBlockData.FileName = strings.ToLower(fileName)
|
||||||
fileBlockData.calculateEncryptionSeed()
|
fileBlockData.calculateEncryptionSeed()
|
||||||
@ -247,6 +264,7 @@ func (v MPQ) ReadFile(fileName string) ([]byte, error) {
|
|||||||
|
|
||||||
// ReadTextFile reads a file and returns it as a string
|
// ReadTextFile reads a file and returns it as a string
|
||||||
func (v MPQ) ReadTextFile(fileName string) (string, error) {
|
func (v MPQ) ReadTextFile(fileName string) (string, error) {
|
||||||
|
fileName = strings.ReplaceAll(fileName, "{LANG}", ResourcePaths.LanguageCode)
|
||||||
data, err := v.ReadFile(fileName)
|
data, err := v.ReadFile(fileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -270,6 +288,5 @@ func (v MPQ) GetFileList() ([]string, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Printf("File Contents:\n%s", strings.TrimRight(string(data), "\x00"))
|
log.Printf("File Contents:\n%s", strings.TrimRight(string(data), "\x00"))
|
||||||
data = nil
|
|
||||||
return []string{""}, nil
|
return []string{""}, nil
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,10 @@ func CreateStream(mpq MPQ, blockTableEntry BlockTableEntry, fileName string) *St
|
|||||||
}
|
}
|
||||||
result.BlockSize = 0x200 << result.MPQData.Data.BlockSize
|
result.BlockSize = 0x200 << result.MPQData.Data.BlockSize
|
||||||
|
|
||||||
|
if result.BlockTableEntry.HasFlag(FilePatchFile) {
|
||||||
|
log.Fatal("Patching is not supported")
|
||||||
|
}
|
||||||
|
|
||||||
if (result.BlockTableEntry.HasFlag(FileCompress) || result.BlockTableEntry.HasFlag(FileImplode)) && !result.BlockTableEntry.HasFlag(FileSingleUnit) {
|
if (result.BlockTableEntry.HasFlag(FileCompress) || result.BlockTableEntry.HasFlag(FileImplode)) && !result.BlockTableEntry.HasFlag(FileSingleUnit) {
|
||||||
result.loadBlockOffsets()
|
result.loadBlockOffsets()
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package ResourcePaths
|
package ResourcePaths
|
||||||
|
|
||||||
|
var LanguageCode string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// --- Screens ---
|
// --- Screens ---
|
||||||
|
|
||||||
@ -17,7 +19,7 @@ const (
|
|||||||
// --- Credits ---
|
// --- Credits ---
|
||||||
|
|
||||||
CreditsBackground = "/data/global/ui/CharSelect/creditsbckgexpand.dc6"
|
CreditsBackground = "/data/global/ui/CharSelect/creditsbckgexpand.dc6"
|
||||||
CreditsText = "/data/local/ui/eng/ExpansionCredits.txt"
|
CreditsText = "/data/local/ui/{LANG}/ExpansionCredits.txt"
|
||||||
|
|
||||||
// --- Character Select Screen ---
|
// --- Character Select Screen ---
|
||||||
|
|
||||||
@ -156,9 +158,9 @@ const (
|
|||||||
|
|
||||||
// --- Data ---
|
// --- Data ---
|
||||||
|
|
||||||
ExpansionStringTable = "/data/local/lng/eng/expansionstring.tbl"
|
ExpansionStringTable = "/data/local/lng/{LANG}/expansionstring.tbl"
|
||||||
StringTable = "/data/local/lng/eng/string.tbl"
|
StringTable = "/data/local/lng/{LANG}/string.tbl"
|
||||||
PatchStringTable = "/data/local/lng/eng/patchstring.tbl"
|
PatchStringTable = "/data/local/lng/{LANG}/patchstring.tbl"
|
||||||
LevelPreset = "/data/global/excel/LvlPrest.bin"
|
LevelPreset = "/data/global/excel/LvlPrest.bin"
|
||||||
LevelType = "/data/global/excel/LvlTypes.bin"
|
LevelType = "/data/global/excel/LvlTypes.bin"
|
||||||
LevelDetails = "/data/global/excel/Levels.bin"
|
LevelDetails = "/data/global/excel/Levels.bin"
|
||||||
@ -224,21 +226,21 @@ const (
|
|||||||
|
|
||||||
// --- Sound Effects ---
|
// --- Sound Effects ---
|
||||||
|
|
||||||
SFXButtonClick = "/data/global/sfx/Cursor/button.wav"
|
SFXButtonClick = "ESOUND_CURSOR_BUTTON_CLICK"
|
||||||
SFXAmazonDeselect = "/data/global/sfx/Cursor/intro/amazon deselect.wav"
|
SFXAmazonDeselect = "ESOUND_CURSOR_AMAZON_DESELECT"
|
||||||
SFXAmazonSelect = "/data/global/sfx/Cursor/intro/amazon select.wav"
|
SFXAmazonSelect = "ESOUND_CURSOR_AMAZON_SELECT"
|
||||||
SFXAssassinDeselect = "/data/global/sfx/Cursor/intro/assassin deselect.wav"
|
SFXAssassinDeselect = "/data/global/sfx/Cursor/intro/assassin deselect.wav"
|
||||||
SFXAssassinSelect = "/data/global/sfx/Cursor/intro/assassin select.wav"
|
SFXAssassinSelect = "/data/global/sfx/Cursor/intro/assassin select.wav"
|
||||||
SFXBarbarianDeselect = "/data/global/sfx/Cursor/intro/barbarian deselect.wav"
|
SFXBarbarianDeselect = "ESOUND_CURSOR_BARBARIAN_DESELECT"
|
||||||
SFXBarbarianSelect = "/data/global/sfx/Cursor/intro/barbarian select.wav"
|
SFXBarbarianSelect = "ESOUND_CURSOR_BARBARIAN_SELECT"
|
||||||
SFXDruidDeselect = "/data/global/sfx/Cursor/intro/druid deselect.wav"
|
SFXDruidDeselect = "/data/global/sfx/Cursor/intro/druid deselect.wav"
|
||||||
SFXDruidSelect = "/data/global/sfx/Cursor/intro/druid select.wav"
|
SFXDruidSelect = "/data/global/sfx/Cursor/intro/druid select.wav"
|
||||||
SFXNecromancerDeselect = "/data/global/sfx/Cursor/intro/necromancer deselect.wav"
|
SFXNecromancerDeselect = "ESOUND_CURSOR_NECROMANCER_DESELECT"
|
||||||
SFXNecromancerSelect = "/data/global/sfx/Cursor/intro/necromancer select.wav"
|
SFXNecromancerSelect = "ESOUND_CURSOR_NECROMANCER_SELECT"
|
||||||
SFXPaladinDeselect = "/data/global/sfx/Cursor/intro/paladin deselect.wav"
|
SFXPaladinDeselect = "ESOUND_CURSOR_PALADIN_DESELECT"
|
||||||
SFXPaladinSelect = "/data/global/sfx/Cursor/intro/paladin select.wav"
|
SFXPaladinSelect = "ESOUND_CURSOR_PALADIN_SELECT"
|
||||||
SFXSorceressDeselect = "/data/global/sfx/Cursor/intro/sorceress deselect.wav"
|
SFXSorceressDeselect = "ESOUND_CURSOR_SORCERESS_DESELECT"
|
||||||
SFXSorceressSelect = "/data/global/sfx/Cursor/intro/sorceress select.wav"
|
SFXSorceressSelect = "ESOUND_CURSOR_SORCERESS_SELECT"
|
||||||
|
|
||||||
// --- Enemy Data ---
|
// --- Enemy Data ---
|
||||||
|
|
||||||
|
@ -16,8 +16,14 @@ type SoundEffect struct {
|
|||||||
|
|
||||||
func CreateSoundEffect(sfx string, fileProvider Common.FileProvider, context *audio.Context, volume float64) *SoundEffect {
|
func CreateSoundEffect(sfx string, fileProvider Common.FileProvider, context *audio.Context, volume float64) *SoundEffect {
|
||||||
result := &SoundEffect{}
|
result := &SoundEffect{}
|
||||||
|
var soundFile string
|
||||||
audioData := fileProvider.LoadFile(sfx)
|
if _, exists := Common.Sounds[sfx]; exists {
|
||||||
|
soundEntry := Common.Sounds[sfx]
|
||||||
|
soundFile = soundEntry.FileName
|
||||||
|
} else {
|
||||||
|
soundFile = sfx
|
||||||
|
}
|
||||||
|
audioData := fileProvider.LoadFile(soundFile)
|
||||||
d, err := wav.Decode(context, audio.BytesReadSeekCloser(audioData))
|
d, err := wav.Decode(context, audio.BytesReadSeekCloser(audioData))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
package Sound
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/essial/OpenDiablo2/Common"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SoundEntry represents a sound entry
|
|
||||||
type SoundEntry struct {
|
|
||||||
Handle string
|
|
||||||
Index int
|
|
||||||
FileName string
|
|
||||||
Volume byte
|
|
||||||
GroupSize uint8
|
|
||||||
Loop bool
|
|
||||||
FadeIn uint8
|
|
||||||
FadeOut uint8
|
|
||||||
DeferInst uint8
|
|
||||||
StopInst uint8
|
|
||||||
Duration uint8
|
|
||||||
Compound int8
|
|
||||||
Reverb bool
|
|
||||||
Falloff uint8
|
|
||||||
Cache uint8
|
|
||||||
AsyncOnly bool
|
|
||||||
Priority uint8
|
|
||||||
Stream uint8
|
|
||||||
Stereo uint8
|
|
||||||
Tracking uint8
|
|
||||||
Solo uint8
|
|
||||||
MusicVol uint8
|
|
||||||
Block1 int
|
|
||||||
Block2 int
|
|
||||||
Block3 int
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateSoundEntry creates a sound entry based on a sound row on sounds.txt
|
|
||||||
func CreateSoundEntry(soundLine string) SoundEntry {
|
|
||||||
props := strings.Split(soundLine, "\t")
|
|
||||||
result := SoundEntry{
|
|
||||||
Handle: props[0],
|
|
||||||
Index: Common.StringToInt(props[1]),
|
|
||||||
FileName: props[2],
|
|
||||||
Volume: Common.StringToUint8(props[3]),
|
|
||||||
GroupSize: Common.StringToUint8(props[4]),
|
|
||||||
Loop: Common.StringToUint8(props[5]) == 1,
|
|
||||||
FadeIn: Common.StringToUint8(props[6]),
|
|
||||||
FadeOut: Common.StringToUint8(props[7]),
|
|
||||||
DeferInst: Common.StringToUint8(props[8]),
|
|
||||||
StopInst: Common.StringToUint8(props[9]),
|
|
||||||
Duration: Common.StringToUint8(props[10]),
|
|
||||||
Compound: Common.StringToInt8(props[11]),
|
|
||||||
Reverb: Common.StringToUint8(props[12]) == 1,
|
|
||||||
Falloff: Common.StringToUint8(props[13]),
|
|
||||||
Cache: Common.StringToUint8(props[14]),
|
|
||||||
AsyncOnly: Common.StringToUint8(props[15]) == 1,
|
|
||||||
Priority: Common.StringToUint8(props[16]),
|
|
||||||
Stream: Common.StringToUint8(props[17]),
|
|
||||||
Stereo: Common.StringToUint8(props[18]),
|
|
||||||
Tracking: Common.StringToUint8(props[19]),
|
|
||||||
Solo: Common.StringToUint8(props[20]),
|
|
||||||
MusicVol: Common.StringToUint8(props[21]),
|
|
||||||
Block1: Common.StringToInt(props[22]),
|
|
||||||
Block2: Common.StringToInt(props[23]),
|
|
||||||
Block3: Common.StringToInt(props[24]),
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
|
"Language": "ENG",
|
||||||
"FullScreen": false,
|
"FullScreen": false,
|
||||||
"Scale": 1,
|
"Scale": 1,
|
||||||
"TicksPerSecond": 60,
|
"TicksPerSecond": 60,
|
||||||
@ -8,6 +9,7 @@
|
|||||||
"BgmVolume": 0.3,
|
"BgmVolume": 0.3,
|
||||||
"MpqPath": "C:/Program Files (x86)/Diablo II",
|
"MpqPath": "C:/Program Files (x86)/Diablo II",
|
||||||
"MpqLoadOrder": [
|
"MpqLoadOrder": [
|
||||||
|
"Patch_D2.mpq",
|
||||||
"d2exp.mpq",
|
"d2exp.mpq",
|
||||||
"d2xmusic.mpq",
|
"d2xmusic.mpq",
|
||||||
"d2xtalk.mpq",
|
"d2xtalk.mpq",
|
||||||
|
Loading…
Reference in New Issue
Block a user