home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / mm1_tracker.lzh / TRACKER4.6 / automaton.c < prev    next >
Text File  |  1994-11-24  |  5KB  |  212 lines

  1. /* automaton.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: automaton.c,v 4.3 1994/11/15 16:11:01 espie Exp espie $
  6.  * $Log: automaton.c,v $
  7.  * Revision 4.3  1994/11/15  16:11:01  espie
  8.  * *** empty log message ***
  9.  *
  10.  * Revision 4.2  1994/08/23  18:19:46  espie
  11.  * Added speedmode option
  12.  * Abstracted IO calls.
  13.  * Use display_pattern.
  14.  * Fixed up repeat code, should work better now.
  15.  * Fixed bug with bad loops.
  16.  * Modified the way set_speed works.
  17.  * Corrected stupid bug (run_in_fg)
  18.  * Added bg/fg test.
  19.  * General cleanup
  20.  * Added finetune.
  21.  * Protracker commands.
  22.  *
  23.  * Revision 2.16  1992/11/17  17:15:37  espie
  24.  * New output for new interface
  25.  * Modified repeat logic: now works irregardless of repeat points.
  26.  * start
  27.  *
  28.  * Revision 2.8  1992/07/14  14:23:41  espie
  29.  * Changed fine speed command and comments.
  30.  * Added two level of fault tolerancy.
  31.  */
  32.      
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37.      
  38. #include "defs.h"
  39. #include "song.h"
  40. #include "channel.h"
  41. #include "extern.h"
  42. #include "prefs.h"
  43.      
  44. ID("$Id: automaton.c,v 4.3 1994/11/15 16:11:01 espie Exp espie $")
  45.      
  46.  
  47. LOCAL void clear_repeats(a, from, upto)
  48. struct automaton *a;
  49. int from, upto;
  50.    {
  51.    int i;
  52.  
  53.    for (i = from; i <= upto; i++)
  54.       a->gonethrough[i] = FALSE;
  55.    }
  56.  
  57. LOCAL void reset_repeats(a)
  58. struct automaton *a;
  59.    {
  60.    clear_repeats(a, 0, a->info->length);
  61.    a->gonethrough[a->info->length] = TRUE;
  62.    }
  63.  
  64. /* updates the pattern to play in the automaton.
  65.  * Checks that the pattern actually exists.
  66.  * Checks for repetitions as well.
  67.  */
  68. LOCAL void set_pattern(a)
  69. struct automaton *a;
  70.    {
  71.    int p;
  72.  
  73.  
  74.    if (a->pattern_num >= a->info->length)
  75.       {
  76.       error = UNRECOVERABLE;
  77.       return;
  78.       }
  79.  
  80.    if (a->gonethrough[a->pattern_num])
  81.       {
  82.       error = ENDED;
  83.       reset_repeats(a);
  84.       }
  85.    else
  86.       a->gonethrough[a->pattern_num] = TRUE;
  87.  
  88.       /* there is a level of indirection in the format,
  89.        * i.e., patterns can be repeated.
  90.        */
  91.    p = a->info->patnumber[a->pattern_num];
  92.    if (p >= a->info->maxpat)
  93.       {
  94.       error = UNRECOVERABLE;
  95.       return;
  96.       }
  97.  
  98.    display_pattern(a->pattern_num, a->info->length, p);
  99.  
  100.    a->pattern = a->info->pblocks + p;
  101.    }
  102.  
  103. /* initialize all the fields of the automaton necessary
  104.  * to play a given song.
  105.  */
  106. void init_automaton(a, song, start)
  107. struct automaton *a;
  108. struct song *song;
  109. int start;
  110.    {
  111.    a->info = &song->info;
  112.    a->pattern_num = start;    /* first pattern */
  113.  
  114.    a->loop_note_num = 0;
  115.    a->loop_counter = 0;
  116.  
  117.    reset_repeats(a);
  118.  
  119.    a->note_num = 0;           /* first note in pattern */
  120.    a->counter = 0;            /* counter for the effect tempo */
  121.    a->speed = NORMAL_SPEED;   /* this is the default effect tempo */
  122.    a->finespeed = NORMAL_FINESPEED;    
  123.                               /* this is the fine speed (100%=NORMAL_FINESPEED) */
  124.    a->do_stuff = DO_NOTHING;   
  125.                               /* some effects affect the automaton,
  126.                                * we keep them here.
  127.                                */
  128.  
  129.    error = NONE;              /* Maybe we should not reset errors at
  130.                                * this point.
  131.                                */
  132.    set_pattern(a);
  133.    }
  134.  
  135. /* Gets to the next pattern, and displays stuff */
  136. LOCAL void advance_pattern(a)
  137. struct automaton *a;
  138.    {
  139.    if (++a->pattern_num >= a->info->length)
  140.       a->pattern_num = 0;
  141.    set_pattern(a);
  142.    a->note_num = 0;
  143.    }
  144.  
  145.         
  146.  
  147. /* process all the stuff which we need to advance in the song,
  148.  * including set_speed, set_skip, set_fastskip, and set_loop.
  149.  */
  150. void next_tick(a)
  151. struct automaton *a;
  152.    {
  153.       /* there are three classes of speed changes:
  154.        * 0 does nothing. (should stop)
  155.        * <32 is the effect speed (resets the fine speed).
  156.        * >=32 changes the finespeed, default 125
  157.        */
  158.     if (a->do_stuff & (SET_SPEED | SET_FINESPEED) == SET_SPEED | SET_FINESPEED)
  159.         switch(get_pref_scalar(PREF_SPEEDMODE))
  160.             {
  161.         case FINESPEED_ONLY:
  162.             a->do_stuff &= ~SET_SPEED;
  163.             break;
  164.         case SPEED_ONLY:
  165.             a->do_stuff &= ~SET_FINESPEED;
  166.         default:
  167.             break;
  168.             }
  169.         
  170.    if ((a->do_stuff & SET_SPEED) && (a->do_stuff & SET_FINESPEED))
  171.       {
  172.       a->speed = a->new_speed;
  173.       a->finespeed = a->new_finespeed; 
  174.       }
  175.    else if (a->do_stuff & SET_FINESPEED)
  176.       {
  177.       a->finespeed = a->new_finespeed;
  178.       }
  179.    else if (a->do_stuff & SET_SPEED)
  180.       {
  181.       a->speed = a->new_speed;
  182.       a->finespeed = NORMAL_FINESPEED;
  183.       }
  184.  
  185.    if (++a->counter >= a->speed)
  186.       {
  187.       a->counter = 0;
  188.          /* loop: may change note in pattern right away */
  189.       if ((a->do_stuff & JUMP_PATTERN) && --a->loop_counter > 0)
  190.          a->note_num = a->loop_note_num;
  191.       else if (a->do_stuff & SET_FASTSKIP)
  192.          {
  193.          a->pattern_num = a->new_pattern;
  194.          set_pattern(a);
  195.          a->note_num = 0;
  196.          }
  197.       else if (a->do_stuff & SET_SKIP)
  198.          {
  199.          advance_pattern(a);
  200.          a->note_num = a->new_note;
  201.          }
  202.       else
  203.          {
  204.          if (++a->note_num >= BLOCK_LENGTH)
  205.             advance_pattern(a);
  206.          }
  207.       a->do_stuff = DO_NOTHING;
  208.       }
  209.    }
  210.  
  211.  
  212.