mirror of
https://github.com/ondra-novak/gates_of_skeldal.git
synced 2025-07-10 00:20:27 -04:00
1425 lines
30 KiB
C
1425 lines
30 KiB
C
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
//#include <i86.h>
|
|
//#include <dpmi.h>
|
|
|
|
#include <mem.h>
|
|
#include <bios.h>
|
|
#include "zvuk.h"
|
|
//#include "pcspeak.h"
|
|
|
|
#define MIX_REZERVA 0x50
|
|
#define XBASS_PARM 5
|
|
/*
|
|
#define build_dac_xlat() \
|
|
{\
|
|
int i;\
|
|
for(i=0;i<256;i++) da_xlat[i]=i;\
|
|
}\
|
|
|
|
#define sendsb(data) \
|
|
*countdown=10;\
|
|
while ((inp(devport+0xc) & 0x80) && *countdown);\
|
|
outp(devport+0xc,data)
|
|
|
|
#define recivesb(data)\
|
|
*countdown=10;\
|
|
while (!(inp(devport+0xe) & 0x80) && *countdown);\
|
|
data=inp(devport+0xa)
|
|
|
|
#define sendwss(reg,data)\
|
|
*countdown=10;\
|
|
while ((inp(devport+0x4) & 0x80) && *countdown);\
|
|
outp(devport+0x4,reg);\
|
|
outp(devport+0x5,data);
|
|
|
|
#define recivewss(reg,data)\
|
|
*countdown=10;\
|
|
while ((inp(devport+0x4) & 0x80) && *countdown);\
|
|
outp(devport+0x4,reg);\
|
|
data=inp(devport+0x5);
|
|
|
|
|
|
|
|
char detect_enables[8];
|
|
#define irqdetect(irq) \
|
|
{\
|
|
if (detect_enables[irq]) \
|
|
devirq=irq;\
|
|
detect_enables[irq]=0;\
|
|
inp(devport+0xE);\
|
|
outp(0x20,0x20);\
|
|
}
|
|
|
|
*/
|
|
typedef struct tchannel
|
|
{
|
|
char *play_pos, *start_loop, *end_loop;
|
|
int32_t speed_maj;
|
|
unsigned short speed_min, minor_pos, sample_type, vol_left, vol_right;
|
|
}TCHANNEL;
|
|
|
|
TCHANNEL chaninfo[32];
|
|
char *mixbuffer=NULL;
|
|
char backsndbuff[BACK_BUFF_SIZE];
|
|
volatile int32_t backsnd=0;
|
|
volatile int32_t backstep=0x10000;
|
|
volatile int backfine=0;
|
|
int32_t ticker_save;
|
|
/*int32_t jumptable[3];
|
|
int32_t getdma;
|
|
int32_t ido;*/
|
|
unsigned short predstih=0x960;
|
|
int32_t lastdma;
|
|
int32_t lastmix;
|
|
int32_t mixpos;
|
|
int32_t surpos;
|
|
int32_t mixsize;
|
|
int32_t dmaposadr;
|
|
int32_t dmasizadr;
|
|
int32_t dmapageadr;
|
|
int32_t dmanum;
|
|
int dmamask;
|
|
int dmamode;
|
|
int dmamodenum=0x58;//rezim DMA (default pro SB - POZOR zmenit pro GUS na 0x48
|
|
int device;
|
|
int32_t samplerate=22050;
|
|
int32_t mixfreq=50;
|
|
int32_t idt_map[2];
|
|
int call_back_data;
|
|
int call_back_sel;
|
|
static char *countdown=(char *)0x440;
|
|
unsigned short dpmiselector;
|
|
char mixer_zavora=0;
|
|
static char hw_intpol=0;
|
|
FILE *bsnd;
|
|
unsigned short bchans;
|
|
short btable[256];
|
|
int bfreq,bblocks,bblock_size,bvolume=255;
|
|
int bxbass=0;
|
|
static int gfxvol=255;
|
|
int32_t blength;
|
|
static char depack[32768];
|
|
//void (__far __interrupt *oldvect)();
|
|
static char swap_chans=0;
|
|
|
|
char da_xlat[256]; // Xlat tabulka pro DA a PC Speaker;
|
|
|
|
|
|
int devport=0x220; //device base port
|
|
int devirq=0; //device main irq
|
|
|
|
char gus_dma_type=0x41; //typ dma prenosu pro GUS (default 8-bit dma 16-bit samples highspeed)
|
|
char gus_last_buff=0;
|
|
|
|
|
|
int test_counter=0;
|
|
int timer_test_port;
|
|
int timer_value=0;
|
|
char intr_test;
|
|
|
|
void (*konec_skladby)(char **jmeno)=NULL;
|
|
|
|
int dmatable[8][4]=
|
|
{
|
|
{0,1,0x87,0x0A0B},
|
|
{2,3,0x83,0x0A0B},
|
|
{4,5,0x81,0x0A0B},
|
|
{6,7,0x82,0x0A0B},
|
|
{0xc0,0xc2,0x8f,0xD4D6},
|
|
{0xc4,0xc6,0x8b,0xD4D6},
|
|
{0xc8,0xca,0x89,0xD4D6},
|
|
{0xcc,0xce,0x8a,0xD4D6}
|
|
};
|
|
|
|
static int irqtable[16]={8,9,0xa,0xb,0xc,0xd,0xe,0xf,0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77};
|
|
|
|
static char names[][25]=
|
|
{
|
|
"Unsupported device",
|
|
"Nosound",
|
|
"Sound Blaster",
|
|
"Sound Blaster 2",
|
|
"Sound Blaster Pro",
|
|
"Sound Blaster 16+",
|
|
"Windows Sound System",
|
|
"Gravis Ultrasound",
|
|
"DAC on LPT",
|
|
"Internal Hooker",
|
|
"Pro Audio Spectrum"
|
|
};
|
|
|
|
char *buff_alloc();
|
|
#pragma aux buff_alloc modify[ebx ecx edx] value [eax]
|
|
void mixer();
|
|
#pragma aux mixer modify [eax ebx ecx edx esi edi]
|
|
void setsbpro();
|
|
#pragma aux setsbpro modify [eax edi]
|
|
void setsb2();
|
|
#pragma aux setsb2 modify [eax edi]
|
|
void setsb2_s();
|
|
#pragma aux setsb2_s modify [eax edi]
|
|
void setsb16();
|
|
#pragma aux setsb16 modify [eax edi]
|
|
void setgus();
|
|
#pragma aux setgus modify [eax edi]
|
|
void init_gus();
|
|
#pragma aux init_gus modify [eax ecx edx edi]
|
|
void stop_gus();
|
|
#pragma aux stop_gus modify [eax ecx edx edi]
|
|
void gus_setchan_vol(int voice,int volume);
|
|
#pragma aux gus_setchan_vol parm [eax][ecx] modify [edx]
|
|
void gus_setchan_pan(int voice,int volume);
|
|
#pragma aux gus_setchan_pan parm [eax][ecx] modify [edx]
|
|
|
|
|
|
void init_dma(int dma)
|
|
{
|
|
dmanum=dma;
|
|
dmaposadr=dmatable[dma][0];
|
|
dmasizadr=dmatable[dma][1];
|
|
dmapageadr=dmatable[dma][2];
|
|
dmamask=dmatable[dma][3] >> 8;
|
|
dmamode=dmatable[dma][3] & 0xff;
|
|
}
|
|
|
|
void prepare_dma(char *adr,int block)
|
|
{
|
|
int poz;int page;
|
|
|
|
outp(0x0C,0);outp(0xD8,0);
|
|
outp(dmamask,(dmanum & 3)+0x04);
|
|
outp(dmamode,(dmanum & 3)+dmamodenum);
|
|
if (dmanum>3)
|
|
{
|
|
block>>=1;
|
|
poz=(int32_t)adr>>1;
|
|
page=((int32_t)adr>>16) & ~1;
|
|
}
|
|
else
|
|
{
|
|
poz=(int32_t)adr;
|
|
page=(int32_t)adr>>16;
|
|
}
|
|
block--;
|
|
outp(dmaposadr,poz & 0xff);
|
|
outp(dmaposadr,(poz>>8) & 0xff);
|
|
outp(dmapageadr,page);
|
|
outp(dmasizadr,block & 0xff);
|
|
outp(dmasizadr,block>>8);
|
|
outp(dmamask,dmanum & 3);
|
|
/*
|
|
printf("adr: %p\n"
|
|
"block: %04X\n"
|
|
"pos: %04X\n"
|
|
"map: %04X\n"
|
|
"dmapage: %X\n"
|
|
"dmapos: %X\n"
|
|
"dmasize: %X\n"
|
|
"dmamask: %X\n",
|
|
adr,block,poz & 0xffff,page,dmapageadr,dmaposadr,dmasizadr,dmamask);
|
|
getche();
|
|
*/
|
|
}
|
|
|
|
|
|
|
|
void reset_blaster()
|
|
{
|
|
int counter=100;
|
|
outp(devport+0x6,1);
|
|
delay(10);
|
|
outp(devport+0x6,0);
|
|
while (inp(devport+0x0A)!=0xAA && counter--) delay(1);
|
|
}
|
|
void start_sbmono()
|
|
{
|
|
prepare_dma(mixbuffer,65536);
|
|
sendsb(0xd1);
|
|
sendsb(0x40);
|
|
sendsb(256 - (1000000 / samplerate));
|
|
sendsb(0x48);
|
|
sendsb(0xff);
|
|
sendsb(0xff);
|
|
sendsb(0x1c);
|
|
}
|
|
|
|
void stop_sbmono()
|
|
{
|
|
sendsb(0xd3);
|
|
sendsb(0xd0);
|
|
//sendsb(0xda);
|
|
//sendsb(0xd0);
|
|
}
|
|
|
|
void start_sb16();
|
|
|
|
void __interrupt __far sb16_irq()
|
|
{
|
|
int i=32767;
|
|
|
|
i=inp(devport+0xf);
|
|
i=inp(devport+0xe);
|
|
// sendsb(0xb6);
|
|
// sendsb(0x30);
|
|
// sendsb(i & 0xff);
|
|
// sendsb(i >> 8); //play(16bit,signed,stereo,16384);
|
|
outp(0x20,0x20);
|
|
outp(0xA0,0x20);
|
|
intr_test=1;
|
|
}
|
|
void start_sb16()
|
|
{
|
|
int i=16383;
|
|
|
|
outp(devport+0x4,0x81);
|
|
if (dmanum>3)
|
|
outp(devport+0x5,(1 << dmanum)| (inp(devport+0x5) & 0xf));
|
|
else
|
|
outp(devport+0x5,1 << dmanum);
|
|
outp(devport+0x4,0x80);
|
|
switch (devirq)
|
|
{
|
|
case 2:outp(devport+0x5,0xf1);break;
|
|
case 5:outp(devport+0x5,0xf2);break;
|
|
case 7:outp(devport+0x5,0xf4);break;
|
|
}
|
|
outp(devport+0x4,0x80);
|
|
prepare_dma(mixbuffer,65536);
|
|
sendsb(0xd1); //speaker(enable)
|
|
sendsb(0x41);
|
|
sendsb(samplerate>>8);
|
|
sendsb(samplerate & 0xff); //Set_sample_rate(samplerate);
|
|
sendsb(0xb4);
|
|
sendsb(0x30);
|
|
sendsb(i & 0xff);
|
|
sendsb(i >> 8); //play(16bit,signed,stereo,16384);
|
|
outp(0x21,inp(0x21) & ~(1<<devirq));
|
|
_dos_setvect(irqtable[devirq],sb16_irq);
|
|
}
|
|
|
|
void stop_sb16()
|
|
{
|
|
sendsb(0xd3); //speaker(disable)
|
|
sendsb(0xd5); //Halt_DMA_16bit()
|
|
sendsb(0xd9); //Exit_autoinit_16bit();
|
|
sendsb(0xd5); //Halt_DMA_16bit()
|
|
if (devirq<8)
|
|
{
|
|
outp(0x21,inp(0x21) | (1<<devirq));
|
|
}
|
|
else
|
|
{
|
|
outp(0xA1,inp(0xA1) | (1<<(devirq-8)));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void start_sbstereo()
|
|
{
|
|
prepare_dma(mixbuffer,65536);
|
|
sendsb(0xd1);
|
|
sendsb(0x40);
|
|
sendsb((65536 - (256000000 / (samplerate*2)))>>8);
|
|
sendsb(0x48);
|
|
sendsb(0xff);
|
|
sendsb(0xff);
|
|
sendsb(0x90);
|
|
outp(devport+0x4,0x0e);
|
|
outp(devport+0x5,0x23-0x20*hw_intpol);
|
|
}
|
|
|
|
void __interrupt __far sb10_irq()
|
|
{
|
|
int i=32767;
|
|
|
|
i=inp(devport+0xe);
|
|
sendsb(0x14);
|
|
sendsb(0xff);
|
|
sendsb(0xff);
|
|
outp(0x20,0x20);
|
|
outp(0xA0,0x20);
|
|
intr_test=1;
|
|
}
|
|
|
|
void start_sb10()
|
|
{
|
|
prepare_dma(mixbuffer,65536);
|
|
sendsb(0xd1);
|
|
sendsb(0x40);
|
|
sendsb(256 - (1000000 / samplerate));
|
|
sendsb(0x14);
|
|
sendsb(0xff);
|
|
sendsb(0xff);
|
|
outp(0x21,inp(0x21) & ~(1<<devirq));
|
|
_dos_setvect(irqtable[devirq],sb10_irq);
|
|
}
|
|
|
|
void stop_sb10()
|
|
{
|
|
sendsb(0xd3); //speaker(disable)
|
|
sendsb(0xd0); //Halt_DMA_8bit()
|
|
outp(0x21,inp(0x21) | (1<<devirq));
|
|
}
|
|
|
|
|
|
void start_wss16()
|
|
{
|
|
int i,r,h;
|
|
int wss_table[]=
|
|
{8000,5513,16000,11025,27429,18900,32000,22050,-1,37800,-1,44100,48000,33075,9600,6615};
|
|
|
|
int dma_table[]=
|
|
{1,2,0,3};
|
|
r=0xffffff;h=0;
|
|
for(i=0;i<16;i++) if (wss_table[i]!=-1 && abs(samplerate-wss_table[i])<r)
|
|
{
|
|
h=i;r=abs(samplerate-wss_table[i]);
|
|
}
|
|
outp(devport,dma_table[dmanum]);
|
|
sendwss(0x09,0x0);
|
|
outp(devport+0x6,0);
|
|
sendwss(0x0a,0x3);
|
|
samplerate=wss_table[h];
|
|
sendwss(0x48,h+0x50);
|
|
prepare_dma(mixbuffer,65536);
|
|
sendwss(0x0e,0xff);
|
|
sendwss(0x0f,0xff);
|
|
sendwss(0x49,0x09);
|
|
sendwss(0x09,0x09);
|
|
}
|
|
|
|
void stop_wss16()
|
|
{
|
|
sendwss(0x49,0);
|
|
sendwss(0x09,0);
|
|
outp(devport+0x6,0);
|
|
}
|
|
|
|
static int clear_buffer=0;
|
|
|
|
void set_backsnd_freq(int bfreq)
|
|
{
|
|
backstep=bfreq*0x10000/samplerate;
|
|
}
|
|
|
|
|
|
int open_backsound(char *filename)
|
|
{
|
|
static char lastname[128];
|
|
|
|
|
|
bblocks=10;
|
|
if (filename!=NULL)
|
|
{
|
|
lastname[127]=0;
|
|
strncpy(lastname,filename,127);
|
|
}
|
|
bsnd=fopen_icase(lastname,"rb");
|
|
if (bsnd==NULL)
|
|
{
|
|
clear_buffer=32;
|
|
return -1;
|
|
}
|
|
fseek(bsnd,0,SEEK_END);
|
|
blength=ftell(bsnd);
|
|
fseek(bsnd,0,SEEK_SET);
|
|
fread(&bchans,1,2,bsnd);
|
|
fread(&bfreq,1,4,bsnd);
|
|
fread(&bblocks,1,4,bsnd);
|
|
fread(&bblocks,1,4,bsnd);
|
|
fseek(bsnd,8,SEEK_CUR);
|
|
fread(&btable,1,sizeof(btable),bsnd);
|
|
set_backsnd_freq(bfreq);
|
|
bblock_size=0;
|
|
fread(&bblock_size,1,2,bsnd);
|
|
fseek(bsnd,-2,SEEK_CUR);
|
|
return 0;
|
|
}
|
|
|
|
|
|
int load_music_block()
|
|
{
|
|
int32_t remain;
|
|
if (bsnd!=NULL && !clear_buffer)
|
|
{
|
|
fread(&remain,1,sizeof(remain),bsnd);
|
|
fseek(bsnd,4,SEEK_CUR);
|
|
fread(&depack,1,remain,bsnd);
|
|
bblock_size=remain;
|
|
}
|
|
else
|
|
{
|
|
memset(&depack,0x80,sizeof(depack));
|
|
remain=sizeof(depack);
|
|
}
|
|
return remain;
|
|
}
|
|
|
|
|
|
int mix_back_sound(int synchro)
|
|
{
|
|
static int remain=0;
|
|
static int last[2],xbass[2];
|
|
static int swap=0,depos=0,nextpos=0;
|
|
static int predstih=32768;
|
|
int count,val,c;
|
|
|
|
if (bvolume==0 && !clear_buffer) return 0;
|
|
if (synchro==1)
|
|
{
|
|
remain=32767;
|
|
depos=0;
|
|
last[0]=0;
|
|
last[1]=0;
|
|
return nextpos;
|
|
}
|
|
if (synchro==2)
|
|
{
|
|
nextpos=backsnd*4+16;
|
|
if (nextpos>BACK_BUFF_SIZE) nextpos-=BACK_BUFF_SIZE;
|
|
return nextpos;
|
|
}
|
|
if (synchro==3)
|
|
{
|
|
nextpos=backsnd*4-16;
|
|
if (nextpos<0) nextpos+=BACK_BUFF_SIZE;
|
|
return nextpos;
|
|
}
|
|
if (synchro>=32768)
|
|
{
|
|
predstih=synchro;
|
|
return nextpos;
|
|
}
|
|
for(;;)
|
|
{
|
|
val=backsnd*4-nextpos;
|
|
if (val<0) val+=BACK_BUFF_SIZE;
|
|
if (val<predstih) return nextpos;
|
|
if (clear_buffer) clear_buffer--;
|
|
for(count=4096;count>0;count--)
|
|
{
|
|
if (remain<=0)
|
|
{
|
|
bblocks--;
|
|
if (bblocks<=0)
|
|
{
|
|
char *new_filename=NULL;
|
|
fclose(bsnd);
|
|
if (konec_skladby!=NULL) konec_skladby(&new_filename);
|
|
open_backsound(new_filename);
|
|
}
|
|
last[0]=0;
|
|
last[1]=0;
|
|
remain=load_music_block();;
|
|
depos=0;
|
|
}
|
|
val=btable[c=depack[depos]];
|
|
if (bchans==2 || swap) remain--,depos++;
|
|
val+=last[swap];
|
|
last[swap++]=val;
|
|
if (c==0) //pridano jako provizorni reseni pro korekci chyby komprimacniho programu
|
|
{
|
|
val-=31767;
|
|
}
|
|
if (swap>1)swap=0;
|
|
if (bxbass)
|
|
{
|
|
int c;
|
|
xbass[swap]+=val;
|
|
c=xbass[swap]>>XBASS_PARM;
|
|
xbass[swap]-=c;
|
|
c=(c*bxbass*4)>>8;
|
|
val+=c;
|
|
}
|
|
val=(val*bvolume)>>8;
|
|
if (val>32676) val=32767;
|
|
if (val<-32767) val=-32767;
|
|
*(short *)(backsndbuff+(nextpos))=val;
|
|
nextpos+=2;
|
|
if (nextpos>=BACK_BUFF_SIZE) nextpos=0;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void fade_music()
|
|
{
|
|
short *p;
|
|
int i,j,k,l,m;
|
|
|
|
mix_back_sound(0);
|
|
k=backsnd*2;
|
|
i=k;
|
|
p=(short *)&backsndbuff;
|
|
m=mix_back_sound(1);
|
|
m=m-k*2;
|
|
if (m<0) m+=BACK_BUFF_SIZE;
|
|
m/=2;
|
|
j=m;m/=256;
|
|
if (m)
|
|
do
|
|
{
|
|
l=j/256;
|
|
p[i]=p[i]*l/m;
|
|
i++;j--;if (j<0) j=0;
|
|
if (i>BACK_BUFF_SIZE/2) i=0;
|
|
}
|
|
while (i!=k);
|
|
memset(&depack,0x80,sizeof(depack));
|
|
}
|
|
|
|
|
|
void stop_sbstereo()
|
|
{
|
|
reset_blaster();
|
|
outp(devport+0x4,0x0e);
|
|
outp(devport+0x5,0x11);
|
|
//sendsb(0xda);
|
|
//sendsb(0xd0);
|
|
}
|
|
|
|
int init_blaster(int port)
|
|
{
|
|
devport=port;
|
|
reset_blaster();
|
|
return(inp(devport+0x0a)==0xaa);
|
|
}
|
|
|
|
|
|
void prepare_mixing(int mode)
|
|
{
|
|
predstih=samplerate/mixfreq+MIX_REZERVA;
|
|
predstih+=MIX_REZERVA+predstih;
|
|
predstih*=(mode/MIX_MONO);
|
|
switch (mode)
|
|
{
|
|
case MIX_MONO:setsb2();break;
|
|
case MIX_MONO_S:setsb2_s();break;
|
|
case MIX_STEREO:setsbpro();break;
|
|
case MIX_16STEREO:setsb16();break;
|
|
case MIX_ULTRA:setgus();break;
|
|
}
|
|
//backsndbuff[0]=128;backstep=0;backsnd=0;
|
|
lastdma=0;
|
|
mixpos=(int32_t)(mixbuffer+predstih);
|
|
memset(chaninfo,0,sizeof(TCHANNEL)*32);
|
|
memset(mixbuffer,0x80,65536);
|
|
}
|
|
|
|
void play_sample(int channel,void *sample,int32_t size,int32_t lstart,int32_t sfreq,int type)
|
|
{
|
|
chaninfo[channel].play_pos=sample;
|
|
chaninfo[channel].start_loop=(char *)sample+lstart;
|
|
chaninfo[channel].end_loop=(char *)sample+size;
|
|
chaninfo[channel].speed_maj=sfreq/samplerate;
|
|
chaninfo[channel].speed_min=(sfreq%samplerate)*65536/samplerate;
|
|
chaninfo[channel].sample_type=type;
|
|
}
|
|
|
|
void chan_break_ext(int channel,void *org_sample,int32_t size_sample)
|
|
{
|
|
chaninfo[channel].start_loop=chaninfo[channel].end_loop=(char *)org_sample+size_sample;
|
|
}
|
|
|
|
void set_channel_volume(int channel,int left,int right)
|
|
{
|
|
left=(left*gfxvol)>>8;
|
|
right=(right*gfxvol)>>8;
|
|
left=max(left,0);left=min(left,32767);
|
|
right=max(right,0);right=min(right,32767);
|
|
if (swap_chans)
|
|
{
|
|
chaninfo[channel].vol_right=left;
|
|
chaninfo[channel].vol_left=right;
|
|
}
|
|
else
|
|
{
|
|
chaninfo[channel].vol_left=left;
|
|
chaninfo[channel].vol_right=right;
|
|
}
|
|
}
|
|
|
|
|
|
int int_relocation();
|
|
#pragma aux int_relocation modify [eax ebx ecx edx esi edi]
|
|
void int_mixer_alloc(int num);
|
|
#pragma aux int_mixer_alloc parm [ebx] modify [eax ecx edx esi edi]
|
|
int int_dealloc();
|
|
#pragma aux int_dealloc modify [eax ebx ecx edx esi edi]
|
|
void high_speed_parm(void *mix,int dosdelay,char *xlattab,int port);
|
|
#pragma aux high_speed_parm parm [ebx][eax][esi][edx] modify [edi]
|
|
void int_high_alloc(int num);
|
|
#pragma aux int_high_alloc parm [ebx] modify [eax ecx edx esi edi]
|
|
void write_adlib(int data);
|
|
#pragma aux write_adlib parm[eax] modify [edx]
|
|
void write_adlib_nodelay(int data);
|
|
#pragma aux write_adlib_nodelay parm[eax] modify [edx]
|
|
|
|
|
|
void __interrupt __far int_nosound_counter()
|
|
{
|
|
test_counter++;
|
|
_chain_intr(oldvect);
|
|
}
|
|
|
|
void __interrupt __far int_adlib()
|
|
{
|
|
outp(0x20,0x20);
|
|
_enable();
|
|
if (inp(timer_test_port) & 0x80)
|
|
{
|
|
test_counter++;
|
|
write_adlib_nodelay(0x8004);
|
|
}
|
|
mixer();
|
|
_disable();
|
|
_chain_intr(oldvect);
|
|
}
|
|
|
|
void __interrupt __far int_normal()
|
|
{
|
|
outp(0x20,0x20);
|
|
_enable();
|
|
test_counter++;
|
|
mixer();
|
|
_disable();
|
|
_chain_intr(oldvect);
|
|
}
|
|
|
|
|
|
void int_init()
|
|
{
|
|
int l;
|
|
|
|
l=0x1234bc/mixfreq;
|
|
timer_test_port=0;
|
|
_disable();
|
|
oldvect=_dos_getvect(0x8);
|
|
_dos_setvect(0x8,int_normal);
|
|
outp(0x43,0x34);
|
|
outp(0x40,l & 0xff);
|
|
outp(0x40,l>>8);
|
|
_enable();
|
|
}
|
|
|
|
void int_init_adlib_timer()
|
|
{
|
|
int l;
|
|
|
|
timer_value=l=255-3125/mixfreq;
|
|
timer_test_port=0x388;
|
|
_disable();
|
|
oldvect=_dos_getvect(0x8);
|
|
_dos_setvect(0x8,int_adlib);
|
|
write_adlib(l*256+3);
|
|
write_adlib(2*256+4);
|
|
_enable();
|
|
}
|
|
/*
|
|
void int_ultrasnd()
|
|
{
|
|
{
|
|
int l;
|
|
|
|
l=0x1234bc/mixfreq;
|
|
timer_test_port=0;
|
|
_disable();
|
|
oldvect=_dos_getvect(0x8);
|
|
_dos_setvect(0x8,gus_irq);
|
|
outp(0x43,0x34);
|
|
outp(0x40,l & 0xff);
|
|
outp(0x40,l>>8);
|
|
_enable();
|
|
}
|
|
}
|
|
*/
|
|
void int_nosound()
|
|
{
|
|
int l;
|
|
_disable();
|
|
oldvect=_dos_getvect(0x8);
|
|
_dos_setvect(0x8,int_nosound_counter);
|
|
l=0x1234bc/mixfreq;
|
|
outp(0x43,0x34);
|
|
outp(0x40,l%256);
|
|
outp(0x40,l/256);
|
|
_enable();
|
|
}
|
|
|
|
void int_highspeed(int port)
|
|
{
|
|
int l;
|
|
_dos_setvect(0x1c,int_normal);
|
|
high_speed_parm(mixbuffer,samplerate/mixfreq,da_xlat,port);
|
|
int_high_alloc(0x8);
|
|
l=0x1234bc/samplerate;
|
|
outp(0x43,0x34);
|
|
outp(0x40,l%256);
|
|
outp(0x40,l/256);
|
|
}
|
|
|
|
|
|
void set_mixing_device(int mix_dev,int mix_freq,...)
|
|
{
|
|
int *p;
|
|
samplerate=mix_freq;
|
|
if (mixbuffer==NULL) mixbuffer=buff_alloc();
|
|
p=&mix_freq;p++;
|
|
device=mix_dev;
|
|
switch (mix_dev)
|
|
{
|
|
case DEV_SB10:
|
|
case DEV_SB20:
|
|
case DEV_SBPRO:
|
|
case DEV_SB16:
|
|
init_blaster(p[0]);
|
|
init_dma(p[1]);
|
|
devirq=p[2];
|
|
break;
|
|
case DEV_DAC:
|
|
if (p[0]==0x42) set_mixing_device(DEV_PCSPEAKER,mix_freq);
|
|
else
|
|
{
|
|
rm_proc_set((int32_t)mixbuffer>>4,dpmiselector,p[0],DAC_MODE);
|
|
if (samplerate>22050) samplerate=22050;
|
|
}
|
|
break;
|
|
case DEV_PCSPEAKER:
|
|
rm_proc_set((int32_t)mixbuffer>>4,dpmiselector,0x42,SPK_MODE);
|
|
if (samplerate>19000) samplerate=19000;
|
|
break;
|
|
case DEV_ULTRA:
|
|
init_dma(p[1]);
|
|
devirq=p[2];
|
|
dmamodenum=0x58;
|
|
if (dmanum>3) gus_dma_type=0x45;else gus_dma_type=0x41;
|
|
break;
|
|
case DEV_WSS:
|
|
devport=p[0];
|
|
init_dma(p[1]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
int32_t pc_speak_position(void);
|
|
|
|
void start_mixing()
|
|
{
|
|
ticker_save=*(int32_t *)0x46c;
|
|
test_counter=0;
|
|
switch (device)
|
|
{
|
|
case DEV_SB10:
|
|
prepare_mixing(MIX_MONO);
|
|
start_sb10();
|
|
int_init();
|
|
break;
|
|
case DEV_SB20:
|
|
prepare_mixing(MIX_MONO);
|
|
start_sbmono();
|
|
int_init();
|
|
break;
|
|
case DEV_SBPRO:
|
|
prepare_mixing(MIX_STEREO);
|
|
start_sbstereo();
|
|
int_init();
|
|
break;
|
|
case DEV_SB16:
|
|
prepare_mixing(MIX_16STEREO);
|
|
start_sb16();
|
|
int_init();
|
|
break;
|
|
case DEV_PCSPEAKER:
|
|
prepare_mixing(MIX_MONO_S);
|
|
pc_speak_set_proc(&getdma);
|
|
load_rm_proc();
|
|
int_init();
|
|
pc_speak_enable();
|
|
pc_speak_run(samplerate,mixfreq);
|
|
break;
|
|
case DEV_DAC:
|
|
prepare_mixing(MIX_MONO_S);
|
|
pc_speak_set_proc(&getdma);
|
|
load_rm_proc();
|
|
int_init();
|
|
pc_speak_run(samplerate,mixfreq);
|
|
break;
|
|
case DEV_ULTRA:
|
|
prepare_mixing(MIX_ULTRA);
|
|
init_gus();
|
|
int_init();
|
|
delay(200);
|
|
break;
|
|
case DEV_WSS:
|
|
prepare_mixing(MIX_16STEREO);
|
|
start_wss16();
|
|
int_init();
|
|
break;
|
|
case DEV_NOSOUND:int_nosound();break;
|
|
}
|
|
mixer_zavora=0;
|
|
}
|
|
|
|
void stop_mixing()
|
|
{
|
|
mixer_zavora=1;
|
|
_disable();
|
|
*(int32_t *)0x46c=ticker_save+(int32_t)(((float)test_counter/mixfreq)*(18.2059));
|
|
outp(0x43,0x34);
|
|
outp(0x40,0);
|
|
outp(0x40,0);
|
|
_enable();
|
|
switch (device)
|
|
{
|
|
case DEV_SB10:
|
|
stop_sb10();
|
|
break;
|
|
case DEV_SB20:
|
|
stop_sbmono();
|
|
break;
|
|
case DEV_SBPRO:
|
|
stop_sbstereo();
|
|
break;
|
|
case DEV_SB16:
|
|
stop_sb16();
|
|
break;
|
|
case DEV_PCSPEAKER:
|
|
pc_speak_stop();
|
|
pc_speak_disable();
|
|
purge_rm_proc();
|
|
break;
|
|
case DEV_DAC:
|
|
pc_speak_stop();
|
|
purge_rm_proc();
|
|
break;
|
|
case DEV_ULTRA:
|
|
stop_gus();
|
|
break;
|
|
case DEV_WSS:
|
|
stop_wss16();
|
|
break;
|
|
}
|
|
_dos_setvect(0x8,oldvect);
|
|
}
|
|
|
|
void __far __interrupt sb_detect_irq2()
|
|
irqdetect(2)
|
|
void __far __interrupt sb_detect_irq3()
|
|
irqdetect(3)
|
|
void __far __interrupt sb_detect_irq5()
|
|
irqdetect(5)
|
|
void __far __interrupt sb_detect_irq7()
|
|
irqdetect(7)
|
|
|
|
|
|
char *device_name(int device)
|
|
{
|
|
|
|
switch (device)
|
|
{
|
|
case DEV_NOSOUND:return names[1];
|
|
case DEV_SB10:return names[2];
|
|
case DEV_SB20:return names[3];
|
|
case DEV_SBPRO:return names[4];
|
|
case DEV_SB16:return names[5];
|
|
case DEV_WSS:return names[6];
|
|
case DEV_ULTRA:return names[7];
|
|
case DEV_DAC:return names[8];
|
|
case DEV_PCSPEAKER:return names[9];
|
|
}
|
|
return names[0];
|
|
}
|
|
|
|
int sb_detect(int *dev,int *port,int *dma, int *irq)
|
|
{
|
|
int i,a,j;
|
|
char ver_lo;
|
|
char ver_hi;
|
|
void __far *irqsave2,__far *irqsave3,__far *irqsave5,__far *irqsave7;
|
|
int dmasaves[4];
|
|
char dmadis[4];
|
|
int dmatesting[4]={1,3,0,1};
|
|
|
|
*port=0x210;
|
|
do
|
|
{
|
|
devport=*port;
|
|
outp(devport+6,1);delay(1);
|
|
outp(devport+6,0);
|
|
for(i=0;i<100 && inp(devport+0xA)!=0xAA;i++) delay(1);
|
|
(*port)+=0x10;
|
|
}
|
|
while (i==100 && devport<0x280);
|
|
if (i==100) return -1; //NOT DETECTED;
|
|
*port=devport;
|
|
_disable();sendsb(0xe1);recivesb(ver_lo);recivesb(ver_hi);_enable();
|
|
switch (ver_hi)
|
|
{
|
|
case 1: *dev=DEV_SB10;break;
|
|
case 2: if (ver_lo) *dev=DEV_SB20;break;
|
|
case 3: *dev=DEV_SBPRO;break;
|
|
case 4: *dev=DEV_SB16;break;
|
|
default: *dev=DEV_SB16;break;
|
|
}
|
|
if (*dev==DEV_SB16)
|
|
{
|
|
outp(devport+4,0x80);
|
|
i=inp(devport+5);
|
|
*irq=5;
|
|
if (i & 8) *irq=7;
|
|
if (i & 4) *irq=7;
|
|
if (i & 2) *irq=5;
|
|
if (i & 1) *irq=2;
|
|
outp(devport+4,0x81);
|
|
i=inp(devport+5);
|
|
*dma=1;
|
|
if (i & 0x20) *dma=5;
|
|
else if (i & 0x40) *dma=6;
|
|
else if (i & 0x80) *dma=7;
|
|
else if (i & 1) *dma=0;
|
|
else if (i & 2) *dma=1;
|
|
else if (i & 8) *dma=3;
|
|
return 0;
|
|
}
|
|
for(i=0;i<4;i++)
|
|
{
|
|
outp(0xc,0);
|
|
a=inp(dmatable[i][0]);
|
|
a=a+256*inp(dmatable[i][0]);
|
|
dmasaves[i]=a;
|
|
}
|
|
irqsave2=_dos_getvect(irqtable[2]);
|
|
irqsave3=_dos_getvect(irqtable[3]);
|
|
irqsave5=_dos_getvect(irqtable[5]);
|
|
irqsave7=_dos_getvect(irqtable[7]);
|
|
_dos_setvect(irqtable[2],sb_detect_irq2);
|
|
_dos_setvect(irqtable[3],sb_detect_irq3);
|
|
_dos_setvect(irqtable[5],sb_detect_irq5);
|
|
_dos_setvect(irqtable[7],sb_detect_irq7);
|
|
ver_lo=inp(0x21);
|
|
outp(0x21,0x53);
|
|
memset(detect_enables,0x1,sizeof(detect_enables));
|
|
delay(100);
|
|
devirq=-1;
|
|
sendsb(0xf2);
|
|
delay(1);
|
|
_dos_setvect(irqtable[2],irqsave2);
|
|
_dos_setvect(irqtable[3],irqsave3);
|
|
_dos_setvect(irqtable[5],irqsave5);
|
|
_dos_setvect(irqtable[7],irqsave7);
|
|
outp(0x21,ver_lo);
|
|
if (devirq==-1) return -2; //DETECTION ERROR
|
|
*irq=devirq;
|
|
for(i=0;i<4;i++)
|
|
{
|
|
outp(0xc,0);
|
|
a=inp(dmatable[i][0]);
|
|
a=a+256*inp(dmatable[i][0]);
|
|
dmadis[i]=(dmasaves[i]==a);
|
|
}
|
|
for (j=0,*dma=-1;j<4 && *dma==-1;j++)
|
|
{
|
|
i=dmatesting[j];
|
|
init_dma(i);
|
|
prepare_dma(NULL,65536);
|
|
sendsb(0xd3);
|
|
sendsb(0x14);
|
|
sendsb(0xff);
|
|
sendsb(0x7f);
|
|
delay(100);
|
|
outp(0xc,0);
|
|
a=inp(dmatable[i][0]);
|
|
a=a+256*inp(dmatable[i][0]);
|
|
if (dmasaves[i]!=a && dmadis[i]) *dma=i;
|
|
reset_blaster();
|
|
}
|
|
if (*dma==-1) return -2;
|
|
return 0;
|
|
}
|
|
|
|
int wss_detect(int *dev,int *port,int *dma,int *irq)
|
|
{
|
|
int wss_ports[]={0x530,0x604,0xe80,0xf40};
|
|
int i,d;
|
|
|
|
for(i=0;i<4;i++)
|
|
{
|
|
devport=wss_ports[i];
|
|
if (!(inp(devport+0x4) & 0x80))
|
|
{
|
|
sendwss(00,0xaa);
|
|
recivewss(00,d)
|
|
if (d==0xAA) break;
|
|
}
|
|
}
|
|
if (i==4) return -1;
|
|
*dev=DEV_WSS;
|
|
*port=devport;
|
|
*dma=1;
|
|
*irq=0;
|
|
return 0;
|
|
}
|
|
|
|
int sound_detect(int *dev,int *port,int *dma, int *irq)
|
|
{
|
|
char *env;
|
|
char *f;
|
|
|
|
*dev=0;
|
|
env=getenv("BS_SOUND");
|
|
if (env!=NULL)
|
|
if (sscanf(env,"%d %x %d %d",dev,port,dma,irq)!=4) *dev=0;
|
|
if (*dev==0)
|
|
if (wss_detect(dev,port,dma,irq)) *dev=0;
|
|
if (*dev==0 && (env=getenv("ULTRASND"))!=NULL)
|
|
{
|
|
char c;int i;
|
|
sscanf(env,"%x%c%d%c%d%c%d",port,&c,dma,&c,&i,&c,irq);
|
|
*dev=DEV_ULTRA;
|
|
}
|
|
if (*dev==0 && (env=getenv("BLASTER"))!=NULL)
|
|
{
|
|
int i;
|
|
f=strchr(env,'T');
|
|
if (f!=NULL)
|
|
{
|
|
sscanf(f+1,"%d",&i);
|
|
switch (i)
|
|
{
|
|
case 1:*dev=DEV_SB10;break;
|
|
case 2:*dev=DEV_SBPRO;break;
|
|
case 3:*dev=DEV_SB20;break;
|
|
case 4:*dev=DEV_SBPRO;break;
|
|
default: *dev=DEV_NOSOUND;break;
|
|
}
|
|
if (i>4) *dev=DEV_SB16;
|
|
}
|
|
f=strchr(env,'A');
|
|
if (f!=NULL) sscanf(f+1,"%x",port);else *dev=0;
|
|
f=strchr(env,'I');
|
|
if (f!=NULL) sscanf(f+1,"%d",irq);else *dev=0;
|
|
f=strchr(env,'D');
|
|
if (f!=NULL) sscanf(f+1,"%d",dma);else *dev=0;
|
|
f=strchr(env,'H');
|
|
if (f!=NULL) sscanf(f+1,"%d",dma);
|
|
}
|
|
if (*dev==0)
|
|
{
|
|
if (sb_detect(dev,port,dma,irq) && sb_detect(dev,port,dma,irq) && sb_detect(dev,port,dma,irq))
|
|
{
|
|
*dev=0;
|
|
}
|
|
}
|
|
return -(*dev==0);
|
|
}
|
|
|
|
/*main()
|
|
{
|
|
printf("%d\n",sizeof(TCHANNEL));
|
|
if (sb_detect(&a,&b,&c,&d))
|
|
{
|
|
printf("SB not present\n");
|
|
return;
|
|
}
|
|
//a=DEV_SBPRO;
|
|
printf("%s\n",device_name(a));
|
|
//printf("IRQ:\n");
|
|
//scanf("%d",&d);
|
|
set_mixing_device(a,22050,b,c,d);
|
|
printf("Port %03X dma %d irq %d freq %d.\n",b,c,d,samplerate);
|
|
open_backsound(MUSIC1);
|
|
start_mixing();
|
|
mixing();
|
|
stop_mixing();
|
|
printf("\n\n\n");
|
|
}
|
|
*/
|
|
void change_music(char *filename)
|
|
{
|
|
mix_back_sound(0);
|
|
if (bsnd!=NULL)fclose(bsnd);
|
|
fade_music();
|
|
open_backsound(filename);
|
|
}
|
|
|
|
int get_timer_value()
|
|
{
|
|
return test_counter;
|
|
}
|
|
|
|
char get_channel_state(int channel)
|
|
{
|
|
return chaninfo[channel].sample_type;
|
|
}
|
|
|
|
void get_channel_volume(int channel,int *left,int *right)
|
|
{
|
|
*left=chaninfo[channel].vol_left;
|
|
*right=chaninfo[channel].vol_right;
|
|
}
|
|
|
|
void mute_channel(int channel)
|
|
{
|
|
chaninfo[channel].sample_type=0;
|
|
}
|
|
|
|
void chan_break_loop(int channel)
|
|
{
|
|
chaninfo[channel].start_loop=chaninfo[channel].end_loop;
|
|
}
|
|
|
|
void get_bass_treble(int *x,int *y)
|
|
{
|
|
if (device==DEV_SB16)
|
|
{
|
|
outp(devport+4,0x44);*x=inp(devport+5);
|
|
outp(devport+4,0x46);*y=inp(devport+5);
|
|
}
|
|
else
|
|
{
|
|
*x=255;
|
|
*y=255;
|
|
}
|
|
}
|
|
|
|
char sb_set_global_volume(int x)
|
|
{
|
|
if (device==DEV_SBPRO)
|
|
{
|
|
outp(devport+4,2);outp(devport+5,(x & 0xf0) | (x>>4));
|
|
}
|
|
else if (device==DEV_SB16)
|
|
{
|
|
outp(devport+4,2);outp(devport+5,(x & 0xf0) | (x>>4));
|
|
outp(devport+4,0x30);outp(devport+5,x);
|
|
outp(devport+4,0x31);outp(devport+5,x);
|
|
}
|
|
else return 1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
char sb_get_global_volume()
|
|
{
|
|
if (device==DEV_SBPRO)
|
|
{
|
|
outp(devport+4,2);return inp(devport+5)&0xf0;
|
|
}
|
|
else if (device==DEV_SB16)
|
|
{
|
|
int check1,check2;
|
|
outp(devport+4,2);check1=inp(devport+5)&0xf0;
|
|
outp(devport+4,0x30);check2=inp(devport+5);
|
|
if (check1!=check2 & 0xe0) return check1;else return check2;
|
|
}
|
|
else return 1;
|
|
}
|
|
|
|
void wss_set_global_volume(int x)
|
|
{
|
|
x>>=4;
|
|
sendwss(06,0xf-x);
|
|
sendwss(07,0xf-x);
|
|
}
|
|
|
|
char wss_get_global_volume()
|
|
{
|
|
int x;
|
|
|
|
recivewss(06,x);
|
|
x<<=4;
|
|
return 0xff-x;
|
|
}
|
|
|
|
void set_music_volume(int volume)
|
|
{
|
|
if (volume==0 && bvolume!=0)
|
|
memset(backsndbuff,0,sizeof(backsndbuff));
|
|
bvolume=volume;
|
|
}
|
|
|
|
int get_music_volume()
|
|
{
|
|
return bvolume;
|
|
}
|
|
|
|
void set_gfx_volume(int volume)
|
|
{
|
|
gfxvol=volume;
|
|
}
|
|
|
|
int get_gfx_volume()
|
|
{
|
|
return gfxvol;
|
|
}
|
|
|
|
|
|
void snd_ping1(int data)
|
|
{
|
|
data;
|
|
}
|
|
|
|
int snd_ping2()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
void set_swap_channels(int data)
|
|
{
|
|
swap_chans=data & 1;
|
|
}
|
|
|
|
int get_swap_channels()
|
|
{
|
|
return swap_chans;
|
|
}
|
|
|
|
void set_treble(int y)
|
|
{
|
|
outp(devport+4,0x44);outp(devport+5,y);
|
|
outp(devport+4,0x45);outp(devport+5,y);
|
|
}
|
|
void set_bass(int x)
|
|
{
|
|
outp(devport+4,0x46);outp(devport+5,x);
|
|
outp(devport+4,0x47);outp(devport+5,x);
|
|
}
|
|
|
|
int get_treble()
|
|
{
|
|
outp(devport+4,0x44);return inp(devport+5);
|
|
}
|
|
int get_bass()
|
|
{
|
|
outp(devport+4,0x46);return inp(devport+5);
|
|
}
|
|
|
|
char gus_swap=0;
|
|
char gus_volume=0xff;
|
|
|
|
void set_gus_swap(int x)
|
|
{
|
|
gus_swap=x;
|
|
gus_setchan_pan(0,x>>4);
|
|
gus_setchan_pan(1,(0xff-x)>>4);
|
|
}
|
|
|
|
void set_xbass(int x)
|
|
{
|
|
bxbass=x;
|
|
}
|
|
|
|
int get_xbass()
|
|
{
|
|
return bxbass;
|
|
}
|
|
|
|
int get_gus_swap()
|
|
{
|
|
return gus_swap;
|
|
}
|
|
|
|
void gus_set_global_volume(int x)
|
|
{
|
|
gus_setchan_vol(0,x<<8);
|
|
gus_setchan_vol(1,x<<8);
|
|
gus_volume=x;
|
|
}
|
|
|
|
int gus_get_global_volume()
|
|
{
|
|
return gus_volume;
|
|
}
|
|
|
|
char get_outfilter()
|
|
{
|
|
return hw_intpol;
|
|
}
|
|
|
|
|
|
char set_outfilter(char value)
|
|
{
|
|
int a;
|
|
|
|
if (device!=DEV_SBPRO) return 1;
|
|
if (value>1) hw_intpol=!hw_intpol;
|
|
else hw_intpol=value;
|
|
do
|
|
{
|
|
a=inp(dmaposadr);
|
|
a+=inp(dmaposadr)<<8;
|
|
}
|
|
while (a & 1);
|
|
do
|
|
{
|
|
a=inp(dmaposadr);
|
|
a+=inp(dmaposadr)<<8;
|
|
}
|
|
while (!(a & 1));
|
|
outp(devport+0x4,0x0e);
|
|
if (hw_intpol) outp(devport+0x5,inp(devport+0x5) & ~0x20);
|
|
else outp(devport+0x5,inp(devport+0x5) | 0x20);
|
|
return 0;
|
|
}
|
|
|
|
typedef void (*FPROC_SET)(int data);
|
|
typedef int (*FPROC_GET)();
|
|
|
|
FPROC_SET set_funct_table[][SND_MAXFUNCT]=
|
|
{
|
|
{snd_ping1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
|
|
{snd_ping1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,set_gfx_volume,set_music_volume,set_xbass},
|
|
{snd_ping1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,set_gfx_volume,set_music_volume,set_xbass},
|
|
{snd_ping1,sb_set_global_volume,NULL,NULL,set_swap_channels,NULL,NULL,set_outfilter,set_gfx_volume,set_music_volume,set_xbass},
|
|
{snd_ping1,sb_set_global_volume,set_bass,set_treble,set_swap_channels,NULL,NULL,NULL,set_gfx_volume,set_music_volume,set_xbass},
|
|
{snd_ping1,wss_set_global_volume,NULL,NULL,set_swap_channels,NULL,NULL,NULL,set_gfx_volume,set_music_volume,set_xbass},
|
|
{snd_ping1,gus_set_global_volume,NULL,NULL,NULL,set_gus_swap,NULL,NULL,set_gfx_volume,set_music_volume,set_xbass},
|
|
{snd_ping1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,set_gfx_volume,set_music_volume,set_xbass},
|
|
{snd_ping1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,set_gfx_volume,set_music_volume,set_xbass},
|
|
};
|
|
|
|
FPROC_GET get_funct_table[][SND_MAXFUNCT]=
|
|
{
|
|
{snd_ping2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL},
|
|
{snd_ping2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,get_gfx_volume,get_music_volume,get_xbass},
|
|
{snd_ping2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,get_gfx_volume,get_music_volume,get_xbass},
|
|
{snd_ping2,sb_get_global_volume,NULL,NULL,get_swap_channels,NULL,NULL,get_outfilter,get_gfx_volume,get_music_volume,get_xbass},
|
|
{snd_ping2,sb_get_global_volume,get_bass,get_treble,get_swap_channels,NULL,NULL,NULL,get_gfx_volume,get_music_volume,get_xbass},
|
|
{snd_ping2,wss_get_global_volume,NULL,NULL,get_swap_channels,NULL,NULL,NULL,get_gfx_volume,get_music_volume,get_xbass},
|
|
{snd_ping2,gus_get_global_volume,NULL,NULL,NULL,get_gus_swap,NULL,NULL,get_gfx_volume,get_music_volume,get_xbass},
|
|
{snd_ping2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,get_gfx_volume,get_music_volume,get_xbass},
|
|
{snd_ping2,NULL,NULL,NULL,NULL,NULL,NULL,NULL,get_gfx_volume,get_music_volume,get_xbass},
|
|
};
|
|
|
|
char check_snd_effect(int funct)
|
|
{
|
|
return set_funct_table[device][funct]!=NULL;
|
|
}
|
|
|
|
char set_snd_effect(int funct,int data)
|
|
{
|
|
if (set_funct_table[device][funct]!=NULL)
|
|
{
|
|
set_funct_table[device][funct](data);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int get_snd_effect(int funct)
|
|
{
|
|
if (get_funct_table[device][funct]!=NULL)
|
|
{
|
|
return get_funct_table[device][funct]();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
void force_music_volume(int volume)
|
|
{
|
|
bvolume=volume;
|
|
}
|