home *** CD-ROM | disk | FTP | other *** search
/ Zodiac Super OZ / MEDIADEPOT.ISO / FILES / 15 / 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.     portamento_dest[stepper] = 0;
  226.     last_portamento[stepper] = 0;
  227.     vibrato_offset[stepper] = 0;
  228.   }
  229.   switch (song_obj.soundsystem) {
  230.     case song::adlib:
  231. // Key-off all channels first to avoid channel lockup
  232.       for(stepper = 0xB0;stepper < 0xB8;stepper++)
  233.         force_write_adlib(stepper, 0);
  234.       for(stepper = 0x20;stepper < 0xF6;stepper++)
  235.         force_write_adlib(stepper, 0);
  236.       force_write_adlib(0x08, 0);
  237.       break;
  238.     case song::sb:
  239.       for(stepper = 0xB0;stepper < 0xB8;stepper++)
  240.         force_write_sb_left(stepper, 0);
  241.       for(stepper = 0x20;stepper < 0xF6;stepper++)
  242.         force_write_sb_left(stepper, 0);
  243.       force_write_sb_left(0x08, 0);
  244.       break;
  245.     default:
  246.       for(stepper = 0xB0;stepper < 0xB8;stepper++) {
  247.         force_write_sb_left(stepper, 0);
  248.         force_write_sb_right(stepper, 0);
  249.       }
  250.       for(stepper = 0x20;stepper < 0xF6;stepper++) {
  251.         force_write_sb_left(stepper, 0);
  252.         force_write_sb_right(stepper, 0);
  253.       }
  254.       write_sb_left(0x08, 0);
  255.       if (song_obj.soundsystem == song::sbpro2) {
  256.         force_write_sb_right(0x04, 0);
  257.         force_write_sb_right(0x05, 0);
  258.       }
  259.       break;
  260.   }
  261. }
  262.  
  263. void music_driver::set_up_card() {
  264.   if (song_obj.soundsystem == song::adlib) {
  265.     force_write_adlib(0x01, 32);
  266.     force_write_adlib(0xBD, song_obj.overall_am_vib.byte);
  267.   }
  268.   else {
  269.     force_write_sb_left(0x01, 32);
  270.     force_write_sb_left(0xBD, song_obj.overall_am_vib.byte);
  271.   }
  272.   if (song_obj.soundsystem == song::sbpro2)
  273.     force_write_sb_right(0x05, 1);
  274. }
  275.  
  276. void music_driver::play_one_note(unsigned char *note, unsigned int channel,
  277.   unsigned int just_effects) {
  278.   unsigned int freq_changed = NO;
  279.   unsigned long int curr_freq;
  280.  
  281.   if ((!just_effects) && (*note & 127)) {
  282. // New note or key-off
  283.     if((*note & 127) == 127) {
  284.       last_note_freq[channel].oct_freq.bitmap.key_on = NO;
  285.       write_frequency(channel); // <-- Handles case of key off + inst change
  286.     }
  287.     else {
  288.       if ((*note & 128) && (*(note+1) & 128)
  289.         && check_for_portamento(note+2)) {
  290.         portamento_dest[channel] =
  291.           ((note_to_freq_table[*note & 127].oct_freq.bitmap.freq_hi << 8)
  292.           + note_to_freq_table[*note & 127].freq_lo)
  293.           << note_to_freq_table[*note & 127].oct_freq.bitmap.octave;
  294.       }
  295.       else {
  296.         last_note_freq[channel].freq_lo =
  297.           note_to_freq_table[*note & 127].freq_lo;
  298.         last_note_freq[channel].oct_freq.byte =
  299.           note_to_freq_table[*note & 127].oct_freq.byte;
  300.         last_note_freq[channel].oct_freq.bitmap.key_on = YES;
  301.         frequency_offset[channel] = 0;
  302.         vibrato_offset[channel] = 0;
  303.         freq_changed = YES;
  304.       }
  305.     }
  306.   }
  307.   if (*note & 128) {
  308.     note++;
  309.     if ((!just_effects) && (*note & 127)) {
  310. /* Instrument change. IMPORTANT: We cannot change the instrument while the
  311.    channel is keyed on. Doing so will cause the channel to lock up. */
  312.       if (last_note_freq[channel].oct_freq.bitmap.key_on) {
  313.         last_note_freq[channel].oct_freq.bitmap.key_on = NO;
  314.         write_frequency(channel);
  315.         last_note_freq[channel].oct_freq.bitmap.key_on = YES;
  316.         freq_changed = YES;
  317.       }
  318.       load_instrument(*note & 127, channel);
  319.     }
  320.     if (*note & 128) {
  321.       int more_commands = YES;
  322.  
  323.       note++;
  324. // Do commands
  325.       while (more_commands) {
  326.         more_commands = (*note & 128);
  327.         switch (*(note++) & 127) {
  328.           case 0x0:
  329.             break;
  330.           case 0x1:
  331.             frequency_offset[channel] += *note;
  332.             freq_changed = YES;
  333.             break;
  334.           case 0x2:
  335.             frequency_offset[channel] -= *note;
  336.             freq_changed = YES;
  337.             break;
  338.           case 0x3:
  339.             // Portamento burns cpu cycles.
  340.             if (*note)
  341.               last_portamento[channel] = *note;
  342.             curr_freq = (((last_note_freq[channel].oct_freq.bitmap.freq_hi
  343.               << 8) + last_note_freq[channel].freq_lo)
  344.               << last_note_freq[channel].oct_freq.bitmap.octave)
  345.               + frequency_offset[channel];
  346.             if (curr_freq < portamento_dest[channel]) {
  347.               if (curr_freq + last_portamento[channel]
  348.                 > portamento_dest[channel])
  349.                 frequency_offset[channel] += portamento_dest[channel]
  350.                   - curr_freq;
  351.               else
  352.                 frequency_offset[channel] += last_portamento[channel];
  353.             }
  354.             else {
  355.               if (curr_freq - last_portamento[channel]
  356.                 < portamento_dest[channel])
  357.                 frequency_offset[channel] += portamento_dest[channel]
  358.                   - curr_freq;
  359.               else
  360.                 frequency_offset[channel] -= last_portamento[channel];
  361.             }
  362.             freq_changed = YES;
  363.             break;
  364.           case 0x4:
  365.             if (vibrato_direction[channel]) {
  366.               vibrato_offset[channel] += *note >> 4;
  367.               if (vibrato_offset[channel] >= ((*note & 15) << 2))
  368.                 vibrato_direction[channel] = 0;
  369.             }
  370.             else {
  371.               vibrato_offset[channel] -= *note >> 4;
  372.               if (vibrato_offset[channel] <= -((*note & 15) << 2))
  373.                 vibrato_direction[channel] = 1;
  374.             }
  375.             freq_changed = YES;
  376.             break;
  377.           case 0xD:
  378.             if (*note & 240)
  379.               shift_volume(channel, (*note & 240) >> 4);
  380.             else
  381.               shift_volume(channel, -(*note & 15));
  382.             break;
  383.           default:
  384. // These commands only need to be done when the note is first played.
  385.             if (!just_effects)
  386.               switch (*(note-1) & 127) {
  387.                 case 0x9:
  388.                   song_obj.secondary_tempo = *note;
  389.                   break;
  390.                 case 0xC:
  391.                   if (*note > 63)
  392.                     set_volume(channel, 0);
  393.                   else
  394.                     set_volume(channel, 63 - *note);
  395.                   break;
  396.                 case 0xB:
  397.                   jump_indicator = *note;
  398.                   break;
  399.                 case 0xF:
  400.                   if (*note) {
  401.                     if (*note == 0xFF)
  402.                       stop_playing();
  403.                     else
  404.                       song_obj.tempo = *note;
  405.                   }
  406.                   else {
  407.                     if (song_obj.current_pattern == song_obj.highest_pattern)
  408.                       jump_indicator = 0;
  409.                     else
  410.                       jump_indicator = song_obj.current_pattern + 1;
  411.                   }
  412.                   break;
  413.               }
  414.             break;
  415.         }
  416.         note++;
  417.       }
  418.     }
  419.   }
  420.   if (freq_changed)
  421.     write_frequency(channel);
  422. }
  423.  
  424. void music_driver::write_frequency(unsigned int channel) {
  425.   int workvar;
  426.   oct_freq_union writer;
  427.   int workoct;
  428.  
  429.   if (frequency_offset[channel] || vibrato_offset[channel]) {
  430. // Some sort of effect (e.g. slide) has altered the frequency.
  431.     writer.byte = last_note_freq[channel].oct_freq.byte;
  432.     workoct = writer.bitmap.octave;
  433.     workvar = (writer.bitmap.freq_hi << 8) +
  434.       last_note_freq[channel].freq_lo
  435.       + (frequency_offset[channel] >> workoct) + vibrato_offset[channel];
  436. // Technically, vibrato_offset should be right-shifted by workoct.
  437.     if (workvar < 1) {
  438.       workvar = note_freqs[0];
  439.       workoct = 0;
  440.     }
  441.     while ((unsigned int) workvar < note_freqs[0]) {
  442.       workvar = workvar << 1;
  443.       workoct--;
  444.     }
  445.     while ((unsigned int) workvar > note_freqs[12]) {
  446.       workvar = workvar >> 1;
  447.       workoct++;
  448.     }
  449.     if (workoct < 0) {
  450.       workoct = 0;
  451.       workvar = note_freqs[0];
  452.     }
  453.     else
  454.       if (workoct > 7) {
  455.         workoct = 7;
  456.         workvar = note_freqs[12];
  457.       }
  458.     writer.bitmap.octave = workoct;
  459.     writer.bitmap.freq_hi = workvar >> 8;
  460.     switch (song_obj.soundsystem) {
  461.       case song::adlib:
  462.         write_adlib(FREQ_LO_OFFSET+channel, (unsigned char) workvar);
  463.         write_adlib(OCT_FREQ_OFFSET+channel, writer.byte);
  464.         break;
  465.       case song::sb:
  466.         write_sb_left(FREQ_LO_OFFSET+channel, (unsigned char) workvar);
  467.         write_sb_left(OCT_FREQ_OFFSET+channel, writer.byte);
  468.         break;
  469.       case song::sbpro1:
  470.       case song::sbpro2:
  471.         if (channel > 8) {
  472.           write_sb_right(FREQ_LO_OFFSET+channel-9, (unsigned char) workvar);
  473.           write_sb_right(OCT_FREQ_OFFSET+channel-9, writer.byte);
  474.         }
  475.         else {
  476.           write_sb_left(FREQ_LO_OFFSET+channel, (unsigned char) workvar);
  477.           write_sb_left(OCT_FREQ_OFFSET+channel, writer.byte);
  478.         }
  479.         break;
  480.     }
  481.   }
  482.   else
  483. // The frequency has not been altered.
  484.     switch (song_obj.soundsystem) {
  485.       case song::adlib:
  486.         write_adlib(FREQ_LO_OFFSET+channel, last_note_freq[channel].freq_lo);
  487.         write_adlib(OCT_FREQ_OFFSET+channel,
  488.           last_note_freq[channel].oct_freq.byte);
  489.         break;
  490.       case song::sb:
  491.         write_sb_left(FREQ_LO_OFFSET+channel, last_note_freq[channel].freq_lo);
  492.         write_sb_left(OCT_FREQ_OFFSET+channel,
  493.           last_note_freq[channel].oct_freq.byte);
  494.         break;
  495.       case song::sbpro1:
  496.       case song::sbpro2:
  497.         if (channel > 8) {
  498.           write_sb_right(FREQ_LO_OFFSET+channel-9,
  499.             last_note_freq[channel].freq_lo);
  500.           write_sb_right(OCT_FREQ_OFFSET+channel-9,
  501.             last_note_freq[channel].oct_freq.byte);
  502.         }
  503.         else {
  504.           write_sb_left(FREQ_LO_OFFSET+channel,
  505.             last_note_freq[channel].freq_lo);
  506.           write_sb_left(OCT_FREQ_OFFSET+channel,
  507.             last_note_freq[channel].oct_freq.byte);
  508.         }
  509.         break;
  510.     }
  511. }
  512.  
  513. void music_driver::set_volume(unsigned int channel,
  514.   unsigned int new_volume) {
  515.   scaling_volume_union workvar;
  516.   
  517. // We only change the volume of operator 2.
  518.   switch (song_obj.soundsystem) {
  519.     case song::adlib:
  520.       workvar.byte =
  521.         shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
  522.       workvar.bitmap.volume = new_volume;
  523.       write_adlib(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
  524.         workvar.byte);
  525.       break;
  526.     case song::sb:
  527.       workvar.byte =
  528.         shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
  529.       workvar.bitmap.volume = new_volume;
  530.       write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
  531.         workvar.byte);
  532.       break;
  533.     case song::sbpro1:
  534.     case song::sbpro2:
  535.       if (channel > 8) {
  536.         workvar.byte =
  537.           shadow_regs_right[SCALING_VOLUME_OFFSET+channel_offset[channel-9+9]];
  538.         workvar.bitmap.volume = new_volume;
  539.         write_sb_right(SCALING_VOLUME_OFFSET+channel_offset[channel-9+9],
  540.           workvar.byte);
  541.       }
  542.       else {
  543.         workvar.byte =
  544.           shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
  545.         workvar.bitmap.volume = new_volume;
  546.         write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
  547.           workvar.byte);
  548.       }
  549.       break;
  550.   }
  551. }
  552.  
  553. void music_driver::shift_volume(unsigned int channel, int volume_shift) {
  554.   scaling_volume_union workvar;
  555.   int worknum;
  556.   
  557. // We only change the volume of operator 2.
  558.   if ((song_obj.soundsystem == song::adlib)
  559.     || (song_obj.soundsystem == song::sb))
  560.     workvar.byte =
  561.       shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
  562.   else {
  563.     if (channel > 8)
  564.       workvar.byte =
  565.         shadow_regs_right[SCALING_VOLUME_OFFSET+channel_offset[channel-9+9]];
  566.     else
  567.       workvar.byte =
  568.         shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
  569.   }
  570.   worknum = workvar.bitmap.volume - volume_shift;
  571.   if (worknum < 0)
  572.     worknum = 0;
  573.   else
  574.     if (worknum > 63)
  575.       worknum = 63;
  576.   workvar.bitmap.volume = worknum;
  577.   switch (song_obj.soundsystem) {
  578.     case song::adlib:
  579.       write_adlib(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
  580.         workvar.byte);
  581.       break;
  582.     case song::sb:
  583.       write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
  584.         workvar.byte);
  585.       break;
  586.     case song::sbpro1:
  587.     case song::sbpro2:
  588.       if (channel > 8)
  589.         write_sb_right(SCALING_VOLUME_OFFSET+channel_offset[channel-9+9],
  590.           workvar.byte);
  591.       else
  592.         write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
  593.           workvar.byte);
  594.       break;
  595.   }
  596. }
  597.  
  598. void music_driver::play_one_line(unsigned int just_effects) {
  599.   unsigned int stepper;
  600.   unsigned int farthest_right;
  601.   int offset;
  602.  
  603.   switch (song_obj.soundsystem) {
  604.     case song::adlib:
  605.     case song::sb:
  606.       if (song_obj.highest_track > 8)
  607.         farthest_right = 8;
  608.       else
  609.         farthest_right = song_obj.highest_track;
  610.       for(stepper = 0;stepper <= farthest_right;stepper++)
  611.         if (song_obj.current_note[stepper])   // Don't play an "empty" track.
  612. #ifdef EDITOR_HOOKS
  613.           if (track_active[stepper])
  614. #endif
  615.             play_one_note(song_obj.current_note[stepper], stepper,
  616.               just_effects);
  617.       break;
  618.     case song::sbpro1:
  619.       if (song_obj.highest_stereo_left > 8)
  620.         farthest_right = 8;
  621.       else
  622.         farthest_right = song_obj.highest_stereo_left;
  623.       if (farthest_right > song_obj.highest_track)
  624.         farthest_right = song_obj.highest_track;
  625.       for(stepper = 0;stepper <= farthest_right;stepper++)
  626.         if (song_obj.current_note[stepper])   // Don't play an "empty" track.
  627. #ifdef EDITOR_HOOKS
  628.           if (track_active[stepper])
  629. #endif
  630.             play_one_note(song_obj.current_note[stepper], stepper,
  631.               just_effects);
  632.       if (song_obj.highest_track > song_obj.highest_stereo_left) {
  633.         if (song_obj.highest_track > song_obj.highest_stereo_left + 9)
  634.           farthest_right = song_obj.highest_stereo_left + 9;
  635.         else
  636.           farthest_right = song_obj.highest_track;
  637.         offset = 8 - song_obj.highest_stereo_left;
  638.         for(stepper = song_obj.highest_stereo_left + 1;
  639.           stepper <= farthest_right;stepper++)
  640.           if (song_obj.current_note[stepper])   // Don't play an "empty" track.
  641. #ifdef EDITOR_HOOKS
  642.           if (track_active[stepper])
  643. #endif
  644.               play_one_note(song_obj.current_note[stepper], stepper + offset,
  645.                 just_effects);
  646.       }
  647.       break;
  648.     case song::sbpro2:
  649.       for(stepper = 0;stepper <= song_obj.highest_track;stepper++)
  650.         if (song_obj.current_note[stepper])   // Don't play an "empty" track.
  651. #ifdef EDITOR_HOOKS
  652.           if (track_active[stepper])
  653. #endif
  654.             play_one_note(song_obj.current_note[stepper], stepper,
  655.               just_effects);
  656.       break;
  657.   }
  658. }
  659.  
  660. void music_driver::update() {
  661. /* Master update routine. Plays notes and advances lines and patterns. Needs
  662.    to be called as often as required by the current tempo (normally this is
  663.    done by an interrupt routine). */
  664.  
  665. #ifdef EDITOR_HOOKS
  666. #ifdef TARGET_MSDOS
  667.   if (show_interrupt) {
  668.     outp(VIDEO_PALETTE_MASK, 0xFF);
  669.     outp(VIDEO_PALETTE_WRITE, 0);
  670.     outp(VIDEO_PALETTE_DATA, 63);
  671.     outp(VIDEO_PALETTE_DATA, 0);
  672.     outp(VIDEO_PALETTE_DATA, 0);
  673.   }
  674. #endif
  675. #endif
  676.   if (should_song_play) {
  677. #ifdef EDITOR_HOOKS
  678.     if (!forbid_count) {
  679. #endif
  680.       if (accumulated_ticks > song_obj.secondary_tempo) {
  681.         if (jump_indicator == -1)
  682.           song_obj.advance_line();
  683.         else
  684. #ifdef EDITOR_HOOKS
  685.           if (play_block_mode)
  686.             song_obj.block_jump(song_obj.current_block);
  687.           else
  688. #endif
  689.             song_obj.position_jump(jump_indicator);
  690.         reset_accumulated_ticks();
  691.       }
  692.       if (accumulated_ticks > 1)
  693.         play_one_line(YES);
  694.       else
  695.         play_one_line(NO);
  696.       accumulated_ticks++;
  697. #ifdef EDITOR_HOOKS
  698.     }
  699. #endif
  700.   }
  701. #ifdef EDITOR_HOOKS
  702. #ifdef TARGET_MSDOS
  703.   if (show_interrupt) {
  704.     outp(VIDEO_PALETTE_MASK, 0xFF);
  705.     outp(VIDEO_PALETTE_WRITE, 0);
  706.     outp(VIDEO_PALETTE_DATA, 0);
  707.     outp(VIDEO_PALETTE_DATA, 0);
  708.     outp(VIDEO_PALETTE_DATA, 0);
  709.   }
  710. #endif
  711. #endif
  712. }
  713.  
  714. int music_driver::wedge_player() {
  715.   if (old_interrupt)
  716.     return 0;
  717.   else {
  718.     set_timer(compute_timer_setting(song_obj.tempo));
  719. #ifdef TARGET_MSDOS
  720.     old_interrupt = getvect(TIMER_INTERRUPT_VECTOR);
  721.     setvect(TIMER_INTERRUPT_VECTOR, timer_int);
  722. #endif
  723.     return 1;
  724.   }
  725. }
  726.  
  727. int music_driver::remove_player() {
  728.   if (old_interrupt) {
  729. #ifdef TARGET_MSDOS
  730.     setvect(TIMER_INTERRUPT_VECTOR, old_interrupt);
  731. #endif
  732.     old_interrupt = 0;
  733.     return 1;
  734.   }
  735.   else
  736.     return 0;
  737. }
  738.  
  739. #ifdef TARGET_MSDOS
  740. void interrupt music_driver::timer_int(...) {
  741. #else
  742. void music_driver::timer_int() {
  743. #endif
  744. // Called once every timer interrupt to call update().
  745.   static unsigned int old_tempo;
  746.   
  747.   music.update();
  748.   if (old_tempo != song_obj.tempo) {
  749.     music.set_timer(music.compute_timer_setting(song_obj.tempo));
  750.     old_tempo = song_obj.tempo;
  751.   }
  752.   music.old_interrupt();
  753. }
  754.  
  755. #ifdef EDITOR_HOOKS
  756. void music_driver::update_am_vib() {
  757.   if (song_obj.soundsystem == song::adlib)
  758.     write_adlib(0xBD, song_obj.overall_am_vib.byte);
  759.   else
  760.     write_sb_left(0xBD, song_obj.overall_am_vib.byte);
  761. }
  762. #endif
  763.