home *** CD-ROM | disk | FTP | other *** search
/ Bila Vrana / BILA_VRANA.iso / 031A / GMS100.ZIP / gms100 / source / musdrv.cpp < prev    next >
C/C++ Source or Header  |  1996-05-15  |  25KB  |  763 lines

  1. #define COMPILING_MUSDRV
  2.  
  3. #include <stdio.h>
  4. #include "globals.h"
  5. #ifdef TARGET_MSDOS
  6. #include <dos.h>
  7. #endif
  8. #include "musdrv.h"
  9. #include "inst.h"
  10. #include "block.h"
  11. #include "song.h"
  12. #ifdef EDITOR_HOOKS
  13. #include "system.h"
  14. #endif
  15.  
  16. music_driver::music_driver() {
  17.   int octavestep, notestep, tablestep;
  18.   
  19.   tablestep = 1;
  20.   for (octavestep = 0;octavestep < 8;octavestep++)
  21.     for (notestep = 0;notestep < 12;notestep++) {
  22.       note_to_freq_table[tablestep].oct_freq.bitmap.key_on = NO;
  23.       note_to_freq_table[tablestep].oct_freq.bitmap.octave = octavestep;
  24.       note_to_freq_table[tablestep].oct_freq.bitmap.freq_hi =
  25.         (note_freqs[notestep] & 0xF00) >> 8;
  26.       note_to_freq_table[tablestep].freq_lo = note_freqs[notestep] & 0x0FF;
  27.       tablestep++;
  28.     }
  29. #ifdef EDITOR_HOOKS
  30.   for (tablestep = 0;tablestep < MAX_TRACKS;tablestep++)
  31.     track_active[tablestep] = YES;
  32. #endif
  33.   reset_accumulated_ticks();
  34.   old_interrupt = 0;
  35.   should_song_play = NO;
  36.   forbid_count = 0;
  37. #ifdef EDITOR_HOOKS
  38.   play_block_mode = NO;
  39.   show_interrupt = NO;
  40. #endif
  41.   sb_base_address = 0x220;
  42. }
  43.  
  44. void music_driver::write_adlib(unsigned char reg, unsigned char value) {
  45.   int stepper;
  46.  
  47.   if (shadow_regs_left[reg] != value) {
  48.     shadow_regs_left[reg] = value;
  49. #ifdef TARGET_MSDOS
  50.     outp(0x388, reg);
  51.     for(stepper = 0;stepper < 6;stepper++)
  52.       inp(0x388);
  53.     outp(0x389, value);
  54.     for(stepper = 0;stepper < 35;stepper++)
  55.       inp(0x388);
  56. #else
  57. stepper = stepper;   // Eliminate spurious warning
  58. #endif
  59.   }
  60. }
  61.  
  62. void music_driver::write_sb_left(unsigned char reg, unsigned char value) {
  63.   int stepper;
  64.  
  65.   if (shadow_regs_left[reg] != value) {
  66.     shadow_regs_left[reg] = value;
  67. #ifdef TARGET_MSDOS
  68.     outp(sb_base_address, reg);
  69.     if (song_obj.soundsystem < song::sbpro2) {
  70.       for(stepper = 0;stepper < 6;stepper++)
  71.         inp(sb_base_address);
  72.       outp(sb_base_address + 1, value);
  73.       for(stepper = 0;stepper < 35;stepper++)
  74.         inp(sb_base_address);
  75.     }
  76.     else {
  77.       outp(sb_base_address + 1, value);
  78.       inp(sb_base_address);   /* Burn a little time just in case the user
  79.                                  has a VERY fast computer. */
  80.     }
  81. #else
  82. stepper = stepper;   // Eliminate spurious warning
  83. #endif
  84.   }
  85. }
  86.  
  87. void music_driver::write_sb_right(unsigned char reg, unsigned char value) {
  88.   int stepper;
  89.  
  90.   if (shadow_regs_right[reg] != value) {
  91.     shadow_regs_right[reg] = value;
  92. #ifdef TARGET_MSDOS
  93.     outp(sb_base_address + 2, reg);
  94.     if (song_obj.soundsystem < song::sbpro2) {
  95.       for(stepper = 0;stepper < 6;stepper++)
  96.         inp(sb_base_address);
  97.       outp(sb_base_address + 3, value);
  98.       for(stepper = 0;stepper < 35;stepper++)
  99.         inp(sb_base_address);
  100.     }
  101.     else {
  102.       outp(sb_base_address + 3, value);
  103.       inp(sb_base_address);   /* Burn a little time just in case the user
  104.                                  has a VERY fast computer. */
  105.     }
  106. #else
  107. stepper = stepper;   // Eliminate spurious warning
  108. #endif
  109.   }
  110. }
  111.  
  112. void music_driver::load_instrument(unsigned int inst_number,
  113.   unsigned int channel) {
  114.   int mod1_offset, mod2_offset;
  115.   instrument *this_inst;
  116.  
  117.   if (inst_number > song_obj.highest_instrument)
  118.     inst_number = 0;
  119.   this_inst = song_obj.instrument_pointer[inst_number];
  120.   if (channel > 8) {
  121.     mod1_offset = channel_offset[channel - 9];
  122.     mod2_offset = channel_offset[channel - 9 + 9];
  123.   }
  124.   else {
  125.     mod1_offset = channel_offset[channel];
  126.     mod2_offset = channel_offset[channel + 9];
  127.   }
  128. /* The performance increase is worth the space all this duplicated code
  129.    takes. */
  130.   switch (song_obj.soundsystem) {
  131.     case song::adlib:
  132.       write_adlib(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
  133.       write_adlib(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
  134.       write_adlib(SCALING_VOLUME_OFFSET+mod1_offset,
  135.         this_inst->scaling_volume1.byte);
  136.       write_adlib(SCALING_VOLUME_OFFSET+mod2_offset,
  137.         this_inst->scaling_volume2.byte);
  138.       write_adlib(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
  139.       write_adlib(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
  140.       write_adlib(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
  141.       write_adlib(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
  142.       write_adlib(OP1MOD_FEEDBACK_OFFSET+channel,
  143.         this_inst->op1mod_feedback.byte);
  144.       write_adlib(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
  145.       write_adlib(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
  146.       break;
  147.     case song::sb:
  148.       write_sb_left(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
  149.       write_sb_left(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
  150.       write_sb_left(SCALING_VOLUME_OFFSET+mod1_offset,
  151.         this_inst->scaling_volume1.byte);
  152.       write_sb_left(SCALING_VOLUME_OFFSET+mod2_offset,
  153.         this_inst->scaling_volume2.byte);
  154.       write_sb_left(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
  155.       write_sb_left(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
  156.       write_sb_left(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
  157.       write_sb_left(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
  158.       write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
  159.         this_inst->op1mod_feedback.byte);
  160.       write_sb_left(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
  161.       write_sb_left(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
  162.       break;
  163.     default:   // SB Pro 1 or 2.
  164.       if (channel > 8) {
  165.         write_sb_right(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
  166.         write_sb_right(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
  167.         write_sb_right(SCALING_VOLUME_OFFSET+mod1_offset,
  168.           this_inst->scaling_volume1.byte);
  169.         write_sb_right(SCALING_VOLUME_OFFSET+mod2_offset,
  170.           this_inst->scaling_volume2.byte);
  171.         write_sb_right(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
  172.         write_sb_right(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
  173.         write_sb_right(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
  174.         write_sb_right(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
  175.         if (song_obj.soundsystem == song::sbpro2) {
  176.           if (channel > song_obj.highest_stereo_left)
  177.             write_sb_right(OP1MOD_FEEDBACK_OFFSET+channel,
  178.               this_inst->op1mod_feedback.byte | STEREO_RIGHT_MASK);
  179.           else
  180.             write_sb_right(OP1MOD_FEEDBACK_OFFSET+channel,
  181.               this_inst->op1mod_feedback.byte | STEREO_LEFT_MASK);
  182.         }
  183.         else
  184.           write_sb_right(OP1MOD_FEEDBACK_OFFSET+channel,
  185.             this_inst->op1mod_feedback.byte);
  186.         write_sb_right(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
  187.         write_sb_right(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
  188.       }
  189.       else {
  190.         write_sb_left(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
  191.         write_sb_left(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
  192.         write_sb_left(SCALING_VOLUME_OFFSET+mod1_offset,
  193.           this_inst->scaling_volume1.byte);
  194.         write_sb_left(SCALING_VOLUME_OFFSET+mod2_offset,
  195.           this_inst->scaling_volume2.byte);
  196.         write_sb_left(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
  197.         write_sb_left(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
  198.         write_sb_left(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
  199.         write_sb_left(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
  200.         if (song_obj.soundsystem == song::sbpro2) {
  201.           if (channel > song_obj.highest_stereo_left)
  202.             write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
  203.               this_inst->op1mod_feedback.byte | STEREO_RIGHT_MASK);
  204.           else
  205.             write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
  206.               this_inst->op1mod_feedback.byte | STEREO_LEFT_MASK);
  207.         }
  208.         else
  209.           write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
  210.             this_inst->op1mod_feedback.byte);
  211.         write_sb_left(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
  212.         write_sb_left(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
  213.       }
  214.       break;
  215.   }
  216. }
  217.  
  218. void music_driver::reset_card() {
  219.   int stepper;
  220.  
  221.   for (stepper = 0;stepper < MAX_TRACKS;stepper++) {
  222.     last_note_freq[stepper].freq_lo = 0;
  223.     last_note_freq[stepper].oct_freq.byte = 0;
  224.     frequency_offset[stepper] = 0;
  225.