home *** CD-ROM | disk | FTP | other *** search
/ Zodiac Super OZ / MEDIADEPOT.ISO / FILES / 15 / GMS100.ZIP / gms100 / source / musdrv.h < prev    next >
C/C++ Source or Header  |  1996-05-15  |  5KB  |  148 lines

  1. // Music driver class contains the actual song playing code
  2.  
  3. #define TIMER_INTERRUPT_VECTOR 0x1C
  4. #define TIMER_CONTROL_PORT 0x43
  5. #define TIMER_COUNTER_PORT 0x40
  6. #define AM_VIB_OFFSET 0x20
  7. #define SCALING_VOLUME_OFFSET 0x40
  8. #define A_D_OFFSET 0x60
  9. #define S_R_OFFSET 0x80
  10. #define OP1MOD_FEEDBACK_OFFSET 0xC0
  11. #define WAVE_OFFSET 0xE0
  12. #define FREQ_LO_OFFSET 0xA0
  13. #define OCT_FREQ_OFFSET 0xB0
  14. #define STEREO_LEFT_MASK 0x10
  15. #define STEREO_RIGHT_MASK 0x20
  16.  
  17. union oct_freq_union {
  18.   unsigned char byte;
  19.   struct {
  20.     unsigned freq_hi: 2;
  21.     unsigned octave: 3;
  22.     unsigned key_on: 1;
  23.   } bitmap;
  24. };
  25.  
  26. struct freq_lo_hi {
  27.   unsigned char freq_lo;
  28.   oct_freq_union oct_freq;
  29. };
  30.  
  31. class music_driver {
  32. public:
  33. // Copy of the sb card's current register settings
  34.   unsigned char shadow_regs[256];
  35.   unsigned char shadow_regs_left[256];
  36.   unsigned char shadow_regs_right[256];
  37.   static const unsigned char channel_offset[9+9];
  38.   static const unsigned int note_freqs[13];
  39.   freq_lo_hi note_to_freq_table[127];
  40.   freq_lo_hi last_note_freq[MAX_TRACKS];
  41.   long int frequency_offset[MAX_TRACKS];
  42.   unsigned int accumulated_ticks;
  43.   unsigned long int portamento_dest[MAX_TRACKS];
  44.   unsigned int last_portamento[MAX_TRACKS];
  45.   unsigned int vibrato_direction[MAX_TRACKS];
  46.   int vibrato_offset[MAX_TRACKS];
  47. #ifdef TARGET_MSDOS
  48.   void interrupt (*old_interrupt)(...);
  49. #else
  50.   void (*old_interrupt)(...);
  51. #endif
  52.   unsigned int should_song_play;
  53.   int jump_indicator;
  54.   unsigned int forbid_count;
  55. #ifdef EDITOR_HOOKS
  56.   unsigned int play_block_mode;
  57.   unsigned int track_active[MAX_TRACKS];
  58.   unsigned int show_interrupt;
  59. #endif
  60.   unsigned int sb_base_address;
  61.  
  62.   music_driver();
  63.   void write_adlib(unsigned char reg, unsigned char value);
  64.   void write_sb_left(unsigned char reg, unsigned char value);
  65.   void write_sb_right(unsigned char reg, unsigned char value);
  66.   void force_write_adlib(unsigned char reg, unsigned char value)
  67.     {shadow_regs_left[reg] = value + 1;write_adlib(reg, value);}
  68.   void force_write_sb_left(unsigned char reg, unsigned char value)
  69.     {shadow_regs_left[reg] = value + 1;write_sb_left(reg, value);}
  70.   void force_write_sb_right(unsigned char reg, unsigned char value)
  71.     {shadow_regs_right[reg] = value + 1;write_sb_right(reg, value);}
  72. /* The force_write_<card> routines will force a write even if the register
  73.    already contains the value. */
  74.   void load_instrument(unsigned int inst_number, unsigned int channel);
  75.   void reset_card();
  76.   void set_up_card();
  77.   void play_one_note(unsigned char *note, unsigned int channel,
  78.     unsigned int just_effects);
  79.   unsigned int check_for_portamento(unsigned char *note);
  80.   void write_frequency(unsigned int channel);
  81.   void set_volume(unsigned int channel, unsigned int new_volume);
  82.   void shift_volume(unsigned int channel, int volume_shift);
  83.   void play_one_line(unsigned int just_effects);
  84.   void update();
  85.   void reset_accumulated_ticks() {accumulated_ticks = 1;jump_indicator = -1;}
  86.   unsigned int compute_timer_setting(unsigned int tempo);
  87. #ifdef TARGET_MSDOS
  88.   static void interrupt timer_int(...);
  89. #else
  90.   static void timer_int();
  91. #endif
  92.   int wedge_player();
  93.   int remove_player();
  94.   void set_timer(unsigned int new_setting);
  95.   void start_playing() {should_song_play = YES;}
  96.   void stop_playing() {should_song_play = NO;}
  97.   unsigned int is_song_playing() {return should_song_play;}
  98.   void forbid_playing() {forbid_count++;}
  99.   void permit_playing() {forbid_count--;}
  100. #ifdef EDITOR_HOOKS
  101.   void update_am_vib();
  102. #endif
  103. };
  104.  
  105. inline unsigned int music_driver::check_for_portamento(unsigned char *note) {
  106.   do {
  107.     if ((*note & 127) == 0x3)
  108.       return YES;
  109.     else
  110.       note += 2;
  111.   }
  112.   while (*(note - 2) & 128);
  113.   return NO;
  114. }
  115.  
  116. inline unsigned int music_driver::compute_timer_setting(unsigned int tempo) {
  117.   return 0x2D8426 / (tempo + 45);
  118. }
  119.  
  120. inline void music_driver::set_timer(unsigned int new_setting) {
  121. #ifdef TARGET_MSDOS
  122.   outp(TIMER_CONTROL_PORT, 0x3C);
  123.   outp(TIMER_COUNTER_PORT, new_setting);
  124.   outp(TIMER_COUNTER_PORT, new_setting >> 8);
  125. #endif
  126. #ifdef TARGET_LINUX
  127. new_setting = new_setting;   // Eliminate spurious warning
  128. #endif
  129. }
  130.  
  131. #ifdef COMPILING_MUSDRV
  132. const unsigned char music_driver::channel_offset[9+9] =
  133.     {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12,
  134.      0x03, 0x04, 0x05, 0x0b, 0x0c, 0x0d, 0x13, 0x14, 0x15};
  135. // Lookup table for the sb card's weird register configuration
  136.  
  137. const unsigned int music_driver::note_freqs[13] =
  138.     {0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202,
  139.      0x220, 0x241, 0x263, 0x287, 0x2AE};
  140. // Frequencies of notes, from C (octave x) to C (octave x+1)
  141. #endif
  142.  
  143. #ifdef COMPILING_MUSDRV
  144. music_driver music;
  145. #else
  146. extern music_driver music;
  147. #endif
  148.