Category : Music and Digitized Voice
Archive   : PAS-SDK1.ZIP
Filename : DIALOG.C
; |*| $Author: BCRANE $
; |*|
; |*| $Date: 09 Sep 1992 13:44:30 $
; |*|
; |*| $Header: X:/sccs/mixers/dialog.c_v 1.11 09 Sep 1992 13:44:30 BCRANE $
; |*|
; |*| $Log: X:/sccs/mixers/dialog.c_v $
*
* Rev 1.11 09 Sep 1992 13:44:30 BCRANE
* changed MixerRect, RecordRect, and all mixer elements start and end x-coords
* up 1.
*
* Rev 1.10 04 Sep 1992 13:24:42 BCRANE
* changed bottom coordinate of MixerRect
*
* Rev 1.9 02 Sep 1992 10:03:04 BCRANE
* added SB volume control
*
* Rev 1.8 22 Jul 1992 08:21:14 BCRANE
* added #if USEMIXERGET to use either MixerGetSettings with
* callback to "subsavecurrent" or "savecurrent". Currently set
* to 1 to use MixerGetSettings.
*
* Rev 1.7 13 Jul 1992 11:57:02 BCRANE
* changed F3/SF3 to F5-F8/SF5-SF8
* now saves setting#.pas where # is 0-3
* modified F1 help to indicate this new feature
*
* Rev 1.6 13 Jul 1992 09:41:56 DCODY
* GetMixerSettings now reports dead mixer settings
*
* Rev 1.5 10 Jul 1992 16:57:44 BCRANE
* changed INPUT to MIXER
*
* Rev 1.4 10 Jul 1992 16:38:52 BCRANE
* finalized (!) save and load defaults - handles input/output mixers
* last-one-active situation, as well as absolute vs. percent values
*
* Rev 1.3 09 Jul 1992 17:45:16 BCRANE
* added load and save current state and getdriverpath
* not fully complete
*
* Rev 1.2 01 Jul 1992 14:40:58 DCODY
* added OEM specific wording
*
* Rev 1.1 23 Jun 1992 16:44:32 DCODY
* PAS2 update
*
* Rev 1.0 15 Jun 1992 09:41:16 BCRANE
* Initial revision.
; |*|
; |*| /*$Logfile: X:/sccs/mixers/dialog.c_v $
; |*|
; |*| /*$Modtimes$
; |*|
; \*/
/*\
|*|---====< DIALOG.C -- PAS User interface module >====----
|*|
|*| Pro Audio Spectrum Mixer User Interface program. This
|*| program provides mixer control from the command line.
|*|
|*| Media Vision, Inc. Copyright (c) 1991, All rights reserved
|*|
\*/
/* minor revisions to allow integration with audiolnk (large model) */
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "dialog.h"
#include
#ifndef OEM
#define OEM 0
#endif
/*\
|*|----====< some prototypes >====----
\*/
int EqualizerLevels ( );
int ScrollObjectHandler ( );
int SwitchObjectHandler ( );
int VolumeLevels ( );
int VolumeButtons ( );
int EffectsButtons ( );
/*\
|*|----====< global data >====----
\*/
#define TRUE -1
#define FALSE 0
static char makemenull[]="";
static char *screenlayout[] = {
"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿",
#if OEM
"³ Spectrum ³",
#else
"³Media Vision Pro AudioSpectrum ³",
#endif
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅ",
"³ FM ³³³",
"³ Synthesizer³³³",
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´ Ã",
"³ External ³³³",
"³ Jack ³³³",
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´ Ã",
"³ Internal ³³³",
"³ Connector ³³³",
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´ Ã",
"³ Microphone ³³³",
"³ Jack ³³³",
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´ Ã",
"³ PC ³³³",
"³ Speaker ³³³",
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´ Ã",
"³ SB Digital ³³³",
"³ Audio ³³³",
"ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´ Ã",
"³ Digital ³³³",
"³ Audio ³³³",
"ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"
};
static char *screen2[] = {
"ÚÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿",
"³Volume ³ Volume Control ³ ³",
"ÃÄÄÄÄÄÄÂÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´",
"³Left ³³³³",
"³Right ³³³³",
"ÃÄÄÄÄÄÄÅÄ´ ÃÄ´",
"³Bass ³³³³",
"ÃÄÄÄÄÄÄÅÄ´ ÃÄ´",
"³Treble³³³³",
"ÀÄÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ",
"ÚÄÄÄÄÄÄÄÄÄÄÄÂÄÂÄÄÄÄÄÄÄÄÄÄÄÂÄ¿",
"³ Loudness ³³ Enhanced ³³",
"ÀÄÄÄÄÄÄÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÁÄÙ",
};
static char *screen3[] = {
"ÄÉÍÍÍÍÍÍ»",
"ºPlay &º",
"ºRecordº",
"ÄÌÍÍÍÍÍ͹",
"ºPlay &º",
"ºRecordº",
"ÄÌÍÍÍÍÍ͹",
"ºPlay &º",
"ºRecordº",
"ÄÌÍÍÍÍÍ͹",
"ºPlay &º",
"ºRecordº",
"ÄÌÍÍÍÍÍ͹",
"ºPlay &º",
"ºRecordº",
"ÄÌÍÍÍÍÍ͹",
"ºPlay &º",
"ºRecordº",
"ÄÌËËËËË˹",
"ÌÎÎÎÎÎι",
"ÌÎÎÎÎÎι",
"ÄÈÊÊÊÊÊʼ",
};
static char *screen4[] = { /* Help2rect */
"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿",
"³ Type the F1 key for help. ³",
"ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"
};
static char EffectsString[] = "±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±";
static char *effectsbkgn[] = {
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString,
EffectsString
};
static char *screen5[] = { /* input mixer helps */
"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿",
"³ Channel Connections ³",
"ÃÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ´",
"³ Left ³³ Left ³",
"³ Left ³³ Right ³",
"³ Right ³³ Left ³",
"³ Right ³³ Right ³",
"ÀÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÙ"
};
static char *screen6[] = { /* input mixer helps */
"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿",
"³ Recording Monitor Level ³",
"ÃÄÄÄÄÄÄÂÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ´",
"³Left ³³³³",
"³Right ³³³³",
"ÀÄÄÄÄÄÄÁÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ"
};
static char *screen7[] = { /* realsound switch */
"ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄ¿",
"³ Real Sound Support ³³",
"ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÙ"
};
static char playmsgi1[] = "Play &";
static char playmsgi2[] = "Record";
static char playmsgo1[] = "Play ";
static char playmsgo2[] = "Only ";
static char *helpscreen[] = {
"ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»",
#if OEM
"º Spectrum º",
"º º",
#else
"º Pro AudioSpectrum, V1.21 º",
"º By Media Vision, Inc. º",
#endif
"ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ",
"º Keyboard Control º",
"º ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ º",
"ºHOME to decrease left volume º",
"º to decrease both volumes º",
"º END to decrease right volume º",
"ºPGUP to increase left volume º",
"º 3 to increase both volumes º",
"ºPGDN to increase right volume º",
"ºENTER to toggle a button on/offº",
"º TAB to move between fields º",
"º F4 reset mixer to defaults º",
"º F2 special effects º",
"ºF5-F8 load mixer settings (use º",
"º Shifted-FKEY to save) º",
"º ESC will exit all dialogs º",
"º ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ º",
"º Copyright (c) 1991 º",
"º All Rights Reserved. º",
"ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ"
};
static char twobar[] = "úúúúúùùùùù";
static char channelconnect[] = "";
static char channeldisconnect[] = "ú ú ú ú ú";
extern char leftswitch;
extern int leftvolume;
extern char ritswitch;
extern int ritvolume;
extern int VolumeNumber;
extern char VolumeSwitch;
extern int Left2LeftState;
extern int Left2RightState;
extern int Right2LeftState;
extern int Right2RightState;
// static char NumLockState;
static VideoStruct OurWnd = { 0,0,0x18,0x4f, 0,0, 0x1f,0, 0,0xb800 };
VideoStruct *CurWnd = &OurWnd;
unsigned int VideoSegment = 0xb800;
static rect Help1Rect = { 1,23, 23,57 };
static rect Help2Rect = {19,47, 21,77 };
static rect MixerRect = { 0, 2, 23,36 };
static rect RecordRect = { 2,35, 23,45 };
static rect VolRect = { 4,47, 16,77 };
static rect EffectsRect = { 1,20, 22,60 };
static rect Screen6Rect = { 2,25, 7,55 };
static rect Screen5Rect = { 9,25, 16,55 };
static rect Screen7Rect = {18,25, 20,55 };
/* file handle for accessing MVPROAS */
static int mv; /* mvsound dos driver */
/* objects */
#define OBJ_SCROLL 1
#define OBJ_VOLUME 2
#define OBJ_BUTTON 3
typedef struct {
int type; // structure type
void *next; // next structure pointer
void *back; // prior structure pointer
int (*scr)(); // object processor
int (*swi)(); // object processor
rect namr; // channel name rectangle
rect scrr; // scroll bar rectangle
rect swir; // record mixer select switch rectangle
char name[10]; // channel name "mic"/"ext", etc
int leftchannel; // current left channel setting
int ritchannel; // current right channel setting
int mixerselect; // choosen mixer
int deadlchannel; // current left channel setting
int deadrchannel; // current right channel setting
int deadmixer; // choosen mixer
} Scroll, *SPtr;
typedef struct {
int type; // structure type
void *next; // next structure pointer
void *back; // prior structure pointer
int (*scr)(); // object processor
rect namr; // channel name rectangle
rect scrr; // scroll bar rectangle
char name[20]; // channel name "mic"/"ext", etc
int channel; // current channel setting
} Volume, *VPtr;
typedef struct {
int type; // structure type
void *next; // next structure pointer
void *back; // prior structure pointer
int (*scr)(); // object processor
rect namr; // channel name rectangle
rect scrr; // scroll bar rectangle
char name[20]; // channel name "mic"/"ext", etc
int state; // current button state
} Button, *BPtr;
typedef struct {
void *head;
void *tail;
void *nextlist;
} ObjectList, *OLPtr;
// Scroll bar objects
static Scroll SynthScroll; // structure prototypes
static Scroll ExtScroll;
static Scroll IntScroll;
static Scroll MicScroll;
static Scroll DigitalScroll;
static Scroll TBScroll;
static Scroll SpkrScroll;
static Scroll OutputMixerScroll;
static Volume LeftVolumeLevel;
static Volume RitVolumeLevel;
static Volume BassVolume;
static Volume TrebVolume;
static Button Loudness;
static Button Enhanced;
static Button Left2Left;
static Button Left2Right;
static Button Right2Left;
static Button Right2Right;
static Button RealSoundButton;
static ObjectList MainList;
static ObjectList EffectsList;
static ObjectList MainList = {
&SynthScroll,
&Enhanced,
&EffectsList
};
static ObjectList EffectsList = {
&OutputMixerScroll,
&RealSoundButton,
0
};
static OLPtr CurrList = &MainList;
static Scroll *CurrentObject = &SynthScroll; // current object pointer
static Scroll SynthScroll = {
OBJ_SCROLL,
&ExtScroll,
0,
&ScrollObjectHandler,
&SwitchObjectHandler,
3, 3, 4,14,
3,18, 4,33,
3,37, 4,42,
"FM ",
0,
0,
0,0,0,0
};
static Scroll ExtScroll = {
OBJ_SCROLL,
&IntScroll,
&SynthScroll,
&ScrollObjectHandler,
&SwitchObjectHandler,
6, 3, 7,14,
6,18, 7,33,
6,37, 7,42,
"EXT ",
0,
0,
0,0,0,0
};
static Scroll IntScroll = {
OBJ_SCROLL,
&MicScroll,
&ExtScroll,
&ScrollObjectHandler,
&SwitchObjectHandler,
9, 3,10,14,
9,18,10,33,
9,37,10,42,
"INT ",
0,
0,
0,0,0,0
};
static Scroll MicScroll = {
OBJ_SCROLL,
&SpkrScroll,
&IntScroll,
&ScrollObjectHandler,
&SwitchObjectHandler,
12, 3,13,14,
12,18,13,33,
12,37,13,42,
"MIC ",
0,
0,
0,0,0,0
};
static Scroll SpkrScroll = {
OBJ_SCROLL,
&TBScroll,
&MicScroll,
&ScrollObjectHandler,
&SwitchObjectHandler,
15, 3,16,14,
15,18,16,33,
15,37,16,42,
"SPEAKER ",
0,
0,
0,0,0,0
};
static Scroll TBScroll = {
OBJ_SCROLL,
&DigitalScroll,
&SpkrScroll,
&ScrollObjectHandler,
&SwitchObjectHandler,
18, 3,19,14,
18,18,19,33,
18,37,19,42,
"SB ",
0,
0,
0,0,0,0
};
static Scroll DigitalScroll = {
OBJ_SCROLL,
&LeftVolumeLevel,
&TBScroll,
&ScrollObjectHandler,
0,
21, 3,22,14,
21,18,22,33,
21,37,22,42,
"PCM ",
0,
0,
0,0,0,0
};
static Volume LeftVolumeLevel = {
OBJ_VOLUME,
&BassVolume,
&DigitalScroll,
&VolumeLevels,
7,48, 7,53,
7,57, 7,72,
"LEVEL ",
0
};
// this object is owned byte LeftVolumeLevel
static Volume RitVolumeLevel = {
OBJ_VOLUME,
0,
0,
&VolumeLevels,
8,48, 8,53,
8,57, 8,72,
"LEVEL ",
0
};
static Volume BassVolume = {
OBJ_VOLUME,
&TrebVolume,
&LeftVolumeLevel,
&EqualizerLevels,
10,48,10,53,
10,57,10,72,
"BASS ",
0
};
static Volume TrebVolume = {
OBJ_VOLUME,
&Loudness,
&BassVolume,
&EqualizerLevels,
12,48,12,53,
12,57,12,72,
"TREBLE ",
0
};
static Button Loudness = {
OBJ_BUTTON,
&Enhanced,
&TrebVolume,
&VolumeButtons,
15,48,15,58,
15,60,15,60,
"LOUDNESS ",
0
};
static Button Enhanced = {
OBJ_BUTTON,
0,
&Loudness,
&VolumeButtons,
15,63,15,72,
15,74,15,74,
"ENHANCED ",
0
};
/*\
|*| effects dialog box structures
\*/
static Scroll OutputMixerScroll = {
OBJ_SCROLL,
&Left2Left,
0,
&ScrollObjectHandler,
0,
5,26,6,31,
5,35,6,50,
0, 0, 0, 0,
"MIXER ",
0,
0,
0,0,0,0
};
static Button Left2Left = {
OBJ_BUTTON,
&Left2Right,
&OutputMixerScroll,
&EffectsButtons,
12,26,12,33,
12,35,12,43,
"Left to Left ",
0
};
static Button Left2Right = {
OBJ_BUTTON,
&Right2Left,
&Left2Left,
&EffectsButtons,
13,26,13,33,
13,35,13,43,
"Left to Right ",
0
};
static Button Right2Left = {
OBJ_BUTTON,
&Right2Right,
&Left2Right,
&EffectsButtons,
14,26,14,33,
14,35,14,43,
"Right to Left ",
0
};
static Button Right2Right = {
OBJ_BUTTON,
&RealSoundButton,
&Right2Left,
&EffectsButtons,
15,26,15,33,
15,35,15,43,
"Right to Right ",
0
};
static Button RealSoundButton = {
OBJ_BUTTON,
0,
&Right2Left,
&EffectsButtons,
19,26,19,49,
19,52,19,52,
" ",
0
};
static int OrigRow; // original row position
static int OrigCol; // original column position
static char CommandString[80]; // text buffer that holds commands to MVPROAS
static char MVResponse[80]; // text buffer that holds the MVPROAS responses
static int screenbuffer[2048]; // screen backup buffer
#define MAIN_DLG 0x0001 // main screen dialog boxes
#define EFFECTS_DLG 0x0002 // recording effects dialog box
static int DialogBox=MAIN_DLG; // bit field indicating witch dialog box is up
typedef struct {
int Filler; // all other screen area
int BkGn_AND; // background AND mask
int BkGn_XOR; // background XOR mask
int Shdw_AND; // shadow AND mask
int Shdw_XOR; // shadow XOR mask
int TmpHi_AND; // temp High AND mask
int TmpHi_XOR; // temp high XOR mask
int TmpLo_AND; // temp low AND mask
int TmpLo_XOR; // temp low XOR mask
int ScrTmpHi_AND; // temp High AND mask
int ScrTmpHi_XOR; // temp high XOR mask
int ScrTmpLo_AND; // temp low AND mask
int ScrTmpLo_XOR; // temp low XOR mask
int ButLo_AND; // button low AND mask
int ButLo_XOR; // button low XOR mask
int ButHi_AND; // button high AND mask
int ButHi_XOR; // button high XOR mask
} scheme, *SCMPtr;
static scheme MonoScheme = { // attribute control for MONO screens
0x0e, // full bright
0x00, // background AND mask
0x07, // background XOR mask
0x77, // shadow AND mask
0x00, // shadow XOR mask
0x77, // temp High AND mask
0x08, // temp high XOR mask
0x77, // temp low AND mask
0x00, // temp low XOR mask
0x77, // scroll temp High AND mask
0x08, // scroll temp high XOR mask
0x77, // scroll temp low AND mask
0x00, // scroll temp low XOR mask
0x00, // button low AND mask
0x1f, // button low XOR mask
0x08, // button high AND mask
0x70, // button high XOR mask
};
static scheme ColorScheme = { // attribute control for COLOR screens
0x09, // bright blue background
0x00, // background AND mask
0x30, // background XOR mask
0x00, // shadow AND mask
0x00, // shadow XOR mask
0x70, // temp High AND mask
0x0e, // temp high XOR mask
0x70, // temp low AND mask
0x00, // temp low XOR mask
0x70, // scroll temp High AND mask
0x0e, // scroll temp high XOR mask
0x70, // scroll temp low AND mask
0x0a, // scroll temp low XOR mask
0x00, // button low AND mask
0x37, // button low XOR mask
0x00, // button high AND mask
0x3f, // button high XOR mask
};
static scheme HelpsColorScheme = { // attribute control for COLOR screens
0x09, // bright blue
0x00, // background AND mask
0x20, // background XOR mask
0x00, // shadow AND mask
0x00, // shadow XOR mask
0x77, // temp High AND mask
0x08, // temp high XOR mask
0x77, // temp low AND mask
0x00, // temp low XOR mask
0x77, // scroll temp High AND mask
0x08, // scroll temp high XOR mask
0x77, // scroll temp low AND mask
0x00, // scroll temp low XOR mask
0x08, // button low AND mask
0x17, // button low XOR mask
0x08, // button high AND mask
0x70, // button high XOR mask
};
static SCMPtr Colors = &ColorScheme; // default to color adapber scheme
/*\
|*|----====< more prototypes >====----
\*/
int MixerDialogInit ( );
int MixerDialogHalt ( );
static int BroadcastMsg ( int );
static int BroadcastToLlist ( int, ObjectList * );
static void DrawScreen ( rect *, char *([]) );
static int GetEvent ( EPtr );
static void MatchObj ( EPtr );
static void PaintScreen ( int );
static int PtInRect ( point *,rect * );
static int SendMixer ( char *, int, int, SPtr, int, int );
static int SendVolume ( char *, int, VPtr, int, int );
static int SystemKey ( EPtr );
static int SystemInit ( );
static void SystemShutDown ( );
extern void BackupVideo ( rect *, char far *, int, int );
extern void RestoreVideo ( rect *, char far *, int, int );
long extern _videogetcurs ( ); /* ***** was near kdn */
/*\
|*|----------------==============================----------------
|*|----------------====< Start of Execution >====----------------
|*|----------------==============================----------------
\*/
static int exitcode = FALSE; // our exit flag
static int CallersFillChar; // Callers screen fill char (0) for none
MixerDialogBox(fill)
int fill;
{
Event ev;
char *s;
/* make the fill character available to the masses */
s = EffectsString;
if ((CallersFillChar = fill) != 0)
while (*s) *s++ = fill;
/* initialize the hardware. */
SystemInit();
/* go forever */
while (!exitcode) {
/* if a keyboard/mouse action, the pass to handlers */
if (GetEvent (&ev)) {
if (!SystemKey(&ev)) {
if (CurrentObject)
(*CurrentObject->scr)(OPEVENT,CurrentObject,&ev);
}
}
/* if no action, just move the cross hairs */
else
UpdateTotalVolume(); /* changes via keyboard */
MatchObj ( &ev ); /* find a new object */
}
/* exit back to caller */
SystemShutDown();
/* reset the exit code so we can process again... */
exitcode=FALSE;
}
/*\
|*|----====< MixerGetSettings() >====----
|*|
|*| call the user back with the appropriate data
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| 0 = okay, !0 = failure
|*|
\*/
MixerGetSettings(c)
void (*c)();
{
SPtr o;
OLPtr l;
/* start at the top & send to all objects, even the caller */
l = &MainList;
while (l) {
o = l->head;
while (o) {
// send the message to the next object
(*o->scr)(OPENINIT,o);
// if the dead mixer, then send this string too!
if (o->type == OBJ_SCROLL) {
SendMixer ("SET ",o->deadmixer,1,o,BI_SETTO,o->deadlchannel);
(*c)(&CommandString);
SendMixer ("SET ",o->deadmixer,2,o,BI_SETTO,o->deadrchannel);
(*c)(&CommandString);
}
(*o->scr)(SENDIT,o,c);
// go to next object
o = o->next;
}
l = l->nextlist;
}
}
/*\
|*|----====< MixerDialogInit() >====----
|*|
|*| Perform any startup needed
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| 0 = okay, !0 = failure
|*|
\*/
int MixerDialogInit()
{
// open the device
//if ((mv = open ("MVPROAS",O_RDWR, S_IREAD | S_IWRITE)) == -1) {
if ((mv = open ("MVPROAS",O_RDWR )) == -1) {
//_ttyout ("\acannot open the MVPROAS device!\n",0);
return(1);
}
// make an IBM PC right arrow appear in some text
helpscreen[10][3]= 26; /* used to be: hackaline[3] = 26; */
// everything is fine...
return (0);
}
/*\
|*|----====< MixerDialogHalt() >====----
|*|
|*| Perform any other shutdown
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| 0 = okay, !0 = failure
|*|
\*/
int MixerDialogHalt()
{
// close down the file handle
close (mv);
// everything is fine...
return (0);
}
/*\
|*|--------------------=======================--------------------
|*|--------------------====< Subroutines >====--------------------
|*|--------------------=======================--------------------
\*/
/*\
|*|----====< void BroadcastMsg ( int ) >====----
|*|
|*| This routine broadcasts a message to all objects.
|*|
\*/
static int BroadcastMsg (msg)
int msg;
{
SPtr o;
/* send to all linked lists of objects */
BroadcastToList (msg,&MainList);
BroadcastToList (msg,&EffectsList);
}
/*\
|*|----====< void BroadcastToList ( int, ObjectList * ) >====----
|*|
|*| This routine broadcasts a message to all objects.
|*|
\*/
static int BroadcastToList (msg,l)
int msg;
ObjectList *l;
{
SPtr o;
/* start at the top & send to all objects, even the caller */
o = l->head;
while (o) {
/* send the message to the next object */
(*o->scr)(msg,o);
/* go to next object */
o = o->next;
}
}
#if 0
/*\
|*|----====< void DupTheEvent ( EPtr, EPtr ); >====----
|*|
|*| Duplicate our event record.
|*|
\*/
void DupTheEvent ( EPtr, EPtr );
static void DupTheEvent(src,dst)
EPtr src,dst;
{
/* duplicate the event using an intrinsic function */
memcpy
(
(char *) dst,
(char *) src,
sizeof (Event)
);
}
#endif
/*\
|*|----====< int EffectsButtons() >====----
|*|
|*| Cross Channel object control
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int EffectsButtons(msg,o,ptr)
int msg;
BPtr o;
void *ptr;
{
void **pptr;
rect r;
int l,ri,i;
char c1,c2;
// get a pointer to the stack
pptr = &ptr;
// process the message
switch (msg) {
case OPEVENT:
switch (((EPtr)pptr[0])->buttons) {
case ENTER:
// ENTER here can toggle the buttons
o->state = ((o->state) ? FALSE : TRUE );
(*o->scr) (DRAWIT,o);
if (o == &RealSoundButton)
SendOnOff ("SET ","REALSOUND ",o);
else
SendOnOff ("SET ","CROSS ",o);
break;
default:
break;
}
break;
case SENDIT:
if (o == &RealSoundButton)
SendOnOff ("SET ","REALSOUND ",o);
else
SendOnOff ("SET ","CROSS ",o);
(*(void(*)())ptr)(&CommandString);
break;
case FOCUS_GIVEN:
// highlight the entire field
if (o == &RealSoundButton) {
//r.row2 = o->namr.row2;
//r.row1 = o->namr.row1;
//r.col2 = r.col1 = o->namr.col2+2;
//_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &r );
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &o->namr );
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
}
else {
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = (r.col1 = o->scrr.col2+2) + 7;
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &o->namr );
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &r );
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
}
break;
case FOCUS_TAKEN:
// remove the highlight from the entire field
if (o == &RealSoundButton) {
//r.row1 = o->namr.row1;
//r.row2 = o->namr.row2;
//r.col2 = r.col1 = o->namr.col2+2;
//_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &r );
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &o->namr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
}
else {
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = (r.col1 = o->scrr.col2+2) + 7;
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &o->namr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &r );
}
break;
case DRAWIT:
// move the cursor to the slide bar area
if (o == &RealSoundButton) {
_videosetcurs ( o->scrr.row1, o->scrr.col1 );
if (o->state)
_zipout ( "X" );
else
_zipout ( "ù" );
}
else {
_videosetcurs ( o->scrr.row1, o->scrr.col1 );
if (o->state)
_zipout ( channelconnect, 0);
else
_zipout ( channeldisconnect, 0);
}
break;
case OPENINIT:
// get the output mixer current state
if (o == &RealSoundButton) {
SendOnOff ("GET ","REALSOUND ",o);
o->state = (MVResponse[0] == '+') ? TRUE : FALSE;
}
else {
SendOnOff ("GET ","CROSS ",o);
DecodeCrossChannel (MVResponse);
if (o == &Left2Left)
o->state = Left2LeftState;
if (o == &Left2Right)
o->state = Left2RightState;
if (o == &Right2Left)
o->state = Right2LeftState;
if (o == &Right2Right)
o->state = Right2RightState;
}
break;
case CLEARIT:
default:
break;
}
}
/*\
|*|----====< int EqualizerLevels() >====----
|*|
|*| BASS/TREBLE slide bar object control
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int EqualizerLevels(msg,o,ptr)
int msg;
VPtr o;
void *ptr;
{
void **pptr;
rect r;
int l,ri,i;
char c1,c2;
// get a pointer to the stack
pptr = &ptr;
// process the message
switch (msg) {
case OPEVENT:
switch (((EPtr)pptr[0])->buttons) {
case ENDKEY:
case HOMEKEY:
case LFARROW:
if (o->channel > 0)
o->channel -= 4;
SendVolume
(
"SET ",
0,
o,
BI_SETTO,
o->channel
);
(*o->scr) (DRAWIT,o);
break;
case PGDNKEY:
case PGUPKEY:
case RIARROW:
if (o->channel < 100)
o->channel += 4;
SendVolume
(
"SET ",
0,
o,
BI_SETTO,
o->channel
);
(*o->scr) (DRAWIT,o);
break;
case ENTER:
// ENTER here can toggle the buttons
if (o == &BassVolume)
(*Loudness.scr)(msg,&Loudness,ptr);
if (o == &TrebVolume)
(*Enhanced.scr)(msg,&Enhanced,ptr);
break;
default:
break;
}
break;
case SENDIT:
SendVolume
(
"SET ",
0,
o,
BI_SETTO,
o->channel
);
(*(void(*)())ptr)(&CommandString);
break;
case FOCUS_GIVEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &o->namr );
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &r );
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r );
break;
case FOCUS_TAKEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &o->namr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
break;
case DRAWIT:
// move the cursor to the slide bar area
_videosetcurs ( o->scrr.row1, o->scrr.col1 );
_zipout ( twobar, 0);
l = (o->channel * 31) / 100;
_videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
_zipout (((l & 1) ? "Þ" : "Ý"), 0);
break;
case OPENINIT:
// get the output mixer current state
SendVolume ("GET ",0,o,0,0);
DecodeVolumeNumber (MVResponse);
o->channel = VolumeNumber;
break;
case CLEARIT:
default:
break;
}
}
/*\
|*|----====< int GetEvent ( EPtr ) >====----
|*|
|*| This routine fetches the next event from the mouse driver
|*|
|*| This routine is used by permission from Douglas S. Cody
|*| Douglas S. Cody, Copyright 1989,1990 (c), All Rights Reserved.
|*|
\*/
static int GetEvent (e)
EPtr e;
{
// if there is a key waiting...
if (_bios_keybrd( _KEYBRD_READY )) {
// ...return it
e->type = EV_KEYB;
return (e->buttons = _bios_keybrd ( _KEYBRD_READ ));
}
// ...else return 0
return( 0 );
}
/*\
|*|----====< void MatchObj(EPtr) >====----
|*|
|*| This routine matches the mouse pointer to a screen object
|*|
\*/
static void MatchObj(e)
EPtr e;
{
SPtr o;
#if 0
// if this is a mouse type, match it to the list
if (e->type == EV_MOUS) {
// if point is still within the current object, just return
if (PtInRect ((point *)&e->vpos,&CurrentObject->scrr) ||
PtInRect ((point *)&e->vpos,&CurrentObject->scrr))
return;
// we must take the focus away so we don't send bogus mouse events
(*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
// the mouse is pointing to something else. try to find it
o = CurrList->head;
while (o) {
if (PtInRect ((point *)&e->vpos,&o->scrr) ||
PtInRect ((point *)&e->vpos,&o->swir)) {
// focus given if the object takes mouse events
CurrentObject = o;
(*o->scr) (FOCUS_GIVEN,o);
break;
}
o = o->next;
}
}
#endif
}
/*\
|*|----====< void DrawScreen (rect *, char *argv[]) >====----
|*|
|*| Perform the screen draw for this screen
|*|
|*| Entry Conditions:
|*| 2 parms
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static void DrawScreen (r,txt)
rect *r;
char *txt[];
{
rect wr;
int x;
// inner box color
wr.row1 = r->row1;
wr.row2 = r->row2;
wr.col1 = r->col1;
wr.col2 = r->col2-2;
_videoattr (Colors->BkGn_AND,Colors->BkGn_XOR,&wr);
// vertical right side shadow
wr.row1 = r->row1+1;
wr.row2 = r->row2+1;
wr.col1 = r->col2-1;
wr.col2 = r->col2+0;
_videoattr (Colors->Shdw_AND,Colors->Shdw_XOR,&wr);
// horizontal bottom shadow
wr.row1 = wr.row2;
wr.col1 = r->col1+2;
_videoattr (Colors->Shdw_AND,Colors->Shdw_XOR,&wr);
// actual text
if (txt) {
for (x=r->row1;x<=r->row2;x++) {
_videosetcurs (x,r->col1);
_zipout (txt[x-r->row1],0);
}
}
// change some attributes on the color screen
if (VideoSegment == 0xb800)
ChangeAttributes (r->row1, r->col1, r->row2, r->col2-2);
}
/*\
|*|----====< PaintScreen (int) >====----
|*|
|*| Draw/Restore the screen
|*|
|*| Entry Conditions:
|*| INT is a TRUE/FALSE flag
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static void PaintScreen (tf)
int tf;
{
rect r;
static int backedup = FALSE;
if (tf) { // paint the screen
if (!backedup)
BackupVideo ( &OurWnd.wndr, (char far *)&screenbuffer[0], 0, 0 );
backedup = TRUE;
if (CallersFillChar)
_videofill ( CallersFillChar, Colors->Filler, &OurWnd.wndr );
DrawScreen ( &MixerRect, &screenlayout[0] );
r.row2 = r.row1 = MixerRect.row1+1;
r.col1 = MixerRect.col1+1;
r.col2 = MixerRect.col2-3;
_videoattr ( Colors->ButHi_AND, Colors->ButHi_XOR,&r);
DrawScreen ( &RecordRect, &screen3[0] );
DrawScreen ( &VolRect, &screen2[0] );
DrawScreen ( &Help2Rect, &screen4[0] );
}
else {
if (backedup) {
RestoreVideo ( &OurWnd.wndr, (char far *) &screenbuffer[0], 0, 0 );
backedup = FALSE;
}
}
}
/*\
|*|----====< ProcessRecordEffects (int) >====----
|*|
|*| Process the Effects dialog box
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static void ProcessRecordEffects(msg)
int msg;
{
rect r;
static void *ol;
static void *effectslastobj;
static void *effectscurrobj;
switch (msg) {
case DRAWIT:
DrawScreen ( &EffectsRect, &effectsbkgn[0] );
DrawScreen ( &Screen6Rect, &screen6[0] );
DrawScreen ( &Screen5Rect, &screen5[0] );
DrawScreen ( &Screen7Rect, &screen7[0] );
BroadcastToList (DRAWIT,CurrList); // draw the controls
break;
case FOCUS_GIVEN:
// let the current object know its not in foreground
(*CurrentObject->scr)(FOCUS_TAKEN,CurrentObject);
// switch linked lists and current objects
ol = CurrList; // switch object lists
CurrList = &EffectsList;
effectslastobj = CurrentObject; // switch objects
if ((CurrentObject = effectscurrobj) == 0)
CurrentObject = CurrList->head;
// paint the screen
ProcessRecordEffects(DRAWIT);
(*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // highlight
// all done till a FOCUS_TAKEN is received
break;
case FOCUS_TAKEN:
// let the current object know its not in foreground
(*CurrentObject->scr)(FOCUS_TAKEN,CurrentObject);
// switch linked lists and current objects
CurrList = ol; // restore the old list
effectscurrobj = CurrentObject; // switch objects
if (effectslastobj)
CurrentObject = effectslastobj;
// restore the screen
PaintScreen (FALSE); // restore the screen
PaintScreen (TRUE); // put up the screen
BroadcastToList (DRAWIT,CurrList); // draw the controls
(*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // highlight
break;
default:
break;
}
}
/*\
|*|----====< PtInRect (point *, rect *) >====----
|*|
|*| return TRUE if point is within the rectangle
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int PtInRect (p,r)
point *p;
rect *r;
{
if ((p->row < r->row1) && (p->row >= r->row2))
return(FALSE);
if ((p->col < r->col1) && (p->col >= r->col2))
return(FALSE);
return (TRUE);
}
/*\
|*|----====< int ScrollObjectHandler() >====----
|*|
|*| Scroll bar object control
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int ScrollObjectHandler (msg,o,ptr)
int msg;
SPtr o;
void *ptr;
{
void **pptr;
rect r;
int l,ri,i,key;
char c1,c2;
// get a pointer to the stack
pptr = &ptr;
// process the message
switch (msg) {
case OPEVENT:
key = 0;
switch (((EPtr)pptr[0])->buttons) {
case ENDKEY: // right = 2;
key++;
case HOMEKEY: // left = 1;
key++;
case LFARROW: // both = 0;
if (key != 2) { // do LEFT on left/both cases
if (o->leftchannel > 0)
o->leftchannel -= 3;
SendMixer
(
"SET ",
o->mixerselect,
1,
o,
BI_SETTO,
o->leftchannel
);
}
if (key != 1) { // do RIGHT on right/both cases
if (o->ritchannel > 0)
o->ritchannel -= 3;
SendMixer
(
"SET ",
o->mixerselect,
2,
o,
BI_SETTO,
o->ritchannel
);
}
(*o->scr) (DRAWIT,o);
break;
case PGDNKEY: // right = 2;
key++;
case PGUPKEY: // left = 1;
key++;
case RIARROW: // both = 0;
if (key != 2) { // do LEFT on left/both cases
if (o->leftchannel < 100)
o->leftchannel += 3;
SendMixer
(
"SET ",
o->mixerselect,
1,
o,
BI_SETTO,
o->leftchannel
);
}
if (key != 1) { // do RIGHT on right/both cases
if (o->ritchannel < 100)
o->ritchannel += 3;
SendMixer
(
"SET ",
o->mixerselect,
2,
o,
BI_SETTO,
o->ritchannel
);
}
(*o->scr) (DRAWIT,o);
break;
default:
break;
}
break;
case SENDIT:
SendMixer ("SET ",o->mixerselect,1,o,BI_SETTO,o->leftchannel);
(*(void(*)())ptr)(&CommandString);
SendMixer ("SET ",o->mixerselect,2,o,BI_SETTO,o->ritchannel);
(*(void(*)())ptr)(&CommandString);
break;
case FOCUS_GIVEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &o->namr );
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &r );
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r );
if (o->swi)
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &o->swir );
break;
case FOCUS_TAKEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &o->namr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
if (o->swi)
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &o->swir );
break;
case DRAWIT:
// move the cursor to the slide bar area
_videosetcurs ( o->scrr.row1, o->scrr.col1 );
_zipout ( twobar, 0);
_videosetcurs ( o->scrr.row1+1, o->scrr.col1 );
_zipout ( twobar, 0);
l = (o->leftchannel * 31) / 100;
_videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
_zipout (((l & 1) ? "Þ" : "Ý"), 0);
l = (o->ritchannel * 31) / 100;
_videosetcurs ( o->scrr.row1+1, o->scrr.col1+(l>>1) );
_zipout (((l & 1) ? "Þ" : "Ý"), 0);
// display a mixer bar
if (o->swi) {
//if (o->mixerselect == BI_INPUTMIXER)
// _videoattr (Colors->ButHi_AND,Colors->ButHi_XOR,&o->swir);
//else
// _videoattr (Colors->ButLo_AND,Colors->ButLo_XOR,&o->swir);
if (o->mixerselect == BI_INPUTMIXER) {
_videosetcurs (o->swir.row1,o->swir.col1);
_zipout (playmsgi1);
_videosetcurs (o->swir.row1+1,o->swir.col1);
_zipout (playmsgi2);
}
else {
_videosetcurs (o->swir.row1,o->swir.col1);
_zipout (playmsgo1);
_videosetcurs (o->swir.row1+1,o->swir.col1);
_zipout (playmsgo2);
}
}
break;
case OPENINIT:
// get the output mixer current state
SendMixer ("GET ",BI_OUTPUTMIXER,0,o,0,0);
DecodeMixer (MVResponse);
if (leftswitch == '+') {
o->mixerselect = BI_OUTPUTMIXER;
o->leftchannel = leftvolume;
}
else {
o->deadmixer = BI_OUTPUTMIXER;
o->deadlchannel = leftvolume;
}
if (ritswitch == '+') {
o->mixerselect = BI_OUTPUTMIXER;
o->ritchannel = ritvolume;
}
else {
o->deadmixer = BI_OUTPUTMIXER;
o->deadrchannel = ritvolume;
}
// get the input mixer current state
SendMixer ("GET ",BI_INPUTMIXER,0,o,0,0);
DecodeMixer (MVResponse);
if (leftswitch == '+') {
o->mixerselect = BI_INPUTMIXER;
o->leftchannel = leftvolume;
}
else {
o->deadmixer = BI_INPUTMIXER;
o->deadlchannel = leftvolume;
}
if (ritswitch == '+') {
o->mixerselect = BI_INPUTMIXER;
o->ritchannel = ritvolume;
}
else {
o->deadmixer = BI_INPUTMIXER;
o->deadrchannel = ritvolume;
}
// make sure both inputs are on the same mixer
SendMixer ("SET ",o->mixerselect,1,o,BI_SETTO,o->leftchannel);
SendMixer ("SET ",o->mixerselect,2,o,BI_SETTO,o->ritchannel);
break;
case CLEARIT:
break;
default:
break;
}
}
/*\
|*|----====< int SendOnOff( char *, char *, int, VPtr, int, int ) >====----
|*|
|*| Send a mixer selection
|*|
|*| Entry Conditions:
|*| char *cmd = "SET", "GET"
|*| VPtr o = Volume device name
|*| int v = new volume setting
|*|
|*| Exit Conditions:
|*| MVResponse string holds the result
|*|
\*/
static int SendOnOff(cmd,dev,o)
char *cmd; // command
char *dev; // device
BPtr o; // channel name & state
{
// build the string
strcpy (CommandString,cmd); // command
strcat (CommandString,dev); // device name
strcat (CommandString,o->name); // input channel
strcat (CommandString,((o->state) ? "ON" : "OFF"));
SendTextOut (CommandString);
}
/*\
|*|----====< int SendMixer( char *, int, int, SPtr, int, int ) >====----
|*|
|*| Send a mixer selection
|*|
|*| char *cmd = "SET", "GET"
|*| int dev = INPUTMIXER or OUTPUTMIXER
|*| int lr = both(0),left(1),right(2)
|*| VPtr o = Volume device name
|*| int f = function (UP/DOWN/TO)
|*| int v = new volume setting
|*|
|*| Exit Conditions:
|*| MVResponse string holds the result
|*|
\*/
static int SendMixer (cmd,dev,lr,o,f,v)
char *cmd; // command
int dev; // device name
int lr; // left/right/both
SPtr o; // input channel name
int f; // movement function
int v; // new mixer value
{
char *fs,*ms,*lrs;
char val[7];
// get the text string equvalent for the function
switch (lr) {
case 1:
lrs = "LEFT "; // LEFT side only
break;
case 2:
lrs = "RIGHT "; // RIGHT side only
break;
case 0: // BOTH
default:
lrs = makemenull;
break;
}
// get the text string equvalent for the function
switch (f) {
case BI_SETTO:
fs = "TO ";
break;
case BI_UPTO:
fs = "UP ";
break;
case BI_DOWNTO:
fs = "DOWN ";
break;
default:
fs = makemenull;
break;
}
// correct the value
if (v < 0) v = 0;
if (v > 100) v = 100;
// build the string
ms = (dev == BI_OUTPUTMIXER) ? "OUTPUT MIXER " : "INPUT MIXER ";
itoa (v,val,10);
strcpy (CommandString,cmd); // command
strcat (CommandString,ms); // device name
strcat (CommandString,lrs); // left/right
strcat (CommandString,o->name); // input channel
strcat (CommandString,fs); // function (up/down/to)
strcat (CommandString,val); // new #
strcat (CommandString," PERCENT");
SendTextOut (CommandString);
}
/*\
|*|----====< int SendVolume( char *, int, VPtr, int, int ) >====----
|*|
|*| Send a mixer selection
|*|
|*| Entry Conditions:
|*| char *cmd = "SET", "GET"
|*| int lr = both(0),left(1),right(2)
|*| VPtr o = Volume device name
|*| int f = function (UP/DOWN/TO)
|*| int v = new volume setting
|*|
|*| Exit Conditions:
|*| MVResponse string holds the result
|*|
\*/
static int SendVolume (cmd,lr,o,f,v)
char *cmd; // command
int lr; // left/right/both
VPtr o; // channel name
int f; // movement function
int v; // new mixer value
{
char *fs,*ms,*lrs;
char val[7];
// get the text string equvalent for the function
switch (lr) {
case 1:
lrs = "LEFT "; // LEFT side only
break;
case 2:
lrs = "RIGHT "; // RIGHT side only
break;
case 0: // BOTH
default:
lrs = makemenull;
break;
}
// get the text string equvalent for the function
switch (f) {
case BI_SETTO:
fs = "TO ";
break;
case BI_UPTO:
fs = "UP ";
break;
case BI_DOWNTO:
fs = "DOWN ";
break;
default:
fs = makemenull;
break;
}
// correct the value on slide bars
if (o->type == OBJ_VOLUME) {
// fudge the volume to correct the rounding errors
if (++v < 0) v = 0;
if (v > 100) v = 100;
}
// build the string
itoa (v,val,10);
strcpy (CommandString,cmd); // command
strcat (CommandString,"VOLUME "); // device name
strcat (CommandString,lrs); // left/right
strcat (CommandString,o->name); // input channel
strcat (CommandString,fs); // function (up/down/to)
if (o->type == OBJ_VOLUME) {
strcat (CommandString,val); // new #
strcat (CommandString," PERCENT");
}
else
strcat (CommandString,((v) ? "ON" : "OFF"));
SendTextOut (CommandString);
}
/*\
|*|----====< int SendTextOut( char * ) >====----
|*|
|*| Send a text string to MVPROAS
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int SendTextOut(s)
char *s;
{
char *b;
b = s;
while (*b++) ;
write (mv,s,b-s);
_dlgflushfile(mv); // the below code is now in dialoga.asm
// _asm {
// mov bx,mv
// mov ah,45h
// int 21h
// jnc thisisbad
// mov bx,ax
// mov ah,3eh
// int 21h
// thisisbad:
// }
read (mv,MVResponse,80);
{
char *m= MVResponse;
do
if (*m == '\n')
*m= ' ';
while (*++m);
do
if (*m == ' ')
*m--= '\0';
else
m--;
while (isspace(*m));
}
}
/*\
|*|----====< int SwitchObjectHandler() >====----
|*|
|*| mixer selection switch object control
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int SwitchObjectHandler(msg,o,ptr)
int msg;
SPtr o;
void *ptr;
{
void **pptr;
// get a pointer to the stack
pptr = &ptr;
// process the message
switch (msg) {
case OPEVENT:
switch (((EPtr)pptr[0])->buttons) {
case ENTER:
// toggle the input/output mixer selection
if (o == &DigitalScroll)
break;
if (o->mixerselect == BI_OUTPUTMIXER)
o->mixerselect = BI_INPUTMIXER;
else
o->mixerselect = BI_OUTPUTMIXER;
SendMixer
(
"SET ",
o->mixerselect,
1,
o,
BI_SETTO,
o->leftchannel
);
SendMixer
(
"SET ",
o->mixerselect,
2,
o,
BI_SETTO,
o->ritchannel
);
(*o->scr) (DRAWIT,o);
default:
break;
}
break;
case SENDIT:
case FOCUS_GIVEN:
case FOCUS_TAKEN:
case DRAWIT:
case CLEARIT:
case OPENINIT:
default:
break;
}
}
/*\
|*|----====< int SystemKey(EPtr); >====----
|*|
|*| Check the event for a system keystroke.
|*|
\*/
static int SystemKey(e)
EPtr e;
{
Event ev;
rect r;
OLPtr ol;
// exit if not a keyboard event
if (e->type != EV_KEYB)
return(0);
// process it...
switch (e->buttons) {
case ESCAPE:
if (DialogBox & EFFECTS_DLG) {
ProcessRecordEffects(FOCUS_TAKEN);
DialogBox &= ~EFFECTS_DLG;
}
else
exitcode = TRUE;
return(1);
case ENTER:
if (CurrentObject->type == OBJ_SCROLL) {
if (CurrentObject->swi)
(*CurrentObject->swi) (OPEVENT,CurrentObject,e);
}
else
(*CurrentObject->scr) (OPEVENT,CurrentObject,e);
return(1);
case HOMEKEY:
case PGDNKEY:
case ENDKEY:
case PGUPKEY:
case PLUSKEY1:
case PLUSKEY2:
case MINUSKEY1:
case MINUSKEY2:
case RIARROW:
case LFARROW:
(*CurrentObject->scr) (OPEVENT,CurrentObject,e);
return(1);
case SH_TABKEY:
case UPARROW:
(*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
if (CurrentObject->back)
CurrentObject = CurrentObject->back;
else
CurrentObject = CurrList->tail;
(*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
return(TRUE);
case TABKEY:
case DNARROW:
(*CurrentObject->scr) (FOCUS_TAKEN,CurrentObject);
if (CurrentObject->next)
CurrentObject = CurrentObject->next;
else
CurrentObject = CurrList->head;
(*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
return(TRUE);
case F1KEY:
// draw the help screen
if (VideoSegment == 0xb800)
Colors = &HelpsColorScheme;
DrawScreen ( &Help1Rect, &helpscreen[0] );
// do some special highlighting for enhanced looks
if (VideoSegment == 0xb800) {
r.row2 = ( r.row1 = Help1Rect.row1 + 1) + 1;
r.col1 = Help1Rect.col1 + 1;
r.col2 = Help1Rect.col2 - 3;
_videoattr
(
0x00,
0x3f,
&r
);
}
// wait for a keystroke
while (!GetEvent (&ev)) ;
if (VideoSegment == 0xb800)
Colors = &ColorScheme;
// restore the screen
PaintScreen (FALSE); // restore the screen
PaintScreen (TRUE); // put up the screen
BroadcastToList (DRAWIT,&MainList); // draw the controls
if (DialogBox & EFFECTS_DLG) {
ProcessRecordEffects(DRAWIT);
BroadcastToList (DRAWIT,&EffectsList);
}
(*CurrentObject->scr)(FOCUS_GIVEN,CurrentObject); // re-highlight
return(TRUE);
case F2KEY:
// try to open and process the effects windows
if (!(DialogBox & EFFECTS_DLG)) {
// do not re-enter
DialogBox |= EFFECTS_DLG;
ProcessRecordEffects(FOCUS_GIVEN);
}
return(TRUE);
case F5KEY: /* F5-F8 load mixer settings from DOS file */
case F6KEY: /* subtract F5 scancode from key pressed */
case F7KEY: /* move high byte to low and use as index (0-3) */
case F8KEY:
loadcurrent((e->buttons- F5KEY)>> 8); /* open, read setting[0-3].pas and SendTextOut */
BroadcastMsg (OPENINIT); // tell everyone we are starting
BroadcastToList (DRAWIT,CurrList); // draw the controls
return(TRUE);
case SF5KEY: /* Shift F5-F8 save mixer settings into DOS file */
case SF6KEY: /* subtract SF5 scancode from key pressed */
case SF7KEY: /* move high byte to load and use as index (0-3) */
case SF8KEY:
savecurrent((e->buttons- SF5KEY)>> 8); /* save setting[0-3].pas */
return(TRUE);
case F4KEY:
// have all objects re-init themselves, then redraw
SendTextOut ("RESET"); // reset the mixers
BroadcastMsg (OPENINIT); // tell everyone we are starting
BroadcastToList (DRAWIT,CurrList); // draw the controls
return(TRUE);
default:
return(FALSE);
}
}
/*\
|*|----====< void SystemShutDown(); >====----
|*|
|*| Exits to the swapper to exit for good, or loads a program.
|*|
\*/
static void SystemShutDown()
{
// MouseInit ( OFF,OFF ); // kill the mouse
// restore the video
PaintScreen ( FALSE ); // take down the screen
_videosetcurs ( OrigRow, OrigCol ); // restore the cursor position
_videocshape ( -1, -1); // now, restore the original shape
// restore numlock
_dlgrestorenumlock(); // the below code is now in dialoga.asm
// _asm {
// push es ; save the numlock state
// sub ax,ax
// mov es,ax
// mov al,NumLockState
// or es:[0x417],al ; possibly set it
// pop es
// }
}
/*\
|*|----====< void SystemInit() >====----
|*|
|*| System wide initialization of the program
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int SystemInit()
{
int n;
long l;
/* setup the mouse & move to the middle of the wave window */
// MouseInit (ON,OFF);
// MouseAction (0x12); // left button down/up action
if (_videocard() == 1) { // if mono, point to that segment
VideoSegment = OurWnd.sseg = 0xb000;
Colors = &MonoScheme;
}
// get the original row, column and kill numlock
l = _videogetcurs();
OrigCol = (int) (l >> 16) & 0xffff;
OrigRow = (int) l & 0xffff;
_dlgsavenumlock(); // the below code is now in dialoga.asm
// _asm {
// push es ; save the numlock state
// sub ax,ax
// mov es,ax
// mov al,0x20
// and al,es:[0x417]
// and byte ptr es:[0x417],0xdf ; clear it...
// mov NumLockState,al
// pop es
// }
// turn off the cursor
_videocshape (0,0x20); // make it invisible
/* init all objects, then paint them on the screen */
BroadcastMsg (OPENINIT); // tell everyone we are starting
PaintScreen (TRUE); // put up the screen
BroadcastToList (DRAWIT,CurrList);// draw the controls
(*CurrentObject->scr) (FOCUS_GIVEN,CurrentObject);
// return good
return (0);
}
/*\
|*|----====< int VolumeButtons() >====----
|*|
|*| Volume slide bar object control
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int VolumeButtons (msg,o,ptr)
int msg;
BPtr o;
void *ptr;
{
void **pptr;
rect r;
int l,ri,i;
char c1,c2;
// get a pointer to the stack
pptr = &ptr;
// process the message
switch (msg) {
case OPEVENT:
switch (((EPtr)pptr[0])->buttons) {
case ENTER:
if (o->state)
o->state = 0;
else
o->state = -1;
SendVolume
(
"SET ",
0,
(VPtr) o,
BI_SETTO,
o->state
);
(*o->scr) (DRAWIT,o);
break;
case ENDKEY:
case HOMEKEY:
case LFARROW:
case PGDNKEY:
case PGUPKEY:
case RIARROW:
// Direction keys can move these sliders
if (o == &Loudness)
(*BassVolume.scr)(msg,&BassVolume,ptr);
if (o == &Enhanced)
(*TrebVolume.scr)(msg,&TrebVolume,ptr);
break;
default:
break;
}
break;
case SENDIT:
SendVolume
(
"SET ",
0,
(VPtr) o,
BI_SETTO,
o->state
);
(*(void(*)())ptr)(&CommandString);
break;
case FOCUS_GIVEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &o->namr );
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &r );
// r.row1 = o->scrr.row1;
// r.row2 = o->scrr.row2;
// r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
// _videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r );
break;
case FOCUS_TAKEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &o->namr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
// r.row1 = o->scrr.row1;
// r.row2 = o->scrr.row2;
// r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
// _videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
break;
case DRAWIT:
// move the cursor to the slide bar area
_videosetcurs ( o->scrr.row1, o->scrr.col1 );
if (o->state)
_zipout ( "X" );
else
_zipout ( "ù" );
break;
case OPENINIT:
// get the output mixer current state
SendVolume ("GET ",0,(VPtr)o,0,0);
DecodeVolumeSwitch (MVResponse);
o->state = (VolumeSwitch == '+') ? -1 : 0;
break;
case CLEARIT:
default:
break;
}
}
/*\
|*|----====< int UpdateTotalVolume() >====----
|*|
|*| update the screen if the user is typing the hot keys
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int UpdateTotalVolume()
{
int lv,rv;
static int delta;
static int mintic = 18;
static int minrest = 0;
//static int lasttime = 0;
// get the clock tic, this whole routine is done once a second
delta += _dlggettimedelta(); // the below code is now in dialoga.asm
// _asm {
// mov ah,0
// int 1Ah
// cmp lasttime,dx ; ax = delta of current/last time
// mov lasttime,dx
// adc delta,0
// }
// if the main dialog box is covered, we cannot draw, so just return
if (DialogBox & EFFECTS_DLG)
return(0);
// if the change is greater than 1 second, update the screen now...
if (delta > mintic) {
delta = 0;
lv = LeftVolumeLevel.channel;
rv = RitVolumeLevel.channel;
(*LeftVolumeLevel.scr)(OPENINIT,&LeftVolumeLevel);
if((lv != LeftVolumeLevel.channel) ||
(rv != RitVolumeLevel.channel)) {
minrest = (1*19)/4; // restore speed after 1 second
mintic = 2; // speed up polling
(*LeftVolumeLevel.scr)(DRAWIT,&LeftVolumeLevel);
}
if (minrest) // if fast poll
if (!--minrest) // check to see if we should
mintic = 18; // slow it down.
}
}
/*\
|*|----====< int VolumeLevels() >====----
|*|
|*| VOLUME LEFT/RIGHT control
|*|
|*| Entry Conditions:
|*| None
|*|
|*| Exit Conditions:
|*| None
|*|
\*/
static int VolumeLevels(msg,o,ptr)
int msg;
VPtr o;
void *ptr;
{
void **pptr;
rect r;
int l,ri,i;
char c1,c2;
#define VOLE_RAMPUP 0x4001 // ramp the volume up
#define VOLE_RAMPDN 0x4002 // ramp the volume down
// get a pointer to the stack
pptr = &ptr;
// process the message
switch (msg) {
case OPEVENT:
switch (((EPtr)pptr[0])->buttons) {
case ENDKEY:
VolumeLevels (VOLE_RAMPUP,&RitVolumeLevel,ptr);
break;
case HOMEKEY:
VolumeLevels (VOLE_RAMPUP,&LeftVolumeLevel,ptr);
break;
case LFARROW:
VolumeLevels (VOLE_RAMPUP,&LeftVolumeLevel,ptr);
VolumeLevels (VOLE_RAMPUP,&RitVolumeLevel,ptr);
break;
case PGDNKEY:
VolumeLevels (VOLE_RAMPDN,&RitVolumeLevel,ptr);
break;
case PGUPKEY:
VolumeLevels (VOLE_RAMPDN,&LeftVolumeLevel,ptr);
break;
case RIARROW:
VolumeLevels (VOLE_RAMPDN,&LeftVolumeLevel,ptr);
VolumeLevels (VOLE_RAMPDN,&RitVolumeLevel,ptr);
break;
default:
break;
}
break;
case SENDIT:
SendVolume // set the left
(
"SET ",
1,
&LeftVolumeLevel,
BI_SETTO,
LeftVolumeLevel.channel
);
(*(void(*)())ptr)(&CommandString);
SendVolume // set the right
(
"SET ",
2,
&RitVolumeLevel,
BI_SETTO,
RitVolumeLevel.channel
);
(*(void(*)())ptr)(&CommandString);
break;
case FOCUS_GIVEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &o->namr );
_videoattr ( Colors->TmpHi_AND, Colors->TmpHi_XOR, &r );
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &o->scrr );
_videoattr ( Colors->ScrTmpHi_AND, Colors->ScrTmpHi_XOR, &r );
// let the right channel know too!
if (o == &LeftVolumeLevel)
(*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
break;
case FOCUS_TAKEN:
// highlight the entire field
r.row1 = o->namr.row1;
r.row2 = o->namr.row2;
r.col2 = r.col1 = o->namr.col2+2;
_videoattr ( Colors->TmpLo_AND, Colors->TmpLo_XOR, &o->namr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
r.row1 = o->scrr.row1;
r.row2 = o->scrr.row2;
r.col2 = r.col1 = o->scrr.col2+2;
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &o->scrr );
_videoattr ( Colors->ScrTmpLo_AND, Colors->ScrTmpLo_XOR, &r );
// let the right channel know too!
if (o == &LeftVolumeLevel)
(*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
break;
case DRAWIT:
// move the cursor to the slide bar area
_videosetcurs ( o->scrr.row1, o->scrr.col1 );
_zipout ( twobar, 0);
l = (o->channel * 31) / 100;
_videosetcurs ( o->scrr.row1, o->scrr.col1+(l>>1) );
_zipout (((l & 1) ? "Þ" : "Ý"), 0);
// let the right channel know too!
if (o == &LeftVolumeLevel)
(*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
break;
case OPENINIT:
// get the output mixer current state
SendVolume
(
"GET ",
((o == &LeftVolumeLevel) ? 1 : 2),
o,
0,
0
);
DecodeVolumeNumber (MVResponse);
o->channel = VolumeNumber;
// let the right channel know too!
if (o == &LeftVolumeLevel)
(*RitVolumeLevel.scr)(msg,&RitVolumeLevel,ptr);
break;
case CLEARIT:
break;
case VOLE_RAMPUP:
// send the volume up
if (o->channel > 0)
o->channel -= 4;
SendVolume // set left/both/right
(
"SET ",
((o == &LeftVolumeLevel) ? 1 : 2),
o,
BI_SETTO,
o->channel
);
(*o->scr) (DRAWIT,o); // redraw it
break;
case VOLE_RAMPDN:
// send the volume down
if (o->channel < 100)
o->channel += 4;
SendVolume
(
"SET ",
((o == &LeftVolumeLevel) ? 1 : 2),
o,
BI_SETTO,
o->channel
);
(*o->scr) (DRAWIT,o);
break;
default:
break;
}
}
/*\
|*| end DIALOG.C
\*/
clrbuf(char *buf, int size)
{
int s;
for (s= 0; s < size; s++)
*buf++= '\0';
}
/* filename is catted onto driver pathname, and the "s." is changed to "#." */
/* where "#" is from 0 to 3, allowing 4 different mixer settings to be saved. */
char *filename= "settings.pas";
/* miscellaneous words used with mvproas */
#define WORD_GET 0
#define WORD_MIXER 1
#define WORD_TO 2
#define WORD_ON 3
#define WORD_OFF 4
#define WORD_LEVEL 5
#define WORD_PERCENT 6
char *words[]= {"GET ", "MIXER ", "TO ", "ON ", "OFF ", "LEVEL ", " PERCENT ", ""};
/* these words are used to retrieve/save the mixer settings */
char *direct[]= {"INPUT ", "OUTPUT ", ""};
char *output[]= {"PCM ", "MIXER "};
char *channel[]= {"LEFT ", "RIGHT ", ""};
char *source[]= {"FM ", "INT ", "EXT ", "SPEAKER ", "MIC ", "" };
char *levels[]= {"BASS ", "TREBLE ", "ENHANCED ", ""};
char *buttons[]= {"REALSOUND ", ""};
char *crossch[]= {"CROSSCHANNEL ", ""};
char *volume[]= {"VOLUME ", ""};
char *onoff[]= {"-", "+", ""};
/* getdriverpath() - use int 2F function BC0B to get path to mvsound.sys */
/* return !0 and fill "pathname" buffer with path to driver if successful */
/* return 0 if failed */
getdriverpath(char far *pathname)
{
int status;
char far *p= pathname;
_asm
{
mov ax, 0BC0Bh
int 2Fh
xor ax, 'M' SHL 8 + 'V'
mov status, ax
jnz sorry
push ds
push es
mov di, word ptr p[2]
mov es, di
mov di, word ptr p[0]
mov ds, dx
mov si, bx
mov cx, 79
again:
lodsb
stosb
or al, al
jz done
loop again
jmp short done
done:
pop es
pop ds
sorry:
}
return(!status);
}
/* evaluate the "## +/- ## +/-" string */
/* the first "## +/-" pair is the left channel, the second is the right */
/* set up four pointers to point to each of the four elements */
/* passed in is "channel", either 'L' or 'R', and "onoroff", either "+" or "-" */
/* if the L/R "onoroff" matches the passed "onoroff", return the L/R val */
char *isonoroff(char channel, char onoroff)
{
char *lfvalue, *lfonoff, *rtvalue, *rtonoff;
char *val, *oo;
/* MVResponse= "LeftVal LeftOnOff RightVal RightOnOff" */
lfvalue= MVResponse;
while (isspace(*lfvalue)) lfvalue++;
lfonoff= lfvalue;
while (!isspace(*lfonoff)) lfonoff++;
while (isspace(*lfonoff)) lfonoff++;
rtvalue= lfonoff;
while (!isspace(*rtvalue)) rtvalue++;
while (isspace(*rtvalue)) rtvalue++;
rtonoff= rtvalue;
while (!isspace(*rtonoff)) rtonoff++;
while (isspace(*rtonoff)) rtonoff++;
/* select val and oo according to Left or Right channel */
switch (channel)
{
case 'l':
case 'L': val= lfvalue; oo= lfonoff; break;
case 'r':
case 'R': val= rtvalue; oo= rtonoff; break;
default: val= NULL; oo= NULL; break;
}
if (*oo == onoroff)
return(val);
return(NULL);
}
/* put an ascii number for "num" into the character left of the "." */
/* from the end of the string, search backwards to the first "." */
/* if not at the start of the string, stuff the ascii number */
putnuminname(char *pathname, int num)
{
int i= strlen(pathname);
while (i && pathname[i] != '.')
i--;
if (i)
pathname[--i]= num+ '0';
}
/* get the driver path, stuff the number into the name, and create the file */
/* save the master L/R volume, the "dead" then the "live" mixer settings */
/* the bass, treble and enhanced status, the realsound setting, and the */
/* crosschannel settings */
/* These are saved as strings in a DOS file suitable for "cat FILE > mvproas" */
/* which is what the "loadcurrent()" function does */
/* The filename is "X:\driver\path\setting#.pas", where "#" is 0-3, allowing */
/* four different settings to be maintained */
#define USEMIXERGET 1
#if USEMIXERGET
FILE *fout;
subsavecurrent(char *cmdstring)
{
if (*cmdstring)
{
fprintf(fout, "%s\n", cmdstring);
}
return(0);
}
savecurrent(int num)
{
char pathname[128];
if (!getdriverpath(pathname))
return(0);
if (strlen(pathname) > 3)
strcat(pathname, "\\");
strcat(pathname, filename);
putnuminname(pathname, num);
fout= fopen(pathname, "w");
if (fout == NULL)
return(0);
MixerGetSettings(subsavecurrent);
fclose(fout);
return(0);
}
#else
savecurrent(int num)
{
int o, d, c, s;
int okay;
FILE *fout;
char pathname[128];
char cmdstring[128];
if (!getdriverpath(pathname))
return(0);
if (strlen(pathname) > 3)
strcat(pathname, "\\");
strcat(pathname, filename);
putnuminname(pathname, num);
fout= fopen(pathname, "w");
if (fout == NULL)
return(0);
/* get LEFT/RIGHT VOLUME */
for (c= 0; *channel[c]; c++)
{
strcpy(cmdstring, words[WORD_GET]);
strcat(cmdstring, volume[0]);
strcat(cmdstring, channel[c]);
strcat(cmdstring, words[WORD_LEVEL]);
clrbuf(MVResponse, 80);
SendTextOut(cmdstring);
fprintf(fout, "S%s%s%s%s\n", &cmdstring[1], words[WORD_TO], MVResponse, words[WORD_PERCENT]);
}
/* get OFF/ON, INPUT/OUTPUT and LEFT/RIGHT and FM/INT/EXT/SPEAKER/MIC */
for (o= 0; *onoff[o]; o++)
for (d= 0; *direct[d]; d++)
for (c= 0; *channel[c]; c++)
for (s= 0; *source[s]; s++)
{
char *val;
strcpy(cmdstring, words[WORD_GET]); /* GET */
strcat(cmdstring, direct[d]); /* INPUT/OUTPUT */
strcat(cmdstring, words[WORD_MIXER]); /* MIXER */
strcat(cmdstring, channel[c]); /* LEFT/RIGHT */
strcat(cmdstring, source[s]); /* FM/INT/EXT/SPEAKER/MIC */
clrbuf(MVResponse, 80);
SendTextOut(cmdstring);
/* if is ON and want ON or is OFF and want OFF, print */
if (val= isonoroff(channel[c][0], *onoff[o]))
{
fprintf(fout, "S%s%s", &cmdstring[1], words[WORD_TO]);
while (!isspace(*val))
{
fputc(*val, fout);
val++;
}
fprintf(fout, "%s\n", words[WORD_PERCENT]);
}
}
/* get ON/OFF, INPUT/OUTPUT for PCM/INPUT */
for (o= 0; *onoff[o]; o++)
for (d= 0; *direct[d]; d++)
for (c= 0; *channel[c]; c++)
{
char *val;
strcpy(cmdstring, words[WORD_GET]);
strcat(cmdstring, direct[d]);
strcat(cmdstring, words[WORD_MIXER]);
strcat(cmdstring, channel[c]);
strcat(cmdstring, output[d]);
clrbuf(MVResponse, 80);
SendTextOut(cmdstring);
if (val= isonoroff(channel[c][0], *onoff[o]))
{
fprintf(fout, "S%s%s", &cmdstring[1], words[WORD_TO]);
while (!isspace(*val))
{
fputc(*val, fout);
val++;
}
fprintf(fout, "%s\n", words[WORD_PERCENT]);
}
}
/* get BASS/TREBLE/ENHANCED */
for (c= 0; *levels[c]; c++)
{
strcpy(cmdstring, words[WORD_GET]);
strcat(cmdstring, volume[0]);
strcat(cmdstring, levels[c]);
clrbuf(MVResponse, 80);
SendTextOut(cmdstring);
fprintf(fout, "S%s%s", &cmdstring[1], words[WORD_TO]);
switch (*MVResponse)
{
case '+': fprintf(fout, "%s\n", words[WORD_ON]); break;
case '-': fprintf(fout, "%s\n", words[WORD_OFF]); break;
default: fprintf(fout, "%s%s\n", MVResponse, words[WORD_PERCENT]);
}
}
/* get REALSOUND */
for (c= 0; *buttons[c]; c++)
{
strcpy(cmdstring, words[WORD_GET]);
strcat(cmdstring, buttons[c]);
clrbuf(MVResponse, 80);
SendTextOut(cmdstring);
fprintf(fout, "S%s%s", &cmdstring[1], words[WORD_TO]);
switch(*MVResponse)
{
case '+': fprintf(fout, "%s\n", words[WORD_ON]); break;
case '-': fprintf(fout, "%s\n", words[WORD_OFF]); break;
}
}
strcpy(cmdstring, words[WORD_GET]);
strcat(cmdstring, crossch[0]);
clrbuf(MVResponse, 80);
SendTextOut(cmdstring);
{
int s= 0;
int t= 0;
int i= 0;
for (s= 0; *channel[s]; s++)
for (t= 0; *channel[t]; t++)
{
fprintf(fout, "S%s%s%s%s%s", &cmdstring[1], channel[s], words[WORD_TO], channel[t], words[WORD_TO]);
while (isspace(MVResponse[i])) i++;
switch (MVResponse[i++])
{
case '+': fprintf(fout, "%s\n", words[WORD_ON]); break;
case '-': fprintf(fout, "%s\n", words[WORD_OFF]); break;
}
}
}
fclose(fout);
}
#endif
/* load setting #num from file "setting#.pas" */
/* open the file, read each line and send it to mvproas */
/* if the file does not exist, save the current settings and then proceed */
/* The file contains mvproas strings, so "cat setting#.pas > mvproas" works */
loadcurrent(int num)
{
int okay;
FILE *finp;
char pathname[128];
char cmdstring[128];
if (!getdriverpath(pathname))
return(0);
if (strlen(pathname) > 3)
strcat(pathname, "\\");
strcat(pathname, filename);
putnuminname(pathname, num);
finp= fopen(pathname, "r");
if (finp == NULL)
{
savecurrent(num);
finp= fopen(pathname, "r");
if (finp == NULL)
return(0);
}
while ((fgets(cmdstring, 127, finp)) != NULL)
SendTextOut(cmdstring);
fclose(finp);
}
/*The GET commands and parameters are:
GET {LEFT or RIGHT} [FM ]
GET {LEFT or RIGHT} [PCM ]
GET {LEFT or RIGHT} [INT ]
GET {LEFT or RIGHT} [EXT ]
GET {LEFT or RIGHT} [SPEAKER]
GET {LEFT or RIGHT} [MIC ]
GET [BASS]
GET [TREBLE]
GET {LEFT or RIGHT} [VOLUME ]
GET [MUTE]
GET [ENHANCED]
GET [REALSOUND]
GET [CROSSCHANNEL]
The following demonstrates several ways to GET volume, button, or mixer levels:
GET FM
GET VOLUME
GET MUTE
GET CROSSCHANNEL
GET REAL
*/
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/