wrote a simple wave loader to remove dependency on a private openal function.
This commit is contained in:
parent
0e484b73da
commit
71204923ad
2 changed files with 172 additions and 114 deletions
12
Makefile
12
Makefile
|
@ -8,10 +8,10 @@ CFLAGS = -g -Wall -pipe -O2
|
|||
CFLAGS += -DLINUX
|
||||
|
||||
CFLAGS += -Dengine=1 -I. -Iinclude -Iwin95 -Iavp -Iavp/win95 -Iavp/support -Iavp/win95/frontend -Iavp/win95/gadgets
|
||||
CFLAGS += $(shell sdl-config --cflags)
|
||||
CFLAGS += $(shell sdl-config --cflags) $(shell openal-config --cflags)
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
|
||||
LDLIBS = $(shell sdl-config --libs) -lopenal
|
||||
LDLIBS = $(shell sdl-config --libs) $(shell openal-config --libs)
|
||||
|
||||
ROOT = main.c files.c winapi.c stubs.c version.c mathline.c opengl.c oglfunc.c openal.c cdplayer.c menus.c net.c frustum.c kshape.c map.c maths.c md5.c mem3dc.c mem3dcpp.cpp module.c morph.c object.c shpanim.c sphere.c tables.c vdb.c
|
||||
AVP = ai_sight.c avpview.c bh_agun.c bh_ais.c bh_alien.c bh_binsw.c bh_cable.c bh_corpse.c bh_deathvol.c bh_debri.c bh_dummy.c bh_fan.c bh_far.c bh_fhug.c bh_gener.c bh_ldoor.c bh_lift.c bh_light.c bh_lnksw.c bh_ltfx.c bh_marin.c bh_mission.c bh_near.c bh_pargen.c bh_plachier.c bh_plift.c bh_pred.c bh_queen.c bh_rubberduck.c bh_selfdest.c bh_snds.c bh_spcl.c bh_swdor.c bh_track.c bh_types.c bh_videoscreen.c bh_waypt.c bh_weap.c bh_xeno.c bonusabilities.c cconvars.cpp cdtrackselection.cpp cheatmodes.c comp_map.c comp_shp.c consolelog.cpp davehook.cpp deaths.c decal.c detaillevels.c dynamics.c dynblock.c equipmnt.c equiputl.cpp extents.c game.c game_statistics.c gamecmds.cpp gamevars.cpp hmodel.c hud.c inventry.c language.c lighting.c load_shp.c los.c maps.c mempool.c messagehistory.c missions.cpp movement.c paintball.c particle.c pfarlocs.c pheromon.c player.c pmove.c psnd.c psndproj.c pvisible.c savegame.c scream.cpp secstats.c sfx.c stratdef.c targeting.c track.c triggers.c weapons.c
|
||||
|
@ -48,15 +48,15 @@ WIN95OBJ = $(call OBJNAMES,$(WIN95),win95)
|
|||
SRC = $(ROOTSRC) $(AVPSRC) $(SHAPESSRC) $(SUPPORTSRC) $(AVPWIN95SRC) $(FRONTENDSRC) $(GADGETSSRC) $(WIN95SRC)
|
||||
OBJ = $(ROOTOBJ) $(AVPOBJ) $(SHAPESOBJ) $(SUPPORTOBJ) $(AVPWIN95OBJ) $(FRONTENDOBJ) $(GADGETSOBJ) $(WIN95OBJ)
|
||||
|
||||
all: AvP
|
||||
all: AvP.bin
|
||||
|
||||
AvP: $(OBJ) # depend $(OBJ)
|
||||
$(CXX) -o AvP $(OBJ) $(LDLIBS)
|
||||
AvP.bin: $(OBJ) # depend $(OBJ)
|
||||
$(CXX) -o AvP.bin $(OBJ) $(LDLIBS)
|
||||
|
||||
compile: $(OBJ)
|
||||
|
||||
clean:
|
||||
-rm -rf depend depend.bak $(OBJ) AvP
|
||||
-rm -rf depend depend.bak $(OBJ) AvP.bin
|
||||
|
||||
distclean: clean
|
||||
-rm -rf `find . -name "*~"`
|
||||
|
|
274
src/openal.c
274
src/openal.c
|
@ -5,9 +5,6 @@
|
|||
|
||||
#include <AL/al.h>
|
||||
#include <AL/alc.h>
|
||||
#include <AL/alut.h>
|
||||
|
||||
#include <SDL/SDL_audio.h> // For a few defines (AUDIO_*)
|
||||
|
||||
#include "fixer.h"
|
||||
|
||||
|
@ -35,6 +32,112 @@ extern int WantSound;
|
|||
|
||||
static int SoundActivated = 0;
|
||||
|
||||
/* start simplistic riff wave parsing */
|
||||
#define lsb8 (buf, x) (((unsigned int)buf[(x)+0] << 0))
|
||||
#define lsb16(buf, x) (((unsigned int)buf[(x)+0] << 0) | ((unsigned int)buf[(x)+1] << 8))
|
||||
#define lsb32(buf, x) (((unsigned int)buf[(x)+0] << 0) | ((unsigned int)buf[(x)+1] << 8) | ((unsigned int)buf[(x)+2] << 16) | ((unsigned int)buf[(x)+3] << 24))
|
||||
|
||||
typedef struct FormatChunk {
|
||||
short wFormatTag;
|
||||
unsigned short wChannels;
|
||||
unsigned long dwSamplesPerSec;
|
||||
unsigned long dwAvgBytesPerSec;
|
||||
unsigned short wBlockAlign;
|
||||
unsigned short wBitsPerSample;
|
||||
} FormatChunk;
|
||||
|
||||
typedef struct DataChunk {
|
||||
unsigned char* pData;
|
||||
unsigned int dwLength;
|
||||
} DataChunk;
|
||||
|
||||
static int ParseWAV( const unsigned char* data, unsigned char** pFmtPtr, unsigned char** pDataPtr )
|
||||
{
|
||||
unsigned char* pData;
|
||||
unsigned char* pDataEnd;
|
||||
unsigned char* fmtPtr;
|
||||
int riffLength;
|
||||
int chunkLength;
|
||||
|
||||
if( data == NULL || pFmtPtr == NULL || pDataPtr == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* assuming input data is complete and not corrupt... */
|
||||
|
||||
pData = (unsigned char*) data;
|
||||
|
||||
/* bytes 0-3 are the RIFF groupId */
|
||||
if( pData[ 0 ] != 'R' || pData[ 1 ] != 'I' || pData[ 2 ] != 'F' || pData[ 3 ] != 'F' ) {
|
||||
/* bad group id */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* bytes 4-7 are the RIFF length. */
|
||||
riffLength = lsb32( pData, 4 );
|
||||
|
||||
pDataEnd = pData + 8 + riffLength;
|
||||
|
||||
if( pData[ 8 ] != 'W' || pData[ 9 ] != 'A' || pData[ 10 ] != 'V' || pData[ 11 ] != 'E' ) {
|
||||
/* bad riff type */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* all valid wave files have the 'fmt ' chunk before the 'data' chunk. */
|
||||
|
||||
/* skip passed the initial header. */
|
||||
pData += 12;
|
||||
|
||||
/* look for the 'fmt ' and 'data' chunks. */
|
||||
fmtPtr = NULL;
|
||||
|
||||
while( pData+8 < pDataEnd ) {
|
||||
|
||||
chunkLength = lsb32( pData, 4 );
|
||||
|
||||
if( fmtPtr == NULL && pData[ 0 ] == 'f' && pData[ 1 ] == 'm' && pData[ 2 ] == 't' && pData[ 3 ] == ' ' ) {
|
||||
fmtPtr = pData;
|
||||
} else if( fmtPtr != NULL && pData[ 0 ] == 'd' && pData[ 1 ] == 'a' && pData[ 2 ] == 't' && pData[ 3 ] == 'a' ) {
|
||||
|
||||
*pFmtPtr = fmtPtr;
|
||||
*pDataPtr = pData;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
pData += 8 + chunkLength;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int SimpleLoadWAV( const unsigned char* data, FormatChunk* pFmtChunk, DataChunk* pDataChunk)
|
||||
{
|
||||
unsigned char* fmtPtr;
|
||||
unsigned char* dataPtr;
|
||||
|
||||
if( data == NULL || pFmtChunk == NULL || pDataChunk == NULL ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( !ParseWAV( data, &fmtPtr, &dataPtr ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pFmtChunk->wFormatTag = lsb16( fmtPtr, 8 );
|
||||
pFmtChunk->wChannels = lsb16( fmtPtr, 10 );
|
||||
pFmtChunk->dwSamplesPerSec = lsb32( fmtPtr, 12 );
|
||||
pFmtChunk->dwAvgBytesPerSec = lsb32( fmtPtr, 16 );
|
||||
pFmtChunk->wBlockAlign = lsb16( fmtPtr, 20 );
|
||||
pFmtChunk->wBitsPerSample = lsb16( fmtPtr, 22 );
|
||||
|
||||
pDataChunk->pData = &dataPtr[ 8 ];
|
||||
pDataChunk->dwLength = lsb32( dataPtr, 4 );
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* end simplistic riff wave parsing */
|
||||
|
||||
/*
|
||||
openal.c TODO:
|
||||
1. There is no EAX/Reverb. But there's probably not much I can do...
|
||||
|
@ -821,29 +924,54 @@ void UpdateSoundFrequencies()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// In libopenal
|
||||
extern void *acLoadWAV (void *data, ALuint *size, void **udata,
|
||||
ALushort *fmt, ALushort *chan, ALushort *freq);
|
||||
|
||||
|
||||
static unsigned char *Force8to16 (unsigned char *buf, int *len)
|
||||
static int LoadWAV( ALvoid* data, ALvoid** bufferPtr, ALushort* format, ALushort* freq, int* len, int* seclen )
|
||||
{
|
||||
unsigned char *nbuf;
|
||||
unsigned int i;
|
||||
|
||||
nbuf = (unsigned char *) AllocateMem (*len * 2);
|
||||
|
||||
for (i = 0; i < *len; i++) {
|
||||
short int x = ((buf[i] << 8) | buf[i]) ^ 0x8000;
|
||||
nbuf[i*2+0] = (x & 0x00ff);
|
||||
nbuf[i*2+1] = (x >> 8) & 0xff;
|
||||
FormatChunk fmtChunk;
|
||||
DataChunk dataChunk;
|
||||
|
||||
if( !SimpleLoadWAV( (unsigned char*)data, &fmtChunk, &dataChunk ) ) {
|
||||
printf("WAV DEBUG: file didn't parse\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*len *= 2;
|
||||
return nbuf;
|
||||
if( fmtChunk.wFormatTag != 1 ) {
|
||||
printf("WAV DEBUG: got format tag %d\n", fmtChunk.wFormatTag );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( fmtChunk.wBitsPerSample == 8 ) {
|
||||
if( fmtChunk.wChannels == 1 ) {
|
||||
*format = AL_FORMAT_MONO8;
|
||||
} else if( fmtChunk.wChannels == 2 ) {
|
||||
*format = AL_FORMAT_STEREO8;
|
||||
} else {
|
||||
printf("WAV DEBUG: too many channels\n" );
|
||||
return 0;
|
||||
}
|
||||
} else if( fmtChunk.wBitsPerSample == 16 ) {
|
||||
if( fmtChunk.wChannels == 1 ) {
|
||||
*format = AL_FORMAT_MONO16;
|
||||
} else if( fmtChunk.wChannels == 2 ) {
|
||||
*format = AL_FORMAT_STEREO16;
|
||||
} else {
|
||||
printf("WAV DEBUG: too many channels\n" );
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
printf("WAV DEBUG: bad bit setup\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*freq = fmtChunk.dwSamplesPerSec;
|
||||
*len = dataChunk.dwLength;
|
||||
*bufferPtr = dataChunk.pData;
|
||||
|
||||
*seclen = DIV_FIXED( dataChunk.dwLength, fmtChunk.dwAvgBytesPerSec );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int LoadWavFile(int soundNum, char * wavFileName)
|
||||
{
|
||||
ALuint size;
|
||||
|
@ -851,7 +979,8 @@ int LoadWavFile(int soundNum, char * wavFileName)
|
|||
ALvoid *data, *bufferPtr;
|
||||
int len, seclen;
|
||||
FILE *fp;
|
||||
|
||||
char* wavname;
|
||||
|
||||
#ifdef OPENAL_DEBUG
|
||||
fprintf(stderr, "LoadWavFile(%d, %s) - sound\n", soundNum, wavFileName);
|
||||
#endif
|
||||
|
@ -872,57 +1001,22 @@ int LoadWavFile(int soundNum, char * wavFileName)
|
|||
fread(data, 1, len, fp);
|
||||
fclose(fp);
|
||||
|
||||
if (acLoadWAV (data, &size, &bufferPtr, &format,
|
||||
&chan, &freq) == NULL) {
|
||||
fprintf(stderr, "LoadWavFile: Unable to convert data\n");
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(data);
|
||||
|
||||
data = bufferPtr;
|
||||
|
||||
len = size;
|
||||
|
||||
/* openal conv. 8->16 is not good at all */
|
||||
if (format == AUDIO_U8) {
|
||||
unsigned char *nb = Force8to16 (data, &len);
|
||||
format = AUDIO_S16LSB;
|
||||
|
||||
free (data);
|
||||
data = nb;
|
||||
}
|
||||
|
||||
if ((format == AUDIO_S16LSB) || (format == AUDIO_S16MSB)) {
|
||||
int bps;
|
||||
|
||||
if (chan == 2) {
|
||||
format = AL_FORMAT_STEREO16;
|
||||
bps = freq * 2 * 2;
|
||||
} /* else if (rchan == 1) */ {
|
||||
format = AL_FORMAT_MONO16;
|
||||
bps = freq * 2 * 1;
|
||||
}
|
||||
|
||||
seclen = DIV_FIXED(len, bps);
|
||||
} else {
|
||||
free(data);
|
||||
if( !LoadWAV( data, &bufferPtr, &format, &len, &seclen, &freq ) ) {
|
||||
free( data );
|
||||
return 0;
|
||||
}
|
||||
|
||||
alGenBuffers (1, &(GameSounds[soundNum].dsBufferP));
|
||||
alBufferData (GameSounds[soundNum].dsBufferP, format, data, len, freq);
|
||||
alBufferData (GameSounds[soundNum].dsBufferP, format, bufferPtr, len, freq);
|
||||
|
||||
{
|
||||
char * wavname = strrchr (wavFileName, '\\');
|
||||
wavname = strrchr (wavFileName, '\\');
|
||||
if (wavname)
|
||||
wavname++;
|
||||
else
|
||||
wavname = wavFileName;
|
||||
GameSounds[soundNum].wavName = (char *)AllocateMem (strlen (wavname) + 1);
|
||||
strcpy (GameSounds[soundNum].wavName, wavname);
|
||||
}
|
||||
|
||||
GameSounds[soundNum].flags = SAMPLE_IN_HW;
|
||||
GameSounds[soundNum].length = (seclen != 0) ? seclen : 1;
|
||||
GameSounds[soundNum].dsFrequency = freq;
|
||||
|
@ -957,58 +1051,22 @@ fprintf(stderr, "OPENAL: ExtractWavFile(%d, %p)\n", soundIndex, bufferPtr);
|
|||
fprintf(stderr, "OPENAL: Loaded %s\n", GameSounds[soundIndex].wavName);
|
||||
#endif
|
||||
|
||||
#if 1 /* TODO: replace with own routine later */
|
||||
if (acLoadWAV (bufferPtr, &rsize, &udata, &rfmt,
|
||||
&rchan, &rfreq) == NULL) {
|
||||
fprintf(stderr, "ExtractWavFile: Unable to convert data\n");
|
||||
return NULL;
|
||||
if( LoadWAV( bufferPtr, &udata, &rfmt, &len, &seclen, &rfreq ) ) {
|
||||
alGenBuffers (1, &(GameSounds[soundIndex].dsBufferP));
|
||||
alBufferData (GameSounds[soundIndex].dsBufferP,
|
||||
rfmt, udata, len, rfreq);
|
||||
|
||||
/* GameSounds[soundIndex].loaded = 1; */
|
||||
GameSounds[soundIndex].flags = SAMPLE_IN_HW;
|
||||
GameSounds[soundIndex].length = (seclen != 0) ? seclen : 1;
|
||||
GameSounds[soundIndex].dsFrequency = rfreq;
|
||||
/* GameSounds[soundIndex].pitch = PITCH_DEFAULTPLAT; */
|
||||
}
|
||||
|
||||
len = rsize;
|
||||
|
||||
/* openal conv. 8->16 is not good at all */
|
||||
if (rfmt == AUDIO_U8) {
|
||||
unsigned char *nb = Force8to16 (udata, &len);
|
||||
rfmt = AUDIO_S16LSB;
|
||||
|
||||
free (udata);
|
||||
udata = nb;
|
||||
}
|
||||
|
||||
if ((rfmt == AUDIO_S16LSB) || (rfmt == AUDIO_S16MSB)) {
|
||||
int bps;
|
||||
|
||||
if (rchan == 2) {
|
||||
rfmt = AL_FORMAT_STEREO16;
|
||||
bps = rfreq * 2 * 2;
|
||||
} /* else if (rchan == 1) */ {
|
||||
rfmt = AL_FORMAT_MONO16;
|
||||
bps = rfreq * 2 * 1;
|
||||
}
|
||||
|
||||
seclen = DIV_FIXED(len, bps);
|
||||
} else
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
alGenBuffers (1, &(GameSounds[soundIndex].dsBufferP));
|
||||
alBufferData (GameSounds[soundIndex].dsBufferP,
|
||||
rfmt, udata, len, rfreq);
|
||||
|
||||
/* GameSounds[soundIndex].loaded = 1; */
|
||||
GameSounds[soundIndex].flags = SAMPLE_IN_HW;
|
||||
GameSounds[soundIndex].length = (seclen != 0) ? seclen : 1;
|
||||
GameSounds[soundIndex].dsFrequency = rfreq;
|
||||
/* GameSounds[soundIndex].pitch = PITCH_DEFAULTPLAT; */
|
||||
|
||||
#if 1 /* TODO: see above */
|
||||
free (udata);
|
||||
|
||||
/* read RIFF chunk length and jump past it */
|
||||
return bufferPtr + 8 +
|
||||
((bufferPtr[4] << 0) | (bufferPtr[5] << 8) |
|
||||
(bufferPtr[6] << 16) | (bufferPtr[7] << 24));
|
||||
#endif
|
||||
}
|
||||
|
||||
int LoadWavFromFastFile(int soundNum, char * wavFileName)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue