home *** CD-ROM | disk | FTP | other *** search
/ C++ Games Programming / CPPGAMES.ISO / mt / mtut1.c < prev    next >
C/C++ Source or Header  |  1989-01-14  |  9KB  |  291 lines

  1. /* mtut1.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. /* Write track data to a selected file. */
  18. void
  19. save_song(void)
  20. {
  21.     int ans;
  22.     char tempfile[14], buf[SCRNWIDE];
  23.     FILE *stream;
  24.     
  25.     clearscreen(g_norm_attrib);
  26.     disp_files(g_songdir, "*.sng");     /* put all song file names up */
  27.     
  28.     if (strcmpi(g_filename, DEFAULT_FILE_NAME) != 0){
  29.         strcpy(buf, "The current song file name is: ");
  30.         strcat(buf, g_filename);
  31.         writeword(buf, 1, g_text_char_v - 4, g_norm_attrib);
  32.         
  33.         while(kbhit()) 
  34.             getch();            /* clear input buffer */
  35.         
  36.         writeword("Keep this song file name?  (ESC to exit) (y/n):", 
  37.             1, g_text_char_v - 3, g_norm_attrib);
  38.         ans = getche();
  39.     }
  40.     else{
  41.         ans = 'N';
  42.     }
  43.     
  44.     if(ans == ESC){
  45.         return;
  46.     }
  47.     else if(toupper(ans) != 'Y'){
  48.         while(1){
  49.             clearline(g_text_char_v - 2, g_norm_attrib);
  50.             getstr(g_text_char_v - 2, 
  51.                 "Enter song file name for disk storage (no .SNG):", 
  52.                 tempfile, 12, g_norm_attrib);
  53.  
  54.             if(*tempfile == '\0' || *tempfile == '\n')
  55.                 return;
  56.             if(!strchr(tempfile, '.'))/* add file extension if not present */
  57.                 strcat(tempfile, ".SNG");
  58.         
  59.             chdir(g_songdir);       /* change directory to song file area */
  60.             stream = fopen(tempfile, "wb");     /* open file */
  61.         
  62.             if(stream == NULL){
  63.                 strcpy(buf, "Could not open library file ");
  64.                 strcat(buf, tempfile);
  65.                 writerr(buf, g_text_char_v, g_norm_attrib, g_norm_attrib);
  66.             }
  67.             else{
  68.                 strcpy(g_filename, tempfile);
  69.                 break;
  70.             }
  71.         }
  72.     }
  73.     else{
  74.         chdir(g_songdir);       /* change directory to song file area */
  75.         stream = fopen(g_filename, "wb");       /* open file */
  76.         if(stream == NULL){
  77.             writerr("Failed to open data file, disk problem?", g_text_char_v, 
  78.                 g_norm_attrib, g_norm_attrib);
  79.             return;
  80.         }
  81.     }
  82.  
  83.     save_tracks(stream);    /* write track data to file */
  84.     
  85.     fclose(stream);
  86.     chdir(g_prodir);        /* change directory back to MT program area */
  87.     return;
  88. }
  89.     
  90.  
  91. void
  92. save_tracks(FILE *stream) /* workhorse function to write track data to file */
  93. {
  94.     int i, j, events;
  95.     struct event far *ep;
  96.     
  97.     count_events();
  98.     put_to_file(g_songtitle, TITLE_WIDE, stream);
  99.     put_to_file(&g_metrate, sizeof(int), stream);
  100.     put_to_file(&g_meter, sizeof(int), stream);
  101.     put_to_file(&g_pitchbend, sizeof(int), stream);
  102.     put_to_file(&g_exclusive, sizeof(int), stream);
  103.     for (i = 0; i < NTRACK; i++){
  104.         put_to_file(g_trackarray[i].name, TRACK_NAME_WIDE, stream);
  105.         put_to_file(&g_trackarray[i].midichan, sizeof(int), stream);
  106.         put_to_file(&g_trackarray[i].numevents, sizeof(long), stream);
  107.         put_to_file(&g_trackarray[i].active, sizeof(int), stream);
  108.         put_to_file(&g_trackarray[i].midivol, sizeof(int), stream);
  109.     }
  110.     
  111.     for (i = 0; i < NTRACK; i++){
  112.         events = g_trackarray[i].numevents;
  113.         ep = g_trackarray[i].first; 
  114.         for (j = 0; j < events; j++){  /* write all five data bytes at once */
  115.             fput_to_file(&ep->nbytes, 5, stream);
  116.             ep = ep->next;
  117.         }
  118.     }
  119. }
  120.  
  121.  
  122. void
  123. load_song(void)                 /* load a disk file into track memory */
  124. {
  125.     int pick, i, ans;
  126.     long count;
  127.     char tempfile[14], buf[SCRNWIDE], *s;
  128.     FILE *stream;
  129.     
  130.     count = 0;      /* check if data in any track, if so warn user */
  131.     for (i = 0; i < NTRACK; i++){
  132.         count += g_trackarray[i].numevents;
  133.     }
  134.     if (count > NTRACK){
  135.         writeword(
  136.             "Loading a file will erase all track data in memory; OK? (y/N)->",
  137.             1, g_text_char_v - 1, g_norm_attrib);
  138.         ans = getche();
  139.         if (toupper(ans) != 'Y')
  140.             return;
  141.         else
  142.             erase_all();    /* user says OK, so erase all data */
  143.     }
  144.     
  145.     pick = pick_file(g_songdir, "*.sng", 
  146.         "Select a song file to load.  ESC to escape without loading.");
  147.     
  148.     if (pick < 0){  
  149.         return;
  150.     }
  151.  
  152.     strcpy(tempfile, g_file_disp[pick].content);
  153.     chdir(g_songdir);               /* change directory to song file area */
  154.     stream = fopen(tempfile, "rb");     /* open file */
  155.     if(stream == NULL){
  156.         strcpy(buf, "Could not open song file ");
  157.         strcat(buf, g_songdir);
  158.         s = strchr(g_songdir, '\0');
  159.         if(*--s != '\\'){
  160.             strcat(buf, "\\");
  161.         }
  162.         strcat(buf, tempfile);
  163.         writerr(buf, g_text_char_v, g_norm_attrib, g_norm_attrib);
  164.         return;
  165.     }
  166.     
  167.     recal_song(stream);     /* read data into memory */
  168.     fclose(stream);         /* close file */
  169.     chdir(g_prodir);        /* change directory back to MT program area */
  170.     strcpy(g_filename, tempfile);   /* save file name for display */
  171.     g_current_measure = 0;
  172. }
  173.  
  174.  
  175. void
  176. recal_song(FILE *stream)            /* do work of reading in file from disk */
  177. {
  178.     int i, j, events;
  179.     struct event far *ep;
  180.     struct event far *lp;
  181.     
  182.     get_from_file(g_songtitle, TITLE_WIDE, stream);
  183.     get_from_file(&g_metrate, sizeof(int), stream);
  184.     get_from_file(&g_meter, sizeof(int), stream);
  185.     get_from_file(&g_pitchbend, sizeof(int), stream);
  186.     get_from_file(&g_exclusive, sizeof(int), stream);
  187.     for (i = 0; i < NTRACK; i++){
  188.         get_from_file(g_trackarray[i].name, TRACK_NAME_WIDE, stream);
  189.         get_from_file(&g_trackarray[i].midichan, sizeof(int), stream);
  190.         get_from_file(&g_trackarray[i].numevents, sizeof(long), stream);
  191.         get_from_file(&g_trackarray[i].active, sizeof(int), stream);
  192.         get_from_file(&g_trackarray[i].midivol, sizeof(int), stream);
  193.     }
  194.     
  195.     /* The event lists are built for each track as the data is read off of */
  196.     /* the disk file.  All 5 bytes for each event's data read in one shot. */
  197.     for (i = 0; i < NTRACK; i++){
  198.         events = g_trackarray[i].numevents;
  199.         ep = g_trackarray[i].first = g_trackarray[i].current = eventalloc(); 
  200.         for (j = 0; j < events; j++){
  201.             fget_from_file(&ep->nbytes, 5, stream); /* read 5 bytes at once */
  202.             lp = ep;
  203.             ep = ep->next = eventalloc();  /* allocate space for next event */
  204.         }
  205. #ifdef TURBOC
  206.         farfree(ep);
  207. #else
  208.         _ffree(ep);
  209. #endif
  210.         lp->next = NULL;
  211.         g_trackarray[i].last = lp;
  212.     }
  213. }
  214.  
  215.  
  216. /* Runs the help screen menu.  Selection of a topic causes another screen */
  217. /* file to be temporarly loaded into memory and displayed. */
  218. void
  219. help_control(void)
  220. {
  221.     int pick, lastpick;
  222.  
  223.     pick = 0;
  224.     while(1){
  225.         clearscreen(g_norm_attrib);
  226.         fdispchain(g_chain[4], 1, g_norm_attrib, g_text_mode);
  227.         
  228.         lastpick = pick;
  229.         while(kbhit()) 
  230.             getch();
  231.         
  232.         pick = movescrn(g_text_mode, mt4, pick, NPARAM4 - 1, g_norm_attrib,
  233.             g_cursor_attrib);
  234.         switch(pick){
  235.         case(0):            /* general */
  236.             helpdisp("mthelp1.scr");
  237.             break;
  238.         case(1):            /* mouse */
  239.             helpdisp("mthelp2.scr");
  240.             break;
  241.         case(2):            /* file functions */
  242.             helpdisp("mthelp3.scr");
  243.             break;
  244.         case(3):            /* edit */
  245.             helpdisp("mthelp4.scr");
  246.             break;
  247.         case(4):            /* record */
  248.             helpdisp("mthelp5.scr");
  249.             break;      
  250.         case(5):            /* title */
  251.             helpdisp("mthelp6.scr");
  252.             break;
  253.         case(6):            /* clear */
  254.             helpdisp("mthelp7.scr");
  255.             break;
  256.         case(7):            /* import */
  257.             helpdisp("mthelp8.scr");
  258.             break;
  259.         case(-2):           /* esc */
  260.         case(8):            /* quit */
  261.             return;
  262.         default:
  263.             writerr("Use arrow keys to move cursor, ret to select.", 
  264.                 g_text_char_v, g_norm_attrib, g_norm_attrib);
  265.             pick = lastpick;
  266.         }
  267.     }
  268. }
  269.  
  270.  
  271. /* Load and display one help screen.  Purge from memory after keypress. */
  272. void
  273. helpdisp(char *filename)
  274. {
  275.     struct strchain *chain;
  276.     
  277.     chain = inpchain(filename, SCRNWIDE);   /* read the screen */
  278.     if(chain == NULL){
  279.         chain = (struct strchain *) malloc(1);
  280.         writerr("Could not open help file - probably not on disk.",
  281.             g_text_char_v, g_emph_attrib, g_norm_attrib);
  282.         return;
  283.     }
  284.     clearscreen(g_norm_attrib);
  285.     fdispchain(chain, 1, g_norm_attrib, g_text_mode);   /* display screen */
  286.     while(!kbhit())                     /* wait for keypress */
  287.         ;
  288.     dechain(chain);                     /* purge screen file from memory */
  289.     getch();
  290. }
  291.