home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
msdos
/
sndbords
/
proaudio
/
mvsa
/
mvsa.c
< prev
next >
Wrap
Text File
|
1993-06-10
|
32KB
|
1,158 lines
; /*\
;---|*|----====< MVSA.C >====----
;---|*|
;---|*| An simple program to drive the Pro Audio "Spectrum Sound"
;---|*| Copyright (c) 1991-1993 Media Vision, Inc. All rights reserved.
;---|*|
;---|*| This code is provided as freeware for anyone wishing to implement
;---|*| the "Spectrum Sound" technique on the Pro Audio Spectrum.
;---|*|
;---|*| The Pro Audio Spectrum's mixer has the ability to perform a
;---|*| close approximation of Dolby's Surround Sound (r) encoding
;---|*| process.
;---|*|
;---|*| The Dolby Surround Sound (r) technique involves filter
;---|*| the signal, and shifting both the left and right channels 180
;---|*| degrees out of phase. Any Surround Sound (r) decoder, sees the
;---|*| signal out of phase, and places the audio in rear speaker.
;---|*|
;---|*| The Pro Audio Spectrum mixer architecture has the ability to
;---|*| create a phase delay in the signal. On all Pro Audio Spectrums,
;---|*| every audio channel mixer can be connected to a "PLAY ONLY" path,
;---|*|
;---|*| or "PLAY and RECORD" path. The actual "PLAY and RECORD" path
;---|*| involves a longer path through the recording circuitry before it
;---|*| is sent out the PLAY path. This longer path creates a delay in
;---|*| the signal that can be used as a Surround Sound (r) Encoder! The
;---|*| technique is now simple: send the left channel through the "PLAY
;---|*| ONLY" path, and the right channel through the "PLAY and RECORD"
;---|*| path!
;---|*|
;---|*| The routine, "MoveMixers" takes the joystick X,Y coordinates,
;---|*| calculates the audio's position, then places it in 3d space
;---|*| via the mixer.
;---|*|
;---|*| REMEMBER! you need to connect the stereo output of the Pro Audio
;---|*| to a Surround Sound receiver/decoder that has 4 speakers hooked up
;---|*| in the LEFT/CENTER/RIGHT and REAR positions.
;---|*|
;---|*| Dolby Surround Sound is a registered trademark of Dolby Labs, Inc.
;---|*|
; \*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include "binary.h"
// position controls
static unsigned int Xpos = 128; // column center position
static unsigned int Ypos = 128; // row center position
static unsigned int Xmid = 128; // col center position
static unsigned int Ymid = 128; // row center position
static unsigned int JoyXScale = 50; // joystick X range scaler
static unsigned int JoyYScale = 50; // joystick Y range scaler
// our buffer management data
static char far *SourceData;
static char far *DMABuffPtr;
static char huge *StartOfDMABuffer;
#define MAXDIV 64
#define DMASIZE 16
static int MaxBuffCount = MAXDIV; // max dma buffer count
static long DmaSize = DMASIZE*1024L; // dma buffer size
static int DivisionSize = DMASIZE*1024L/(MAXDIV);
// misc global variables
static char *FileName = 0; // source file name
static long SampleRate = 11025; // the output sample rate
static int swaplr = 0; // swap left/right channels
// joystick stuff...
static int ButtonState = 0; // joystick button states
static int keyboardonly = 0;
// our prototypes
static void far _saveregs FillNextBlock ( );
static int GetKey ( int );
// low level access routines
void UserFunc ( void (far*)() );
void InitPCM ( );
void InitMVSound ( );
void far *DMABuffer ( char far *, int, int );
char huge *FindDMABuffer ( char huge *, int );
int PCMInfo ( long ,int, int, int );
void huge *_memmalloc ( long );
static void SurroundFill ( char far *, char far *, int );
// this table is a quarter wave staring at 75h down to 0h
unsigned char scalers[] = {
0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75, 0x75,
0x75, 0x73, 0x75, 0x73, 0x73, 0x75, 0x73, 0x73,
0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73,
0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x71,
0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71,
0x71, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70,
0x70, 0x70, 0x70, 0x6e, 0x6e, 0x6e, 0x6e, 0x6e,
0x6e, 0x6e, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c,
0x6c, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x69, 0x69,
0x69, 0x69, 0x69, 0x69, 0x69, 0x67, 0x67, 0x67,
0x67, 0x67, 0x65, 0x65, 0x65, 0x65, 0x63, 0x63,
0x63, 0x63, 0x63, 0x62, 0x62, 0x62, 0x62, 0x62,
0x60, 0x60, 0x60, 0x60, 0x5e, 0x5e, 0x5e, 0x5e,
0x5e, 0x5c, 0x5c, 0x5c, 0x5c, 0x5b, 0x5b, 0x5b,
0x59, 0x59, 0x59, 0x59, 0x57, 0x57, 0x57, 0x57,
0x55, 0x55, 0x55, 0x54, 0x54, 0x54, 0x54, 0x52,
0x52, 0x52, 0x50, 0x50, 0x50, 0x50, 0x4e, 0x4e,
0x4e, 0x4d, 0x4d, 0x4d, 0x4b, 0x4b, 0x4b, 0x49,
0x49, 0x49, 0x49, 0x47, 0x47, 0x47, 0x46, 0x46,
0x46, 0x44, 0x44, 0x44, 0x42, 0x42, 0x42, 0x40,
0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3d, 0x3d, 0x3d,
0x3b, 0x3b, 0x3b, 0x39, 0x39, 0x39, 0x38, 0x38,
0x36, 0x36, 0x36, 0x34, 0x34, 0x32, 0x32, 0x32,
0x31, 0x31, 0x31, 0x2f, 0x2f, 0x2d, 0x2d, 0x2d,
0x2b, 0x2b, 0x2b, 0x2a, 0x2a, 0x28, 0x28, 0x28,
0x26, 0x26, 0x26, 0x24, 0x24, 0x23, 0x23, 0x23,
0x21, 0x21, 0x21, 0x1f, 0x1f, 0x1d, 0x1d, 0x1d,
0x1c, 0x1c, 0x1a, 0x1a, 0x1a, 0x18, 0x18, 0x16,
0x16, 0x16, 0x15, 0x15, 0x13, 0x13, 0x13, 0x11,
0x11, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0c, 0x0c,
0x0c, 0x0a, 0x0a, 0x08, 0x08, 0x07, 0x07, 0x07,
0x05, 0x05, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00
};
// mixer selection
char mixerchannels[16] = {
BI_L_FM, BI_R_FM, // 0
-1, -1, // 1
BI_L_EXT, BI_R_EXT, // 2
BI_L_INT, BI_R_INT, // 3
BI_L_MIC, BI_R_MIC, // 4
BI_L_PCM, BI_R_PCM, // 5
BI_L_SPEAKER, BI_R_SPEAKER, // 6
BI_L_SBDAC, BI_R_SBDAC // 7
};
int mixerselect = 5; // PCM
char *mixernames[8] = {
"FM",
" ",
"External Line-in",
"Internal Line-in jack",
"Microphone",
"Pro Audio PCM",
"PC Speaker",
"SB PCM"
};
int LastLeftPos = 128;
int LastRitPos = 128;
; /*\
;---|*|----====< main >====----
;---|*|
;---|*| Removes the PCM system & deallocates the buffer memory.
;---|*| There is no return value.
;---|*|
; \*/
void main(argc,argv)
int argc;
char *argv[];
{
int looping = -1;
// process any switches, etc.
CommandLine(argc,argv);
// setup the underlying driver...
if (!SetupSound()) {
printf ("Unable to setup the sound routines!\n");
exit(-1);
}
// calibrate the joystick
Calibrate();
// setup the buffers, etc.
LoadDataBuffers ( );
// disable the ^C
signal (SIGINT,SIG_IGN);
// let'er rip...
PCMPlay();
// loop until time to exit
PrintStats (0x07);
while (looping) {
// process any user keys, and break out if desired
if (kbhit())
if (ProcessKeys())
break;
// read the joystick if one is available
if (!keyboardonly) {
DelayTimer(1);
ReadJoyStick ( JoyXScale, JoyYScale );
MoveMixers ( mixerselect );
}
// then print the coordinates
PrintStats (0x03);
}
// kill the PCM & exit
StopPCM();
}
; /*\
;---|*|----====< Calibrate >====----
;---|*|
;---|*| Calibrate the joystick position and scale down to 0-256
;---|*|
; \*/
Calibrate()
{
int y;
char *s,*t;
// exit if there is no joystick
if (keyboardonly) {
Xmid = Ymid = Xpos = Ypos = 128;
JoyXScale = 25600/416;
JoyYScale = 25600/416;
return(0);
}
// ask the user to position, then read the setting
y = CursorYPos();
printf ("Please position the Joystick in the bottom right corner.\n");
printf ("Press a fire button when in position\n\n");
PrintStats (0x01);
while (1) {
// get the whole coordinates
ReadJoyStick(100,100);
PrintStats (0x01);
// check for an exit request
if (kbhit()) {
if (getch() == 0x1b)
return(0);
}
// we're done when a button is depressed
if (ButtonState & 0x0f)
break;
}
// remove our user directions from the screen
SetCursor (0,y);
printf (" \n");
printf (" \n");
// we want a scale between 0 & 256
if (Xpos > 255)
JoyXScale = 25600/Xpos;
if (Ypos > 255)
JoyYScale = 25600/Ypos;
JoyXScale--;
JoyYScale--;
Ymid = Ypos * JoyYScale / 100 / 2;
Xmid = Xpos * JoyXScale / 100 / 2;
}
; /*\
;---|*|----====< CommandLine >====----
;---|*|
;---|*| process the command line switches
;---|*|
; \*/
int CommandLine(argc,argv)
int argc;
char *argv[];
{
char *s;
int n,temp;
long l;
// print the helps, then exit if no additional parameters
if (argc < 2) {
GiveHelps(0x07);
exit(-1);
}
GiveHelps(0x01);
// process the rest...
n = 1;
while (n < argc) {
s = argv[n++];
if (*s == '/') s++;
if (*s == '-') s++;
switch (*s & 0x5f) {
case '?' & 0x5f:
case 'H':
GiveHelps(0x06);
exit(0);
case 'F':
FileName = ++s;
printf ("Will play the file, \"%s\"\n",FileName);
break;
case 'K':
keyboardonly = -1;
printf ("Taking input from the keyboard only\n");
break;
case 'M':
if (sscanf (++s,"%d",&temp) == 1) {
mixerselect = temp & 0x07;
if (mixerchannels[mixerselect] == -1)
mixerselect = 5;
printf ("mixer index %d\n", mixerselect);
}
break;
case 'R':
if (sscanf (++s,"%ld",&l) == 1) {
SampleRate = l;
printf ("Using %ld sample rate\n",l);
}
break;
case 'X':
swaplr = -1;
printf ("Swapping left and right channels\n");
break;
default:
break;
}
}
printf ("\n");
}
; /*\
;---|*|----====< CursorYPos >====----
;---|*|
;---|*| Return the curreny cursor Y position on the screen
;---|*|
; \*/
CursorYPos()
{
int retval;
// get it from the video bios
_asm {
mov ah,03h
mov bx,0
int 10h
sub dl,dl
xchg dl,dh
mov [retval],dx
}
return(retval);
}
; /*\
;---|*|----====< DelayTimer >====----
;---|*|
;---|*| Delay this many clock ticks
;---|*|
; \*/
DelayTimer(ticks)
int ticks;
{
int timer = -1;
int delta = -1;
// while we have time to waste...
DeltaTime();
while (ticks) {
// if the clock ticked, count down one...
if (DeltaTime())
ticks--;
}
}
; /*\
;---|*|----====< DeltaTime >====----
;---|*|
;---|*| Return the delta of clock ticks
;---|*|
; \*/
DeltaTime()
{
int retval;
static int timer = -1;
// get the clock tick, save, sub from last tick & return the value
_asm {
mov ah,0
int 1ah
xchg dx,[timer]
sub dx,[timer]
mov [retval],dx
}
// return the delta
return(retval);
}
; /*\
;---|*|----====< FillNextBlock >====----
;---|*|
;---|*| Fill the DMA buffer with the next block
;---|*|
; \*/
void far _saveregs FillNextBlock()
{
static int next = 0;
static char far *src = 0;
static char far *trg = 0;
// first time in checks...
if (!trg) {
trg = StartOfDMABuffer;
src = SourceData;
}
// fill the buffer with data
SurroundFill(trg,src,DivisionSize);
// move the pointer for the next call...
if (++next == MaxBuffCount) {
trg = StartOfDMABuffer;
src = SourceData;
next = 0;
}
else {
(int)src += DivisionSize;
(int)trg += DivisionSize*4;
}
}
; /*\
;---|*|----====< GetKey >====----
;---|*|
;---|*| Return a keystroke
;---|*|
; \*/
static int GetKey(flag)
int flag;
{
int c = 0;
// flush if flag is set, then wait for a key
if (flag) {
while (kbhit()) getch();
while (!kbhit()) ;
}
// if there is a key, return 16 bits of it...
if (kbhit()) {
if ((c = getch()) == 0)
c = getch() << 8;
}
// return the character
return(c);
}
; /*\
;---|*|----====< GetMixers >====----
;---|*|
;---|*| See if the Pro Audio is installed, and setup the mixer code
;---|*|
; \*/
GetMixers ( )
{
// get the mixer vectors
if (!MVInitMixerCode()) {
printf ("Cannot find MVSOUND.SYS\n");
return(0);
}
// set both channels through the record path
cMVSetMixerFunction( 100, BI_INPUTMIXER, BI_L_PCM );
cMVSetMixerFunction( 100, BI_INPUTMIXER, BI_R_PCM );
// set the monitor setting to full on
cMVSetMixerFunction( 100, BI_OUTPUTMIXER, BI_L_IMIXER );
cMVSetMixerFunction( 100, BI_OUTPUTMIXER, BI_R_IMIXER );
// return hunky-dory
return(-1);
}
; /*\
;---|*|----====< GiveHelps >====----
;---|*|
;---|*| Tell the user how to use this program.
;---|*|
; \*/
GiveHelps(flags)
int flags;
{
if (flags & 0x01) {
printf ("\n\n\n\n\n\n\n\n\n\n\n");
printf ("Media Vision Pro Audio Spectrum Sound Demo Program, V1.0\n");
printf ("Copyright (c) 1993. Media Vision, Inc. All Rights Reserved. V1.0\n\n");
printf ("This program demonstrates a close approximation of Dolby Surround Sound (r)\n");
printf ("encoding using the Pro Audio's on-board mixer. The output of the Pro Audio\n");
printf ("can plugged into any stereo receiver that supports Dolby Surround. With\n");
printf ("four speakers attached, the audio signal can be placed on any of the\n");
printf ("speakers.\n\n");
}
if (flags & 0x02) {
printf ("The Dolby Surround Sound (r) technique involves filter the signal, and\n");
printf ("shifting both the left and right channels 180 degrees out of phase. Any\n");
printf ("Surround Sound (r) decoder, sees the signal out of phase, and places\n");
printf ("the audio in rear speaker.\n\n");
printf ("Type a key to continue...");
GetKey (1);
printf ("\r \n");
printf (" The Pro Audio Spectrum mixer ┌───────────────────────────────────────────┐\n");
printf (" architecture has the ability │ │\n");
printf (" to create a phase delay in │ │\n");
printf (" the audio signal. On all Pro │linein ══════╦═══════════╗ │\n");
printf (" Audio Spectrum cards, every │CD-in ════╦═║═════════╗ ║ │\n");
printf (" audio mixer channel can be │FM ══╦═║═║═══════╗ ║ ║ │\n");
printf (" connected to a \"PLAY ONLY\" │ ║ ║ ║ ║ ║ ║ │\n");
printf (" path or \"PLAY and RECORD\" │ │\n");
printf (" path. The actual \"PLAY and │ ┌──────┐ ┌──────┐ ┌────────┐ ┌─│\n");
printf (" RECORD\" path involves a longer │ │play &╞═╦═>╡ play ╞═>╡ Master ╞═╡ │\n");
printf (" path through the recording │ │record│ ║ │ only │ │ Volume │ └─│\n");
printf (" circuitry before it is sent │ └──────┘ ║ └──────┘ └────────┘ │\n");
printf (" out the play path. This longer │ ║ │\n");
printf (" path creates a delay in the │ ║ ║ ║ ║ ║ ║ ║ │\n");
printf (" signal that can be used as a │PCM ══╩═║═║═══════╝ ║ ║ │\n");
printf (" Surround Sound (r) Encoder! │Mic ════╩═║═════════╝ ║ │\n");
printf (" The technique is now simple: │SB PCM ══════╩═══════════╝ │\n");
printf (" send the left channel │ ║ │\n");
printf (" through the \"PLAY ONLY\" │ │\n");
printf (" path, and the right channel │ PCM │\n");
printf (" through the \"PLAY and │ record │\n");
printf (" RECORD\" path! └───────────────────────────────────────────┘\n\n");
printf ("Type a key to continue...");
GetKey (1);
printf ("\r \n");
printf ("REMEMBER! you need to connect the stereo output of the Pro Audio\n");
printf ("to a Surround Sound receiver/decoder that has 4 speakers hooked up\n");
printf ("in the LEFT/CENTER/RIGHT and REAR positions.\n\n");
printf (" ╓─ Left\n");
printf (" ┌──────────│ ┌─────────────────┐ ╟─ Center\n");
printf (" │Pro Audio │═══>│ Stereo Surround ╞══>╣ \n");
printf (" │Spectrum │ │ Sound Receiver │ ╟─ Rear \n");
printf (" └──────────│ └─────────────────┘ ╙─ Right \n\n");
printf ("NOTE: Dolby Surround Sound is a registered trademark of Dolby Labs, Inc.\n\n");
printf ("Type a key to continue...");
GetKey (1);
printf ("\r \n");
}
if (flags & 0x04) {
printf ("To Use: DOS> MVSA -Fxxxxx -K -Mxx -Rxxxxx -X\n\n");
printf ("Where: -Fxxxxx is a raw PCM file to be played.\n");
printf (" -K Use this if you don't have a joystick.\n");
printf (" -Mxx is the mixer channel:\n");
printf (" 0 = for FM channels. 4 = Microphone.\n");
printf (" 2 = External Line-in jack. 5 = Pro Audio PCM. (default)\n");
printf (" 3 = Internal Line-in jack. 6 = PC Speaker.\n");
printf (" -Rxxxxx is the sample rate.\n");
printf (" -X to swap left and right channels\n\n");
printf ("This program uses a joystick to position the sound around the four speaker.\n");
printf ("If you do not have a joystick, then use the -K switch to use keyboard input.\n");
printf ("Other devices, such as, the FM chip may be selected via keys 0-7.\n\n");
}
}
; /*\
;---|*|----====< LoadDataBuffers >====----
;---|*|
;---|*| Load the buffers with the data from disk
;---|*|
; \*/
LoadDataBuffers ( )
{
FILE *inf;
char far *fp;
int n;
// get the block memory for the source data
if ((fp = SourceData = (char far *)_memmalloc(DmaSize)) == 0)
return(0);
// fill with silence
for (n=0;n<DmaSize;n++)
*fp++ = 0x80;
// load the file, if present
if (FileName) {
// open the file via a stream call...
if ((inf = fopen (FileName,"rb")) == 0) {
printf ("Unable to open the input file!!!\n");
return(0);
}
// read the entire file into the DMA buffer
n = fileno(inf);
fp = SourceData;
_asm {
push ds
mov ah,03fh
mov bx,[n]
mov cx,0x20
lds dx,[fp]
int 21h
pop ds
push ds
mov ah,03fh
mov bx,[n]
mov cx,[DmaSize]
lds dx,[fp]
mov di,dx
add di,cx
sub di,2
int 21h
mov bx,dx
mov ax,[bx]
mov [di],ax
pop ds
}
fclose (inf);
}
// Prime the system with the data for the start.
for (n=0;n<MaxBuffCount;n++)
FillNextBlock();
}
; /*\
;---|*|----====< PrintStats >====----
;---|*|
;---|*| Print several lines of statistics
;---|*|
; \*/
PrintStats(flags)
int flags;
{
static int oldy = -1;
// move the screen up if first pass
if (oldy == -1)
printf ("\n\n\n\n");
// on the first pass, get the old cursor row position
if (oldy == -1) {
oldy = CursorYPos() - 4; // give us four lines to work with
if (oldy < 0)
oldy = 0;
}
// position the cursor
SetCursor (0,oldy);
// print the data
if (flags & 0x01)
printf ("Joystick: x=%d y=%d \n",Xpos,Ypos);
else
printf ("\n");
if (flags & 0x02)
printf ("Left/Right: l=%d r=%d \n",LastLeftPos,LastRitPos);
else
printf ("\n");
if (flags & 0x04)
printf ("Mixer channel is %s (%d) \n",mixernames[mixerselect],mixerselect);
else
printf ("\n");
}
; /*\
;---|*|----====< ProcessKeys >====----
;---|*|
;---|*| process the keystrokes
;---|*|
; \*/
ProcessKeys()
{
int c;
// process the keys...
if ((c = GetKey(0)) != 0) {
if (c < 0x100) {
// escape will exit
if (c == 0x1B)
return(-1);
// process any of the keys 0-9
if (isdigit(c)) {
c -= '0';
if ( !((mixerchannels[c<<1] == -1) || (c > 7)) )
mixerselect = c;
PrintStats (0x04);
}
}
else {
switch (c) {
// left arrow
case 0x4B00:
if (Xpos)
Xpos--;
break;
// right arrow
case 0x4D00:
if (Xpos < 256)
Xpos++;
break;
// up arrow
case 0x4800:
if (Ypos)
Ypos--;
break;
// down arrow
case 0x5000:
if (Ypos < 256)
Ypos++;
break;
default:
break;
}
}
MoveMixers ( mixerselect );
}
return(0);
}
; /*\
;---|*|----====< MoveMixers >====----
;---|*|
;---|*| Move the mixer channels around with the Joystick. This routine
;---|*| does the magic of simulating surround sound encoding.
;---|*|
; \*/
MoveMixers(ch)
int ch;
{
unsigned int l;
unsigned int r;
unsigned int cheat = 50; // MVA508 adjustment to keep the volumes up higher
int path = BI_INPUTMIXER;
int y;
// convert linear Xpos to a curve for both left and right channels
r = scalers[0] - (l = scalers[Xpos]);
// we want to give the Y coordinate a half curve so it is loudest when
// directly in front of us.
y = Ymid - ((Ypos > Ymid) ? (Ymid*2 - Ypos) : Ypos);
// y is now some value between 0 & 127, where 127 is loudest, 0 is off
y = scalers[y<<1]; // get the curve by multiplying by 2
// The proaudio mixer API works on a percentage scale, so...
// ...scale it into 0-100
r = r * 100 / 256 * y / 100 + cheat;
l = l * 100 / 256 * y / 100 + cheat;
// make sure the percentage stays within range
if (l > 100) l = 100;
if (l < 0) l = 0;
if (r > 100) r = 100;
if (r < 0) r = 0;
// If the Y position is behind us, send the right channel
// to the record path of the mixer.
if (Ypos >= Ymid)
path = BI_OUTPUTMIXER;
// swap left and right, if the users wants this done...
if (swaplr) {
l ^= r;
r ^= l;
l ^= r;
}
// move the volumes in the mixer. The right channel gets delayed if
// the joystick is moved behind us.
cMVSetMixerFunction( LastLeftPos=l, BI_INPUTMIXER, mixerchannels[(ch<<1)+0] );
cMVSetMixerFunction( LastRitPos =r, path, mixerchannels[(ch<<1)+1] );
}
; /*\
;---|*|----====< ReadJoyStick >====----
;---|*|
;---|*| We will now read the joystick settings from the BIOS
;---|*|
; \*/
ReadJoyStick(xscale,yscale)
int xscale;
int yscale;
{
int AXpos; // joystick A X position
int AYpos; // joystick A Y position
int BXpos; // joystick B X position
int BYpos; // joystick B Y position
_asm {
// get the coordinates
mov ah,84h
mov dx,1
int 15h
mov AXpos,ax
mov AYpos,bx
mov BXpos,cx
mov BYpos,dx
mov ah,84h
sub dx,dx
int 15h
shr al,4
cbw
xor al,0x0f
mov [ButtonState],ax
// scale them down to 0-256
mov ax,[AXpos]
mov cx,[xscale]
mul cx
mov cx,100
div cx
inc ax
mov [Xpos],ax
mov ax,[AYpos]
mov cx,[yscale]
mul cx
mov cx,100
div cx
inc ax
mov [Ypos],ax
}
}
; /*\
;---|*|----====< SetCursor >====----
;---|*|
;---|*| position the cursor to a new X/Y
;---|*|
; \*/
SetCursor (x,y)
int x,y;
{
// go through the bios
_asm {
mov ah,02h
mov bx,0
mov dh,byte ptr [y]
mov dl,byte ptr [x]
int 10h
}
}
; /*\
;---|*|----====< SetupSound >====----
;---|*|
;---|*| Setup the sound output routines
;---|*|
; \*/
SetupSound()
{
// setup the sound routines
InitMVSound();
InitPCM();
if (!GetMixers())
return(0);
// setup our callback routine
UserFunc( ((void(far*)())&FillNextBlock) );
// allocate and verify the dma buffer memory
if ((DMABuffPtr = (char huge *)_memmalloc((unsigned long)DmaSize*8)) == 0)
return(0);
if ((StartOfDMABuffer=FindDMABuffer(DMABuffPtr,(DmaSize*4)/1024)) == 0)
return (0);
// if the low level code doesn't like it, bomb out
if (!DMABuffer ( StartOfDMABuffer, DmaSize*4/1024, MaxBuffCount ))
return(0);
// variable rate, stereo, no compression, and 16 bit PCM
PCMInfo( SampleRate , 1, 0, 16 );
return(-1);
}
; /*\
;---|*|----====< SurroundFill >====----
;---|*|
;---|*| This routine fill the next portion of the DMA buffer.
;---|*|
; \*/
void SurroundFill(trg,src,len)
char far *trg;
char far *src;
int len;
{
int Lmul;
int Rmul;
unsigned int Rinv = 0x00;
char far *tp = scalers;
// calculate the multiplyers based on the current X/Y
Lmul = 255;
Rmul = 255;
// move all the data into the target buffer
_asm {
push si
push di
push es
push ds
mov cx,[len]
les di,[trg] // get the target pointer
lds si,[src] // get the source buffer
cld
;
sufi05:
mov ds,word ptr [src+2] // reload the target segment
mov al,[si] // get the first sample
xor al,0x80
cbw
mov bx,[Lmul]
mul bl // scale it...
stosw
mov ds,word ptr [src+2] // reload the target segment
lodsb // reload the first sample
xor al,0x80
cbw
mov bx,[Rmul]
mul bl // scale it...
xor ax,[Rinv] // maybe invert the right channel
sub ax,[Rinv]
stosw
loop sufi05 // do all the samples
pop ds
pop es
pop di
pop si
}
}
; /*\
;---|*| end of MVSA.C
; \*/