mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-01-14 21:36:40 -05:00
Added audio streaming capabilities (#471)
This commit is contained in:
parent
c6721432a6
commit
490c00b7b2
@ -273,17 +273,37 @@ func (v *MPQ) ReadFile(fileName string) ([]byte, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
fileBlockData.FileName = strings.ToLower(fileName)
|
fileBlockData.FileName = strings.ToLower(fileName)
|
||||||
|
|
||||||
fileBlockData.calculateEncryptionSeed()
|
fileBlockData.calculateEncryptionSeed()
|
||||||
mpqStream, err := CreateStream(v, fileBlockData, fileName)
|
mpqStream, err := CreateStream(v, fileBlockData, fileName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer := make([]byte, fileBlockData.UncompressedFileSize)
|
buffer := make([]byte, fileBlockData.UncompressedFileSize)
|
||||||
mpqStream.Read(buffer, 0, fileBlockData.UncompressedFileSize)
|
mpqStream.Read(buffer, 0, fileBlockData.UncompressedFileSize)
|
||||||
return buffer, nil
|
return buffer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *MPQ) ReadFileStream(fileName string) (*MpqDataStream, error) {
|
||||||
|
fileBlockData, err := v.getFileBlockData(fileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fileBlockData.FileName = strings.ToLower(fileName)
|
||||||
|
fileBlockData.calculateEncryptionSeed()
|
||||||
|
|
||||||
|
mpqStream, err := CreateStream(v, fileBlockData, fileName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &MpqDataStream{stream: mpqStream}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
data, err := v.ReadFile(fileName)
|
data, err := v.ReadFile(fileName)
|
||||||
@ -303,7 +323,7 @@ func (v *BlockTableEntry) calculateEncryptionSeed() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetFileList returns the list of files in this MPQ
|
// GetFileList returns the list of files in this MPQ
|
||||||
func (v * MPQ) GetFileList() ([]string, error) {
|
func (v *MPQ) GetFileList() ([]string, error) {
|
||||||
data, err := v.ReadFile("(listfile)")
|
data, err := v.ReadFile("(listfile)")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
20
d2common/d2fileformats/d2mpq/mpq_data_stream.go
Normal file
20
d2common/d2fileformats/d2mpq/mpq_data_stream.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package d2mpq
|
||||||
|
|
||||||
|
type MpqDataStream struct {
|
||||||
|
stream *Stream
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MpqDataStream) Read(p []byte) (n int, err error) {
|
||||||
|
totalRead := m.stream.Read(p, 0, uint32(len(p)))
|
||||||
|
return int(totalRead), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MpqDataStream) Seek(offset int64, whence int) (int64, error) {
|
||||||
|
m.stream.CurrentPosition = uint32(offset + int64(whence))
|
||||||
|
return int64(m.stream.CurrentPosition), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MpqDataStream) Close() error {
|
||||||
|
m.stream = nil
|
||||||
|
return nil
|
||||||
|
}
|
@ -86,7 +86,7 @@ func (v *Stream) Read(buffer []byte, offset, count uint32) uint32 {
|
|||||||
toRead := count
|
toRead := count
|
||||||
readTotal := uint32(0)
|
readTotal := uint32(0)
|
||||||
for toRead > 0 {
|
for toRead > 0 {
|
||||||
read := v.readInternal(buffer, offset, count)
|
read := v.readInternal(buffer, offset, toRead)
|
||||||
if read == 0 {
|
if read == 0 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,17 @@ func LoadArchive(archivePath string) (*d2mpq.MPQ, error) {
|
|||||||
return singleton.archiveManager.loadArchive(archivePath)
|
return singleton.archiveManager.loadArchive(archivePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadFileStream(filePath string) (*d2mpq.MpqDataStream, error) {
|
||||||
|
verifyWasInit()
|
||||||
|
|
||||||
|
data, err := singleton.fileManager.loadFileStream(filePath)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error loading file stream %s (%v)", filePath, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
|
||||||
func LoadFile(filePath string) ([]byte, error) {
|
func LoadFile(filePath string) ([]byte, error) {
|
||||||
verifyWasInit()
|
verifyWasInit()
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package d2asset
|
package d2asset
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
@ -22,6 +23,18 @@ func createFileManager(config d2config.Configuration, archiveManager *archiveMan
|
|||||||
return &fileManager{d2common.CreateCache(fileBudget), archiveManager, config}
|
return &fileManager{d2common.CreateCache(fileBudget), archiveManager, config}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (fm *fileManager) loadFileStream(filePath string) (*d2mpq.MpqDataStream, error) {
|
||||||
|
filePath = fm.fixupFilePath(filePath)
|
||||||
|
|
||||||
|
archive, err := fm.archiveManager.loadArchiveForFile(filePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return archive.ReadFileStream(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
func (fm *fileManager) loadFile(filePath string) ([]byte, error) {
|
func (fm *fileManager) loadFile(filePath string) ([]byte, error) {
|
||||||
filePath = fm.fixupFilePath(filePath)
|
filePath = fm.fixupFilePath(filePath)
|
||||||
if value, found := fm.cache.Retrieve(filePath); found {
|
if value, found := fm.cache.Retrieve(filePath); found {
|
||||||
|
@ -32,9 +32,7 @@ func Initialize(audioProvider AudioProvider) error {
|
|||||||
// PlayBGM plays an infinitely looping background track
|
// PlayBGM plays an infinitely looping background track
|
||||||
func PlayBGM(song string) error {
|
func PlayBGM(song string) error {
|
||||||
verifyWasInit()
|
verifyWasInit()
|
||||||
go func() {
|
|
||||||
singleton.PlayBGM(song)
|
singleton.PlayBGM(song)
|
||||||
}()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,11 +45,11 @@ func (eap *AudioProvider) PlayBGM(song string) {
|
|||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
audioData, err := d2asset.LoadFile(song)
|
audioStream, err := d2asset.LoadFileStream(song)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
d, err := wav.Decode(eap.audioContext, audio.BytesReadSeekCloser(audioData))
|
d, err := wav.Decode(eap.audioContext, audioStream)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user