home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Audio 4.94 - Over 11,000 Files
/
audio-11000.iso
/
msdos
/
sndbords
/
proaudio
/
pas_sdk1
/
pas
/
subs
/
mixers
/
dialog.c
< prev
next >
Wrap
Text File
|
1992-09-09
|
77KB
|
3,483 lines
; /*\
; |*| $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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <bios.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <io.h>
#include "dialog.h"
#include <binary.h>
#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
*/