home *** CD-ROM | disk | FTP | other *** search
/ Inside Multimedia 1995 August / IMM0895.ISO01.iso / share / os2 / track061 / automato.c < prev    next >
Text File  |  1992-10-30  |  3KB  |  139 lines

  1. /* automaton.c */
  2.  
  3. /* modified by David Nichols for OS/2 PM MOD player */
  4.  
  5. /* $Author: espie $
  6.  * $Id: automaton.c,v 2.5 1991/11/20 20:46:35 espie Exp espie $
  7.  * $Revision: 2.5 $
  8.  * $Log: automaton.c,v $
  9.  * Revision 2.5  1991/11/20  20:46:35  espie
  10.  * Minor correction.
  11.  *
  12.  * Revision 2.4  1991/11/19  16:07:19  espie
  13.  * Added comments, moved minor stuff around.
  14.  *
  15.  * Revision 2.3  1991/11/18  01:23:30  espie
  16.  * Added two level of fault tolerancy.
  17.  *
  18.  * Revision 2.2  1991/11/18  01:12:31  espie
  19.  * Minor changes.
  20.  *
  21.  * Revision 2.1  1991/11/17  23:07:58  espie
  22.  * Coming from str32.
  23.  *
  24.  *
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30.  
  31. #include "defs.h"
  32.  
  33. /* updates the pattern to play in the automaton.
  34.  * Checks that the pattern actually exists.
  35.  */
  36.  
  37. void set_pattern (struct automaton *a)
  38. {
  39.   static int p;
  40.  
  41.   if (a->pattern_num >= a->info->length)
  42.     {
  43.       error = UNRECOVERABLE;
  44.       return;
  45.     }
  46.  
  47.   /* there is a level of indirection in the format,
  48.    * i.e., patterns can be repeated.
  49.    */
  50.   p = a->info->patnumber[a->pattern_num];
  51.   if (p >= a->info->maxpat)
  52.     {
  53.       error = UNRECOVERABLE;
  54.       return;
  55.     }
  56.   a->pattern = a->info->pblocks + p;
  57. }
  58.  
  59. /* initialize all the fields of the automaton necessary
  60.  * to play a given song.
  61.  */
  62.  
  63. void init_automaton (struct automaton *a, struct song *song)
  64. {
  65.   a->info = song->info;
  66.   a->pattern_num = 0;        /* first pattern */
  67.   a->note_num = 0;        /* first note in pattern */
  68.   a->counter = 0;        /* counter for the effect tempo */
  69.   a->speed = NORMAL_SPEED;    /* this is the default effect tempo */
  70.   a->finespeed = NORMAL_FINESPEED;
  71.   /* this is the fine speed (100%)    */
  72.   a->do_stuff = DO_NOTHING;
  73.   /* some effects affect the automaton,
  74.    * we keep them here.
  75.    */
  76.  
  77.   error = NONE;            /* Maybe we should not reset errors at
  78.                                  * this point.
  79.                                  */
  80.   set_pattern (a);
  81. }
  82.  
  83. /* Gets to the next pattern, and displays stuff */
  84.  
  85. void advance_pattern (struct automaton *a)
  86. {
  87.   if (++a->pattern_num >= a->info->length)
  88.     {
  89.       a->pattern_num = 0;
  90.       error = ENDED;
  91.     }
  92.   set_pattern (a);
  93.   a->note_num = 0;
  94. }
  95.  
  96. /* process all the stuff which we need to advance in the song,
  97.  * including set_speed, set_skip and set_fastskip.
  98.  */
  99. void next_tick (struct automaton *a)
  100. {
  101.   if (a->do_stuff & SET_SPEED && a->new_speed)
  102.     {
  103.       /* there are three classes of speed changes:
  104.        * 0 does nothing.
  105.        * <32 is the effect speed (resets the fine speed).
  106.        * >=32 changes the finespeed, so this is 32% to 255%
  107.        */
  108.       if (a->new_speed >= 32)
  109.     a->finespeed = a->new_speed;
  110.       else
  111.     {
  112.       a->speed = a->new_speed;
  113.       a->finespeed = 100;
  114.     }
  115.     }
  116.   if (++a->counter >= a->speed)
  117.     {
  118.       a->counter = 0;
  119.  
  120.       if (a->do_stuff & SET_FASTSKIP)
  121.     {
  122.       a->pattern_num = a->new_pattern;
  123.       set_pattern (a);
  124.       a->note_num = 0;
  125.     }
  126.       else if (a->do_stuff & SET_SKIP)
  127.     {
  128.       advance_pattern (a);
  129.       a->note_num = a->new_note;
  130.     }
  131.       else
  132.     {
  133.       if (++a->note_num >= BLOCK_LENGTH)
  134.         advance_pattern (a);
  135.     }
  136.       a->do_stuff = DO_NOTHING;
  137.     }
  138. }
  139.