home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Bila Vrana
/
BILA_VRANA.iso
/
031A
/
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;