home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / mt / mtut2.c < prev    next >
C/C++ Source or Header  |  1989-02-08  |  9KB  |  241 lines

  1. /* mtut2.c save and load functions */
  2. /* `MIDI Sequencing In C', Jim Conger, M&T Books, 1989 */
  3.  
  4. #include <stdio.h>
  5. #include <conio.h>
  6. #include <string.h>
  7.  
  8. #include "screenf.h"
  9. #include "standard.h"
  10. #include "mpu401.h"
  11. #include "mt.h"
  12. #include "video.h"
  13. #include "filefunc.h"
  14. #include "mtdeclar.h"
  15.  
  16.  
  17. /* Runs the import menu for loading one track off of a disk file. */
  18. void 
  19. import_menu(void)
  20. {
  21.     int source_track, dest_track, i, pick, temp_metrate, temp_meter, 
  22.         temp_pitchbend, temp_exclusive, ans;
  23.     char tempfile[14], buf[SCRNWIDE], nbuf[10], *s, 
  24.         temp_songtitle[TITLE_WIDE];
  25.     FILE *stream;
  26.     struct trackdata temp_trackarray[NTRACK];
  27.  
  28.     while (1){
  29.         pick = pick_file(g_songdir, "*.sng", 
  30.             "Select a file to use for loading track data.  ESC to quit.");
  31.         if (pick < 0){  
  32.             return;
  33.         }
  34.     
  35.         strcpy(tempfile, g_file_disp[pick].content);
  36.         chdir(g_songdir);               /* change directory to song area */
  37.         stream = fopen(tempfile, "rb");
  38.         if(stream == NULL){
  39.             strcpy(buf, "Could not open song file ");
  40.             strcat(buf, g_songdir);
  41.             s = strchr(g_songdir, '\0');
  42.             if(*--s != '\\'){
  43.                 strcat(buf, "\\");
  44.             }
  45.             strcat(buf, tempfile);
  46.             writerr(buf, g_text_char_v, g_norm_attrib, g_norm_attrib);
  47.             chdir(g_prodir);
  48.             return;
  49.         }
  50.         else{
  51.             break;
  52.         }
  53.     }
  54.     
  55.     /* Read import file header, but not the track data (yet). */
  56.     
  57.     get_from_file(temp_songtitle, TITLE_WIDE, stream);
  58.     get_from_file(&temp_metrate, sizeof(int), stream);
  59.     get_from_file(&temp_meter, sizeof(int), stream);
  60.     get_from_file(&temp_pitchbend, sizeof(int), stream);
  61.     get_from_file(&temp_exclusive, sizeof(int), stream);
  62.     for (i = 0; i < NTRACK; i++){
  63.         get_from_file(temp_trackarray[i].name, TRACK_NAME_WIDE, stream);
  64.         get_from_file(&temp_trackarray[i].midichan, sizeof(int), stream);
  65.         get_from_file(&temp_trackarray[i].numevents, sizeof(long), stream);
  66.         get_from_file(&temp_trackarray[i].active, sizeof(int), stream);
  67.         get_from_file(&temp_trackarray[i].midivol, sizeof(int), stream);
  68.     }
  69.  
  70.     /* clear screen and put import menu up */
  71.     clearscreen(g_norm_attrib);
  72.     fdispchain(g_chain[5], 1, g_norm_attrib, g_text_mode);
  73.  
  74.     /* put each track's name, channel and number of events on screen */
  75.     
  76.     fwriteword(temp_songtitle, 26, 5, g_emph_attrib, g_text_mode);
  77.     for (i = 0; i < NTRACK; i++){
  78.         fwriteword(temp_trackarray[i].name, 8 + (i * 9), 7, g_emph_attrib,
  79.             g_text_mode);
  80.         write_int(temp_trackarray[i].midichan + 1, 10 + (i * 9), 8, 
  81.             g_emph_attrib);
  82.         write_int(temp_trackarray[i].numevents, 10 + (i * 9), 9, 
  83.             g_emph_attrib);
  84.     }
  85.  
  86.     fwriteword(g_songtitle, 26, 13, g_emph_attrib, g_text_mode);
  87.     for (i = 0; i < NTRACK; i++){
  88.         fwriteword(g_trackarray[i].name, 8 + (i * 9), 15, g_emph_attrib,
  89.             g_text_mode);
  90.         write_int(g_trackarray[i].midichan + 1, 10 + (i * 9), 16, 
  91.             g_emph_attrib);
  92.         write_int(g_trackarray[i].numevents, 10 + (i * 9), 17, g_emph_attrib);
  93.     }
  94.  
  95.     if (temp_meter != g_meter){     /* warn if the meters do not match */
  96.         strcpy(buf, "Note: Song in memory has meter = ");
  97.         itoa(g_meter, nbuf, 10);
  98.         strcat(buf, nbuf);
  99.         strcat(buf, ", Source meter = ");
  100.         itoa(temp_meter, nbuf, 10);
  101.         strcat(buf, nbuf);
  102.         writerr(buf, g_text_char_v, g_norm_attrib, g_norm_attrib);
  103.     }
  104.         
  105.         
  106.     pick = source_track = dest_track = 0;
  107.     show_source(source_track);      /* highlight the default source and */
  108.     show_dest(dest_track);          /* destination tracks on menu */
  109.     
  110.     /* Source and destination track selection rows on the import screen */
  111.     /* are elements of the mt51[] and mt52 menus.  finitscrn() is used to */
  112.     /* display the items.  Changed selections are made by updating the */
  113.     /* menu's "content" fields in show_source() and show_dest(). */
  114.     
  115.     while (1){
  116.         finitscrn(mt51, 0, NTRACK - 1, g_emph_attrib, g_text_mode);
  117.         finitscrn(mt52, 0, NTRACK - 1, g_emph_attrib, g_text_mode);
  118.         finitscrn(mt5, 0, NPARAM5 - 1, g_emph_attrib, g_text_mode);
  119.         
  120.         pick = movescrn(g_text_mode, mt5, pick, NPARAM5 - 1, 
  121.             g_emph_attrib, g_cursor_attrib);
  122.         switch(pick){
  123.         case(0):        /* pick source track */
  124.             source_track = movescrn(g_text_mode, mt51, dest_track, 
  125.                 NTRACK - 1, g_emph_attrib, g_cursor_attrib);
  126.             if (source_track >= 0)
  127.                 show_source(source_track);
  128.             break;
  129.         case(1):        /* pick dest track */
  130.             dest_track = movescrn(g_text_mode, mt52, source_track, 
  131.                 NTRACK - 1, g_emph_attrib, g_cursor_attrib);
  132.             if (dest_track >= 0)
  133.                 show_dest(dest_track);
  134.             break;
  135.         case(2):        /* import selected track */
  136.             while(kbhit())  
  137.                 getch();
  138.             if (g_trackarray[dest_track].numevents > 1){
  139.                 writeword(
  140.                     "Existing data in Dest track will be written over. OK?",
  141.                     1, g_text_char_v - 1, g_norm_attrib);
  142.                 ans = getche();
  143.                 clearline(g_text_char_v - 1, g_norm_attrib);
  144.                 if (toupper(ans) != 'Y'){
  145.                     break;
  146.                 }
  147.             }
  148.             clearline(g_text_char_v - 1, g_norm_attrib);
  149.             writeword("Importing track data...", 1, g_text_char_v - 1, 
  150.                 g_norm_attrib);
  151.             import_track(stream, source_track, dest_track, 
  152.                 temp_trackarray);
  153.             fclose(stream);
  154.             chdir(g_prodir);
  155.             g_current_measure = 0;
  156.             change_channel(dest_track, g_trackarray[dest_track].midichan);
  157.             return;
  158.         case(3):        /* quit */
  159.         case(-2):       /* ESC key */
  160.             fclose(stream);
  161.             chdir(g_prodir);
  162.             return;
  163.         }
  164.     }
  165. }
  166.  
  167.  
  168. /* Reads in one track's data by skipping over track data on disk for prior */
  169. /* tracks, then building a new event list for the selected track as the */
  170. /* data is being read off of the disk.   Old data on dest. track is purged. */
  171. void 
  172. import_track(FILE *stream, int source_track, int dest_track, 
  173.     struct trackdata temp_trackarray[])
  174. {
  175.     int i, j, events;
  176.     struct event far *ep;
  177.     struct event far *lp;
  178.     
  179.     lp = eventalloc();                  /* lp points to a safe place */
  180.     ep = g_trackarray[dest_track].first;
  181.     clear_events(ep->next);             /* erase existing data in track */
  182.     g_trackarray[dest_track].current = ep;
  183.     
  184.     for (i = 0; i < source_track; i++){     /* run though data ahead of */
  185.         events = temp_trackarray[i].numevents;  /* source track */
  186.         for (j = 0; j < events; j++){
  187.             fget_from_file(&lp->nbytes, 5, stream);
  188.         }
  189.     }               /* each event is copied to over the lp memory area */
  190.     
  191. #ifdef TURBOC
  192.     farfree(lp);    /* no longer need dummy lp event to write over */
  193. #else
  194.     _ffree(lp);
  195. #endif
  196.                                         /* read source track into memory */
  197.     events = temp_trackarray[source_track].numevents;
  198.     for (j = 0; j < events; j++){
  199.         fget_from_file(&ep->nbytes, 5, stream);
  200.         lp = ep;
  201.         ep = ep->next = eventalloc();   /* add new events to list for data */
  202.     }
  203. #ifdef TURBOC
  204.     farfree(ep);
  205. #else
  206.     _ffree(ep);
  207. #endif
  208.     lp->next = NULL;
  209.     g_trackarray[dest_track].last = lp;
  210.     g_trackarray[dest_track].numevents = events;
  211.     g_trackarray[dest_track].midivol = 100;
  212. }
  213.  
  214.  
  215. void
  216. show_source(int track)          /* update import menu for selected track */
  217. {
  218.     int i;
  219.     
  220.     for (i = 0; i < NTRACK; i++){
  221.         if (i == track)
  222.             strcpy(mt51[i].content, "*Source*");
  223.         else
  224.             strcpy(mt51[i].content, "        ");
  225.     }
  226. }
  227.  
  228.  
  229. void
  230. show_dest(int track)            /* update import menu for destination track */
  231. {
  232.     int i;
  233.     
  234.     for (i = 0; i < NTRACK; i++){
  235.         if (i == track)
  236.             strcpy(mt52[i].content, "**Dest**");
  237.         else
  238.             strcpy(mt52[i].content, "        ");
  239.     }
  240. }
  241.