home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Zodiac Super OZ
/
MEDIADEPOT.ISO
/
FILES
/
15
/
GMS100.ZIP
/
gms100
/
source
/
musdrv.h
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-15
|
5KB
|
148 lines
// Music driver class contains the actual song playing code
#define TIMER_INTERRUPT_VECTOR 0x1C
#define TIMER_CONTROL_PORT 0x43
#define TIMER_COUNTER_PORT 0x40
#define AM_VIB_OFFSET 0x20
#define SCALING_VOLUME_OFFSET 0x40
#define A_D_OFFSET 0x60
#define S_R_OFFSET 0x80
#define OP1MOD_FEEDBACK_OFFSET 0xC0
#define WAVE_OFFSET 0xE0
#define FREQ_LO_OFFSET 0xA0
#define OCT_FREQ_OFFSET 0xB0
#define STEREO_LEFT_MASK 0x10
#define STEREO_RIGHT_MASK 0x20
union oct_freq_union {
unsigned char byte;
struct {
unsigned freq_hi: 2;
unsigned octave: 3;
unsigned key_on: 1;
} bitmap;
};
struct freq_lo_hi {
unsigned char freq_lo;
oct_freq_union oct_freq;
};
class music_driver {
public:
// Copy of the sb card's current register settings
unsigned char shadow_regs[256];
unsigned char shadow_regs_left[256];
unsigned char shadow_regs_right[256];
static const unsigned char channel_offset[9+9];
static const unsigned int note_freqs[13];
freq_lo_hi note_to_freq_table[127];
freq_lo_hi last_note_freq[MAX_TRACKS];
long int frequency_offset[MAX_TRACKS];
unsigned int accumulated_ticks;
unsigned long int portamento_dest[MAX_TRACKS];
unsigned int last_portamento[MAX_TRACKS];
unsigned int vibrato_direction[MAX_TRACKS];
int vibrato_offset[MAX_TRACKS];
#ifdef TARGET_MSDOS
void interrupt (*old_interrupt)(...);
#else
void (*old_interrupt)(...);
#endif
unsigned int should_song_play;
int jump_indicator;
unsigned int forbid_count;
#ifdef EDITOR_HOOKS
unsigned int play_block_mode;
unsigned int track_active[MAX_TRACKS];
unsigned int show_interrupt;
#endif
unsigned int sb_base_address;
music_driver();
void write_adlib(unsigned char reg, unsigned char value);
void write_sb_left(unsigned char reg, unsigned char value);
void write_sb_right(unsigned char reg, unsigned char value);
void force_write_adlib(unsigned char reg, unsigned char value)
{shadow_regs_left[reg] = value + 1;write_adlib(reg, value);}
void force_write_sb_left(unsigned char reg, unsigned char value)
{shadow_regs_left[reg] = value + 1;write_sb_left(reg, value);}
void force_write_sb_right(unsigned char reg, unsigned char value)
{shadow_regs_right[reg] = value + 1;write_sb_right(reg, value);}
/* The force_write_<card> routines will force a write even if the register
already contains the value. */
void load_instrument(unsigned int inst_number, unsigned int channel);
void reset_card();
void set_up_card();
void play_one_note(unsigned char *note, unsigned int channel,
unsigned int just_effects);
unsigned int check_for_portamento(unsigned char *note);
void write_frequency(unsigned int channel);
void set_volume(unsigned int channel, unsigned int new_volume);
void shift_volume(unsigned int channel, int volume_shift);
void play_one_line(unsigned int just_effects);
void update();
void reset_accumulated_ticks() {accumulated_ticks = 1;jump_indicator = -1;}
unsigned int compute_timer_setting(unsigned int tempo);
#ifdef TARGET_MSDOS
static void interrupt timer_int(...);
#else
static void timer_int();
#endif
int wedge_player();
int remove_player();
void set_timer(unsigned int new_setting);
void start_playing() {should_song_play = YES;}
void stop_playing() {should_song_play = NO;}
unsigned int is_song_playing() {return should_song_play;}
void forbid_playing() {forbid_count++;}
void permit_playing() {forbid_count--;}
#ifdef EDITOR_HOOKS
void update_am_vib();
#endif
};
inline unsigned int music_driver::check_for_portamento(unsigned char *note) {
do {
if ((*note & 127) == 0x3)
return YES;
else
note += 2;
}
while (*(note - 2) & 128);
return NO;
}
inline unsigned int music_driver::compute_timer_setting(unsigned int tempo) {
return 0x2D8426 / (tempo + 45);
}
inline void music_driver::set_timer(unsigned int new_setting) {
#ifdef TARGET_MSDOS
outp(TIMER_CONTROL_PORT, 0x3C);
outp(TIMER_COUNTER_PORT, new_setting);
outp(TIMER_COUNTER_PORT, new_setting >> 8);
#endif
#ifdef TARGET_LINUX
new_setting = new_setting; // Eliminate spurious warning
#endif
}
#ifdef COMPILING_MUSDRV
const unsigned char music_driver::channel_offset[9+9] =
{0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12,
0x03, 0x04, 0x05, 0x0b, 0x0c, 0x0d, 0x13, 0x14, 0x15};
// Lookup table for the sb card's weird register configuration
const unsigned int music_driver::note_freqs[13] =
{0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202,
0x220, 0x241, 0x263, 0x287, 0x2AE};
// Frequencies of notes, from C (octave x) to C (octave x+1)
#endif
#ifdef COMPILING_MUSDRV
music_driver music;
#else
extern music_driver music;
#endif