home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C++ Games Programming
/
CPPGAMES.ISO
/
thx
/
source
/
utils
/
sfxplay.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-12
|
8KB
|
396 lines
#include <fstream.h>
#include <iomanip.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <dos.h>
#include <dir.h>
#include <alloc.h>
#include <string.h>
#include <io.h>
#include <values.h>
#include <fcntl.h>
const int TRUE = 1;
const int FALSE = 0;
const int MAX = 100;
struct clip_info
{
long size;
char huge * data;
};
static clip_info clip[MAX];
void list_entries(char* libname,int count);
int find_and_load_driver();
int load_driver();
void init_driver();
void set_port(unsigned port);
void set_status_flag(char* ptr);
void terminate_driver();
void play_clip(char huge *data);
void print_version();
void stop_clip();
unsigned port;
unsigned hdma,ldma;
int playing;
char* realptr;
char* driverptr;
int main(int argc,char** argv)
{
int i;
unsigned long mem_used;
//-----------------------------------------------------
// check for two arguments
if (argc<2)
{
cout << "\nUSAGE : SFXPLAY <sfxlib>\n";
cout << " SFXPLAY is a utility which loads an SFX (sound effects)\n";
cout << " library, and allows the user to sample the entries.\n";
cout << " The SFX file should have first been created with SFXMAKE.\n";
return -1;
}
//--------------------------------------------------------
// make sure library exists
if (access(argv[1],0)!=0)
{
cout << "can't find sfx file '" << argv[1] << "'\n";
return -1;
}
//--------------------------------------------------------
// set up the sound card
cout << "looking for sound card...\n";
int sound_supported=find_and_load_driver();
if (sound_supported)
{
init_driver();
set_port(port);
set_status_flag((char*)&playing);
cout << "sound card detected...\n";
}
else
{
cout << "sound card NOT detected...\n";
return -1;
}
//---------------------------------------------------------
// read the sfx library
int handle;
if (_dos_open(argv[1],O_RDONLY,&handle) != 0)
{
cerr << "No file named " << argv[1];
exit(1);
}
int count;
long size;
char far *buf;
unsigned chread;
_dos_read(handle,(char*)&count,sizeof(count),&chread);
mem_used=0L;
for (i=0;i<count;i++)
{
_dos_read(handle,(char*)&size,sizeof(size),&chread);
clip[i].size=size;
unsigned int paras = (unsigned) ((size+15) / 16);
unsigned int segment;
if (_dos_allocmem(paras, &segment) != 0) {
cerr << "insufficient memory";
exit(1);
}
FP_SEG(buf) = segment;
FP_OFF(buf) = 0;
char huge *fptr = (char huge *) buf;
clip[i].data=buf;
mem_used+=size;
do
{
int chs = MAXINT;
if (size < chs)
chs = (int)size;
_dos_read(handle,fptr,chs,&chread);
fptr += chread;
size -= chread;
} while (size > 0);
}
_dos_close(handle);
//-----------------------------------------------------
// print out statistics
list_entries(argv[1],count);
//------------------------------------------------------
// play the requested clips in a loop
char str[40];
char* p;
int num;
do{
query:;
cout << "> ";
cin >> str;
p=strchr(str,'\n');
if (p) *p='\0';
p=strchr(str,' ');
if (p) *p='\0';
if (stricmp(str,"exit")==0 || stricmp(str,"quit")==0) break;
if (stricmp(str,"mem")==0 || stricmp(str,"memory")==0)
{
cout << "Memory in use: " << mem_used << '\n';
cout << "Memory left : " << coreleft() << '\n';
goto query;
}
if (stricmp(str,"list")==0)
{
list_entries(argv[1],count);
goto query;
}
if (strlen(str)==0)
{
cout << "type \"list[ENTER]\" for help\n";
goto query;
}
p=str;
while (*p)
{
if (!((*p>='0' && *p<='9') || !*p))
{
cout << "type \"list[ENTER]\" for help\n";
goto query;
}
p++;
}
num=atoi(str);
if (num<1 || num>count)
cout << "request " << num << " out of range\n";
else
{
cout << "playing entry " << num
<< " (" << clip[num-1].size << ") bytes\n";
play_clip(clip[num-1].data);
}
} while (1); // tag
for (i=0;i<count;i++)
_dos_freemem(FP_SEG(clip[num-1].data));
//------------------------------------------------
// shut down sound card
terminate_driver();
delete realptr;
cout << "sound driver terminated...\n";
return 0;
} // main
//--------------------------------------------------
// 'list_entries' simply reports the entry sizes
//--------------------------------------------------
void list_entries(char* libname,int count)
{
int i;
cout << strupr(libname) << " contains " << count << " entries\n";
cout << "--------------------\n";
for (i=0;i<count;i++)
{
cout << (i+1) << ": " << clip[i].size << " bytes\n";
}
cout << "--------------------\n";
cout << "Type in a number, \"mem\", \"list\", or \"exit\", then press [ENTER]\n\n";
}
int find_and_load_driver()
{
char* t;
char* blaster;
t=getenv("BLASTER");
if (!t)
{
cout << " BLASTER environment variable not set\n";
return FALSE;
}
blaster=strdup(t);
cout << blaster << '\n';
t=strtok(blaster," \t");
while (t)
{
switch (toupper(t[0]))
{
case 'A':
port=(int)strtol(t+1,0,16);
break;
case 'I':
//irq=atoi(t+1);
break;
case 'D':
ldma=atoi(t+1);
break;
case 'H':
hdma=atoi(t+1);
break;
case 'P':
//midiport=(int)strtol(t+1,0,16);
break;
case 'T':
//type=atoi(t+1);
break;
}
t=strtok(0," \t");
}
free(blaster);
if (!load_driver())
return FALSE;
return TRUE;
}
int load_driver()
{
static char driver[MAXPATH];
char* t;
long size;
struct ffblk ffblk;
t=getenv("SOUND");
if (!t)
{
cout << " SOUND environment variable not set\n";
return FALSE;
}
strcpy(driver,t);
strcat(driver,"\\drv\\ct-voice.drv");
if (access(driver,0)!=0)
{
cout << " can't find file [" << driver << "]\n";
return FALSE;
}
findfirst(driver,&ffblk,0);
size=ffblk.ff_fsize;
realptr=new char[(int)size+16];
if (!realptr) return FALSE;
driverptr=(char*)MK_FP(FP_SEG(realptr)+1,0);
// force driveptr to point to a paragraph boundary
ifstream dfile(driver,ios::binary);
dfile.read(driverptr,(int)size);
dfile.close();
print_version();
return TRUE;
}
void set_port(unsigned port)
{
asm {
mov bx,1
mov ax,port
call driverptr
}
cout << " using port " << setbase(16) << port
<< setbase(10) << '\n';
}
void set_status_flag(char* ptr)
{
unsigned segm = FP_SEG(ptr);
unsigned offm = FP_OFF(ptr);
asm {
mov bx,5
mov es,segm
mov di,offm
call driverptr
}
}
void init_driver()
{
int initstatus;
asm {
mov bx,3
call driverptr
mov initstatus,ax
}
}
void play_clip(char huge *data)
{
if (playing)
{
stop_clip();
cout << "current clip interrupted / starting new clip...\n";
}
if (data[0]!='C') // 'C' for "Creative"
{
cout << "only VOC files are supported at this time!\n";
return;
}
unsigned segm = FP_SEG(data);
unsigned offm = FP_OFF(data)+data[20];
asm {
mov bx,6
mov ax,segm
mov es,ax
mov di,offm
call driverptr
}
}
void terminate_driver()
{
asm {
mov bx,9
call driverptr
}
}
void print_version()
{
unsigned version;
asm {
mov bx,0
call driverptr
mov version,ax
}
unsigned major=((version>>8) & 0x0ff);
unsigned minor=(version&0x00ff);
cout << " driver version: " << major << "." << minor << "\n";
}
void stop_clip()
{
asm {
mov bx,8
call driverptr
}
}