greed/CODE/MODLOAD.C

516 lines
14 KiB
C
Raw Permalink Normal View History

2014-12-12 00:00:00 +00:00
/****************************************************************************
*
* Digital Sound Interface Kit (DSIK)
* Version 2.00
*
* by Carlos Hasan
*
* Filename: modload.c
* Version: Revision 1.0
*
* Language: WATCOM C
* Environment: IBM PC (DOS/4GW)
*
* Description: File loading routines for module and sample files.
*
* Revision History:
* ----------------
*
* Revision 1.0 94/09/24 16:57:58 chv
* Initial revision
*
****************************************************************************/
#include <io.h>
#include <fcntl.h>
#include <malloc.h>
#include "d_global.h"
#include "audio.h"
int dError;
char *dErrorMsg[] = {
"Ok",
"Invalid or unsupported file format",
"Unable to open file",
"File is corrupted",
"Not enough system memory",
"Not enough soundcard memory" };
/****************************************************************************
*
* Function: LoadSample
* Parameters: Handle - file handle
* Length - sample block length
*
* Returns: Sample structure containing the WAVE digital sample
* or NULL when an error has occurred.
*
* Description: Used to load RIFF/DSMF sample blocks.
*
****************************************************************************/
static Sample *LoadSample(int Handle, long Length)
{
Sample *SampPtr;
void *DataPtr;
if (!(SampPtr = (Sample*)malloc(sizeof(Sample)))) {
dError = ERR_NOMEM;
return NULL;
}
if (read(Handle,SampPtr,sizeof(Sample)) != sizeof(Sample)) {
dError = ERR_FILEIO;
free(SampPtr);
return NULL;
}
if (!SampPtr->Length || (SampPtr->Flags & SF_LIBRARY)) {
SampPtr->DataPtr = NULL;
return SampPtr;
}
if (!(DataPtr = SampPtr->DataPtr = malloc(SampPtr->Length))) {
dError = ERR_NOMEM;
free(SampPtr);
return NULL;
}
if (read(Handle,SampPtr->DataPtr,SampPtr->Length) != SampPtr->Length) {
dError = ERR_FILEIO;
free(DataPtr);
free(SampPtr);
return NULL;
}
if (!dMemAlloc(SampPtr)) {
dError = ERR_NODRAM;
free(DataPtr);
free(SampPtr);
return NULL;
}
if (dGetDriverFlags() & AF_DRAM) {
free(DataPtr);
}
if (!(SampPtr->Flags & SF_LOOPED)) {
SampPtr->LoopStart = SampPtr->LoopEnd = SampPtr->Length;
}
return SampPtr;
}
/****************************************************************************
*
* Function: FreeSample
* Parameters: SampPtr - Sample structure pointer
*
* Description: Releases memory used by digital samples.
*
****************************************************************************/
static void FreeSample(Sample *SampPtr)
{
if (SampPtr) {
if (SampPtr->DataPtr && !(SampPtr->Flags & SF_LIBRARY)) {
dMemFree(SampPtr);
if (!(dGetDriverFlags() & AF_DRAM))
free(SampPtr->DataPtr);
}
free(SampPtr);
}
}
/****************************************************************************
*
* Function: LoadPattern
* Parameters: Handle - file handle
* Length - RIFF pattern block length
*
* Returns: Pattern structure containing the music pattern data
* or NULL when an error has occurred.
*
* Description: Used to load RIFF/DSMF pattern blocks.
*
****************************************************************************/
static Pattern *LoadPattern(int Handle, long Length)
{
Pattern *PattPtr;
if (!(PattPtr = (Pattern*)malloc(Length))) {
dError = ERR_NOMEM;
return NULL;
}
if (read(Handle,PattPtr,Length) != Length) {
dError = ERR_FILEIO;
free(PattPtr);
return NULL;
}
return PattPtr;
}
/****************************************************************************
*
* Function: FreePattern
* Parameters: PattPtr - pattern data pointer
*
* Description: Releases memory used by the patterns.
*
****************************************************************************/
static void FreePattern(Pattern *PattPtr)
{
if (PattPtr) free(PattPtr);
}
/****************************************************************************
*
* Function: dLoadModuleFile
* Parameters: Handle - DOS file handle
* Length - file length
*
* Returns: Music module address or NULL when an error has occurred
* while loading the file.
*
* Description: Load RIFF/DSMF music modules from disk.
*
****************************************************************************/
DSM *dLoadModuleFile(int Handle, long Length)
{
RiffHeader Header;
RiffBlock Block;
DSM *Module;
int SampNum, PattNum;
if (!(Module = (DSM*)calloc(1,sizeof(DSM)))) {
dError = ERR_NOMEM;
return NULL;
}
SampNum = PattNum = 0;
if (read(Handle,&Header,sizeof(Header)) != sizeof(Header)) {
dError = ERR_FILEIO;
dFreeModule(Module);
return NULL;
}
if (Header.ID != ID_RIFF || Header.Type != ID_DSMF) {
dError = ERR_FORMAT;
dFreeModule(Module);
return NULL;
}
Header.Length -= sizeof(Header.Type);
if ((sizeof(Header) + Header.Length) > Length) {
dError = ERR_FORMAT;
dFreeModule(Module);
return NULL;
}
while (Header.Length) {
if (read(Handle,&Block,sizeof(Block)) != sizeof(Block)) {
dError = ERR_FILEIO;
dFreeModule(Module);
return NULL;
}
Header.Length -= sizeof(Block) + Block.Length;
if (Block.ID == ID_SONG) {
if (read(Handle,&Module->Header,Block.Length) != Block.Length) {
dError = ERR_FILEIO;
dFreeModule(Module);
return NULL;
}
Module->Samples = (Sample**)calloc(Module->Header.NumSamples,sizeof(Sample *));
Module->Patterns = (Pattern**)calloc(Module->Header.NumPatterns,sizeof(Pattern *));
if (!Module->Samples || !Module->Patterns) {
dError = ERR_NOMEM;
dFreeModule(Module);
return NULL;
}
}
else if (Block.ID == ID_INST) {
if (SampNum >= Module->Header.NumSamples) {
dError = ERR_FORMAT;
dFreeModule(Module);
return NULL;
}
if (!(Module->Samples[SampNum++] =
LoadSample(Handle,Block.Length))) {
dFreeModule(Module);
return NULL;
}
}
else if (Block.ID == ID_PATT) {
if (PattNum >= Module->Header.NumPatterns) {
dError = ERR_FORMAT;
dFreeModule(Module);
return NULL;
}
if (!(Module->Patterns[PattNum++] =
LoadPattern(Handle,Block.Length))) {
dFreeModule(Module);
return NULL;
}
}
else {
if (lseek(Handle,Block.Length,SEEK_CUR) < 0) {
dError = ERR_FILEIO;
dFreeModule(Module);
return NULL;
}
}
}
return Module;
}
/****************************************************************************
*
* Function: dFreeModule
* Parameters: Module - music module pointer
*
* Description: Releases all the resources used by the music module.
*
****************************************************************************/
void dFreeModule(DSM *Module)
{
int Index;
if (Module) {
if (Module->Samples) {
for (Index = 0; Index < Module->Header.NumSamples; Index++)
if (Module->Samples[Index])
FreeSample(Module->Samples[Index]);
free(Module->Samples);
}
if (Module->Patterns) {
for (Index = 0; Index < Module->Header.NumPatterns; Index++)
if (Module->Patterns[Index])
FreePattern(Module->Patterns[Index]);
free(Module->Patterns);
}
free(Module);
}
}
/****************************************************************************
*
* Function: dLoadSampleFile
* Parameters: Handle - file handle
* Length - sample length
*
* Returns: Sample structure containing the WAVE digital sample
* or NULL when an error has occurred.
*
* Description: Used to load RIFF/WAVE sample files.
*
****************************************************************************/
Sample *dLoadSampleFile(int Handle, long Length)
{
Sample *SampPtr;
void *DataPtr;
struct {
RiffHeader Hdr;
RiffBlock Fmt;
WaveFmt F;
RiffBlock Data;
} Wave;
if (read(Handle,&Wave,sizeof(Wave)) != sizeof(Wave)) {
dError = ERR_FILEIO;
return NULL;
}
if (Wave.Hdr.ID!=ID_RIFF || Wave.Hdr.Type!=ID_WAVE ||
Wave.Fmt.ID!=ID_FMT || Wave.Data.ID!=ID_DATA ||
Wave.F.Format!=WAVE_FMT_PCM || Wave.F.Channels!=1 || Wave.F.BitsPerSample!=8)
{
dError=ERR_FORMAT;
return NULL;
}
if (sizeof(RiffBlock)+Wave.Hdr.Length>Length)
{
Wave.Data.Length=Length-sizeof(Wave);
Wave.Hdr.Length=sizeof(Wave);
}
if (!(SampPtr=(Sample*)calloc(1,sizeof(Sample))))
{
dError=ERR_NOMEM;
return NULL;
}
SampPtr->Flags=SF_8BITS | SF_UNSIGNED;
SampPtr->Volume=64;
SampPtr->Length=SampPtr->LoopStart=SampPtr->LoopEnd=Wave.Data.Length;
SampPtr->DataPtr=NULL;
SampPtr->Rate=Wave.F.SampleRate;
if (!SampPtr->Length)
{
return SampPtr;
}
DataPtr=malloc(SampPtr->Length);
if (!DataPtr)
{
dError=ERR_NOMEM;
free(SampPtr);
return NULL;
}
SampPtr->DataPtr=DataPtr;
if (read(Handle,DataPtr,SampPtr->Length)!=SampPtr->Length)
{
dError=ERR_FILEIO;
free(DataPtr);
free(SampPtr);
return NULL;
}
if (!dMemAlloc(SampPtr))
{
dError=ERR_NODRAM;
free(DataPtr);
free(SampPtr);
return NULL;
}
if (dGetDriverFlags()&AF_DRAM)
{
free(DataPtr);
}
return SampPtr;
}
/****************************************************************************
*
* Function: dFreeSample
* Parameters: SampPtr - Sample pointer
*
* Description: Releases the memory used by a WAVE sample.
*
****************************************************************************/
void dFreeSample(Sample *SampPtr)
{
FreeSample(SampPtr);
}
/****************************************************************************
*
* Function: dLoadModule
* Parameters: Filename - music module path filename
*
* Returns: Music module address or NULL when an error has occurred
* while loading the file.
*
* Description: Load RIFF/DSMF music modules from disk.
*
****************************************************************************/
DSM *dLoadModule(char *Filename)
{
int Handle;
long Length;
DSM *Module;
if ((Handle = open(Filename,O_RDONLY|O_BINARY)) < 0) {
dError = ERR_NOFILE;
return NULL;
}
if ((Length = filelength(Handle)) < 0) {
dError = ERR_FILEIO;
close(Handle);
return NULL;
}
Module = dLoadModuleFile(Handle,Length);
close(Handle);
return Module;
}
/****************************************************************************
*
* Function: dLoadSample
* Parameters: Filename - music module path filename
*
* Returns: Music module address or NULL when an error has occurred
* while loading the file.
*
* Description: Load RIFF/WAVE sample files from disk.
*
****************************************************************************/
Sample *dLoadSample(char *Filename)
{
int Handle;
long Length;
Sample *SampPtr;
if ((Handle = open(Filename,O_RDONLY|O_BINARY)) < 0) {
dError = ERR_NOFILE;
return NULL;
}
if ((Length = filelength(Handle)) < 0) {
dError = ERR_FILEIO;
close(Handle);
return NULL;
}
SampPtr = dLoadSampleFile(Handle,Length);
close(Handle);
return SampPtr;
}
/****************************************************************************
*
* Function: dLoadSetup
* Parameters: SC - soundcard structure
* Filename - full config path filename
*
* Returns: Zero value on success.
*
* Description: Load the soundcard configuration parameters.
*
****************************************************************************/
int dLoadSetup(SoundCard *SC, char *Filename)
{
int Handle;
if ((Handle = open(Filename,O_RDONLY|O_BINARY)) < 0)
return 1;
if (read(Handle,SC,sizeof(SoundCard)) != sizeof(SoundCard)) {
close(Handle);
return 1;
}
close(Handle);
return 0;
}
/****************************************************************************
*
* Function: dSaveSetup
* Parameters: SC - soundcard structure
* Filename - full config path filename
*
* Returns: Zero value on success.
*
* Description: Save the soundcard configuration parameters.
*
****************************************************************************/
int dSaveSetup(SoundCard *SC, char *Filename)
{
int Handle;
if ((Handle = open(Filename,O_CREAT|O_WRONLY|O_BINARY,S_IRWXU)) < 0)
return 1;
if (write(Handle,SC,sizeof(SoundCard)) != sizeof(SoundCard)) {
close(Handle);
return 1;
}
close(Handle);
return 0;
}