Cleanup audio IO

This commit is contained in:
Alexander Batalov 2022-12-26 11:48:47 +03:00
parent 1b0cd6d757
commit a05ab09e1b
5 changed files with 120 additions and 104 deletions

View File

@ -9,36 +9,52 @@
#include "memory_manager.h" #include "memory_manager.h"
#include "pointer_registry.h" #include "pointer_registry.h"
#include "sound.h" #include "sound.h"
#include "sound_decoder.h"
namespace fallout { namespace fallout {
static bool _defaultCompressionFunc(char* filePath); typedef enum AudioFlags {
AUDIO_IN_USE = 0x01,
AUDIO_COMPRESSED = 0x02,
} AudioFileFlags;
typedef struct Audio {
int flags;
int stream;
SoundDecoder* soundDecoder;
int fileSize;
int sampleRate;
int channels;
int position;
} Audio;
static bool defaultCompressionFunc(char* filePath);
static int audioSoundDecoderReadHandler(int fileHandle, void* buf, unsigned int size); static int audioSoundDecoderReadHandler(int fileHandle, void* buf, unsigned int size);
// 0x5108BC // 0x5108BC
static AudioFileIsCompressedProc* _queryCompressedFunc = _defaultCompressionFunc; static AudioQueryCompressedFunc* queryCompressedFunc = defaultCompressionFunc;
// 0x56CB00 // 0x56CB00
static int gAudioListLength; static int gAudioListLength;
// 0x56CB04 // 0x56CB04
static AudioFile* gAudioList; static Audio* gAudioList;
// 0x41A2B0 // 0x41A2B0
static bool _defaultCompressionFunc(char* filePath) static bool defaultCompressionFunc(char* filePath)
{ {
char* pch = strrchr(filePath, '.'); char* pch = strrchr(filePath, '.');
if (pch != NULL) { if (pch != NULL) {
strcpy(pch + 1, "war"); strcpy(pch + 1, "raw");
} }
return false; return false;
} }
// 0x41A2D0 // 0x41A2D0
static int audioSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned int size) static int audioSoundDecoderReadHandler(int handle, void* buffer, unsigned int size)
{ {
return fileRead(buffer, 1, size, (File*)intToPtr(fileHandle)); return fileRead(buffer, 1, size, (File*)intToPtr(handle));
} }
// AudioOpen // AudioOpen
@ -49,7 +65,7 @@ int audioOpen(const char* fname, int flags, ...)
snprintf(path, sizeof(path), "%s", fname); snprintf(path, sizeof(path), "%s", fname);
int compression; int compression;
if (_queryCompressedFunc(path)) { if (queryCompressedFunc(path)) {
compression = 2; compression = 2;
} else { } else {
compression = 0; compression = 0;
@ -84,27 +100,27 @@ int audioOpen(const char* fname, int flags, ...)
int index; int index;
for (index = 0; index < gAudioListLength; index++) { for (index = 0; index < gAudioListLength; index++) {
if ((gAudioList[index].flags & AUDIO_FILE_IN_USE) == 0) { if ((gAudioList[index].flags & AUDIO_IN_USE) == 0) {
break; break;
} }
} }
if (index == gAudioListLength) { if (index == gAudioListLength) {
if (gAudioList != NULL) { if (gAudioList != NULL) {
gAudioList = (AudioFile*)internal_realloc_safe(gAudioList, sizeof(*gAudioList) * (gAudioListLength + 1), __FILE__, __LINE__); // "..\int\audio.c", 216 gAudioList = (Audio*)internal_realloc_safe(gAudioList, sizeof(*gAudioList) * (gAudioListLength + 1), __FILE__, __LINE__); // "..\int\audio.c", 216
} else { } else {
gAudioList = (AudioFile*)internal_malloc_safe(sizeof(*gAudioList), __FILE__, __LINE__); // "..\int\audio.c", 218 gAudioList = (Audio*)internal_malloc_safe(sizeof(*gAudioList), __FILE__, __LINE__); // "..\int\audio.c", 218
} }
gAudioListLength++; gAudioListLength++;
} }
AudioFile* audioFile = &(gAudioList[index]); Audio* audioFile = &(gAudioList[index]);
audioFile->flags = AUDIO_FILE_IN_USE; audioFile->flags = AUDIO_IN_USE;
audioFile->fileHandle = ptrToInt(stream); audioFile->stream = ptrToInt(stream);
if (compression == 2) { if (compression == 2) {
audioFile->flags |= AUDIO_FILE_COMPRESSED; audioFile->flags |= AUDIO_COMPRESSED;
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize)); audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->fileSize *= 2; audioFile->fileSize *= 2;
} else { } else {
audioFile->fileSize = fileGetSize(stream); audioFile->fileSize = fileGetSize(stream);
@ -116,30 +132,30 @@ int audioOpen(const char* fname, int flags, ...)
} }
// 0x41A50C // 0x41A50C
int audioClose(int fileHandle) int audioClose(int handle)
{ {
AudioFile* audioFile = &(gAudioList[fileHandle - 1]); Audio* audioFile = &(gAudioList[handle - 1]);
fileClose((File*)intToPtr(audioFile->fileHandle, true)); fileClose((File*)intToPtr(audioFile->stream, true));
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) { if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
soundDecoderFree(audioFile->soundDecoder); soundDecoderFree(audioFile->soundDecoder);
} }
memset(audioFile, 0, sizeof(AudioFile)); memset(audioFile, 0, sizeof(Audio));
return 0; return 0;
} }
// 0x41A574 // 0x41A574
int audioRead(int fileHandle, void* buffer, unsigned int size) int audioRead(int handle, void* buffer, unsigned int size)
{ {
AudioFile* audioFile = &(gAudioList[fileHandle - 1]); Audio* audioFile = &(gAudioList[handle - 1]);
int bytesRead; int bytesRead;
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) { if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
bytesRead = soundDecoderDecode(audioFile->soundDecoder, buffer, size); bytesRead = soundDecoderDecode(audioFile->soundDecoder, buffer, size);
} else { } else {
bytesRead = fileRead(buffer, 1, size, (File*)intToPtr(audioFile->fileHandle)); bytesRead = fileRead(buffer, 1, size, (File*)intToPtr(audioFile->stream));
} }
audioFile->position += bytesRead; audioFile->position += bytesRead;
@ -148,13 +164,13 @@ int audioRead(int fileHandle, void* buffer, unsigned int size)
} }
// 0x41A5E0 // 0x41A5E0
long audioSeek(int fileHandle, long offset, int origin) long audioSeek(int handle, long offset, int origin)
{ {
int pos; int pos;
unsigned char* buf; unsigned char* buf;
int v10; int v10;
AudioFile* audioFile = &(gAudioList[fileHandle - 1]); Audio* audioFile = &(gAudioList[handle - 1]);
switch (origin) { switch (origin) {
case SEEK_SET: case SEEK_SET:
@ -170,11 +186,11 @@ long audioSeek(int fileHandle, long offset, int origin)
assert(false && "Should be unreachable"); assert(false && "Should be unreachable");
} }
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) { if ((audioFile->flags & AUDIO_COMPRESSED) != 0) {
if (pos < audioFile->position) { if (pos < audioFile->position) {
soundDecoderFree(audioFile->soundDecoder); soundDecoderFree(audioFile->soundDecoder);
fileSeek((File*)intToPtr(audioFile->fileHandle), 0, SEEK_SET); fileSeek((File*)intToPtr(audioFile->stream), 0, SEEK_SET);
audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize)); audioFile->soundDecoder = soundDecoderInit(audioSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->position = 0; audioFile->position = 0;
audioFile->fileSize *= 2; audioFile->fileSize *= 2;
@ -182,11 +198,11 @@ long audioSeek(int fileHandle, long offset, int origin)
buf = (unsigned char*)internal_malloc_safe(4096, __FILE__, __LINE__); // "..\int\audio.c", 361 buf = (unsigned char*)internal_malloc_safe(4096, __FILE__, __LINE__); // "..\int\audio.c", 361
while (pos > 4096) { while (pos > 4096) {
pos -= 4096; pos -= 4096;
audioRead(fileHandle, buf, 4096); audioRead(handle, buf, 4096);
} }
if (pos != 0) { if (pos != 0) {
audioRead(fileHandle, buf, pos); audioRead(handle, buf, pos);
} }
internal_free_safe(buf, __FILE__, __LINE__); // // "..\int\audio.c", 367 internal_free_safe(buf, __FILE__, __LINE__); // // "..\int\audio.c", 367
@ -196,11 +212,11 @@ long audioSeek(int fileHandle, long offset, int origin)
v10 = audioFile->position - pos; v10 = audioFile->position - pos;
while (v10 > 1024) { while (v10 > 1024) {
v10 -= 1024; v10 -= 1024;
audioRead(fileHandle, buf, 1024); audioRead(handle, buf, 1024);
} }
if (v10 != 0) { if (v10 != 0) {
audioRead(fileHandle, buf, v10); audioRead(handle, buf, v10);
} }
// TODO: Probably leaks memory. // TODO: Probably leaks memory.
@ -208,21 +224,21 @@ long audioSeek(int fileHandle, long offset, int origin)
return audioFile->position; return audioFile->position;
} else { } else {
return fileSeek((File*)intToPtr(audioFile->fileHandle), offset, origin); return fileSeek((File*)intToPtr(audioFile->stream), offset, origin);
} }
} }
// 0x41A78C // 0x41A78C
long audioGetSize(int fileHandle) long audioGetSize(int handle)
{ {
AudioFile* audioFile = &(gAudioList[fileHandle - 1]); Audio* audioFile = &(gAudioList[handle - 1]);
return audioFile->fileSize; return audioFile->fileSize;
} }
// 0x41A7A8 // 0x41A7A8
long audioTell(int fileHandle) long audioTell(int handle)
{ {
AudioFile* audioFile = &(gAudioList[fileHandle - 1]); Audio* audioFile = &(gAudioList[handle - 1]);
return audioFile->position; return audioFile->position;
} }
@ -235,9 +251,9 @@ int audioWrite(int handle, const void* buf, unsigned int size)
} }
// 0x41A7D4 // 0x41A7D4
int audioInit(AudioFileIsCompressedProc* isCompressedProc) int audioInit(AudioQueryCompressedFunc* func)
{ {
_queryCompressedFunc = isCompressedProc; queryCompressedFunc = func;
gAudioList = NULL; gAudioList = NULL;
gAudioListLength = 0; gAudioListLength = 0;

View File

@ -1,18 +1,18 @@
#ifndef AUDIO_H #ifndef AUDIO_H
#define AUDIO_H #define AUDIO_H
#include "audio_file.h"
namespace fallout { namespace fallout {
typedef bool(AudioQueryCompressedFunc)(char* filePath);
int audioOpen(const char* fname, int mode, ...); int audioOpen(const char* fname, int mode, ...);
int audioClose(int fileHandle); int audioClose(int handle);
int audioRead(int fileHandle, void* buffer, unsigned int size); int audioRead(int handle, void* buffer, unsigned int size);
long audioSeek(int fileHandle, long offset, int origin); long audioSeek(int handle, long offset, int origin);
long audioGetSize(int fileHandle); long audioGetSize(int handle);
long audioTell(int fileHandle); long audioTell(int handle);
int audioWrite(int handle, const void* buf, unsigned int size); int audioWrite(int handle, const void* buf, unsigned int size);
int audioInit(AudioFileIsCompressedProc* isCompressedProc); int audioInit(AudioQueryCompressedFunc* func);
void audioExit(); void audioExit();
} // namespace fallout } // namespace fallout

View File

@ -9,14 +9,30 @@
#include "platform_compat.h" #include "platform_compat.h"
#include "pointer_registry.h" #include "pointer_registry.h"
#include "sound.h" #include "sound.h"
#include "sound_decoder.h"
namespace fallout { namespace fallout {
static bool _defaultCompressionFunc__(char* filePath); typedef enum AudioFileFlags {
static int audioFileSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned int size); AUDIO_FILE_IN_USE = 0x01,
AUDIO_FILE_COMPRESSED = 0x02,
} AudioFileFlags;
typedef struct AudioFile {
int flags;
int stream;
SoundDecoder* soundDecoder;
int fileSize;
int sampleRate;
int channels;
int position;
} AudioFile;
static bool defaultCompressionFunc(char* filePath);
static int audioFileSoundDecoderReadHandler(int handle, void* buffer, unsigned int size);
// 0x5108C0 // 0x5108C0
static AudioFileIsCompressedProc* _queryCompressedFunc_2 = _defaultCompressionFunc__; static AudioFileQueryCompressedFunc* queryCompressedFunc = defaultCompressionFunc;
// 0x56CB10 // 0x56CB10
static AudioFile* gAudioFileList; static AudioFile* gAudioFileList;
@ -25,20 +41,20 @@ static AudioFile* gAudioFileList;
static int gAudioFileListLength; static int gAudioFileListLength;
// 0x41A850 // 0x41A850
static bool _defaultCompressionFunc__(char* filePath) static bool defaultCompressionFunc(char* filePath)
{ {
char* pch = strrchr(filePath, '.'); char* pch = strrchr(filePath, '.');
if (pch != NULL) { if (pch != NULL) {
strcpy(pch + 1, "war"); strcpy(pch + 1, "raw");
} }
return false; return false;
} }
// 0x41A870 // 0x41A870
static int audioFileSoundDecoderReadHandler(int fileHandle, void* buffer, unsigned int size) static int audioFileSoundDecoderReadHandler(int handle, void* buffer, unsigned int size)
{ {
return fread(buffer, 1, size, (FILE*)intToPtr(fileHandle)); return fread(buffer, 1, size, (FILE*)intToPtr(handle));
} }
// 0x41A88C // 0x41A88C
@ -48,7 +64,7 @@ int audioFileOpen(const char* fname, int flags, ...)
strcpy(path, fname); strcpy(path, fname);
int compression; int compression;
if (_queryCompressedFunc_2(path)) { if (queryCompressedFunc(path)) {
compression = 2; compression = 2;
} else { } else {
compression = 0; compression = 0;
@ -98,11 +114,11 @@ int audioFileOpen(const char* fname, int flags, ...)
AudioFile* audioFile = &(gAudioFileList[index]); AudioFile* audioFile = &(gAudioFileList[index]);
audioFile->flags = AUDIO_FILE_IN_USE; audioFile->flags = AUDIO_FILE_IN_USE;
audioFile->fileHandle = ptrToInt(stream); audioFile->stream = ptrToInt(stream);
if (compression == 2) { if (compression == 2) {
audioFile->flags |= AUDIO_FILE_COMPRESSED; audioFile->flags |= AUDIO_FILE_COMPRESSED;
audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize)); audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->fileSize *= 2; audioFile->fileSize *= 2;
} else { } else {
audioFile->fileSize = getFileSize(stream); audioFile->fileSize = getFileSize(stream);
@ -114,10 +130,10 @@ int audioFileOpen(const char* fname, int flags, ...)
} }
// 0x41AAA0 // 0x41AAA0
int audioFileClose(int fileHandle) int audioFileClose(int handle)
{ {
AudioFile* audioFile = &(gAudioFileList[fileHandle - 1]); AudioFile* audioFile = &(gAudioFileList[handle - 1]);
fclose((FILE*)intToPtr(audioFile->fileHandle, true)); fclose((FILE*)intToPtr(audioFile->stream, true));
if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) { if ((audioFile->flags & AUDIO_FILE_COMPRESSED) != 0) {
soundDecoderFree(audioFile->soundDecoder); soundDecoderFree(audioFile->soundDecoder);
@ -130,16 +146,16 @@ int audioFileClose(int fileHandle)
} }
// 0x41AB08 // 0x41AB08
int audioFileRead(int fileHandle, void* buffer, unsigned int size) int audioFileRead(int handle, void* buffer, unsigned int size)
{ {
AudioFile* ptr = &(gAudioFileList[fileHandle - 1]); AudioFile* ptr = &(gAudioFileList[handle - 1]);
int bytesRead; int bytesRead;
if ((ptr->flags & AUDIO_FILE_COMPRESSED) != 0) { if ((ptr->flags & AUDIO_FILE_COMPRESSED) != 0) {
bytesRead = soundDecoderDecode(ptr->soundDecoder, buffer, size); bytesRead = soundDecoderDecode(ptr->soundDecoder, buffer, size);
} else { } else {
bytesRead = fread(buffer, 1, size, (FILE*)intToPtr(ptr->fileHandle)); bytesRead = fread(buffer, 1, size, (FILE*)intToPtr(ptr->stream));
} }
ptr->position += bytesRead; ptr->position += bytesRead;
@ -148,13 +164,13 @@ int audioFileRead(int fileHandle, void* buffer, unsigned int size)
} }
// 0x41AB74 // 0x41AB74
long audioFileSeek(int fileHandle, long offset, int origin) long audioFileSeek(int handle, long offset, int origin)
{ {
void* buf; void* buf;
int remaining; int remaining;
int a4; int a4;
AudioFile* audioFile = &(gAudioFileList[fileHandle - 1]); AudioFile* audioFile = &(gAudioFileList[handle - 1]);
switch (origin) { switch (origin) {
case SEEK_SET: case SEEK_SET:
@ -174,20 +190,20 @@ long audioFileSeek(int fileHandle, long offset, int origin)
if (a4 <= audioFile->position) { if (a4 <= audioFile->position) {
soundDecoderFree(audioFile->soundDecoder); soundDecoderFree(audioFile->soundDecoder);
fseek((FILE*)intToPtr(audioFile->fileHandle), 0, 0); fseek((FILE*)intToPtr(audioFile->stream), 0, 0);
audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->fileHandle, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize)); audioFile->soundDecoder = soundDecoderInit(audioFileSoundDecoderReadHandler, audioFile->stream, &(audioFile->channels), &(audioFile->sampleRate), &(audioFile->fileSize));
audioFile->fileSize *= 2; audioFile->fileSize *= 2;
audioFile->position = 0; audioFile->position = 0;
if (a4) { if (a4) {
buf = internal_malloc_safe(4096, __FILE__, __LINE__); // "..\int\audiof.c", 364 buf = internal_malloc_safe(4096, __FILE__, __LINE__); // "..\int\audiof.c", 364
while (a4 > 4096) { while (a4 > 4096) {
audioFileRead(fileHandle, buf, 4096); audioFileRead(handle, buf, 4096);
a4 -= 4096; a4 -= 4096;
} }
if (a4 != 0) { if (a4 != 0) {
audioFileRead(fileHandle, buf, a4); audioFileRead(handle, buf, a4);
} }
internal_free_safe(buf, __FILE__, __LINE__); // "..\int\audiof.c", 370 internal_free_safe(buf, __FILE__, __LINE__); // "..\int\audiof.c", 370
} }
@ -195,46 +211,46 @@ long audioFileSeek(int fileHandle, long offset, int origin)
buf = internal_malloc_safe(0x400, __FILE__, __LINE__); // "..\int\audiof.c", 316 buf = internal_malloc_safe(0x400, __FILE__, __LINE__); // "..\int\audiof.c", 316
remaining = audioFile->position - a4; remaining = audioFile->position - a4;
while (remaining > 1024) { while (remaining > 1024) {
audioFileRead(fileHandle, buf, 1024); audioFileRead(handle, buf, 1024);
remaining -= 1024; remaining -= 1024;
} }
if (remaining != 0) { if (remaining != 0) {
audioFileRead(fileHandle, buf, remaining); audioFileRead(handle, buf, remaining);
} }
// TODO: Obiously leaks memory. // TODO: Obiously leaks memory.
} }
return audioFile->position; return audioFile->position;
} }
return fseek((FILE*)intToPtr(audioFile->fileHandle), offset, origin); return fseek((FILE*)intToPtr(audioFile->stream), offset, origin);
} }
// 0x41AD20 // 0x41AD20
long audioFileGetSize(int fileHandle) long audioFileGetSize(int handle)
{ {
AudioFile* audioFile = &(gAudioFileList[fileHandle - 1]); AudioFile* audioFile = &(gAudioFileList[handle - 1]);
return audioFile->fileSize; return audioFile->fileSize;
} }
// 0x41AD3C // 0x41AD3C
long audioFileTell(int fileHandle) long audioFileTell(int handle)
{ {
AudioFile* audioFile = &(gAudioFileList[fileHandle - 1]); AudioFile* audioFile = &(gAudioFileList[handle - 1]);
return audioFile->position; return audioFile->position;
} }
// AudiofWrite // AudiofWrite
// 0x41AD58 // 0x41AD58
int audioFileWrite(int fileHandle, const void* buffer, unsigned int size) int audioFileWrite(int handle, const void* buffer, unsigned int size)
{ {
debugPrint("AudiofWrite shouldn't be ever called\n"); debugPrint("AudiofWrite shouldn't be ever called\n");
return 0; return 0;
} }
// 0x41AD68 // 0x41AD68
int audioFileInit(AudioFileIsCompressedProc* isCompressedProc) int audioFileInit(AudioFileQueryCompressedFunc* func)
{ {
_queryCompressedFunc_2 = isCompressedProc; queryCompressedFunc = func;
gAudioFileList = NULL; gAudioFileList = NULL;
gAudioFileListLength = 0; gAudioFileListLength = 0;

View File

@ -1,35 +1,18 @@
#ifndef AUDIO_FILE_H #ifndef AUDIO_FILE_H
#define AUDIO_FILE_H #define AUDIO_FILE_H
#include "sound_decoder.h"
namespace fallout { namespace fallout {
typedef enum AudioFileFlags { typedef bool(AudioFileQueryCompressedFunc)(char* filePath);
AUDIO_FILE_IN_USE = 0x01,
AUDIO_FILE_COMPRESSED = 0x02,
} AudioFileFlags;
typedef struct AudioFile {
int flags;
int fileHandle;
SoundDecoder* soundDecoder;
int fileSize;
int sampleRate;
int channels;
int position;
} AudioFile;
typedef bool(AudioFileIsCompressedProc)(char* filePath);
int audioFileOpen(const char* fname, int flags, ...); int audioFileOpen(const char* fname, int flags, ...);
int audioFileClose(int a1); int audioFileClose(int handle);
int audioFileRead(int a1, void* buf, unsigned int size); int audioFileRead(int handle, void* buf, unsigned int size);
long audioFileSeek(int handle, long offset, int origin); long audioFileSeek(int handle, long offset, int origin);
long audioFileGetSize(int a1); long audioFileGetSize(int handle);
long audioFileTell(int a1); long audioFileTell(int handle);
int audioFileWrite(int handle, const void* buf, unsigned int size); int audioFileWrite(int handle, const void* buf, unsigned int size);
int audioFileInit(AudioFileIsCompressedProc* isCompressedProc); int audioFileInit(AudioFileQueryCompressedFunc* func);
void audioFileExit(); void audioFileExit();
} // namespace fallout } // namespace fallout

View File

@ -6,6 +6,7 @@
#include "animation.h" #include "animation.h"
#include "art.h" #include "art.h"
#include "audio.h" #include "audio.h"
#include "audio_file.h"
#include "combat.h" #include "combat.h"
#include "debug.h" #include "debug.h"
#include "game_config.h" #include "game_config.h"