1
1
mirror of https://github.com/OpenDiablo2/OpenDiablo2 synced 2024-12-27 04:26:29 -05:00

Added audio streaming capabilities (#471)

This commit is contained in:
Tim Sarbin 2020-06-27 02:49:27 -04:00 committed by GitHub
parent c6721432a6
commit 490c00b7b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 69 additions and 7 deletions

View File

@ -273,17 +273,37 @@ func (v *MPQ) ReadFile(fileName string) ([]byte, error) {
if err != nil {
return []byte{}, err
}
fileBlockData.FileName = strings.ToLower(fileName)
fileBlockData.calculateEncryptionSeed()
mpqStream, err := CreateStream(v, fileBlockData, fileName)
if err != nil {
return []byte{}, err
}
buffer := make([]byte, fileBlockData.UncompressedFileSize)
mpqStream.Read(buffer, 0, fileBlockData.UncompressedFileSize)
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
func (v *MPQ) ReadTextFile(fileName string) (string, error) {
data, err := v.ReadFile(fileName)
@ -303,7 +323,7 @@ func (v *BlockTableEntry) calculateEncryptionSeed() {
}
// 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)")
if err != nil {
return nil, err

View 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
}

View File

@ -86,7 +86,7 @@ func (v *Stream) Read(buffer []byte, offset, count uint32) uint32 {
toRead := count
readTotal := uint32(0)
for toRead > 0 {
read := v.readInternal(buffer, offset, count)
read := v.readInternal(buffer, offset, toRead)
if read == 0 {
break
}

View File

@ -80,6 +80,17 @@ func LoadArchive(archivePath string) (*d2mpq.MPQ, error) {
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) {
verifyWasInit()

View File

@ -1,6 +1,7 @@
package d2asset
import (
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
"strings"
"github.com/OpenDiablo2/OpenDiablo2/d2common"
@ -22,6 +23,18 @@ func createFileManager(config d2config.Configuration, archiveManager *archiveMan
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) {
filePath = fm.fixupFilePath(filePath)
if value, found := fm.cache.Retrieve(filePath); found {

View File

@ -32,9 +32,7 @@ func Initialize(audioProvider AudioProvider) error {
// PlayBGM plays an infinitely looping background track
func PlayBGM(song string) error {
verifyWasInit()
go func() {
singleton.PlayBGM(song)
}()
singleton.PlayBGM(song)
return nil
}

View File

@ -45,11 +45,11 @@ func (eap *AudioProvider) PlayBGM(song string) {
log.Panic(err)
}
}
audioData, err := d2asset.LoadFile(song)
audioStream, err := d2asset.LoadFileStream(song)
if err != nil {
panic(err)
}
d, err := wav.Decode(eap.audioContext, audio.BytesReadSeekCloser(audioData))
d, err := wav.Decode(eap.audioContext, audioStream)
if err != nil {
log.Fatal(err)
}