; /*\ ; |*| $Author: DCODY $ ; |*| ; |*| $Date: 20 Nov 1992 16:35:26 $ ; |*| ; |*| $Header: X:/sccs/mixers/dialog.c_v 1.16 20 Nov 1992 16:35:26 DCODY $ ; |*| ; |*| $Log: X:/sccs/mixers/dialog.c_v $ * * Rev 1.16 20 Nov 1992 16:35:26 DCODY * changed the dissolve screen restore to work only on exit of the dialog. Also * corrected a couple Borland C barfs. * * Rev 1.15 12 Nov 1992 10:02:40 DCODY * added dissolve on screen restoration. Changed some code for * Borland compatibility. * * Rev 1.14 20 Oct 1992 15:53:30 BCRANE * changed text on Speaker control to include SB Volume * * Rev 1.13 19 Oct 1992 11:41:18 BCRANE * added "blank" strings for when no SB volume control on PAS+ * * Rev 1.12 16 Oct 1992 10:19:30 BCRANE * fixed error in getting the pathname * DOS has "C:\" for the root, whereas we store only "C:", so * building the pathname for the settings.pas file was "C:settings.pas" * when mvsound.sys was in the root directory. * * 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 *screenlayoutblank[]= { "ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄ´ Ã", "³ ³³ ³", "³ ³³ ³" }; 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 *screen3blank[]= { "ÄÌÍÍÍÍÍ͹", "º º", "º º" }; 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, 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,int) >====---- |*| |*| Draw/Restore the screen |*| |*| Entry Conditions: |*| INT is a TRUE/FALSE flag |*| INT is a WIPE or DISSOLVE to original flag |*| |*| Exit Conditions: |*| None |*| \*/ static void PaintScreen (tf,fl) int tf; int fl; { 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) { if (fl) dissolve (25,80,(char far *)&screenbuffer[0]); else 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,FALSE); // restore the screen PaintScreen (TRUE,FALSE); // 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,FALSE); // restore the screen PaintScreen (TRUE,FALSE); // 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,TRUE ); // 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,FALSE); // 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; } } ; /*\ ;---|*|----====< clrbuf() >====---- ;---|*| ;---|*| zero out a buffer ;---|*| ; \*/ clrbuf(char *buf, int size) { int s; for (s= 0; s < size; s++) *buf++= '\0'; } ; /*\ ;---|*|----====< dissolve() >====---- ;---|*| ;---|*| Take a buffer, and write it to the screen in a random fashion ;---|*| ; \*/ dissolve(h,width,buff) int h; int width; char far *buff; { int pixels,lastnum; int regwidth; long mask; unsigned long seq; int row, col; // find the smallest "register" that produces enough pixel numbers pixels = h * width; lastnum = pixels -1; mask = 0x500; seq = 1; do { row = seq / width; col = seq % width; if (row < h) plug (row,col,buff); // compute the next element if (seq & 1) { _asm { mov ax,word ptr [seq] shr ax,1 xor ax,word ptr [mask] mov word ptr [seq],ax } //seq = (seq >> 1) ~ mask; } else seq >>= 1; } while (seq != 1); plug (0,0,buff); } plug(row,col,buff) int row; int col; char far *buff; { _asm { push es push si mov ax,[row] mov si,160 mul si add ax,[col] add ax,[col] mov si,ax les bx,[buff] mov ax,es:[bx+si] mov bx,0b800h mov es,bx mov es:[si],ax mov dx,250h mov cx,40h } xyz: _asm { in al,dx loop xyz pop es } } /* 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 push si push di 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: _asm { lodsb stosb or al, al jz done loop again jmp short done } done: _asm { sub cx, 77 jnz notroot mov bx,-1 mov byte ptr es:[di], 0 dec di mov byte ptr es:[di], 05ch } notroot: _asm { pop di pop si 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 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); } /* 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 */ unlinkTBScroll() { Scroll *n= (Scroll *) TBScroll.next; Scroll *b= (Scroll *) TBScroll.back; n->back= b; b->next= n; screen3[15]= screen3blank[0]; screen3[16]= screen3blank[1]; screen3[17]= screen3blank[2]; screenlayout[17]= screenlayoutblank[0]; screenlayout[18]= screenlayoutblank[1]; screenlayout[19]= screenlayoutblank[2]; screenlayout[15][2]= 'P'; screenlayout[15][3]= 'C'; screenlayout[15][4]= ' '; screenlayout[15][5]= 'S'; screenlayout[15][6]= 'p'; screenlayout[15][7]= 'e'; screenlayout[15][8]= 'a'; screenlayout[15][9]= 'k'; screenlayout[15][10]='e'; screenlayout[15][11]='r'; screenlayout[16][2]= 'S'; screenlayout[16][3]= 'B'; screenlayout[16][4]= ' '; screenlayout[16][5]= 'V'; screenlayout[16][6]= 'o'; screenlayout[16][7]= 'l'; screenlayout[16][8]= 'u'; screenlayout[16][9]= 'm'; screenlayout[16][10]='e'; screenlayout[16][11]=' '; } ; /*\ ;---|*| end DIALOG.C ; \*/