home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C++ Games Programming
/
CPPGAMES.ISO
/
mt
/
mtut1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-01-14
|
9KB
|
291 lines
/* mtut1.c save and load functions */
/* `MIDI Sequencing In C', Jim Conger, M&T Books, 1989 */
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include "screenf.h"
#include "standard.h"
#include "mpu401.h"
#include "mt.h"
#include "video.h"
#include "filefunc.h"
#include "mtdeclar.h"
/* Write track data to a selected file. */
void
save_song(void)
{
int ans;
char tempfile[14], buf[SCRNWIDE];
FILE *stream;
clearscreen(g_norm_attrib);
disp_files(g_songdir, "*.sng"); /* put all song file names up */
if (strcmpi(g_filename, DEFAULT_FILE_NAME) != 0){
strcpy(buf, "The current song file name is: ");
strcat(buf, g_filename);
writeword(buf, 1, g_text_char_v - 4, g_norm_attrib);
while(kbhit())
getch(); /* clear input buffer */
writeword("Keep this song file name? (ESC to exit) (y/n):",
1, g_text_char_v - 3, g_norm_attrib);
ans = getche();
}
else{
ans = 'N';
}
if(ans == ESC){
return;
}
else if(toupper(ans) != 'Y'){
while(1){
clearline(g_text_char_v - 2, g_norm_attrib);
getstr(g_text_char_v - 2,
"Enter song file name for disk storage (no .SNG):",
tempfile, 12, g_norm_attrib);
if(*tempfile == '\0' || *tempfile == '\n')
return;
if(!strchr(tempfile, '.'))/* add file extension if not present */
strcat(tempfile, ".SNG");
chdir(g_songdir); /* change directory to song file area */
stream = fopen(tempfile, "wb"); /* open file */
if(stream == NULL){
strcpy(buf, "Could not open library file ");
strcat(buf, tempfile);
writerr(buf, g_text_char_v, g_norm_attrib, g_norm_attrib);
}
else{
strcpy(g_filename, tempfile);
break;
}
}
}
else{
chdir(g_songdir); /* change directory to song file area */
stream = fopen(g_filename, "wb"); /* open file */
if(stream == NULL){
writerr("Failed to open data file, disk problem?", g_text_char_v,
g_norm_attrib, g_norm_attrib);
return;
}
}
save_tracks(stream); /* write track data to file */
fclose(stream);
chdir(g_prodir); /* change directory back to MT program area */
return;
}
void
save_tracks(FILE *stream) /* workhorse function to write track data to file */
{
int i, j, events;
struct event far *ep;
count_events();
put_to_file(g_songtitle, TITLE_WIDE, stream);
put_to_file(&g_metrate, sizeof(int), stream);
put_to_file(&g_meter, sizeof(int), stream);
put_to_file(&g_pitchbend, sizeof(int), stream);
put_to_file(&g_exclusive, sizeof(int), stream);
for (i = 0; i < NTRACK; i++){
put_to_file(g_trackarray[i].name, TRACK_NAME_WIDE, stream);
put_to_file(&g_trackarray[i].midichan, sizeof(int), stream);
put_to_file(&g_trackarray[i].numevents, sizeof(long), stream);
put_to_file(&g_trackarray[i].active, sizeof(int), stream);
put_to_file(&g_trackarray[i].midivol, sizeof(int), stream);
}
for (i = 0; i < NTRACK; i++){
events = g_trackarray[i].numevents;
ep = g_trackarray[i].first;
for (j = 0; j < events; j++){ /* write all five data bytes at once */
fput_to_file(&ep->nbytes, 5, stream);
ep = ep->next;
}
}
}
void
load_song(void) /* load a disk file into track memory */
{
int pick, i, ans;
long count;
char tempfile[14], buf[SCRNWIDE], *s;
FILE *stream;
count = 0; /* check if data in any track, if so warn user */
for (i = 0; i < NTRACK; i++){
count += g_trackarray[i].numevents;
}
if (count > NTRACK){
writeword(
"Loading a file will erase all track data in memory; OK? (y/N)->",
1, g_text_char_v - 1, g_norm_attrib);
ans = getche();
if (toupper(ans) != 'Y')
return;
else
erase_all(); /* user says OK, so erase all data */
}
pick = pick_file(g_songdir, "*.sng",
"Select a song file to load. ESC to escape without loading.");
if (pick < 0){
return;
}
strcpy(tempfile, g_file_disp[pick].content);
chdir(g_songdir); /* change directory to song file area */
stream = fopen(tempfile, "rb"); /* open file */
if(stream == NULL){
strcpy(buf, "Could not open song file ");
strcat(buf, g_songdir);
s = strchr(g_songdir, '\0');
if(*--s != '\\'){
strcat(buf, "\\");
}
strcat(buf, tempfile);
writerr(buf, g_text_char_v, g_norm_attrib, g_norm_attrib);
return;
}
recal_song(stream); /* read data into memory */
fclose(stream); /* close file */
chdir(g_prodir); /* change directory back to MT program area */
strcpy(g_filename, tempfile); /* save file name for display */
g_current_measure = 0;
}
void
recal_song(FILE *stream) /* do work of reading in file from disk */
{
int i, j, events;
struct event far *ep;
struct event far *lp;
get_from_file(g_songtitle, TITLE_WIDE, stream);
get_from_file(&g_metrate, sizeof(int), stream);
get_from_file(&g_meter, sizeof(int), stream);
get_from_file(&g_pitchbend, sizeof(int), stream);
get_from_file(&g_exclusive, sizeof(int), stream);
for (i = 0; i < NTRACK; i++){
get_from_file(g_trackarray[i].name, TRACK_NAME_WIDE, stream);
get_from_file(&g_trackarray[i].midichan, sizeof(int), stream);
get_from_file(&g_trackarray[i].numevents, sizeof(long), stream);
get_from_file(&g_trackarray[i].active, sizeof(int), stream);
get_from_file(&g_trackarray[i].midivol, sizeof(int), stream);
}
/* The event lists are built for each track as the data is read off of */
/* the disk file. All 5 bytes for each event's data read in one shot. */
for (i = 0; i < NTRACK; i++){
events = g_trackarray[i].numevents;
ep = g_trackarray[i].first = g_trackarray[i].current = eventalloc();
for (j = 0; j < events; j++){
fget_from_file(&ep->nbytes, 5, stream); /* read 5 bytes at once */
lp = ep;
ep = ep->next = eventalloc(); /* allocate space for next event */
}
#ifdef TURBOC
farfree(ep);
#else
_ffree(ep);
#endif
lp->next = NULL;
g_trackarray[i].last = lp;
}
}
/* Runs the help screen menu. Selection of a topic causes another screen */
/* file to be temporarly loaded into memory and displayed. */
void
help_control(void)
{
int pick, lastpick;
pick = 0;
while(1){
clearscreen(g_norm_attrib);
fdispchain(g_chain[4], 1, g_norm_attrib, g_text_mode);
lastpick = pick;
while(kbhit())
getch();
pick = movescrn(g_text_mode, mt4, pick, NPARAM4 - 1, g_norm_attrib,
g_cursor_attrib);
switch(pick){
case(0): /* general */
helpdisp("mthelp1.scr");
break;
case(1): /* mouse */
helpdisp("mthelp2.scr");
break;
case(2): /* file functions */
helpdisp("mthelp3.scr");
break;
case(3): /* edit */
helpdisp("mthelp4.scr");
break;
case(4): /* record */
helpdisp("mthelp5.scr");
break;
case(5): /* title */
helpdisp("mthelp6.scr");
break;
case(6): /* clear */
helpdisp("mthelp7.scr");
break;
case(7): /* import */
helpdisp("mthelp8.scr");
break;
case(-2): /* esc */
case(8): /* quit */
return;
default:
writerr("Use arrow keys to move cursor, ret to select.",
g_text_char_v, g_norm_attrib, g_norm_attrib);
pick = lastpick;
}
}
}
/* Load and display one help screen. Purge from memory after keypress. */
void
helpdisp(char *filename)
{
struct strchain *chain;
chain = inpchain(filename, SCRNWIDE); /* read the screen */
if(chain == NULL){
chain = (struct strchain *) malloc(1);
writerr("Could not open help file - probably not on disk.",
g_text_char_v, g_emph_attrib, g_norm_attrib);
return;
}
clearscreen(g_norm_attrib);
fdispchain(chain, 1, g_norm_attrib, g_text_mode); /* display screen */
while(!kbhit()) /* wait for keypress */
;
dechain(chain); /* purge screen file from memory */
getch();
}