home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C++ Games Programming
/
CPPGAMES.ISO
/
thx
/
source
/
theatrix
/
vocal.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-30
|
6KB
|
323 lines
#include <fstream.h>
#include <iomanip.h>
#include <values.h> // MAXINT
#include <io.h>
#include <dir.h>
#include <dos.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "theatrix.h"
#include "vocal.h"
#include "xms.h"
SoundMedia VocalHand::sfxlib;
VocalHand::Driver VocalHand::driver;
static char far *realptr;
static char far *driverptr;
static char far *initptr;
static char far *deinitptr;
unsigned *VocalHand::isplaying;
unsigned VocalHand::playing;
unsigned VocalHand::port;
unsigned VocalHand::irq;
void VocalHand::startup()
{
cout << "looking for sound card...\n";
if ((driver=load_digpak_driver()) == nodriver)
driver = load_ct_voice_driver();
if (driver != nodriver) {
if (driver == ctvoicedriver) {
get_soundcard_settings();
set_port(port);
set_irq(irq);
init_driver();
if (driver != nodriver) {
cout << "CT-VOICE driver initialized...\n";
set_status_flag((char*)&playing);
return;
}
}
else if (driver == digpakdriver) {
init_driver();
cout << "DIGPAK driver initialized...\n";
return;
}
}
cout << "sound driver not initialized...\n";
}
void VocalHand::shutdown()
{
if (driver != nodriver) {
terminate_driver();
cout << "sound driver terminated...\n";
}
}
void VocalHand::load_sfxlib(char* fname)
{
sfxlib.load_library(fname);
set_sfxlib(fname);
}
void VocalHand::set_sfxlib(char* fname)
{
curlib=sfxlib.library_number(fname);
}
void VocalHand::thxplay_sound_clip(int index)
{
if (driver == nodriver)
return;
MediaClip& mc = sfxlib.getclip(curlib,index-1);
if (sound_clip_is_playing())
stop_sound_clip();
if (driver == digpakdriver) {
struct {
char *clip; // address of sample.
unsigned length; // length of sample.
unsigned *isplaying; // Address of play status flag.
unsigned samplrate; // sampling rate
} snd;
snd.clip = mc.buf+32;
snd.length = *(unsigned*)(mc.buf+27) - 2;
snd.isplaying = 0;
int sr = *(mc.buf+30) & 255;
snd.samplrate = (unsigned) (-1000000L / (sr - 256));
unsigned segm = FP_SEG(&snd);
unsigned off = FP_OFF(&snd);
asm {
push ds
push si
mov si,off
mov ax,segm
mov ds,ax
mov ax,0x68b
int 0x66
pop si
pop ds
}
isplaying = snd.isplaying;
}
else {
char* data=mc.buf;
unsigned segm = FP_SEG(data);
unsigned offm = FP_OFF(data)+data[20];
asm {
mov bx,6
mov ax,segm
push es
push di
mov es,ax
mov di,offm
call driverptr
pop di
pop es
}
isplaying = &playing;
}
}
void VocalHand::stop_sound_clip()
{
if (driver == digpakdriver) {
_AX = 0x68f;
geninterrupt(0x66);
}
else if (driver == ctvoicedriver) {
asm {
mov bx,8
call driverptr
}
}
isplaying = 0;
}
int VocalHand::sound_clip_is_playing()
{
return isplaying ? *isplaying : 0;
}
int VocalHand::get_num_clips()
{
return sfxlib.clipcount(curlib);
}
VocalHand::Driver VocalHand::load_digpak_driver()
{
long size;
struct ffblk ffblk;
if (findfirst("soundrv.com",&ffblk,0) == -1)
return nodriver;
size=ffblk.ff_fsize;
realptr=new char[(int)size+16];
driverptr=(char*)MK_FP(FP_SEG(realptr)+1,0);
ifstream dfile("soundrv.com",ios::binary);
dfile.read(driverptr,(int)size);
if (strncmp(driverptr+3, "DIGPAK", 6)) {
delete realptr;
realptr = 0;
return nodriver;
}
initptr = (char*)MK_FP(FP_SEG(driverptr)-0x10, 0x200);
deinitptr = (char*)MK_FP(FP_SEG(driverptr)-0x10, 0x203);
return digpakdriver;
}
void VocalHand::get_soundcard_settings()
{
char* t = getenv("BLASTER");
if (!t) {
cout << " BLASTER environment variable not set\n";
return;
}
cout << t << '\n';
t = strtok(t," \t");
while (t)
{
switch (toupper(t[0])) {
case 'A':
port=(int)strtol(t+1,0,16);
break;
case 'I':
irq=atoi(t+1);
break;
}
t=strtok(0," \t");
}
}
VocalHand::Driver VocalHand::load_ct_voice_driver()
{
char driver[MAXPATH];
char cwd[MAXPATH];
int curdisk;
char* t;
long size;
struct ffblk ffblk;
t=getenv("SOUND");
if (!t) {
cout << " SOUND environment variable not set\n";
return nodriver;
}
curdisk = getdisk();
getcwd(cwd, MAXPATH);
if (*(t+1) == ':')
setdisk(tolower(*t) - 'a');
strcpy(driver, t);
strcat(driver, "\\drv");
chdir(driver);
if (findfirst("ct-voice.drv",&ffblk,0) == -1) {
cout << " can't find ct-voice.drv\n";
return nodriver;
}
size=ffblk.ff_fsize;
realptr=new char[(int)size+16];
// force driveptr to point to a paragraph boundary
driverptr=(char*)MK_FP(FP_SEG(realptr)+1,0);
ifstream dfile("ct-voice.drv",ios::binary);
dfile.read(driverptr,(int)size);
setdisk(curdisk);
chdir(cwd);
return ctvoicedriver;
}
void VocalHand::init_driver()
{
unsigned drv = 1;
if (driver == digpakdriver) {
asm {
call initptr
mov drv,ax
}
}
else if (driver == ctvoicedriver) {
asm {
mov bx,3
call driverptr
mov drv,ax
}
}
if (drv) {
driver = nodriver;
delete realptr;
realptr = 0;
}
}
void VocalHand::terminate_driver()
{
if (driver == digpakdriver) {
asm {
call deinitptr
}
}
else if (driver == ctvoicedriver) {
asm {
mov bx,9
call driverptr
}
}
driver = nodriver;
delete realptr;
realptr = 0;
}
void VocalHand::set_port(unsigned port)
{
asm {
mov bx,1
mov ax,port
call driverptr
}
cout << " using port " << setbase(16) << port
<< setbase(10) << '\n';
}
void VocalHand::set_irq(unsigned irq)
{
asm {
mov bx,2
mov ax,irq
call driverptr
}
cout << " using irq " << irq << '\n';
}
void VocalHand::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
}
}