home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
15
/
GMS100.ZIP
/
gms100
/
source
/
musdrv.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-15
|
25KB
|
763 lines
#define COMPILING_MUSDRV
#include <stdio.h>
#include "globals.h"
#ifdef TARGET_MSDOS
#include <dos.h>
#endif
#include "musdrv.h"
#include "inst.h"
#include "block.h"
#include "song.h"
#ifdef EDITOR_HOOKS
#include "system.h"
#endif
music_driver::music_driver() {
int octavestep, notestep, tablestep;
tablestep = 1;
for (octavestep = 0;octavestep < 8;octavestep++)
for (notestep = 0;notestep < 12;notestep++) {
note_to_freq_table[tablestep].oct_freq.bitmap.key_on = NO;
note_to_freq_table[tablestep].oct_freq.bitmap.octave = octavestep;
note_to_freq_table[tablestep].oct_freq.bitmap.freq_hi =
(note_freqs[notestep] & 0xF00) >> 8;
note_to_freq_table[tablestep].freq_lo = note_freqs[notestep] & 0x0FF;
tablestep++;
}
#ifdef EDITOR_HOOKS
for (tablestep = 0;tablestep < MAX_TRACKS;tablestep++)
track_active[tablestep] = YES;
#endif
reset_accumulated_ticks();
old_interrupt = 0;
should_song_play = NO;
forbid_count = 0;
#ifdef EDITOR_HOOKS
play_block_mode = NO;
show_interrupt = NO;
#endif
sb_base_address = 0x220;
}
void music_driver::write_adlib(unsigned char reg, unsigned char value) {
int stepper;
if (shadow_regs_left[reg] != value) {
shadow_regs_left[reg] = value;
#ifdef TARGET_MSDOS
outp(0x388, reg);
for(stepper = 0;stepper < 6;stepper++)
inp(0x388);
outp(0x389, value);
for(stepper = 0;stepper < 35;stepper++)
inp(0x388);
#else
stepper = stepper; // Eliminate spurious warning
#endif
}
}
void music_driver::write_sb_left(unsigned char reg, unsigned char value) {
int stepper;
if (shadow_regs_left[reg] != value) {
shadow_regs_left[reg] = value;
#ifdef TARGET_MSDOS
outp(sb_base_address, reg);
if (song_obj.soundsystem < song::sbpro2) {
for(stepper = 0;stepper < 6;stepper++)
inp(sb_base_address);
outp(sb_base_address + 1, value);
for(stepper = 0;stepper < 35;stepper++)
inp(sb_base_address);
}
else {
outp(sb_base_address + 1, value);
inp(sb_base_address); /* Burn a little time just in case the user
has a VERY fast computer. */
}
#else
stepper = stepper; // Eliminate spurious warning
#endif
}
}
void music_driver::write_sb_right(unsigned char reg, unsigned char value) {
int stepper;
if (shadow_regs_right[reg] != value) {
shadow_regs_right[reg] = value;
#ifdef TARGET_MSDOS
outp(sb_base_address + 2, reg);
if (song_obj.soundsystem < song::sbpro2) {
for(stepper = 0;stepper < 6;stepper++)
inp(sb_base_address);
outp(sb_base_address + 3, value);
for(stepper = 0;stepper < 35;stepper++)
inp(sb_base_address);
}
else {
outp(sb_base_address + 3, value);
inp(sb_base_address); /* Burn a little time just in case the user
has a VERY fast computer. */
}
#else
stepper = stepper; // Eliminate spurious warning
#endif
}
}
void music_driver::load_instrument(unsigned int inst_number,
unsigned int channel) {
int mod1_offset, mod2_offset;
instrument *this_inst;
if (inst_number > song_obj.highest_instrument)
inst_number = 0;
this_inst = song_obj.instrument_pointer[inst_number];
if (channel > 8) {
mod1_offset = channel_offset[channel - 9];
mod2_offset = channel_offset[channel - 9 + 9];
}
else {
mod1_offset = channel_offset[channel];
mod2_offset = channel_offset[channel + 9];
}
/* The performance increase is worth the space all this duplicated code
takes. */
switch (song_obj.soundsystem) {
case song::adlib:
write_adlib(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
write_adlib(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
write_adlib(SCALING_VOLUME_OFFSET+mod1_offset,
this_inst->scaling_volume1.byte);
write_adlib(SCALING_VOLUME_OFFSET+mod2_offset,
this_inst->scaling_volume2.byte);
write_adlib(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
write_adlib(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
write_adlib(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
write_adlib(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
write_adlib(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte);
write_adlib(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
write_adlib(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
break;
case song::sb:
write_sb_left(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
write_sb_left(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
write_sb_left(SCALING_VOLUME_OFFSET+mod1_offset,
this_inst->scaling_volume1.byte);
write_sb_left(SCALING_VOLUME_OFFSET+mod2_offset,
this_inst->scaling_volume2.byte);
write_sb_left(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
write_sb_left(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
write_sb_left(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
write_sb_left(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte);
write_sb_left(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
write_sb_left(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
break;
default: // SB Pro 1 or 2.
if (channel > 8) {
write_sb_right(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
write_sb_right(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
write_sb_right(SCALING_VOLUME_OFFSET+mod1_offset,
this_inst->scaling_volume1.byte);
write_sb_right(SCALING_VOLUME_OFFSET+mod2_offset,
this_inst->scaling_volume2.byte);
write_sb_right(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
write_sb_right(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
write_sb_right(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
write_sb_right(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
if (song_obj.soundsystem == song::sbpro2) {
if (channel > song_obj.highest_stereo_left)
write_sb_right(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte | STEREO_RIGHT_MASK);
else
write_sb_right(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte | STEREO_LEFT_MASK);
}
else
write_sb_right(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte);
write_sb_right(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
write_sb_right(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
}
else {
write_sb_left(AM_VIB_OFFSET+mod1_offset, this_inst->am_vib1.byte);
write_sb_left(AM_VIB_OFFSET+mod2_offset, this_inst->am_vib2.byte);
write_sb_left(SCALING_VOLUME_OFFSET+mod1_offset,
this_inst->scaling_volume1.byte);
write_sb_left(SCALING_VOLUME_OFFSET+mod2_offset,
this_inst->scaling_volume2.byte);
write_sb_left(A_D_OFFSET+mod1_offset, this_inst->a_d1.byte);
write_sb_left(A_D_OFFSET+mod2_offset, this_inst->a_d2.byte);
write_sb_left(S_R_OFFSET+mod1_offset, this_inst->s_r1.byte);
write_sb_left(S_R_OFFSET+mod2_offset, this_inst->s_r2.byte);
if (song_obj.soundsystem == song::sbpro2) {
if (channel > song_obj.highest_stereo_left)
write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte | STEREO_RIGHT_MASK);
else
write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte | STEREO_LEFT_MASK);
}
else
write_sb_left(OP1MOD_FEEDBACK_OFFSET+channel,
this_inst->op1mod_feedback.byte);
write_sb_left(WAVE_OFFSET+mod1_offset, this_inst->wave1.byte);
write_sb_left(WAVE_OFFSET+mod2_offset, this_inst->wave2.byte);
}
break;
}
}
void music_driver::reset_card() {
int stepper;
for (stepper = 0;stepper < MAX_TRACKS;stepper++) {
last_note_freq[stepper].freq_lo = 0;
last_note_freq[stepper].oct_freq.byte = 0;
frequency_offset[stepper] = 0;
portamento_dest[stepper] = 0;
last_portamento[stepper] = 0;
vibrato_offset[stepper] = 0;
}
switch (song_obj.soundsystem) {
case song::adlib:
// Key-off all channels first to avoid channel lockup
for(stepper = 0xB0;stepper < 0xB8;stepper++)
force_write_adlib(stepper, 0);
for(stepper = 0x20;stepper < 0xF6;stepper++)
force_write_adlib(stepper, 0);
force_write_adlib(0x08, 0);
break;
case song::sb:
for(stepper = 0xB0;stepper < 0xB8;stepper++)
force_write_sb_left(stepper, 0);
for(stepper = 0x20;stepper < 0xF6;stepper++)
force_write_sb_left(stepper, 0);
force_write_sb_left(0x08, 0);
break;
default:
for(stepper = 0xB0;stepper < 0xB8;stepper++) {
force_write_sb_left(stepper, 0);
force_write_sb_right(stepper, 0);
}
for(stepper = 0x20;stepper < 0xF6;stepper++) {
force_write_sb_left(stepper, 0);
force_write_sb_right(stepper, 0);
}
write_sb_left(0x08, 0);
if (song_obj.soundsystem == song::sbpro2) {
force_write_sb_right(0x04, 0);
force_write_sb_right(0x05, 0);
}
break;
}
}
void music_driver::set_up_card() {
if (song_obj.soundsystem == song::adlib) {
force_write_adlib(0x01, 32);
force_write_adlib(0xBD, song_obj.overall_am_vib.byte);
}
else {
force_write_sb_left(0x01, 32);
force_write_sb_left(0xBD, song_obj.overall_am_vib.byte);
}
if (song_obj.soundsystem == song::sbpro2)
force_write_sb_right(0x05, 1);
}
void music_driver::play_one_note(unsigned char *note, unsigned int channel,
unsigned int just_effects) {
unsigned int freq_changed = NO;
unsigned long int curr_freq;
if ((!just_effects) && (*note & 127)) {
// New note or key-off
if((*note & 127) == 127) {
last_note_freq[channel].oct_freq.bitmap.key_on = NO;
write_frequency(channel); // <-- Handles case of key off + inst change
}
else {
if ((*note & 128) && (*(note+1) & 128)
&& check_for_portamento(note+2)) {
portamento_dest[channel] =
((note_to_freq_table[*note & 127].oct_freq.bitmap.freq_hi << 8)
+ note_to_freq_table[*note & 127].freq_lo)
<< note_to_freq_table[*note & 127].oct_freq.bitmap.octave;
}
else {
last_note_freq[channel].freq_lo =
note_to_freq_table[*note & 127].freq_lo;
last_note_freq[channel].oct_freq.byte =
note_to_freq_table[*note & 127].oct_freq.byte;
last_note_freq[channel].oct_freq.bitmap.key_on = YES;
frequency_offset[channel] = 0;
vibrato_offset[channel] = 0;
freq_changed = YES;
}
}
}
if (*note & 128) {
note++;
if ((!just_effects) && (*note & 127)) {
/* Instrument change. IMPORTANT: We cannot change the instrument while the
channel is keyed on. Doing so will cause the channel to lock up. */
if (last_note_freq[channel].oct_freq.bitmap.key_on) {
last_note_freq[channel].oct_freq.bitmap.key_on = NO;
write_frequency(channel);
last_note_freq[channel].oct_freq.bitmap.key_on = YES;
freq_changed = YES;
}
load_instrument(*note & 127, channel);
}
if (*note & 128) {
int more_commands = YES;
note++;
// Do commands
while (more_commands) {
more_commands = (*note & 128);
switch (*(note++) & 127) {
case 0x0:
break;
case 0x1:
frequency_offset[channel] += *note;
freq_changed = YES;
break;
case 0x2:
frequency_offset[channel] -= *note;
freq_changed = YES;
break;
case 0x3:
// Portamento burns cpu cycles.
if (*note)
last_portamento[channel] = *note;
curr_freq = (((last_note_freq[channel].oct_freq.bitmap.freq_hi
<< 8) + last_note_freq[channel].freq_lo)
<< last_note_freq[channel].oct_freq.bitmap.octave)
+ frequency_offset[channel];
if (curr_freq < portamento_dest[channel]) {
if (curr_freq + last_portamento[channel]
> portamento_dest[channel])
frequency_offset[channel] += portamento_dest[channel]
- curr_freq;
else
frequency_offset[channel] += last_portamento[channel];
}
else {
if (curr_freq - last_portamento[channel]
< portamento_dest[channel])
frequency_offset[channel] += portamento_dest[channel]
- curr_freq;
else
frequency_offset[channel] -= last_portamento[channel];
}
freq_changed = YES;
break;
case 0x4:
if (vibrato_direction[channel]) {
vibrato_offset[channel] += *note >> 4;
if (vibrato_offset[channel] >= ((*note & 15) << 2))
vibrato_direction[channel] = 0;
}
else {
vibrato_offset[channel] -= *note >> 4;
if (vibrato_offset[channel] <= -((*note & 15) << 2))
vibrato_direction[channel] = 1;
}
freq_changed = YES;
break;
case 0xD:
if (*note & 240)
shift_volume(channel, (*note & 240) >> 4);
else
shift_volume(channel, -(*note & 15));
break;
default:
// These commands only need to be done when the note is first played.
if (!just_effects)
switch (*(note-1) & 127) {
case 0x9:
song_obj.secondary_tempo = *note;
break;
case 0xC:
if (*note > 63)
set_volume(channel, 0);
else
set_volume(channel, 63 - *note);
break;
case 0xB:
jump_indicator = *note;
break;
case 0xF:
if (*note) {
if (*note == 0xFF)
stop_playing();
else
song_obj.tempo = *note;
}
else {
if (song_obj.current_pattern == song_obj.highest_pattern)
jump_indicator = 0;
else
jump_indicator = song_obj.current_pattern + 1;
}
break;
}
break;
}
note++;
}
}
}
if (freq_changed)
write_frequency(channel);
}
void music_driver::write_frequency(unsigned int channel) {
int workvar;
oct_freq_union writer;
int workoct;
if (frequency_offset[channel] || vibrato_offset[channel]) {
// Some sort of effect (e.g. slide) has altered the frequency.
writer.byte = last_note_freq[channel].oct_freq.byte;
workoct = writer.bitmap.octave;
workvar = (writer.bitmap.freq_hi << 8) +
last_note_freq[channel].freq_lo
+ (frequency_offset[channel] >> workoct) + vibrato_offset[channel];
// Technically, vibrato_offset should be right-shifted by workoct.
if (workvar < 1) {
workvar = note_freqs[0];
workoct = 0;
}
while ((unsigned int) workvar < note_freqs[0]) {
workvar = workvar << 1;
workoct--;
}
while ((unsigned int) workvar > note_freqs[12]) {
workvar = workvar >> 1;
workoct++;
}
if (workoct < 0) {
workoct = 0;
workvar = note_freqs[0];
}
else
if (workoct > 7) {
workoct = 7;
workvar = note_freqs[12];
}
writer.bitmap.octave = workoct;
writer.bitmap.freq_hi = workvar >> 8;
switch (song_obj.soundsystem) {
case song::adlib:
write_adlib(FREQ_LO_OFFSET+channel, (unsigned char) workvar);
write_adlib(OCT_FREQ_OFFSET+channel, writer.byte);
break;
case song::sb:
write_sb_left(FREQ_LO_OFFSET+channel, (unsigned char) workvar);
write_sb_left(OCT_FREQ_OFFSET+channel, writer.byte);
break;
case song::sbpro1:
case song::sbpro2:
if (channel > 8) {
write_sb_right(FREQ_LO_OFFSET+channel-9, (unsigned char) workvar);
write_sb_right(OCT_FREQ_OFFSET+channel-9, writer.byte);
}
else {
write_sb_left(FREQ_LO_OFFSET+channel, (unsigned char) workvar);
write_sb_left(OCT_FREQ_OFFSET+channel, writer.byte);
}
break;
}
}
else
// The frequency has not been altered.
switch (song_obj.soundsystem) {
case song::adlib:
write_adlib(FREQ_LO_OFFSET+channel, last_note_freq[channel].freq_lo);
write_adlib(OCT_FREQ_OFFSET+channel,
last_note_freq[channel].oct_freq.byte);
break;
case song::sb:
write_sb_left(FREQ_LO_OFFSET+channel, last_note_freq[channel].freq_lo);
write_sb_left(OCT_FREQ_OFFSET+channel,
last_note_freq[channel].oct_freq.byte);
break;
case song::sbpro1:
case song::sbpro2:
if (channel > 8) {
write_sb_right(FREQ_LO_OFFSET+channel-9,
last_note_freq[channel].freq_lo);
write_sb_right(OCT_FREQ_OFFSET+channel-9,
last_note_freq[channel].oct_freq.byte);
}
else {
write_sb_left(FREQ_LO_OFFSET+channel,
last_note_freq[channel].freq_lo);
write_sb_left(OCT_FREQ_OFFSET+channel,
last_note_freq[channel].oct_freq.byte);
}
break;
}
}
void music_driver::set_volume(unsigned int channel,
unsigned int new_volume) {
scaling_volume_union workvar;
// We only change the volume of operator 2.
switch (song_obj.soundsystem) {
case song::adlib:
workvar.byte =
shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
workvar.bitmap.volume = new_volume;
write_adlib(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
workvar.byte);
break;
case song::sb:
workvar.byte =
shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
workvar.bitmap.volume = new_volume;
write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
workvar.byte);
break;
case song::sbpro1:
case song::sbpro2:
if (channel > 8) {
workvar.byte =
shadow_regs_right[SCALING_VOLUME_OFFSET+channel_offset[channel-9+9]];
workvar.bitmap.volume = new_volume;
write_sb_right(SCALING_VOLUME_OFFSET+channel_offset[channel-9+9],
workvar.byte);
}
else {
workvar.byte =
shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
workvar.bitmap.volume = new_volume;
write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
workvar.byte);
}
break;
}
}
void music_driver::shift_volume(unsigned int channel, int volume_shift) {
scaling_volume_union workvar;
int worknum;
// We only change the volume of operator 2.
if ((song_obj.soundsystem == song::adlib)
|| (song_obj.soundsystem == song::sb))
workvar.byte =
shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
else {
if (channel > 8)
workvar.byte =
shadow_regs_right[SCALING_VOLUME_OFFSET+channel_offset[channel-9+9]];
else
workvar.byte =
shadow_regs_left[SCALING_VOLUME_OFFSET+channel_offset[channel+9]];
}
worknum = workvar.bitmap.volume - volume_shift;
if (worknum < 0)
worknum = 0;
else
if (worknum > 63)
worknum = 63;
workvar.bitmap.volume = worknum;
switch (song_obj.soundsystem) {
case song::adlib:
write_adlib(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
workvar.byte);
break;
case song::sb:
write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
workvar.byte);
break;
case song::sbpro1:
case song::sbpro2:
if (channel > 8)
write_sb_right(SCALING_VOLUME_OFFSET+channel_offset[channel-9+9],
workvar.byte);
else
write_sb_left(SCALING_VOLUME_OFFSET+channel_offset[channel+9],
workvar.byte);
break;
}
}
void music_driver::play_one_line(unsigned int just_effects) {
unsigned int stepper;
unsigned int farthest_right;
int offset;
switch (song_obj.soundsystem) {
case song::adlib:
case song::sb:
if (song_obj.highest_track > 8)
farthest_right = 8;
else
farthest_right = song_obj.highest_track;
for(stepper = 0;stepper <= farthest_right;stepper++)
if (song_obj.current_note[stepper]) // Don't play an "empty" track.
#ifdef EDITOR_HOOKS
if (track_active[stepper])
#endif
play_one_note(song_obj.current_note[stepper], stepper,
just_effects);
break;
case song::sbpro1:
if (song_obj.highest_stereo_left > 8)
farthest_right = 8;
else
farthest_right = song_obj.highest_stereo_left;
if (farthest_right > song_obj.highest_track)
farthest_right = song_obj.highest_track;
for(stepper = 0;stepper <= farthest_right;stepper++)
if (song_obj.current_note[stepper]) // Don't play an "empty" track.
#ifdef EDITOR_HOOKS
if (track_active[stepper])
#endif
play_one_note(song_obj.current_note[stepper], stepper,
just_effects);
if (song_obj.highest_track > song_obj.highest_stereo_left) {
if (song_obj.highest_track > song_obj.highest_stereo_left + 9)
farthest_right = song_obj.highest_stereo_left + 9;
else
farthest_right = song_obj.highest_track;
offset = 8 - song_obj.highest_stereo_left;
for(stepper = song_obj.highest_stereo_left + 1;
stepper <= farthest_right;stepper++)
if (song_obj.current_note[stepper]) // Don't play an "empty" track.
#ifdef EDITOR_HOOKS
if (track_active[stepper])
#endif
play_one_note(song_obj.current_note[stepper], stepper + offset,
just_effects);
}
break;
case song::sbpro2:
for(stepper = 0;stepper <= song_obj.highest_track;stepper++)
if (song_obj.current_note[stepper]) // Don't play an "empty" track.
#ifdef EDITOR_HOOKS
if (track_active[stepper])
#endif
play_one_note(song_obj.current_note[stepper], stepper,
just_effects);
break;
}
}
void music_driver::update() {
/* Master update routine. Plays notes and advances lines and patterns. Needs
to be called as often as required by the current tempo (normally this is
done by an interrupt routine). */
#ifdef EDITOR_HOOKS
#ifdef TARGET_MSDOS
if (show_interrupt) {
outp(VIDEO_PALETTE_MASK, 0xFF);
outp(VIDEO_PALETTE_WRITE, 0);
outp(VIDEO_PALETTE_DATA, 63);
outp(VIDEO_PALETTE_DATA, 0);
outp(VIDEO_PALETTE_DATA, 0);
}
#endif
#endif
if (should_song_play) {
#ifdef EDITOR_HOOKS
if (!forbid_count) {
#endif
if (accumulated_ticks > song_obj.secondary_tempo) {
if (jump_indicator == -1)
song_obj.advance_line();
else
#ifdef EDITOR_HOOKS
if (play_block_mode)
song_obj.block_jump(song_obj.current_block);
else
#endif
song_obj.position_jump(jump_indicator);
reset_accumulated_ticks();
}
if (accumulated_ticks > 1)
play_one_line(YES);
else
play_one_line(NO);
accumulated_ticks++;
#ifdef EDITOR_HOOKS
}
#endif
}
#ifdef EDITOR_HOOKS
#ifdef TARGET_MSDOS
if (show_interrupt) {
outp(VIDEO_PALETTE_MASK, 0xFF);
outp(VIDEO_PALETTE_WRITE, 0);
outp(VIDEO_PALETTE_DATA, 0);
outp(VIDEO_PALETTE_DATA, 0);
outp(VIDEO_PALETTE_DATA, 0);
}
#endif
#endif
}
int music_driver::wedge_player() {
if (old_interrupt)
return 0;
else {
set_timer(compute_timer_setting(song_obj.tempo));
#ifdef TARGET_MSDOS
old_interrupt = getvect(TIMER_INTERRUPT_VECTOR);
setvect(TIMER_INTERRUPT_VECTOR, timer_int);
#endif
return 1;
}
}
int music_driver::remove_player() {
if (old_interrupt) {
#ifdef TARGET_MSDOS
setvect(TIMER_INTERRUPT_VECTOR, old_interrupt);
#endif
old_interrupt = 0;
return 1;
}
else
return 0;
}
#ifdef TARGET_MSDOS
void interrupt music_driver::timer_int(...) {
#else
void music_driver::timer_int() {
#endif
// Called once every timer interrupt to call update().
static unsigned int old_tempo;
music.update();
if (old_tempo != song_obj.tempo) {
music.set_timer(music.compute_timer_setting(song_obj.tempo));
old_tempo = song_obj.tempo;
}
music.old_interrupt();
}
#ifdef EDITOR_HOOKS
void music_driver::update_am_vib() {
if (song_obj.soundsystem == song::adlib)
write_adlib(0xBD, song_obj.overall_am_vib.byte);
else
write_sb_left(0xBD, song_obj.overall_am_vib.byte);
}
#endif