home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega A/V
/
mega_av.zip
/
mega_av
/
SOUNDUTL
/
MUSIQUE.ZIP
/
SOURCE.ZIP
/
MUSIQUE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-06
|
17KB
|
576 lines
/* Warning! This C source contains extended characters! */
#include <stdio.h>
#include <dir.h>
#include <dos.h>
#include <string.h>
#include <bios.h>
#include <process.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <musique.h>
#include <musique.e>
void bellit(void)
/* short bell */
{
sound(SNDFREQ);
delay(SNDLENGTH);
nosound();
}
void myresetmode(PARAMETERTYPE *parameter)
/* Turbo-C doesn't like extended or non-text modes */
/* resets the video mode iff necessary */
/* does not rely on knowing the screen size since no clear screen done */
/* some incomplete BIOSes may force complete reset all the time */
{
union REGS regs;
regs.h.ah=(unsigned)'\xF'; /* get current video mode */
int86(0x10,®s,®s);
if (regs.h.al!=(unsigned char)parameter->videomode) {
regs.h.ah=(unsigned)'\x0'; /* reset video mode */
regs.h.al=(unsigned char)parameter->videomode;
int86(0x10,®s,®s);
}
}
void setborder(int color)
/* sets the border color */
/* color is in high 4 nibbles */
{
union REGS regs;
/* CGA EGA VGA */
regs.h.bl=(unsigned char)(color>>4);
regs.h.bh=(unsigned)'\x0';
regs.x.ax=(unsigned)0xB00;
int86(0x10,®s,®s);
}
void highbackground(void)
/* disables blinking/enables high intensity background */
{
union REGS regs;
int addr;
unsigned char data;
/* MDA CGA */
addr=peek((unsigned)0x40,(unsigned)0x63)+0x4;
data=(unsigned)(peekb((unsigned)0x40,(unsigned)0x65) & '\xDF');
outportb(addr,data);
/* MCGA EGA VGA */
regs.h.bl=(unsigned)'\x0';
regs.x.ax=(unsigned)0x1003;
int86(0x10,®s,®s);
}
void myclrscr(PARAMETERTYPE *parameter, int color)
/* Turbo-C doesn't like extended or non-text modes */
/* clear screen, sets border, and enables high intensity background */
/* color is is high 4 nibbles */
{
union REGS regs;
regs.x.ax=(unsigned)0x700; /* scroll whole screen */
regs.h.bh=(unsigned char)color;
regs.x.cx=(unsigned)0x0;
regs.h.dl=(unsigned char)(parameter->maxcolumn-1);
regs.h.dh=(unsigned char)(parameter->maxline-1);
int86(0x10,®s,®s);
regs.h.ah=(unsigned)'\x2'; /* cursor in upper-left corner */
regs.h.bh=(unsigned)'\x0';
regs.x.dx=(unsigned)0x0;
int86(0x10,®s,®s);
highbackground();
setborder(color);
}
void mysetmode(PARAMETERTYPE *parameter)
/* Turbo-C doesn't like extended or non-text modes */
/* sets the video mode and border, enables high intensity background */
/* avoids a complete video mode reset when possible */
/* some incomplete BIOSes may force complete reset all the time */
{
union REGS regs;
regs.h.ah=(unsigned)'\xF'; /* get current video mode */
int86(0x10,®s,®s);
if (regs.h.al!=(unsigned char)parameter->videomode) {
regs.h.ah=(unsigned)'\x0'; /* reset video mode */
regs.h.al=(unsigned char)parameter->videomode;
int86(0x10,®s,®s);
}
myclrscr(parameter,colorborder); /* always set screen attributes to border */
}
void blankstring(char target[], int targetlength)
/* creates a string full of spaces */
{
int ptr;
for (ptr=0 ; ptr<targetlength ; ptr++) target[ptr]=' ';
target[targetlength]='\0';
}
void initialize(SONGSTYPE *songs, PARAMETERTYPE *parameter, char menuname[])
{
language=FRENCH;
coloroutline=DEFAULTOUTLINE;
colortitle=DEFAULTTITLE;
coloritem=DEFAULTITEM;
colorcurrent=DEFAULTCURRENT;
colorpicked=DEFAULTPICKED;
colorcursor=DEFAULTCURSOR;
colorborder=DEFAULTBORDER;
songs->songnumber=0;
songs->songcorner=songs->songcurrent=1;
songs->songpath[0]='\0';
songs->songpathoffset=1;
/* used for overwriting items to erase them on the screen */
blankstring(songs->song[0].diskname,DISKNAMELENGTH);
blankstring(songs->song[0].score,SCORELENGTH);
blankstring(songs->song[0].DOSname,DOSNAMELENGTH);
blankstring(songs->song[0].songname,SONGNAMELENGTH);
songs->song[0].picked=0;
songs->song[0].DOSpath=songs->songpath;
strcpy(menuname,DEFAULTMENU);
strcpy(parameter->speed,DEFAULTSPEED);
parameter->tempdrive=ODDDRIVE;
parameter->ports[0]=ODDPORTS;
parameter->videomode=ODDMODE;
parameter->A=parameter->B=parameter->C=FALSE;
parameter->verbose=FALSE;
parameter->DOS=FALSE;
parameter->pause=FALSE;
parameter->mouse=FALSE;
parameter->rawvideo=TRUE;
switch (peek((unsigned)0x40,(unsigned)0x63)) {
case 0x3B4:parameter->videosegment=0xB000;
break;
case 0x3D4:parameter->videosegment=0xB800;
break;
default:error(34);
}
}
void busyfloppy(void)
/* waits until floppy shuts off */
{
while ((0xF & (int)peekb((unsigned)0x40,(unsigned)0x3F))!=0) ;
}
void cuttail(char text[])
/* cuts the tail of spaces */
{
int scanner;
scanner=strlen(text);
while ((text[--scanner]==' ') && (scanner>=0)) text[scanner]='\0';
}
int locateasong(SONGTYPE *song, PARAMETERTYPE *parameter)
/* checks that a module exists and maybe asks for the correct floppy */
/* looks for .MOD first, then for .ZIP (iff PKUNZIP.EXE located) */
/* returns -1 if not found, 0-1-2 for .MOD, and 3-4-5 for .ZIP */
/* looks in: temporary drive-path supplied(if not .)-current drive */
/* uses normal, read-only, hidden, system, archive bits for looking */
{
struct ffblk fff;
char filename[LINELENGTH+LINELENGTH]; /* path could be long */
int notfound;
char currenttext[3];
strcpy(currenttext,"A:");
currenttext[0]+=(char)parameter->currentdrive;
/* look on temporary drive for .MOD */
strcpy(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,MPENDING);
notfound=findfirst(filename,&fff,39);
if (notfound) {
if (parameter->pkunzipfound) {
/* look on temporary drive for .ZIP */
strcpy(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,PKENDING);
notfound=findfirst(filename,&fff,39);
}
if (notfound) {
if (strcmp((*song).DOSpath,ODDPATH)!=0) {
/* look on menu path for .MOD */
strcpy(filename,(*song).DOSpath);
strcat(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,MPENDING);
notfound=findfirst(filename,&fff,39);
}
if (notfound) {
if (parameter->pkunzipfound)
if (strcmp((*song).DOSpath,ODDPATH)!=0) {
/* look on menu path for .ZIP */
strcpy(filename,(*song).DOSpath);
strcat(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,PKENDING);
notfound=findfirst(filename,&fff,39);
}
if (notfound)
do {
/* look on current drive for .MOD */
strcpy(filename,currenttext);
strcat(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,MPENDING);
notfound=findfirst(filename,&fff,39);
if (notfound) {
if (parameter->pkunzipfound) {
/* look on current drive for .ZIP */
strcpy(filename,currenttext);
strcat(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,PKENDING);
notfound=findfirst(filename,&fff,39);
}
if (notfound)
if (parameter->currentdrive<=1) {
/* song on floppy; ask user */
bellit();
message(23);
printf("%s\n",(*song).diskname);
message(22);
switch (bioskey(0)) {
case KEYESC:return(-1); /* aborted */
default:break;
}
}
else {
/* song not on floppy; give up */
printf("<%s>\n",(*song).songname);
message(24);
if (parameter->pause) {
message(25);
bellit();
bioskey(0);
}
else {
bellit();
delay(NOTFOUNDDELAY);
bellit();
delay(NOTFOUNDDELAY);
bellit();
delay(NOTFOUNDDELAY);
bellit();
delay(NOTFOUNDDELAY);
bellit();
}
return(-1); /* not found */
}
else {
message(35);
return(5); /* .ZIP under current drive */
}
}
else {
message(32);
return(2); /* .MOD under current drive */
}
} while (TRUE);
else {
message(34);
return(4); /* .ZIP under path */
}
}
else {
message(31);
return(1); /* .MOD under path */
}
}
else {
message(33);
return(3); /* .ZIP under temporary drive */
}
}
else {
message(36);
return(0); /* .MOD under temporary drive */
}
}
void checkasong(char DOSname[])
/* checks that a module exists */
{
struct ffblk fff;
char filename[LINELENGTH];
strcpy(filename,DOSname);
cuttail(filename);
strcat(filename,MPENDING);
/* normal, read-only, hidden, system, archive */
if (findfirst(filename,&fff,39)) error(18);
}
void deleteasong(char DOSname[])
/* deletes a song */
{
char filename[LINELENGTH];
int errorint;
message(40);
strcpy(filename,DOSname);
cuttail(filename);
strcat(filename,MPENDING);
errorint=unlink(filename);
if (errorint==-1) error(19);
}
void shutup(int port)
/* turns off gradually a parallel port */
{
int value;
value=(int)inportb(port);
while (value>0) {
value--;
outportb(port,(unsigned char)value);
delay(SHUTUPDELAY);
}
}
void movemodule(SONGTYPE *song, int found, PARAMETERTYPE *parameter)
/* moves a module onto the temporary drive */
/* because the module must be in the current directory for ModPlay */
/* this is simpler than to look at DOSpath and to be clever with logged drive */
/* found=1 is from path, found=2 is from current drive */
{
char buffer[BUFFERSIZE];
char filename[LINELENGTH+LINELENGTH]; /* path could be long */
FILE *source,*target;
int errorint,tomove,moved;
char temporarytext[3];
char currenttext[3];
message(38);
strcpy(temporarytext,"A:");
strcpy(currenttext,"A:");
temporarytext[0]+=(char)parameter->tempdrive;
currenttext[0]+=(char)parameter->currentdrive;
if (found==1) strcpy(filename,(*song).DOSpath);
else strcpy(filename,currenttext);
strcat(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,MPENDING);
source=fopen(filename,"rb");
if (source==NULL) error(25);
strcpy(filename,temporarytext);
strcat(filename,(*song).DOSname);
cuttail(filename);
strcat(filename,MPENDING);
target=fopen(filename,"wb");
if (target==NULL) error(26);
tomove=(int)fread(buffer,(unsigned)1,(unsigned)BUFFERSIZE,source);
while (tomove!=0) {
moved=(int)fwrite(buffer,(unsigned)1,(unsigned)tomove,target);
if (moved!=tomove) error(27);
tomove=(int)fread(buffer,(unsigned)1,(unsigned)BUFFERSIZE,source);
}
errorint=fclose(source);
if (errorint==EOF) error(28);
errorint=fclose(target);
if (errorint==EOF) error(29);
}
void playasong(SONGTYPE *song, PARAMETERTYPE *parameter)
/*finds, maybe decompresses, waits, plays, shuts off, and maybe deletes a song*/
{
char command[LINELENGTH+LINELENGTH]; /* path could be long */
char currenttext[3];
int found,errorint;
strcpy(currenttext,"A:");
currenttext[0]+=(char)parameter->currentdrive;
/* look for MOD or ZIP under temporary drive, menu path, and current drive */
found=locateasong(song,parameter);
if (found>=0) {
/* song found */
if (found>=3) {
/* must be decompressed on the temporary drive known clear */
message(37);
/* known on the temporary drive */
strcpy(command,PKUNZIP0);
strcat(command," ");
if (found==4) strcat(command,(*song).DOSpath);
else
if (found==5) strcat(command,currenttext);
strcat(command,(*song).DOSname);
cuttail(command);
message(43);
printf("%s\n",command);
if (parameter->pause) {
bellit();
message(22);
switch (bioskey(0)) {
case KEYESC:error(9); /* aborted */
default:break;
}
}
errorint=system(command);
printf("\n");
if (errorint==-1) error(20);
checkasong((*song).DOSname);
}
else
/* if temporary drive is clear, move module there */
if (found>=1) movemodule(song,found,parameter);
message(39);
/* known on the temporary drive */
strcpy(command,MODPLAY0);
strcat(command," ");
strcat(command,parameter->ports);
strcat(command," ");
strcat(command,parameter->speed);
strcat(command," ");
strcat(command,(*song).DOSname);
cuttail(command);
message(43);
printf("%s\n",command);
if (parameter->pause) {
bellit();
message(22);
switch (bioskey(0)) {
case KEYESC:error(9); /* aborted */
default:break;
}
}
busyfloppy();
errorint=system(command);
if (errorint==-1) error(20);
if (parameter->A) {
message(29);
shutup(PORT1);
}
if (parameter->B) {
message(29);
shutup(PORT2);
}
if (parameter->C) {
message(29);
shutup(PORT3);
}
/* if .MOD was copied/created, it must be deleted since not there before */
if (found>=1) deleteasong((*song).DOSname);
}
}
void cleanup(PARAMETERTYPE *parameter)
/* deletes temporary programs on the temporary drive */
{
int errorint;
if (parameter->pkunzipcopied || parameter->modplaycopied) {
message(6);
if (parameter->modplaycopied) {
errorint=unlink(MODPLAY1);
if (errorint==-1) {
errorint=unlink(MODPLAY2);
if (errorint==-1) {
errorint=unlink(MODPLAY3);
if (errorint==-1) error(21);
}
}
}
if (parameter->pkunzipcopied) {
errorint=unlink(PKUNZIP1);
if (errorint==-1) error(21);
}
}
}
void playbatch(SONGSTYPE *songs, PARAMETERTYPE *parameter)
/* plays the current batch of modules and Escape aborts */
{
int songptr;
int priority;
int songcancel;
songcancel=FALSE;
for (priority=1 ; priority<=songs->songpriority ; priority++)
if (!songcancel) {
for (songptr=1 ; songptr<=songs->songnumber ; songptr++)
if (songs->song[songptr].picked==priority) {
songs->song[songptr].picked=0;
playasong(&(songs->song[songptr]),parameter);
break;
}
while (bioskey(1))
if (bioskey(0)==KEYESC) songcancel=TRUE;
else bellit();
}
if (songcancel)
for (songptr=1 ; songptr<=songs->songnumber ; songptr++)
songs->song[songptr].picked=0;
}
int main(int argc, char *argv[])
{
char menuname[LINELENGTH];
FILE *menufile;
SONGSTYPE songs;
PARAMETERTYPE parameter;
MOUSETYPE mousedata;
int errorint;
int songabort; /* TRUE indicates terminate MUSIQUE */
directvideo=0; /* safety for extended color text modes */
delay(1); /* solves initial delay() bug(?) */
srand((unsigned)time(NULL));
initialize(&songs,¶meter,menuname);
scanarguments(argc,argv,menuname,¶meter);
if (parameter.videomode!=ODDMODE) myresetmode(¶meter);
/* Copyright notice so Borland is happy */
message(1);
message(2);
printf("%s\n",menuname);
menufile=fopen(menuname,"rt");
if (menufile==NULL) {
strcat(menuname,MENUENDING);
message(2);
printf("%s\n",menuname);
menufile=fopen(menuname,"rt");
if (menufile==NULL) error(2);
}
message(3);
readmenu(menufile,&songs);
message(4);
printf("%s\n",menuname);
errorint=fclose(menufile);
if (errorint==EOF) error(3);
message(5);
readparameter(¶meter,&mousedata,songs.songnumber);
myclrscr(¶meter,colorborder); /* clear screen, set border & high stuff */
setdisk(parameter.tempdrive);
if (getdisk()!=parameter.tempdrive) error(32);
do {
/* screen already cleared here */
printoutline(¶meter);
if (parameter.mouse)
mouseshow(mousedata.x,mousedata.y,&(mousedata.c),&(mousedata.color));
printsongs(&songs,¶meter,&mousedata);
songabort=picksongs(&songs,¶meter,&mousedata);
if (parameter.mouse)
mousehide(mousedata.x,mousedata.y,mousedata.c,mousedata.color);
myclrscr(¶meter,7);
if (!songabort) {
playbatch(&songs,¶meter);
mysetmode(¶meter); /* reset mode/clear screen, border & high stuff */
}
} while (!songabort);
/* screen already cleared here */
cleanup(¶meter);
setdisk(parameter.currentdrive);
if (getdisk()!=parameter.currentdrive) error(33);
return(0);
}