Updated Game_Music_Emu to latest VGMPlay branch
This commit is contained in:
parent
9020667054
commit
09e546591a
342 changed files with 90075 additions and 39784 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,77 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "C140_Emu.h"
|
||||
#include "c140.h"
|
||||
|
||||
C140_Emu::C140_Emu() { chip = 0; }
|
||||
|
||||
C140_Emu::~C140_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_c140( chip );
|
||||
}
|
||||
|
||||
int C140_Emu::set_rate( int type, double sample_rate, double clock_rate )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_c140( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_c140( sample_rate, clock_rate, type );
|
||||
if ( !chip )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void C140_Emu::reset()
|
||||
{
|
||||
device_reset_c140( chip );
|
||||
c140_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void C140_Emu::write( int addr, int data )
|
||||
{
|
||||
c140_w( chip, addr, data );
|
||||
}
|
||||
|
||||
void C140_Emu::write_rom( int size, int start, int length, void * data )
|
||||
{
|
||||
c140_write_rom( chip, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void C140_Emu::mute_voices( int mask )
|
||||
{
|
||||
c140_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void C140_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
c140_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// C140 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef C140_EMU_H
|
||||
#define C140_EMU_H
|
||||
|
||||
class C140_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
C140_Emu();
|
||||
~C140_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int type, double sample_rate, double clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 24 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,147 +0,0 @@
|
|||
// Fir_Resampler chip emulator container that mixes into the output buffer
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef CHIP_RESAMPLER_H
|
||||
#define CHIP_RESAMPLER_H
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#include "Fir_Resampler.h"
|
||||
typedef Fir_Resampler_Norm Chip_Resampler_Downsampler;
|
||||
|
||||
int const resampler_extra = 0; //34;
|
||||
|
||||
template<class Emu>
|
||||
class Chip_Resampler_Emu : public Emu {
|
||||
int last_time;
|
||||
short* out;
|
||||
typedef short dsample_t;
|
||||
enum { disabled_time = -1 };
|
||||
enum { gain_bits = 14 };
|
||||
blargg_vector<dsample_t> sample_buf;
|
||||
int sample_buf_size;
|
||||
int oversamples_per_frame;
|
||||
int buf_pos;
|
||||
int buffered;
|
||||
int resampler_size;
|
||||
int gain_;
|
||||
|
||||
Chip_Resampler_Downsampler resampler;
|
||||
|
||||
void mix_samples( short * buf, int count )
|
||||
{
|
||||
dsample_t * inptr = sample_buf.begin();
|
||||
for ( unsigned i = 0; i < count * 2; i++ )
|
||||
{
|
||||
int sample = inptr[i];
|
||||
sample += buf[i];
|
||||
if ((short)sample != sample) sample = 0x7FFF ^ (sample >> 31);
|
||||
buf[i] = sample;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
Chip_Resampler_Emu() { last_time = disabled_time; out = NULL; }
|
||||
blargg_err_t setup( double oversample, double rolloff, double gain )
|
||||
{
|
||||
gain_ = (int) ((1 << gain_bits) * gain);
|
||||
RETURN_ERR( resampler.set_rate( oversample ) );
|
||||
return reset_resampler();
|
||||
}
|
||||
|
||||
blargg_err_t reset()
|
||||
{
|
||||
Emu::reset();
|
||||
resampler.clear();
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t reset_resampler()
|
||||
{
|
||||
unsigned int pairs;
|
||||
double rate = resampler.rate();
|
||||
if ( rate >= 1.0 ) pairs = 64.0 * rate;
|
||||
else pairs = 64.0 / rate;
|
||||
RETURN_ERR( sample_buf.resize( (pairs + (pairs >> 2)) * 2 ) );
|
||||
resize( pairs );
|
||||
resampler_size = oversamples_per_frame + (oversamples_per_frame >> 2);
|
||||
RETURN_ERR( resampler.resize_buffer( resampler_size ) );
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
void resize( int pairs )
|
||||
{
|
||||
int new_sample_buf_size = pairs * 2;
|
||||
//new_sample_buf_size = new_sample_buf_size / 4 * 4; // TODO: needed only for 3:2 downsampler
|
||||
if ( sample_buf_size != new_sample_buf_size )
|
||||
{
|
||||
if ( (unsigned) new_sample_buf_size > sample_buf.size() )
|
||||
{
|
||||
check( false );
|
||||
return;
|
||||
}
|
||||
sample_buf_size = new_sample_buf_size;
|
||||
oversamples_per_frame = int (pairs * resampler.rate()) * 2 + 2;
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
buf_pos = buffered = 0;
|
||||
resampler.clear();
|
||||
}
|
||||
|
||||
void enable( bool b = true ) { last_time = b ? 0 : disabled_time; }
|
||||
bool enabled() const { return last_time != disabled_time; }
|
||||
void begin_frame( short* buf ) { out = buf; last_time = 0; }
|
||||
|
||||
int run_until( int time )
|
||||
{
|
||||
int count = time - last_time;
|
||||
while ( count > 0 )
|
||||
{
|
||||
if ( last_time < 0 )
|
||||
return false;
|
||||
last_time = time;
|
||||
if ( buffered )
|
||||
{
|
||||
int samples_to_copy = buffered;
|
||||
if ( samples_to_copy > count ) samples_to_copy = count;
|
||||
memcpy( out, sample_buf.begin(), samples_to_copy * sizeof(short) * 2 );
|
||||
memcpy( sample_buf.begin(), sample_buf.begin() + samples_to_copy * 2, ( buffered - samples_to_copy ) * 2 * sizeof(short) );
|
||||
buffered -= samples_to_copy;
|
||||
count -= samples_to_copy;
|
||||
continue;
|
||||
}
|
||||
int sample_count = oversamples_per_frame - resampler.written() + resampler_extra;
|
||||
memset( resampler.buffer(), 0, sample_count * sizeof(*resampler.buffer()) );
|
||||
Emu::run( sample_count >> 1, resampler.buffer() );
|
||||
for ( unsigned i = 0; i < sample_count; i++ )
|
||||
{
|
||||
dsample_t * ptr = resampler.buffer() + i;
|
||||
*ptr = ( *ptr * gain_ ) >> gain_bits;
|
||||
}
|
||||
short* p = out;
|
||||
resampler.write( sample_count );
|
||||
sample_count = resampler.read( sample_buf.begin(), count * 2 > sample_buf_size ? sample_buf_size : count * 2 ) >> 1;
|
||||
if ( sample_count > count )
|
||||
{
|
||||
out += count * Emu::out_chan_count;
|
||||
mix_samples( p, count );
|
||||
memmove( sample_buf.begin(), sample_buf.begin() + count * 2, (sample_count - count) * 2 * sizeof(short) );
|
||||
buffered = sample_count - count;
|
||||
return true;
|
||||
}
|
||||
else if (!sample_count) return true;
|
||||
out += sample_count * Emu::out_chan_count;
|
||||
mix_samples( p, sample_count );
|
||||
count -= sample_count;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "K051649_Emu.h"
|
||||
#include "k051649.h"
|
||||
|
||||
K051649_Emu::K051649_Emu() { SCC = 0; }
|
||||
|
||||
K051649_Emu::~K051649_Emu()
|
||||
{
|
||||
if ( SCC ) device_stop_k051649( SCC );
|
||||
}
|
||||
|
||||
int K051649_Emu::set_rate( int clock_rate )
|
||||
{
|
||||
if ( SCC )
|
||||
{
|
||||
device_stop_k051649( SCC );
|
||||
SCC = 0;
|
||||
}
|
||||
|
||||
SCC = device_start_k051649( clock_rate );
|
||||
if ( !SCC )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void K051649_Emu::reset()
|
||||
{
|
||||
device_reset_k051649( SCC );
|
||||
k051649_set_mute_mask( SCC, 0 );
|
||||
}
|
||||
|
||||
void K051649_Emu::write( int port, int offset, int data )
|
||||
{
|
||||
k051649_w( SCC, (port << 1) | 0x00, offset);
|
||||
k051649_w( SCC, (port << 1) | 0x01, data);
|
||||
}
|
||||
|
||||
void K051649_Emu::mute_voices( int mask )
|
||||
{
|
||||
k051649_set_mute_mask( SCC, mask );
|
||||
}
|
||||
|
||||
void K051649_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
k051649_update( SCC, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
// K051649 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef K051649_EMU_H
|
||||
#define K051649_EMU_H
|
||||
|
||||
class K051649_Emu {
|
||||
void* SCC;
|
||||
public:
|
||||
K051649_Emu();
|
||||
~K051649_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 5 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int port, int offset, int data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,77 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "K053260_Emu.h"
|
||||
#include "k053260.h"
|
||||
|
||||
K053260_Emu::K053260_Emu() { chip = 0; }
|
||||
|
||||
K053260_Emu::~K053260_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_k053260( chip );
|
||||
}
|
||||
|
||||
int K053260_Emu::set_rate( int clock_rate )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_k053260( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_k053260( clock_rate );
|
||||
if ( !chip )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void K053260_Emu::reset()
|
||||
{
|
||||
device_reset_k053260( chip );
|
||||
k053260_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void K053260_Emu::write( int addr, int data )
|
||||
{
|
||||
k053260_w( chip, addr, data);
|
||||
}
|
||||
|
||||
void K053260_Emu::write_rom( int size, int start, int length, void * data )
|
||||
{
|
||||
k053260_write_rom( chip, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void K053260_Emu::mute_voices( int mask )
|
||||
{
|
||||
k053260_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void K053260_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
k053260_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// K053260 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef K053260_EMU_H
|
||||
#define K053260_EMU_H
|
||||
|
||||
class K053260_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
K053260_Emu();
|
||||
~K053260_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 5 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,79 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "K054539_Emu.h"
|
||||
#include "k054539.h"
|
||||
|
||||
K054539_Emu::K054539_Emu() { chip = 0; }
|
||||
|
||||
K054539_Emu::~K054539_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_k054539( chip );
|
||||
}
|
||||
|
||||
int K054539_Emu::set_rate( int clock_rate, int flags )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_k054539( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_k054539( clock_rate );
|
||||
if ( !chip )
|
||||
return 1;
|
||||
|
||||
k054539_init_flags( chip, flags );
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void K054539_Emu::reset()
|
||||
{
|
||||
device_reset_k054539( chip );
|
||||
k054539_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void K054539_Emu::write( int addr, int data )
|
||||
{
|
||||
k054539_w( chip, addr, data);
|
||||
}
|
||||
|
||||
void K054539_Emu::write_rom( int size, int start, int length, void * data )
|
||||
{
|
||||
k054539_write_rom( chip, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void K054539_Emu::mute_voices( int mask )
|
||||
{
|
||||
k054539_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void K054539_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
k054539_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// K054539 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef K054539_EMU_H
|
||||
#define K054539_EMU_H
|
||||
|
||||
class K054539_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
K054539_Emu();
|
||||
~K054539_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock_rate, int flags );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 5 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -220,7 +220,7 @@ void Music_Emu::set_fade( int start_msec, int length_msec )
|
|||
fade_set = true;
|
||||
this->length_msec = start_msec;
|
||||
this->fade_msec = length_msec;
|
||||
track_filter.set_fade( msec_to_samples( start_msec ),
|
||||
track_filter.set_fade( start_msec < 0 ? Track_Filter::indefinite_count : msec_to_samples( start_msec ),
|
||||
length_msec * sample_rate() / (1000 / stereo) );
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,18 @@
|
|||
#include "Nes_Vrc7_Apu.h"
|
||||
|
||||
#include "ym2413.h"
|
||||
extern "C" {
|
||||
#include "../vgmplay/chips/emu2413.h"
|
||||
}
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "blargg_source.h"
|
||||
|
||||
static unsigned char vrc7_inst[(16 + 3) * 8] =
|
||||
{
|
||||
#include "../vgmplay/chips/vrc7tone.h"
|
||||
};
|
||||
|
||||
int const period = 36; // NES CPU clocks per FM clock
|
||||
|
||||
Nes_Vrc7_Apu::Nes_Vrc7_Apu()
|
||||
|
@ -14,7 +22,9 @@ Nes_Vrc7_Apu::Nes_Vrc7_Apu()
|
|||
|
||||
blargg_err_t Nes_Vrc7_Apu::init()
|
||||
{
|
||||
CHECK_ALLOC( opll = ym2413_init( 3579545, 3579545 / 72, 1 ) );
|
||||
CHECK_ALLOC( opll = OPLL_new( 3579545, 3579545 / 72 ) );
|
||||
OPLL_SetChipMode((OPLL *) opll, 1);
|
||||
OPLL_setPatch((OPLL *) opll, vrc7_inst);
|
||||
|
||||
set_output( 0 );
|
||||
volume( 1.0 );
|
||||
|
@ -25,7 +35,7 @@ blargg_err_t Nes_Vrc7_Apu::init()
|
|||
Nes_Vrc7_Apu::~Nes_Vrc7_Apu()
|
||||
{
|
||||
if ( opll )
|
||||
ym2413_shutdown( opll );
|
||||
OPLL_delete( (OPLL *) opll );
|
||||
}
|
||||
|
||||
void Nes_Vrc7_Apu::set_output( Blip_Buffer* buf )
|
||||
|
@ -71,7 +81,7 @@ void Nes_Vrc7_Apu::reset()
|
|||
osc.regs [j] = 0;
|
||||
}
|
||||
|
||||
ym2413_reset_chip( opll );
|
||||
OPLL_reset( (OPLL *) opll );
|
||||
}
|
||||
|
||||
void Nes_Vrc7_Apu::write_reg( int data )
|
||||
|
@ -85,11 +95,13 @@ void Nes_Vrc7_Apu::write_data( blip_time_t time, int data )
|
|||
int chan = addr & 15;
|
||||
if ( (unsigned) type < 3 && chan < osc_count )
|
||||
oscs [chan].regs [type] = data;
|
||||
if ( addr < 0x08 )
|
||||
inst [addr] = data;
|
||||
|
||||
if ( time > next_time )
|
||||
run_until( time );
|
||||
ym2413_write( opll, 0, addr );
|
||||
ym2413_write( opll, 1, data );
|
||||
OPLL_writeIO( (OPLL *) opll, 0, addr );
|
||||
OPLL_writeIO( (OPLL *) opll, 1, data );
|
||||
}
|
||||
|
||||
void Nes_Vrc7_Apu::end_frame( blip_time_t time )
|
||||
|
@ -117,7 +129,7 @@ void Nes_Vrc7_Apu::save_snapshot( vrc7_snapshot_t* out ) const
|
|||
for ( int j = 0; j < 3; ++j )
|
||||
out->regs [i] [j] = oscs [i].regs [j];
|
||||
}
|
||||
memcpy( out->inst, ym2413_get_inst0( opll ), 8 );
|
||||
memcpy( out->inst, inst, 8 );
|
||||
}
|
||||
|
||||
void Nes_Vrc7_Apu::load_snapshot( vrc7_snapshot_t const& in )
|
||||
|
@ -134,18 +146,19 @@ void Nes_Vrc7_Apu::load_snapshot( vrc7_snapshot_t const& in )
|
|||
oscs [i].regs [j] = in.regs [i] [j];
|
||||
}
|
||||
|
||||
memcpy( inst, in.inst, 8 );
|
||||
for ( i = 0; i < 8; ++i )
|
||||
{
|
||||
ym2413_write( opll, 0, i );
|
||||
ym2413_write( opll, 1, in.inst [i] );
|
||||
OPLL_writeIO( (OPLL *) opll, 0, i );
|
||||
OPLL_writeIO( (OPLL *) opll, 1, in.inst [i] );
|
||||
}
|
||||
|
||||
for ( i = 0; i < 3; ++i )
|
||||
{
|
||||
for ( int j = 0; j < 6; ++j )
|
||||
{
|
||||
ym2413_write( opll, 0, 0x10 + i * 0x10 + j );
|
||||
ym2413_write( opll, 1, oscs [j].regs [i] );
|
||||
OPLL_writeIO( (OPLL *) opll, 0, 0x10 + i * 0x10 + j );
|
||||
OPLL_writeIO( (OPLL *) opll, 1, oscs [j].regs [i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,16 +170,15 @@ void Nes_Vrc7_Apu::run_until( blip_time_t end_time )
|
|||
blip_time_t time = next_time;
|
||||
void* opll = this->opll; // cache
|
||||
Blip_Buffer* const mono_output = mono.output;
|
||||
e_int32 buffer [2];
|
||||
e_int32* buffers[2] = {&buffer[0], &buffer[1]};
|
||||
if ( mono_output )
|
||||
{
|
||||
// optimal case
|
||||
do
|
||||
{
|
||||
ym2413_advance_lfo( opll );
|
||||
int amp = 0;
|
||||
for ( int i = 0; i < osc_count; i++ )
|
||||
amp += ym2413_calcch( opll, i );
|
||||
ym2413_advance( opll );
|
||||
OPLL_calc_stereo( (OPLL *) opll, buffers, 1, -1 );
|
||||
int amp = buffer [0] + buffer [1];
|
||||
int delta = amp - mono.last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
|
@ -182,13 +194,14 @@ void Nes_Vrc7_Apu::run_until( blip_time_t end_time )
|
|||
mono.last_amp = 0;
|
||||
do
|
||||
{
|
||||
ym2413_advance_lfo( opll );
|
||||
OPLL_advance( (OPLL *) opll );
|
||||
for ( int i = 0; i < osc_count; ++i )
|
||||
{
|
||||
Vrc7_Osc& osc = oscs [i];
|
||||
if ( osc.output )
|
||||
{
|
||||
int amp = ym2413_calcch( opll, i );
|
||||
OPLL_calc_stereo( (OPLL *) opll, buffers, 1, i );
|
||||
int amp = buffer [0] + buffer [1];
|
||||
int delta = amp - osc.last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
|
@ -197,7 +210,6 @@ void Nes_Vrc7_Apu::run_until( blip_time_t end_time )
|
|||
}
|
||||
}
|
||||
}
|
||||
ym2413_advance( opll );
|
||||
time += period;
|
||||
}
|
||||
while ( time < end_time );
|
||||
|
|
|
@ -43,6 +43,8 @@ private:
|
|||
};
|
||||
|
||||
Vrc7_Osc oscs [osc_count];
|
||||
BOOST::uint8_t kon;
|
||||
BOOST::uint8_t inst [8];
|
||||
void* opll;
|
||||
int addr;
|
||||
blip_time_t next_time;
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Okim6258_Emu.h"
|
||||
#include "okim6258.h"
|
||||
|
||||
Okim6258_Emu::Okim6258_Emu() { chip = 0; }
|
||||
|
||||
Okim6258_Emu::~Okim6258_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_okim6258( chip );
|
||||
}
|
||||
|
||||
int Okim6258_Emu::set_rate( int clock, int divider, int adpcm_type, int output_12bits )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_okim6258( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_okim6258( clock, divider, adpcm_type, output_12bits );
|
||||
if ( !chip )
|
||||
return 0;
|
||||
|
||||
reset();
|
||||
return okim6258_get_vclk( chip );
|
||||
}
|
||||
|
||||
void Okim6258_Emu::reset()
|
||||
{
|
||||
device_reset_okim6258( chip );
|
||||
}
|
||||
|
||||
void Okim6258_Emu::write( int addr, int data )
|
||||
{
|
||||
okim6258_write( chip, addr, data );
|
||||
}
|
||||
|
||||
int Okim6258_Emu::get_clock()
|
||||
{
|
||||
return okim6258_get_vclk( chip );
|
||||
}
|
||||
|
||||
void Okim6258_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
okim6258_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
// OKIM6258 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef OKIM6258_EMU_H
|
||||
#define OKIM6258_EMU_H
|
||||
|
||||
class Okim6258_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
Okim6258_Emu();
|
||||
~Okim6258_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock, int divider, int adpcm_type, int output_12bits );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Returns current sample rate of the chip
|
||||
int get_clock();
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,77 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Okim6295_Emu.h"
|
||||
#include "okim6295.h"
|
||||
|
||||
Okim6295_Emu::Okim6295_Emu() { chip = 0; }
|
||||
|
||||
Okim6295_Emu::~Okim6295_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_okim6295( chip );
|
||||
}
|
||||
|
||||
int Okim6295_Emu::set_rate( int clock_rate )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_okim6295( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_okim6295( clock_rate );
|
||||
if ( !chip )
|
||||
return 0;
|
||||
|
||||
reset();
|
||||
return (clock_rate & 0x7FFFFFFF) / ((clock_rate & 0x80000000) ? 132 : 165);
|
||||
}
|
||||
|
||||
void Okim6295_Emu::reset()
|
||||
{
|
||||
device_reset_okim6295( chip );
|
||||
okim6295_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void Okim6295_Emu::write( int addr, int data )
|
||||
{
|
||||
okim6295_w( chip, addr, data );
|
||||
}
|
||||
|
||||
void Okim6295_Emu::write_rom( int size, int start, int length, void * data )
|
||||
{
|
||||
okim6295_write_rom( chip, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void Okim6295_Emu::mute_voices( int mask )
|
||||
{
|
||||
okim6295_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void Okim6295_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
okim6295_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// OKIM6295 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef OKIM6295_EMU_H
|
||||
#define OKIM6295_EMU_H
|
||||
|
||||
class Okim6295_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
Okim6295_Emu();
|
||||
~Okim6295_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 4 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -2,8 +2,16 @@
|
|||
|
||||
#include "blargg_source.h"
|
||||
|
||||
#include "ym2413.h"
|
||||
#include "fmopl.h"
|
||||
extern "C" {
|
||||
#include "../vgmplay/chips/mamedef.h"
|
||||
#include "../vgmplay/chips/emu2413.h"
|
||||
#include "../vgmplay/chips/fmopl.h"
|
||||
}
|
||||
|
||||
static unsigned char vrc7_inst[(16 + 3) * 8] =
|
||||
{
|
||||
#include "../vgmplay/chips/vrc7tone.h"
|
||||
};
|
||||
|
||||
Opl_Apu::Opl_Apu() { opl = 0; opl_memory = 0; }
|
||||
|
||||
|
@ -20,26 +28,29 @@ blargg_err_t Opl_Apu::init( long clock, long rate, blip_time_t period, type_t ty
|
|||
case type_opll:
|
||||
case type_msxmusic:
|
||||
case type_smsfmunit:
|
||||
opl = ym2413_init( clock, rate, 0 );
|
||||
opl = OPLL_new( (BOOST::uint32_t) clock, (BOOST::uint32_t) rate );
|
||||
OPLL_SetChipMode( (OPLL *) opl, 0);
|
||||
break;
|
||||
|
||||
case type_vrc7:
|
||||
opl = ym2413_init( clock, rate, 1 );
|
||||
opl = OPLL_new( (BOOST::uint32_t) clock, (BOOST::uint32_t) rate );
|
||||
OPLL_SetChipMode((OPLL *) opl, 1 );
|
||||
OPLL_setPatch((OPLL *) opl, vrc7_inst);
|
||||
break;
|
||||
|
||||
case type_opl:
|
||||
opl = ym3526_init( clock, rate );
|
||||
opl = ym3526_init( (BOOST::uint32_t) clock, (BOOST::uint32_t) rate );
|
||||
break;
|
||||
|
||||
case type_msxaudio:
|
||||
//logfile = fopen("c:\\temp\\msxaudio.log", "wb");
|
||||
opl = y8950_init( clock, rate );
|
||||
opl = y8950_init( (BOOST::uint32_t) clock, (BOOST::uint32_t) rate );
|
||||
opl_memory = malloc( 32768 );
|
||||
y8950_set_delta_t_memory( opl, opl_memory, 32768 );
|
||||
break;
|
||||
|
||||
case type_opl2:
|
||||
opl = ym3812_init( clock, rate );
|
||||
opl = ym3812_init( (BOOST::uint32_t) clock, (BOOST::uint32_t) rate );
|
||||
break;
|
||||
}
|
||||
reset();
|
||||
|
@ -56,7 +67,7 @@ Opl_Apu::~Opl_Apu()
|
|||
case type_msxmusic:
|
||||
case type_smsfmunit:
|
||||
case type_vrc7:
|
||||
ym2413_shutdown( opl );
|
||||
OPLL_delete( (OPLL *) opl );
|
||||
break;
|
||||
|
||||
case type_opl:
|
||||
|
@ -88,7 +99,7 @@ void Opl_Apu::reset()
|
|||
case type_msxmusic:
|
||||
case type_smsfmunit:
|
||||
case type_vrc7:
|
||||
ym2413_reset_chip( opl );
|
||||
OPLL_reset( (OPLL *) opl );
|
||||
break;
|
||||
|
||||
case type_opl:
|
||||
|
@ -114,8 +125,8 @@ void Opl_Apu::write_data( blip_time_t time, int data )
|
|||
case type_msxmusic:
|
||||
case type_smsfmunit:
|
||||
case type_vrc7:
|
||||
ym2413_write( opl, 0, addr );
|
||||
ym2413_write( opl, 1, data );
|
||||
OPLL_writeIO( (OPLL *) opl, 0, addr );
|
||||
OPLL_writeIO( (OPLL *) opl, 1, data );
|
||||
break;
|
||||
|
||||
case type_opl:
|
||||
|
@ -149,7 +160,7 @@ int Opl_Apu::read( blip_time_t time, int port )
|
|||
case type_msxmusic:
|
||||
case type_smsfmunit:
|
||||
case type_vrc7:
|
||||
return ym2413_read( opl, port );
|
||||
return port ? 0xFF : 0;
|
||||
|
||||
case type_opl:
|
||||
return ym3526_read( opl, port );
|
||||
|
@ -192,15 +203,15 @@ void Opl_Apu::run_until( blip_time_t end_time )
|
|||
case type_smsfmunit:
|
||||
case type_vrc7:
|
||||
{
|
||||
SAMP bufMO[ 1024 ];
|
||||
SAMP bufRO[ 1024 ];
|
||||
SAMP * buffers[2] = { bufMO, bufRO };
|
||||
e_int32 bufMO[ 1024 ];
|
||||
e_int32 bufRO[ 1024 ];
|
||||
e_int32 * buffers[2] = { bufMO, bufRO };
|
||||
|
||||
while ( count > 0 )
|
||||
{
|
||||
unsigned todo = count;
|
||||
if ( todo > 1024 ) todo = 1024;
|
||||
ym2413_update_one( opl, buffers, todo );
|
||||
OPLL_calc_stereo( (OPLL *) opl, buffers, todo, -1 );
|
||||
|
||||
if ( output_ )
|
||||
{
|
||||
|
@ -229,7 +240,9 @@ void Opl_Apu::run_until( blip_time_t end_time )
|
|||
case type_msxaudio:
|
||||
case type_opl2:
|
||||
{
|
||||
OPLSAMPLE buffer[ 1024 ];
|
||||
OPLSAMPLE bufL[ 1024 ];
|
||||
OPLSAMPLE bufR[ 1024 ];
|
||||
OPLSAMPLE* buffers[2] = {bufL, bufR};
|
||||
|
||||
while ( count > 0 )
|
||||
{
|
||||
|
@ -237,9 +250,9 @@ void Opl_Apu::run_until( blip_time_t end_time )
|
|||
if ( todo > 1024 ) todo = 1024;
|
||||
switch (type_)
|
||||
{
|
||||
case type_opl: ym3526_update_one( opl, buffer, todo ); break;
|
||||
case type_msxaudio: y8950_update_one( opl, buffer, todo ); break;
|
||||
case type_opl2: ym3812_update_one( opl, buffer, todo ); break;
|
||||
case type_opl: ym3526_update_one( opl, buffers, todo ); break;
|
||||
case type_msxaudio: y8950_update_one( opl, buffers, todo ); break;
|
||||
case type_opl2: ym3812_update_one( opl, buffers, todo ); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -248,7 +261,7 @@ void Opl_Apu::run_until( blip_time_t end_time )
|
|||
int last_amp = this->last_amp;
|
||||
for ( unsigned i = 0; i < todo; i++ )
|
||||
{
|
||||
int amp = buffer [i];
|
||||
int amp = bufL [i] + bufR [i];
|
||||
int delta = amp - last_amp;
|
||||
if ( delta )
|
||||
{
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Pwm_Emu.h"
|
||||
#include "pwm.h"
|
||||
|
||||
Pwm_Emu::Pwm_Emu() { chip = 0; }
|
||||
|
||||
Pwm_Emu::~Pwm_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_pwm( chip );
|
||||
}
|
||||
|
||||
int Pwm_Emu::set_rate( int clock )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_pwm( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_pwm( clock );
|
||||
if ( !chip )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Pwm_Emu::reset()
|
||||
{
|
||||
device_reset_pwm( chip );
|
||||
}
|
||||
|
||||
void Pwm_Emu::write( int channel, int data )
|
||||
{
|
||||
pwm_chn_w( chip, channel, data );
|
||||
}
|
||||
|
||||
void Pwm_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
pwm_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
// PWM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef PWM_EMU_H
|
||||
#define PWM_EMU_H
|
||||
|
||||
class Pwm_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
Pwm_Emu();
|
||||
~Pwm_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 24 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to channel
|
||||
void write( int channel, int data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,83 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Qsound_Apu.h"
|
||||
#include "qmix.h"
|
||||
|
||||
Qsound_Apu::Qsound_Apu() { chip = 0; rom = 0; rom_size = 0; sample_rate = 0; }
|
||||
|
||||
Qsound_Apu::~Qsound_Apu()
|
||||
{
|
||||
if ( chip ) free( chip );
|
||||
if ( rom ) free( rom );
|
||||
}
|
||||
|
||||
int Qsound_Apu::set_rate( int clock_rate )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
free( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = malloc( _qmix_get_state_size() );
|
||||
if ( !chip )
|
||||
return 0;
|
||||
|
||||
reset();
|
||||
|
||||
return clock_rate / 166;
|
||||
}
|
||||
|
||||
void Qsound_Apu::set_sample_rate( int sample_rate )
|
||||
{
|
||||
this->sample_rate = sample_rate;
|
||||
if ( chip ) _qmix_set_sample_rate( chip, sample_rate );
|
||||
}
|
||||
|
||||
void Qsound_Apu::reset()
|
||||
{
|
||||
_qmix_clear_state( chip );
|
||||
_qmix_set_sample_rate( chip, sample_rate );
|
||||
if ( rom ) _qmix_set_sample_rom( chip, rom, rom_size );
|
||||
}
|
||||
|
||||
void Qsound_Apu::write( int addr, int data )
|
||||
{
|
||||
_qmix_command( chip, addr, data );
|
||||
}
|
||||
|
||||
void Qsound_Apu::write_rom( int size, int start, int length, void const* data )
|
||||
{
|
||||
if ( size > rom_size )
|
||||
{
|
||||
rom_size = size;
|
||||
rom = realloc( rom, size );
|
||||
}
|
||||
if ( start > size ) start = size;
|
||||
if ( start + length > size ) length = size - start;
|
||||
memcpy( (uint8*)rom + start, data, length );
|
||||
if ( chip ) _qmix_set_sample_rom( chip, rom, rom_size );
|
||||
}
|
||||
|
||||
void Qsound_Apu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
sint16 buf[ 1024 * 2 ];
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
_qmix_render( chip, buf, todo );
|
||||
|
||||
for (int i = 0; i < todo * 2; i++)
|
||||
{
|
||||
int output = buf [i];
|
||||
output += out [0];
|
||||
if ( (short)output != output ) output = 0x7FFF ^ ( output >> 31 );
|
||||
out [0] = output;
|
||||
out++;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// Capcom QSound sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef QSOUND_APU_H
|
||||
#define QSOUND_APU_H
|
||||
|
||||
class Qsound_Apu {
|
||||
void* chip;
|
||||
void* rom;
|
||||
int rom_size;
|
||||
int sample_rate;
|
||||
public:
|
||||
Qsound_Apu();
|
||||
~Qsound_Apu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock_rate );
|
||||
void set_sample_rate( int sample_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int size, int start, int length, void const* data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Rf5C164_Emu.h"
|
||||
#include "scd_pcm.h"
|
||||
|
||||
Rf5C164_Emu::Rf5C164_Emu() { chip = 0; }
|
||||
|
||||
Rf5C164_Emu::~Rf5C164_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_rf5c164( chip );
|
||||
}
|
||||
|
||||
int Rf5C164_Emu::set_rate( int clock )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_rf5c164( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_rf5c164( clock );
|
||||
if ( !chip )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Rf5C164_Emu::reset()
|
||||
{
|
||||
device_reset_rf5c164( chip );
|
||||
rf5c164_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void Rf5C164_Emu::write( int addr, int data )
|
||||
{
|
||||
rf5c164_w( chip, addr, data );
|
||||
}
|
||||
|
||||
void Rf5C164_Emu::write_mem( int addr, int data )
|
||||
{
|
||||
rf5c164_mem_w( chip, addr, data );
|
||||
}
|
||||
|
||||
void Rf5C164_Emu::write_ram( int start, int length, void * data )
|
||||
{
|
||||
rf5c164_write_ram( chip, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void Rf5C164_Emu::mute_voices( int mask )
|
||||
{
|
||||
rf5c164_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void Rf5C164_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
rf5c164_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
// RF5C164 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef RF5C164_EMU_H
|
||||
#define RF5C164_EMU_H
|
||||
|
||||
class Rf5C164_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
Rf5C164_Emu();
|
||||
~Rf5C164_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 8 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Writes to memory
|
||||
void write_mem( int addr, int data );
|
||||
|
||||
// Writes length bytes from data at start offset in RAM
|
||||
void write_ram( int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,82 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Rf5C68_Emu.h"
|
||||
#include "rf5c68.h"
|
||||
|
||||
Rf5C68_Emu::Rf5C68_Emu() { chip = 0; }
|
||||
|
||||
Rf5C68_Emu::~Rf5C68_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_rf5c68( chip );
|
||||
}
|
||||
|
||||
int Rf5C68_Emu::set_rate()
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_rf5c68( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_rf5c68();
|
||||
if ( !chip )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Rf5C68_Emu::reset()
|
||||
{
|
||||
device_reset_rf5c68( chip );
|
||||
rf5c68_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void Rf5C68_Emu::write( int addr, int data )
|
||||
{
|
||||
rf5c68_w( chip, addr, data );
|
||||
}
|
||||
|
||||
void Rf5C68_Emu::write_mem( int addr, int data )
|
||||
{
|
||||
rf5c68_mem_w( chip, addr, data );
|
||||
}
|
||||
|
||||
void Rf5C68_Emu::write_ram( int start, int length, void * data )
|
||||
{
|
||||
rf5c68_write_ram( chip, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void Rf5C68_Emu::mute_voices( int mask )
|
||||
{
|
||||
rf5c68_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void Rf5C68_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
rf5c68_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
// RF5C68 sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef RF5C68_EMU_H
|
||||
#define RF5C68_EMU_H
|
||||
|
||||
class Rf5C68_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
Rf5C68_Emu();
|
||||
~Rf5C68_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate();
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 8 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Writes to memory
|
||||
void write_mem( int addr, int data );
|
||||
|
||||
// Writes length bytes from data at start offset in RAM
|
||||
void write_ram( int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,77 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "SegaPcm_Emu.h"
|
||||
#include "segapcm.h"
|
||||
|
||||
SegaPcm_Emu::SegaPcm_Emu() { chip = 0; }
|
||||
|
||||
SegaPcm_Emu::~SegaPcm_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_segapcm( chip );
|
||||
}
|
||||
|
||||
int SegaPcm_Emu::set_rate( int intf_type )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_segapcm( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_segapcm( intf_type );
|
||||
if ( !chip )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SegaPcm_Emu::reset()
|
||||
{
|
||||
device_reset_segapcm( chip );
|
||||
segapcm_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void SegaPcm_Emu::write( int addr, int data )
|
||||
{
|
||||
sega_pcm_w( chip, addr, data );
|
||||
}
|
||||
|
||||
void SegaPcm_Emu::write_rom( int size, int start, int length, void * data )
|
||||
{
|
||||
sega_pcm_write_rom( chip, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void SegaPcm_Emu::mute_voices( int mask )
|
||||
{
|
||||
segapcm_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void SegaPcm_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
SEGAPCM_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// Sega PCM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef SEGAPCM_EMU_H
|
||||
#define SEGAPCM_EMU_H
|
||||
|
||||
class SegaPcm_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
SegaPcm_Emu();
|
||||
~SegaPcm_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int intf_type );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 16 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -5,136 +5,14 @@
|
|||
#define VGM_CORE_H
|
||||
|
||||
#include "Gme_Loader.h"
|
||||
#include "Ymz280b_Emu.h"
|
||||
#include "Ymf262_Emu.h"
|
||||
#include "Ym2612_Emu.h"
|
||||
#include "Ym2610b_Emu.h"
|
||||
#include "Ym2608_Emu.h"
|
||||
#include "Ym3812_Emu.h"
|
||||
#include "Ym2413_Emu.h"
|
||||
#include "Ym2151_Emu.h"
|
||||
#include "C140_Emu.h"
|
||||
#include "SegaPcm_Emu.h"
|
||||
#include "Rf5C68_Emu.h"
|
||||
#include "Rf5C164_Emu.h"
|
||||
#include "Pwm_Emu.h"
|
||||
#include "Okim6258_Emu.h"
|
||||
#include "Okim6295_Emu.h"
|
||||
#include "K051649_Emu.h"
|
||||
#include "K053260_Emu.h"
|
||||
#include "K054539_Emu.h"
|
||||
#include "Qsound_Apu.h"
|
||||
#include "Ym2203_Emu.h"
|
||||
#include "Ay_Apu.h"
|
||||
#include "Gb_Apu.h"
|
||||
#include "Hes_Apu.h"
|
||||
#include "Sms_Apu.h"
|
||||
#include "Multi_Buffer.h"
|
||||
#include "Chip_Resampler.h"
|
||||
|
||||
template<class Emu>
|
||||
class Chip_Emu : public Emu {
|
||||
int last_time;
|
||||
short* out;
|
||||
enum { disabled_time = -1 };
|
||||
public:
|
||||
Chip_Emu() { last_time = disabled_time; out = NULL; }
|
||||
void enable( bool b = true ) { last_time = b ? 0 : disabled_time; }
|
||||
bool enabled() const { return last_time != disabled_time; }
|
||||
void begin_frame( short* buf ) { out = buf; last_time = 0; }
|
||||
|
||||
int run_until( int time )
|
||||
{
|
||||
int count = time - last_time;
|
||||
if ( count > 0 )
|
||||
{
|
||||
if ( last_time < 0 )
|
||||
return false;
|
||||
last_time = time;
|
||||
short* p = out;
|
||||
out += count * Emu::out_chan_count;
|
||||
Emu::run( count, p );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
#include "../vgmplay/VGMPlay.h"
|
||||
|
||||
class Vgm_Core : public Gme_Loader {
|
||||
public:
|
||||
typedef VGM_HEADER header_t;
|
||||
|
||||
// VGM file header
|
||||
struct header_t
|
||||
{
|
||||
enum { size_min = 0x40 };
|
||||
enum { size_151 = 0x80 };
|
||||
enum { size_max = 0xC0 };
|
||||
|
||||
char tag [4]; // 0x00
|
||||
byte data_size [4]; // 0x04
|
||||
byte version [4]; // 0x08
|
||||
byte psg_rate [4]; // 0x0C
|
||||
byte ym2413_rate [4]; // 0x10
|
||||
byte gd3_offset [4]; // 0x14
|
||||
byte track_duration [4]; // 0x18
|
||||
byte loop_offset [4]; // 0x1C
|
||||
byte loop_duration [4]; // 0x20
|
||||
byte frame_rate [4]; // 0x24 v1.01 V
|
||||
byte noise_feedback [2]; // 0x28 v1.10 V
|
||||
byte noise_width; // 0x2A
|
||||
byte sn76489_flags; // 0x2B v1.51 <
|
||||
byte ym2612_rate [4]; // 0x2C v1.10 V
|
||||
byte ym2151_rate [4]; // 0x30
|
||||
byte data_offset [4]; // 0x34 v1.50 V
|
||||
byte segapcm_rate [4]; // 0x38 v1.51 V
|
||||
byte segapcm_reg [4]; // 0x3C
|
||||
byte rf5c68_rate [4]; // 0x40
|
||||
byte ym2203_rate [4]; // 0x44
|
||||
byte ym2608_rate [4]; // 0x48
|
||||
byte ym2610_rate [4]; // 0x4C
|
||||
byte ym3812_rate [4]; // 0x50
|
||||
byte ym3526_rate [4]; // 0x54
|
||||
byte y8950_rate [4]; // 0x58
|
||||
byte ymf262_rate [4]; // 0x5C
|
||||
byte ymf278b_rate [4]; // 0x60
|
||||
byte ymf271_rate [4]; // 0x64
|
||||
byte ymz280b_rate [4]; // 0x68
|
||||
byte rf5c164_rate [4]; // 0x6C
|
||||
byte pwm_rate [4]; // 0x70
|
||||
byte ay8910_rate [4]; // 0x74
|
||||
byte ay8910_type; // 0x78
|
||||
byte ay8910_flags; // 0x79
|
||||
byte ym2203_ay8910_flags;// 0x7A
|
||||
byte ym2608_ay8910_flags;// 0x7B
|
||||
byte volume_modifier; // 0x7C v1.60 V
|
||||
byte reserved; // 0x7D
|
||||
byte loop_base; // 0x7E
|
||||
byte loop_modifier; // 0x7F v1.51 <
|
||||
byte gbdmg_rate [4]; // 0x80 v1.61 V
|
||||
byte nesapu_rate [4]; // 0x84
|
||||
byte multipcm_rate [4]; // 0x88
|
||||
byte upd7759_rate [4]; // 0x8C
|
||||
byte okim6258_rate [4]; // 0x90
|
||||
byte okim6258_flags; // 0x94
|
||||
byte k054539_flags; // 0x95
|
||||
byte c140_type; // 0x96
|
||||
byte reserved_flags; // 0x97
|
||||
byte okim6295_rate [4]; // 0x98
|
||||
byte k051649_rate [4]; // 0x9C
|
||||
byte k054539_rate [4]; // 0xA0
|
||||
byte huc6280_rate [4]; // 0xA4
|
||||
byte c140_rate [4]; // 0xA8
|
||||
byte k053260_rate [4]; // 0xAC
|
||||
byte pokey_rate [4]; // 0xB0
|
||||
byte qsound_rate [4]; // 0xB4
|
||||
byte reserved2 [4]; // 0xB8
|
||||
byte extra_offset [4]; // 0xBC
|
||||
|
||||
// True if header has valid file signature
|
||||
bool valid_tag() const;
|
||||
int size() const;
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
// Header for currently loaded file
|
||||
header_t const& header() const { return _header; }
|
||||
|
||||
|
@ -142,22 +20,6 @@ public:
|
|||
byte const* file_begin() const { return Gme_Loader::file_begin(); }
|
||||
byte const* file_end () const { return Gme_Loader::file_end(); }
|
||||
|
||||
// If file uses FM, initializes FM sound emulator using *sample_rate. If
|
||||
// *sample_rate is zero, sets *sample_rate to the proper accurate rate and
|
||||
// uses that. The output of the FM sound emulator is resampled to the
|
||||
// final sampling rate.
|
||||
blargg_err_t init_chips( double* fm_rate, bool reinit = false );
|
||||
|
||||
// True if any FM chips are used by file. Always false until init_fm()
|
||||
// is called.
|
||||
bool uses_fm() const { return ym2612[0].enabled() || ym2413[0].enabled() || ym2151[0].enabled() || c140.enabled() ||
|
||||
segapcm.enabled() || rf5c68.enabled() || rf5c164.enabled() || pwm.enabled() || okim6258[0].enabled() || okim6295[0].enabled() ||
|
||||
k051649.enabled() || k053260.enabled() || k054539.enabled() || ym2203[0].enabled() || ym3812[0].enabled() || ymf262[0].enabled() ||
|
||||
ymz280b.enabled() || ym2610[0].enabled() || ym2608[0].enabled() || qsound[0].enabled() ||
|
||||
(header().ay8910_rate[0] | header().ay8910_rate[1] | header().ay8910_rate[2] | header().ay8910_rate[3]) ||
|
||||
(header().huc6280_rate[0] | header().huc6280_rate[1] | header().huc6280_rate[2] | header().huc6280_rate[3]) ||
|
||||
(header().gbdmg_rate[0] | header().gbdmg_rate[1] | header().gbdmg_rate[2] | header().gbdmg_rate[3]); }
|
||||
|
||||
// Adjusts music tempo, where 1.0 is normal. Can be changed while playing.
|
||||
// Loading a file resets tempo to 1.0.
|
||||
void set_tempo( double );
|
||||
|
@ -167,77 +29,15 @@ public:
|
|||
// Starts track
|
||||
void start_track();
|
||||
|
||||
// Runs PSG-only VGM for msec and returns number of clocks it ran for
|
||||
blip_time_t run_psg( int msec );
|
||||
|
||||
// Plays FM for at most count samples into *out, and returns number of
|
||||
// samples actually generated (always even). Also runs PSG for blip_time.
|
||||
int play_frame( blip_time_t blip_time, int count, blip_sample_t out [] );
|
||||
// samples actually generated (always even).
|
||||
int play_( int count, short out [] );
|
||||
|
||||
// True if all of file data has been played
|
||||
bool track_ended() const { return pos >= file_end(); }
|
||||
bool track_ended() const { return !!vgmp->VGMEnd; }
|
||||
|
||||
// 0 for PSG and YM2612 DAC, 1 for AY, 2 for HuC6280, 3 for GB DMG
|
||||
Stereo_Buffer stereo_buf[4];
|
||||
|
||||
// PCM sound is always generated here
|
||||
Blip_Buffer * blip_buf[2];
|
||||
|
||||
// PSG sound chips, for assigning to Blip_Buffer, and setting volume and EQ
|
||||
Sms_Apu psg[2];
|
||||
Ay_Apu ay[2];
|
||||
Hes_Apu huc6280[2];
|
||||
Gb_Apu gbdmg[2];
|
||||
|
||||
// PCM synth, for setting volume and EQ
|
||||
Blip_Synth_Fast pcm;
|
||||
|
||||
// FM sound chips
|
||||
Chip_Resampler_Emu<Ymf262_Emu> ymf262[2];
|
||||
Chip_Resampler_Emu<Ym3812_Emu> ym3812[2];
|
||||
Chip_Resampler_Emu<Ym2612_Emu> ym2612[2];
|
||||
Chip_Resampler_Emu<Ym2610b_Emu> ym2610[2];
|
||||
Chip_Resampler_Emu<Ym2608_Emu> ym2608[2];
|
||||
Chip_Resampler_Emu<Ym2413_Emu> ym2413[2];
|
||||
Chip_Resampler_Emu<Ym2151_Emu> ym2151[2];
|
||||
Chip_Resampler_Emu<Ym2203_Emu> ym2203[2];
|
||||
|
||||
// PCM sound chips
|
||||
Chip_Resampler_Emu<C140_Emu> c140;
|
||||
Chip_Resampler_Emu<SegaPcm_Emu> segapcm;
|
||||
Chip_Resampler_Emu<Rf5C68_Emu> rf5c68;
|
||||
Chip_Resampler_Emu<Rf5C164_Emu> rf5c164;
|
||||
Chip_Resampler_Emu<Pwm_Emu> pwm;
|
||||
Chip_Resampler_Emu<Okim6258_Emu> okim6258[2]; int okim6258_hz[2];
|
||||
Chip_Resampler_Emu<Okim6295_Emu> okim6295[2]; int okim6295_hz;
|
||||
Chip_Resampler_Emu<K051649_Emu> k051649;
|
||||
Chip_Resampler_Emu<K053260_Emu> k053260;
|
||||
Chip_Resampler_Emu<K054539_Emu> k054539;
|
||||
Chip_Resampler_Emu<Ymz280b_Emu> ymz280b; int ymz280b_hz;
|
||||
Chip_Resampler_Emu<Qsound_Apu> qsound[2];
|
||||
|
||||
// DAC control
|
||||
typedef struct daccontrol_data
|
||||
{
|
||||
bool Enable;
|
||||
byte Bank;
|
||||
} DACCTRL_DATA;
|
||||
|
||||
byte DacCtrlUsed;
|
||||
byte DacCtrlUsg[0xFF];
|
||||
DACCTRL_DATA DacCtrl[0xFF];
|
||||
byte DacCtrlMap[0xFF];
|
||||
int DacCtrlTime[0xFF];
|
||||
void ** dac_control;
|
||||
|
||||
void dac_control_grow(byte chip_id);
|
||||
|
||||
int dac_control_recursion;
|
||||
|
||||
int run_dac_control( int time );
|
||||
|
||||
public:
|
||||
void chip_reg_write(unsigned Sample, byte ChipType, byte ChipID, byte Port, byte Offset, byte Data);
|
||||
// Skips the specified number of samples
|
||||
void skip_( int count );
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
|
@ -248,106 +48,11 @@ protected:
|
|||
virtual blargg_err_t load_mem_( byte const [], int );
|
||||
|
||||
private:
|
||||
// blip_time_t // PSG clocks
|
||||
typedef int vgm_time_t; // 44100 per second, REGARDLESS of sample rate
|
||||
typedef int fm_time_t; // FM sample count
|
||||
|
||||
int sample_rate;
|
||||
int vgm_rate; // rate of log, 44100 normally, adjusted by tempo
|
||||
double fm_rate; // FM samples per second
|
||||
|
||||
header_t _header;
|
||||
|
||||
// VGM to FM time
|
||||
int fm_time_factor;
|
||||
int fm_time_offset;
|
||||
fm_time_t to_fm_time( vgm_time_t ) const;
|
||||
|
||||
// VGM to PSG time
|
||||
int blip_time_factor;
|
||||
blip_time_t to_psg_time( vgm_time_t ) const;
|
||||
|
||||
int blip_ay_time_factor;
|
||||
int ay_time_offset;
|
||||
blip_time_t to_ay_time( vgm_time_t ) const;
|
||||
|
||||
int blip_huc6280_time_factor;
|
||||
int huc6280_time_offset;
|
||||
blip_time_t to_huc6280_time( vgm_time_t ) const;
|
||||
|
||||
int blip_gbdmg_time_factor;
|
||||
int gbdmg_time_offset;
|
||||
blip_time_t to_gbdmg_time( vgm_time_t ) const;
|
||||
|
||||
// Current time and position in log
|
||||
vgm_time_t vgm_time;
|
||||
byte const* pos;
|
||||
byte const* loop_begin;
|
||||
bool has_looped;
|
||||
|
||||
// PCM
|
||||
enum { PCM_BANK_COUNT = 0x40 };
|
||||
typedef struct _vgm_pcm_bank_data
|
||||
{
|
||||
unsigned DataSize;
|
||||
byte* Data;
|
||||
unsigned DataStart;
|
||||
} VGM_PCM_DATA;
|
||||
typedef struct _vgm_pcm_bank
|
||||
{
|
||||
unsigned BankCount;
|
||||
VGM_PCM_DATA* Bank;
|
||||
unsigned DataSize;
|
||||
byte* Data;
|
||||
unsigned DataPos;
|
||||
unsigned BnkPos;
|
||||
} VGM_PCM_BANK;
|
||||
|
||||
typedef struct pcmbank_table
|
||||
{
|
||||
byte ComprType;
|
||||
byte CmpSubType;
|
||||
byte BitDec;
|
||||
byte BitCmp;
|
||||
unsigned EntryCount;
|
||||
void* Entries;
|
||||
} PCMBANK_TBL;
|
||||
|
||||
VGM_PCM_BANK PCMBank[PCM_BANK_COUNT];
|
||||
PCMBANK_TBL PCMTbl;
|
||||
|
||||
void ReadPCMTable(unsigned DataSize, const byte* Data);
|
||||
void AddPCMData(byte Type, unsigned DataSize, const byte* Data);
|
||||
bool DecompressDataBlk(VGM_PCM_DATA* Bank, unsigned DataSize, const byte* Data);
|
||||
const byte* GetPointerFromPCMBank(byte Type, unsigned DataPos);
|
||||
|
||||
byte const* pcm_pos; // current position in PCM data
|
||||
int dac_amp[2];
|
||||
int dac_disabled[2]; // -1 if disabled
|
||||
void write_pcm( vgm_time_t, int chip, int amp );
|
||||
|
||||
blip_time_t run( vgm_time_t );
|
||||
int run_ym2151( int chip, int time );
|
||||
int run_ym2203( int chip, int time );
|
||||
int run_ym2413( int chip, int time );
|
||||
int run_ym2612( int chip, int time );
|
||||
int run_ym3812( int chip, int time );
|
||||
int run_ymf262( int chip, int time );
|
||||
int run_ym2610( int chip, int time );
|
||||
int run_ym2608( int chip, int time );
|
||||
int run_ymz280b( int time );
|
||||
int run_c140( int time );
|
||||
int run_segapcm( int time );
|
||||
int run_rf5c68( int time );
|
||||
int run_rf5c164( int time );
|
||||
int run_pwm( int time );
|
||||
int run_okim6258( int chip, int time );
|
||||
int run_okim6295( int chip, int time );
|
||||
int run_k051649( int time );
|
||||
int run_k053260( int time );
|
||||
int run_k054539( int time );
|
||||
int run_qsound( int chip, int time );
|
||||
void update_fm_rates( int* ym2151_rate, int* ym2413_rate, int* ym2612_rate ) const;
|
||||
VGM_PLAYER* vgmp;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "Vgm_Emu.h"
|
||||
|
||||
#include "blargg_endian.h"
|
||||
#include "blargg_common.h"
|
||||
|
||||
/* Copyright (C) 2003-2008 Shay Green. This module is free software; you
|
||||
can redistribute it and/or modify it under the terms of the GNU Lesser
|
||||
|
@ -24,15 +25,10 @@ double const oversample_factor = 1.5;
|
|||
|
||||
Vgm_Emu::Vgm_Emu()
|
||||
{
|
||||
resampler.set_callback( play_frame_, this );
|
||||
disable_oversampling_ = false;
|
||||
muted_voices = 0;
|
||||
set_type( gme_vgm_type );
|
||||
set_max_initial_silence( 1 );
|
||||
set_silence_lookahead( 1 ); // tracks should already be trimmed
|
||||
|
||||
static equalizer_t const eq = { -14.0, 80 , 0,0,0,0,0,0,0,0 };
|
||||
set_equalizer( eq );
|
||||
}
|
||||
|
||||
Vgm_Emu::~Vgm_Emu() { }
|
||||
|
@ -40,7 +36,6 @@ Vgm_Emu::~Vgm_Emu() { }
|
|||
void Vgm_Emu::unload()
|
||||
{
|
||||
core.unload();
|
||||
Classic_Emu::unload();
|
||||
}
|
||||
|
||||
// Track info
|
||||
|
@ -59,33 +54,85 @@ static byte const* skip_gd3_str( byte const in [], byte const* end )
|
|||
static byte const* get_gd3_str( byte const* in, byte const* end, char field [] )
|
||||
{
|
||||
byte const* mid = skip_gd3_str( in, end );
|
||||
int len = (mid - in) / 2 - 1;
|
||||
int len = (int)((mid - in) / 2) - 1;
|
||||
if ( len > 0 )
|
||||
{
|
||||
char * in_utf8 = blargg_to_utf8( (blargg_wchar_t *) in );
|
||||
len = min( len, (int) Gme_File::max_field_ );
|
||||
field [len] = 0;
|
||||
for ( int i = 0; i < len; i++ )
|
||||
field [i] = (in [i * 2 + 1] ? '?' : in [i * 2]); // TODO: convert to utf-8
|
||||
field [i] = in_utf8 [i];
|
||||
free(in_utf8);
|
||||
}
|
||||
return mid;
|
||||
}
|
||||
|
||||
static byte const* get_gd3_pair( byte const* in, byte const* end, char field [] )
|
||||
static byte const* get_gd3_pair( byte const* in, byte const* end, char field [], char field_j [] )
|
||||
{
|
||||
return skip_gd3_str( get_gd3_str( in, end, field ), end );
|
||||
return get_gd3_str( get_gd3_str( in, end, field ), end, field_j );
|
||||
}
|
||||
|
||||
static void parse_gd3( byte const in [], byte const* end, track_info_t* out )
|
||||
static void parse_gd3( byte const in [], byte const* end, track_info_t* out, track_info_t* out_j )
|
||||
{
|
||||
in = get_gd3_pair( in, end, out->song );
|
||||
in = get_gd3_pair( in, end, out->game );
|
||||
in = get_gd3_pair( in, end, out->system );
|
||||
in = get_gd3_pair( in, end, out->author );
|
||||
in = get_gd3_pair( in, end, out->song , out_j->song );
|
||||
in = get_gd3_pair( in, end, out->game , out_j->game );
|
||||
in = get_gd3_pair( in, end, out->system , out_j->system );
|
||||
in = get_gd3_pair( in, end, out->author , out_j->author );
|
||||
in = get_gd3_str ( in, end, out->copyright );
|
||||
in = get_gd3_pair( in, end, out->dumper );
|
||||
in = get_gd3_pair( in, end, out->dumper , out_j->dumper );
|
||||
in = get_gd3_str ( in, end, out->comment );
|
||||
}
|
||||
|
||||
static blargg_err_t write_gd3_str( gme_writer_t writer, void* your_data, const char field [] )
|
||||
{
|
||||
blargg_wchar_t * wstring = blargg_to_wide( field );
|
||||
if (!wstring)
|
||||
return "Out of memory";
|
||||
blargg_err_t err = writer( your_data, wstring, blargg_wcslen( wstring ) * 2 + 2 );
|
||||
free( wstring );
|
||||
return err;
|
||||
}
|
||||
|
||||
static blargg_err_t write_gd3_pair( gme_writer_t writer, void* your_data, const char field [], const char field_j [] )
|
||||
{
|
||||
RETURN_ERR(write_gd3_str( writer, your_data, field ));
|
||||
RETURN_ERR(write_gd3_str( writer, your_data, field ));
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
static blargg_err_t write_gd3_strings( gme_writer_t writer, void* your_data, const track_info_t* in, const track_info_t* in_j )
|
||||
{
|
||||
RETURN_ERR(write_gd3_pair( writer, your_data, in->song , in_j->song ));
|
||||
RETURN_ERR(write_gd3_pair( writer, your_data, in->game , in_j->game ));
|
||||
RETURN_ERR(write_gd3_pair( writer, your_data, in->system , in_j->system ));
|
||||
RETURN_ERR(write_gd3_pair( writer, your_data, in->author , in_j->author ));
|
||||
RETURN_ERR(write_gd3_str ( writer, your_data, in->copyright ));
|
||||
RETURN_ERR(write_gd3_pair( writer, your_data, in->dumper , in_j->dumper ));
|
||||
RETURN_ERR(write_gd3_str ( writer, your_data, in->comment ));
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
static gme_err_t writer_calc_size(void* param, const void* ptr, long count)
|
||||
{
|
||||
*(long *)param += count;
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
static blargg_err_t write_gd3( gme_writer_t writer, void* your_data, const track_info_t* in, const track_info_t* in_j )
|
||||
{
|
||||
long string_size = 0;
|
||||
byte version[4];
|
||||
RETURN_ERR(writer( your_data, "Gd3 ", 4 ));
|
||||
set_le32(version, 0x100);
|
||||
RETURN_ERR(writer( your_data, version, 4 ));
|
||||
write_gd3_strings( &writer_calc_size, &string_size, in, in_j );
|
||||
if ( string_size > 1000000000 )
|
||||
return "GD3 tag too large";
|
||||
set_le32(version, (int)string_size);
|
||||
RETURN_ERR(writer( your_data, version, 4));
|
||||
return write_gd3_strings( writer, your_data, in, in_j );
|
||||
}
|
||||
|
||||
int const gd3_header_size = 12;
|
||||
|
||||
static int check_gd3_header( byte const h [], int remain )
|
||||
|
@ -102,11 +149,11 @@ static int check_gd3_header( byte const h [], int remain )
|
|||
|
||||
static void get_vgm_length( Vgm_Emu::header_t const& h, track_info_t* out )
|
||||
{
|
||||
int length = get_le32( h.track_duration ) * 10 / 441; // 1000 / 44100
|
||||
int length = get_le32( &h.lngTotalSamples ) * 10 / 441; // 1000 / 44100
|
||||
if ( length > 0 )
|
||||
{
|
||||
int loop = get_le32( h.loop_duration );
|
||||
if ( loop > 0 && get_le32( h.loop_offset ) )
|
||||
int loop = get_le32( &h.lngLoopSamples );
|
||||
if ( loop > 0 && get_le32( &h.lngLoopOffset ) )
|
||||
{
|
||||
out->loop_length = loop * 10 / 441;
|
||||
out->intro_length = length - out->loop_length;
|
||||
|
@ -124,19 +171,6 @@ static void get_vgm_length( Vgm_Emu::header_t const& h, track_info_t* out )
|
|||
|
||||
blargg_err_t Vgm_Emu::track_info_( track_info_t* out, int ) const
|
||||
{
|
||||
get_vgm_length( header(), out );
|
||||
|
||||
int gd3_offset = get_le32( header().gd3_offset );
|
||||
if ( gd3_offset <= 0 )
|
||||
return blargg_ok;
|
||||
|
||||
byte const* gd3 = core.file_begin() + gd3_offset + offsetof( header_t, gd3_offset );
|
||||
int gd3_size = check_gd3_header( gd3, core.file_end() - gd3 );
|
||||
if ( gd3_size )
|
||||
{
|
||||
byte const* gd3_data = gd3 + gd3_header_size;
|
||||
parse_gd3( gd3_data, gd3_data + gd3_size, out );
|
||||
}
|
||||
|
||||
return blargg_ok;
|
||||
}
|
||||
|
@ -146,12 +180,12 @@ blargg_err_t Vgm_Emu::gd3_data( const unsigned char ** data, int * size )
|
|||
*data = 0;
|
||||
*size = 0;
|
||||
|
||||
int gd3_offset = get_le32( header().gd3_offset );
|
||||
int gd3_offset = header().lngGD3Offset;
|
||||
if ( gd3_offset <= 0 )
|
||||
return blargg_ok;
|
||||
|
||||
byte const* gd3 = core.file_begin() + gd3_offset + offsetof( header_t, gd3_offset );
|
||||
int gd3_size = check_gd3_header( gd3, core.file_end() - gd3 );
|
||||
byte const* gd3 = core.file_begin() + gd3_offset;
|
||||
int gd3_size = check_gd3_header( gd3, (int)(core.file_end() - gd3) );
|
||||
if ( gd3_size )
|
||||
{
|
||||
*data = gd3;
|
||||
|
@ -163,149 +197,221 @@ blargg_err_t Vgm_Emu::gd3_data( const unsigned char ** data, int * size )
|
|||
|
||||
static void hash_vgm_file( Vgm_Emu::header_t const& h, byte const* data, int data_size, Music_Emu::Hash_Function& out )
|
||||
{
|
||||
out.hash_( &h.data_size[0], sizeof(h.data_size) );
|
||||
out.hash_( &h.version[0], sizeof(h.version) );
|
||||
out.hash_( &h.psg_rate[0], sizeof(h.psg_rate) );
|
||||
out.hash_( &h.ym2413_rate[0], sizeof(h.ym2413_rate) );
|
||||
out.hash_( &h.track_duration[0], sizeof(h.track_duration) );
|
||||
out.hash_( &h.loop_offset[0], sizeof(h.loop_offset) );
|
||||
out.hash_( &h.loop_duration[0], sizeof(h.loop_duration) );
|
||||
out.hash_( &h.frame_rate[0], sizeof(h.frame_rate) );
|
||||
out.hash_( &h.noise_feedback[0], sizeof(h.noise_feedback) );
|
||||
out.hash_( &h.noise_width, sizeof(h.noise_width) );
|
||||
out.hash_( &h.sn76489_flags, sizeof(h.sn76489_flags) );
|
||||
out.hash_( &h.ym2612_rate[0], sizeof(h.ym2612_rate) );
|
||||
out.hash_( &h.ym2151_rate[0], sizeof(h.ym2151_rate) );
|
||||
out.hash_( &h.data_offset[0], sizeof(h.data_offset) );
|
||||
out.hash_( &h.segapcm_rate[0], sizeof(h.segapcm_rate) );
|
||||
out.hash_( &h.segapcm_reg[0], sizeof(h.segapcm_reg) );
|
||||
out.hash_( &h.rf5c68_rate[0], sizeof(h.rf5c68_rate) );
|
||||
out.hash_( &h.ym2203_rate[0], sizeof(h.ym2203_rate) );
|
||||
out.hash_( &h.ym2608_rate[0], sizeof(h.ym2608_rate) );
|
||||
out.hash_( &h.ym2610_rate[0], sizeof(h.ym2610_rate) );
|
||||
out.hash_( &h.ym3812_rate[0], sizeof(h.ym3812_rate) );
|
||||
out.hash_( &h.ym3526_rate[0], sizeof(h.ym3526_rate) );
|
||||
out.hash_( &h.y8950_rate[0], sizeof(h.y8950_rate) );
|
||||
out.hash_( &h.ymf262_rate[0], sizeof(h.ymf262_rate) );
|
||||
out.hash_( &h.ymf278b_rate[0], sizeof(h.ymf278b_rate) );
|
||||
out.hash_( &h.ymf271_rate[0], sizeof(h.ymf271_rate) );
|
||||
out.hash_( &h.ymz280b_rate[0], sizeof(h.ymz280b_rate) );
|
||||
out.hash_( &h.rf5c164_rate[0], sizeof(h.rf5c164_rate) );
|
||||
out.hash_( &h.pwm_rate[0], sizeof(h.pwm_rate) );
|
||||
out.hash_( &h.ay8910_rate[0], sizeof(h.ay8910_rate) );
|
||||
out.hash_( &h.ay8910_type, sizeof(h.ay8910_type) );
|
||||
out.hash_( &h.ay8910_flags, sizeof(h.ay8910_flags) );
|
||||
out.hash_( &h.ym2203_ay8910_flags, sizeof(h.ym2203_ay8910_flags) );
|
||||
out.hash_( &h.ym2608_ay8910_flags, sizeof(h.ym2608_ay8910_flags) );
|
||||
out.hash_( &h.reserved, sizeof(h.reserved) );
|
||||
out.hash_( &h.gbdmg_rate[0], sizeof(h.gbdmg_rate) );
|
||||
out.hash_( &h.nesapu_rate[0], sizeof(h.nesapu_rate) );
|
||||
out.hash_( &h.multipcm_rate[0], sizeof(h.multipcm_rate) );
|
||||
out.hash_( &h.upd7759_rate[0], sizeof(h.upd7759_rate) );
|
||||
out.hash_( &h.okim6258_rate[0], sizeof(h.okim6258_rate) );
|
||||
out.hash_( &h.okim6258_flags, sizeof(h.okim6258_flags) );
|
||||
out.hash_( &h.k054539_flags, sizeof(h.k054539_flags) );
|
||||
out.hash_( &h.c140_type, sizeof(h.c140_type) );
|
||||
out.hash_( &h.reserved_flags, sizeof(h.reserved_flags) );
|
||||
out.hash_( &h.okim6295_rate[0], sizeof(h.okim6295_rate) );
|
||||
out.hash_( &h.k051649_rate[0], sizeof(h.k051649_rate) );
|
||||
out.hash_( &h.k054539_rate[0], sizeof(h.k054539_rate) );
|
||||
out.hash_( &h.huc6280_rate[0], sizeof(h.huc6280_rate) );
|
||||
out.hash_( &h.c140_rate[0], sizeof(h.c140_rate) );
|
||||
out.hash_( &h.k053260_rate[0], sizeof(h.k053260_rate) );
|
||||
out.hash_( &h.pokey_rate[0], sizeof(h.pokey_rate) );
|
||||
out.hash_( &h.qsound_rate[0], sizeof(h.qsound_rate) );
|
||||
out.hash_( &h.reserved2[0], sizeof(h.reserved2) );
|
||||
out.hash_( &h.extra_offset[0], sizeof(h.extra_offset) );
|
||||
out.hash_( (const byte *) &h.lngEOFOffset, sizeof(h.lngEOFOffset) );
|
||||
out.hash_( (const byte *) &h.lngVersion, sizeof(h.lngVersion) );
|
||||
out.hash_( (const byte *) &h.lngHzPSG, sizeof(h.lngHzPSG) );
|
||||
out.hash_( (const byte *) &h.lngHzYM2413, sizeof(h.lngHzYM2413) );
|
||||
out.hash_( (const byte *) &h.lngTotalSamples, sizeof(h.lngTotalSamples) );
|
||||
out.hash_( (const byte *) &h.lngLoopOffset, sizeof(h.lngLoopOffset) );
|
||||
out.hash_( (const byte *) &h.lngLoopSamples, sizeof(h.lngLoopSamples) );
|
||||
out.hash_( (const byte *) &h.lngRate, sizeof(h.lngRate) );
|
||||
out.hash_( (const byte *) &h.shtPSG_Feedback, sizeof(h.shtPSG_Feedback) );
|
||||
out.hash_( (const byte *) &h.bytPSG_SRWidth, sizeof(h.bytPSG_SRWidth) );
|
||||
out.hash_( (const byte *) &h.bytPSG_Flags, sizeof(h.bytPSG_Flags) );
|
||||
out.hash_( (const byte *) &h.lngHzYM2612, sizeof(h.lngHzYM2612) );
|
||||
out.hash_( (const byte *) &h.lngHzYM2151, sizeof(h.lngHzYM2151) );
|
||||
out.hash_( (const byte *) &h.lngDataOffset, sizeof(h.lngDataOffset) );
|
||||
out.hash_( (const byte *) &h.lngHzSPCM, sizeof(h.lngHzSPCM) );
|
||||
out.hash_( (const byte *) &h.lngSPCMIntf, sizeof(h.lngSPCMIntf) );
|
||||
out.hash_( (const byte *) &h.lngHzRF5C68, sizeof(h.lngHzRF5C68) );
|
||||
out.hash_( (const byte *) &h.lngHzYM2203, sizeof(h.lngHzYM2203) );
|
||||
out.hash_( (const byte *) &h.lngHzYM2608, sizeof(h.lngHzYM2608) );
|
||||
out.hash_( (const byte *) &h.lngHzYM2610, sizeof(h.lngHzYM2610) );
|
||||
out.hash_( (const byte *) &h.lngHzYM3812, sizeof(h.lngHzYM3812) );
|
||||
out.hash_( (const byte *) &h.lngHzYM3526, sizeof(h.lngHzYM3526) );
|
||||
out.hash_( (const byte *) &h.lngHzY8950, sizeof(h.lngHzY8950) );
|
||||
out.hash_( (const byte *) &h.lngHzYMF262, sizeof(h.lngHzYMF262) );
|
||||
out.hash_( (const byte *) &h.lngHzYMF278B, sizeof(h.lngHzYMF278B) );
|
||||
out.hash_( (const byte *) &h.lngHzYMF271, sizeof(h.lngHzYMF271) );
|
||||
out.hash_( (const byte *) &h.lngHzYMZ280B, sizeof(h.lngHzYMZ280B) );
|
||||
out.hash_( (const byte *) &h.lngHzRF5C164, sizeof(h.lngHzRF5C164) );
|
||||
out.hash_( (const byte *) &h.lngHzPWM, sizeof(h.lngHzPWM) );
|
||||
out.hash_( (const byte *) &h.lngHzAY8910, sizeof(h.lngHzAY8910) );
|
||||
out.hash_( (const byte *) &h.bytAYType, sizeof(h.bytAYType) );
|
||||
out.hash_( (const byte *) &h.bytAYFlag, sizeof(h.bytAYFlag) );
|
||||
out.hash_( (const byte *) &h.bytAYFlagYM2203, sizeof(h.bytAYFlagYM2203) );
|
||||
out.hash_( (const byte *) &h.bytAYFlagYM2608, sizeof(h.bytAYFlagYM2608) );
|
||||
out.hash_( (const byte *) &h.bytReserved2, sizeof(h.bytReserved2) );
|
||||
out.hash_( (const byte *) &h.lngHzGBDMG, sizeof(h.lngHzGBDMG) );
|
||||
out.hash_( (const byte *) &h.lngHzNESAPU, sizeof(h.lngHzNESAPU) );
|
||||
out.hash_( (const byte *) &h.lngHzMultiPCM, sizeof(h.lngHzMultiPCM) );
|
||||
out.hash_( (const byte *) &h.lngHzUPD7759, sizeof(h.lngHzUPD7759) );
|
||||
out.hash_( (const byte *) &h.lngHzOKIM6258, sizeof(h.lngHzOKIM6258) );
|
||||
out.hash_( (const byte *) &h.bytOKI6258Flags, sizeof(h.bytOKI6258Flags) );
|
||||
out.hash_( (const byte *) &h.bytK054539Flags, sizeof(h.bytK054539Flags) );
|
||||
out.hash_( (const byte *) &h.bytC140Type, sizeof(h.bytC140Type) );
|
||||
out.hash_( (const byte *) &h.bytReservedFlags, sizeof(h.bytReservedFlags) );
|
||||
out.hash_( (const byte *) &h.lngHzOKIM6295, sizeof(h.lngHzOKIM6295) );
|
||||
out.hash_( (const byte *) &h.lngHzK051649, sizeof(h.lngHzK051649) );
|
||||
out.hash_( (const byte *) &h.lngHzK054539, sizeof(h.lngHzK054539) );
|
||||
out.hash_( (const byte *) &h.lngHzHuC6280, sizeof(h.lngHzHuC6280) );
|
||||
out.hash_( (const byte *) &h.lngHzC140, sizeof(h.lngHzC140) );
|
||||
out.hash_( (const byte *) &h.lngHzK053260, sizeof(h.lngHzK053260) );
|
||||
out.hash_( (const byte *) &h.lngHzPokey, sizeof(h.lngHzPokey) );
|
||||
out.hash_( (const byte *) &h.lngHzQSound, sizeof(h.lngHzQSound) );
|
||||
out.hash_( (const byte *) &h.lngHzSCSP, sizeof(h.lngHzSCSP) );
|
||||
// out.hash_( (const byte *) &h.lngExtraOffset, sizeof(h.lngExtraOffset) );
|
||||
out.hash_( (const byte *) &h.lngHzWSwan, sizeof(h.lngHzWSwan) );
|
||||
out.hash_( (const byte *) &h.lngHzVSU, sizeof(h.lngHzVSU) );
|
||||
out.hash_( (const byte *) &h.lngHzSAA1099, sizeof(h.lngHzSAA1099) );
|
||||
out.hash_( (const byte *) &h.lngHzES5503, sizeof(h.lngHzES5503) );
|
||||
out.hash_( (const byte *) &h.lngHzES5506, sizeof(h.lngHzES5506) );
|
||||
out.hash_( (const byte *) &h.bytES5503Chns, sizeof(h.bytES5503Chns) );
|
||||
out.hash_( (const byte *) &h.bytES5506Chns, sizeof(h.bytES5506Chns) );
|
||||
out.hash_( (const byte *) &h.bytC352ClkDiv, sizeof(h.bytC352ClkDiv) );
|
||||
out.hash_( (const byte *) &h.bytESReserved, sizeof(h.bytESReserved) );
|
||||
out.hash_( (const byte *) &h.lngHzX1_010, sizeof(h.lngHzX1_010) );
|
||||
out.hash_( (const byte *) &h.lngHzC352, sizeof(h.lngHzC352) );
|
||||
out.hash_( (const byte *) &h.lngHzGA20, sizeof(h.lngHzGA20) );
|
||||
out.hash_( data, data_size );
|
||||
}
|
||||
|
||||
struct VGM_FILE_mem
|
||||
{
|
||||
VGM_FILE vf;
|
||||
const BOOST::uint8_t* buffer;
|
||||
UINT32 ptr;
|
||||
UINT32 size;
|
||||
};
|
||||
|
||||
static int VGMF_mem_Read(VGM_FILE* f, void* out, UINT32 count)
|
||||
{
|
||||
VGM_FILE_mem* mf = (VGM_FILE_mem *) f;
|
||||
if (count + mf->ptr > mf->size)
|
||||
count = mf->size - mf->ptr;
|
||||
memcpy(out, mf->buffer + mf->ptr, count);
|
||||
mf->ptr += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
static int VGMF_mem_Seek(VGM_FILE* f, UINT32 offset)
|
||||
{
|
||||
VGM_FILE_mem* mf = (VGM_FILE_mem *) f;
|
||||
if (offset > mf->size)
|
||||
offset = mf->size;
|
||||
mf->ptr = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static UINT32 VGMF_mem_GetSize(VGM_FILE* f)
|
||||
{
|
||||
VGM_FILE_mem* mf = (VGM_FILE_mem *) f;
|
||||
return mf->size;
|
||||
}
|
||||
|
||||
struct Vgm_File : Gme_Info_
|
||||
{
|
||||
Vgm_Emu::header_t h;
|
||||
blargg_vector<byte> original_header;
|
||||
blargg_vector<byte> data;
|
||||
blargg_vector<byte> gd3;
|
||||
|
||||
track_info_t metadata;
|
||||
track_info_t metadata_j;
|
||||
|
||||
Vgm_File() { set_type( gme_vgm_type ); }
|
||||
|
||||
blargg_err_t load_( Data_Reader& in )
|
||||
blargg_err_t load_mem_( const byte* in, int file_size )
|
||||
{
|
||||
int file_size = in.remain();
|
||||
if ( file_size <= h.size_min )
|
||||
VGM_FILE_mem memFile;
|
||||
|
||||
memFile.vf.Read = &VGMF_mem_Read;
|
||||
memFile.vf.Seek = &VGMF_mem_Seek;
|
||||
memFile.vf.GetSize = &VGMF_mem_GetSize;
|
||||
memFile.buffer = in;
|
||||
memFile.ptr = 0;
|
||||
memFile.size = file_size;
|
||||
|
||||
if (!GetVGMFileInfo_Handle((VGM_FILE *) &memFile, &h, 0))
|
||||
return blargg_err_file_type;
|
||||
|
||||
RETURN_ERR( in.read( &h, h.size_min ) );
|
||||
if ( !h.valid_tag() )
|
||||
return blargg_err_file_type;
|
||||
|
||||
if ( h.size() > h.size_min )
|
||||
RETURN_ERR( in.read( &h.rf5c68_rate, h.size() - h.size_min ) );
|
||||
|
||||
h.cleanup();
|
||||
|
||||
int data_offset = get_le32( h.data_offset ) + offsetof( Vgm_Core::header_t, data_offset );
|
||||
int data_size = file_size - offsetof( Vgm_Core::header_t, data_offset ) - data_offset;
|
||||
int gd3_offset = get_le32( h.gd3_offset );
|
||||
if ( gd3_offset > 0 )
|
||||
gd3_offset += offsetof( Vgm_Core::header_t, gd3_offset );
|
||||
|
||||
int amount_to_skip = gd3_offset - h.size();
|
||||
int data_offset = get_le32( &h.lngDataOffset );
|
||||
int data_size = file_size - data_offset;
|
||||
int gd3_offset = get_le32( &h.lngGD3Offset );
|
||||
|
||||
if ( gd3_offset > 0 && gd3_offset > data_offset )
|
||||
{
|
||||
data_size = gd3_offset - data_offset;
|
||||
amount_to_skip = 0;
|
||||
|
||||
RETURN_ERR( data.resize( data_size ) );
|
||||
RETURN_ERR( in.skip( data_offset - h.size() ) );
|
||||
RETURN_ERR( in.read( data.begin(), data_size ) );
|
||||
memcpy( data.begin(), in + data_offset, data_size );
|
||||
}
|
||||
|
||||
int remain = file_size - gd3_offset;
|
||||
byte gd3_h [gd3_header_size];
|
||||
if ( gd3_offset > 0 && remain >= gd3_header_size )
|
||||
{
|
||||
RETURN_ERR( in.skip( amount_to_skip ) );
|
||||
RETURN_ERR( in.read( gd3_h, sizeof gd3_h ) );
|
||||
memcpy( gd3_h, in + gd3_offset, sizeof gd3_h );
|
||||
int gd3_size = check_gd3_header( gd3_h, remain );
|
||||
if ( gd3_size )
|
||||
{
|
||||
RETURN_ERR( gd3.resize( gd3_size ) );
|
||||
RETURN_ERR( in.read( gd3.begin(), gd3.size() ) );
|
||||
memcpy( gd3.begin(), in + sizeof gd3_h + gd3_offset, gd3.size() );
|
||||
}
|
||||
|
||||
if ( data_offset > gd3_offset )
|
||||
{
|
||||
RETURN_ERR( data.resize( data_size ) );
|
||||
RETURN_ERR( in.skip( data_offset - gd3_offset - sizeof gd3_h - gd3.size() ) );
|
||||
RETURN_ERR( in.read( data.begin(), data.end() - data.begin() ) );
|
||||
memcpy( data.begin(), in + data_offset, data_size );
|
||||
}
|
||||
}
|
||||
|
||||
return blargg_ok;
|
||||
int header_size = data_offset;
|
||||
if ( gd3_offset && data_offset > gd3_offset )
|
||||
header_size = gd3_offset;
|
||||
RETURN_ERR( original_header.resize( header_size ) );
|
||||
memcpy( original_header.begin(), in, header_size );
|
||||
|
||||
memset( &metadata, 0, sizeof(metadata) );
|
||||
memset( &metadata_j, 0, sizeof(metadata_j) );
|
||||
get_vgm_length( h, &metadata );
|
||||
if ( gd3.size() )
|
||||
parse_gd3( gd3.begin(), gd3.end(), &metadata, &metadata_j );
|
||||
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t track_info_( track_info_t* out, int ) const
|
||||
{
|
||||
get_vgm_length( h, out );
|
||||
if ( gd3.size() )
|
||||
parse_gd3( gd3.begin(), gd3.end(), out );
|
||||
*out = metadata;
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t hash_( Hash_Function& out ) const
|
||||
{
|
||||
hash_vgm_file( h, data.begin(), data.end() - data.begin(), out );
|
||||
hash_vgm_file( h, data.begin(), (int)(data.end() - data.begin()), out );
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t set_track_info_( const track_info_t* in, int )
|
||||
{
|
||||
metadata = *in;
|
||||
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t save_( gme_writer_t writer, void* your_data ) const
|
||||
{
|
||||
byte buffer[4];
|
||||
int data_size = (int)(data.end() - data.begin());
|
||||
int gd3_offset = (int)(original_header.end() - original_header.begin()) + data_size;
|
||||
|
||||
RETURN_ERR( writer( your_data, original_header.begin(), 0x14 ) );
|
||||
set_le32(buffer, gd3_offset - 0x14);
|
||||
RETURN_ERR( writer( your_data, buffer, 4 ) );
|
||||
RETURN_ERR( writer( your_data, original_header.begin() + 0x18, original_header.end() - original_header.begin() - 0x18 ) );
|
||||
RETURN_ERR( writer( your_data, data.begin(), data_size ) );
|
||||
|
||||
return write_gd3( writer, your_data, &metadata, &metadata_j );
|
||||
}
|
||||
};
|
||||
|
||||
static Music_Emu* new_vgm_emu () { return BLARGG_NEW Vgm_Emu ; }
|
||||
static Music_Emu* new_vgm_file() { return BLARGG_NEW Vgm_File; }
|
||||
|
||||
gme_type_t_ const gme_vgm_type [1] = {{ "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGM", 1 }};
|
||||
gme_type_t_ const gme_vgm_type [1] = {{ "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGM", 0 }};
|
||||
|
||||
gme_type_t_ const gme_vgz_type [1] = {{ "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGZ", 1 }};
|
||||
gme_type_t_ const gme_vgz_type [1] = {{ "Sega SMS/Genesis", 1, &new_vgm_emu, &new_vgm_file, "VGZ", 0 }};
|
||||
|
||||
// Setup
|
||||
|
||||
|
@ -316,179 +422,23 @@ void Vgm_Emu::set_tempo_( double t )
|
|||
|
||||
blargg_err_t Vgm_Emu::set_sample_rate_( int sample_rate )
|
||||
{
|
||||
RETURN_ERR( core.stereo_buf[0].set_sample_rate( sample_rate, 1000 / 30 ) );
|
||||
RETURN_ERR( core.stereo_buf[1].set_sample_rate( sample_rate, 1000 / 30 ) );
|
||||
RETURN_ERR( core.stereo_buf[2].set_sample_rate( sample_rate, 1000 / 30 ) );
|
||||
RETURN_ERR( core.stereo_buf[3].set_sample_rate( sample_rate, 1000 / 30 ) );
|
||||
core.set_sample_rate(sample_rate);
|
||||
return Classic_Emu::set_sample_rate_( sample_rate );
|
||||
}
|
||||
|
||||
void Vgm_Emu::update_eq( blip_eq_t const& eq )
|
||||
{
|
||||
core.psg[0].treble_eq( eq );
|
||||
core.psg[1].treble_eq( eq );
|
||||
core.ay[0].treble_eq( eq );
|
||||
core.ay[1].treble_eq( eq );
|
||||
core.huc6280[0].treble_eq( eq );
|
||||
core.huc6280[1].treble_eq( eq );
|
||||
core.gbdmg[0].treble_eq( eq );
|
||||
core.gbdmg[1].treble_eq( eq );
|
||||
core.pcm.treble_eq( eq );
|
||||
}
|
||||
|
||||
void Vgm_Emu::set_voice( int i, Blip_Buffer* c, Blip_Buffer* l, Blip_Buffer* r )
|
||||
{
|
||||
if ( i < core.psg[0].osc_count )
|
||||
{
|
||||
core.psg[0].set_output( i, c, l, r );
|
||||
core.psg[1].set_output( i, c, l, r );
|
||||
}
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
void Vgm_Emu::mute_voices_( int mask )
|
||||
{
|
||||
muted_voices = mask;
|
||||
|
||||
Classic_Emu::mute_voices_( mask );
|
||||
|
||||
// TODO: what was this for?
|
||||
//core.pcm.output( &core.blip_buf );
|
||||
|
||||
// TODO: silence PCM if FM isn't used?
|
||||
if ( core.uses_fm() )
|
||||
{
|
||||
core.psg[0].set_output( ( mask & 0x80 ) ? 0 : core.stereo_buf[0].center() );
|
||||
core.psg[1].set_output( ( mask & 0x80 ) ? 0 : core.stereo_buf[0].center() );
|
||||
core.ay[0].set_output( ( mask & 0x80 ) ? 0 : core.stereo_buf[1].center() );
|
||||
core.ay[1].set_output( ( mask & 0x80 ) ? 0 : core.stereo_buf[1].center() );
|
||||
for ( unsigned i = 0, j = 1; i < core.huc6280[0].osc_count; i++, j <<= 1)
|
||||
{
|
||||
Blip_Buffer * center = ( mask & j ) ? 0 : core.stereo_buf[2].center();
|
||||
Blip_Buffer * left = ( mask & j ) ? 0 : core.stereo_buf[2].left();
|
||||
Blip_Buffer * right = ( mask & j ) ? 0 : core.stereo_buf[2].right();
|
||||
core.huc6280[0].set_output( i, center, left, right );
|
||||
core.huc6280[1].set_output( i, center, left, right );
|
||||
}
|
||||
for (unsigned i = 0, j = 1; i < core.gbdmg[0].osc_count; i++, j <<= 1)
|
||||
{
|
||||
Blip_Buffer * center = (mask & j) ? 0 : core.stereo_buf[3].center();
|
||||
Blip_Buffer * left = (mask & j) ? 0 : core.stereo_buf[3].left();
|
||||
Blip_Buffer * right = (mask & j) ? 0 : core.stereo_buf[3].right();
|
||||
core.gbdmg[0].set_output(i, center, left, right);
|
||||
core.gbdmg[1].set_output(i, center, left, right);
|
||||
}
|
||||
if (core.ym2612[0].enabled())
|
||||
{
|
||||
core.pcm.volume( (mask & 0x40) ? 0.0 : 0.1115 / 256 * fm_gain * gain() );
|
||||
core.ym2612[0].mute_voices( mask );
|
||||
if ( core.ym2612[1].enabled() )
|
||||
core.ym2612[1].mute_voices( mask );
|
||||
}
|
||||
|
||||
if ( core.ym2413[0].enabled() )
|
||||
{
|
||||
int m = mask & 0x3F;
|
||||
if ( mask & 0x20 )
|
||||
m |= 0x01E0; // channels 5-8
|
||||
if ( mask & 0x40 )
|
||||
m |= 0x3E00;
|
||||
core.ym2413[0].mute_voices( m );
|
||||
if ( core.ym2413[1].enabled() )
|
||||
core.ym2413[1].mute_voices( m );
|
||||
}
|
||||
|
||||
if ( core.ym2151[0].enabled() )
|
||||
{
|
||||
core.ym2151[0].mute_voices( mask );
|
||||
if ( core.ym2151[1].enabled() )
|
||||
core.ym2151[1].mute_voices( mask );
|
||||
}
|
||||
|
||||
if ( core.c140.enabled() )
|
||||
{
|
||||
int m = 0;
|
||||
int m_add = 7;
|
||||
for ( unsigned i = 0; i < 8; i++, m_add <<= 3 )
|
||||
{
|
||||
if ( mask & ( 1 << i ) ) m += m_add;
|
||||
}
|
||||
core.c140.mute_voices( m );
|
||||
}
|
||||
|
||||
if ( core.rf5c68.enabled() )
|
||||
{
|
||||
core.rf5c68.mute_voices( mask );
|
||||
}
|
||||
|
||||
if ( core.rf5c164.enabled() )
|
||||
{
|
||||
core.rf5c164.mute_voices( mask );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::load_mem_( byte const data [], int size )
|
||||
{
|
||||
RETURN_ERR( core.load_mem( data, size ) );
|
||||
|
||||
set_voice_count( core.psg[0].osc_count );
|
||||
|
||||
double fm_rate = 0.0;
|
||||
if ( !disable_oversampling_ )
|
||||
fm_rate = sample_rate() * oversample_factor;
|
||||
RETURN_ERR( core.init_chips( &fm_rate ) );
|
||||
|
||||
double psg_gain = ( ( core.header().psg_rate[3] & 0xC0 ) == 0x40 ) ? 0.5 : 1.0;
|
||||
|
||||
if ( core.uses_fm() )
|
||||
{
|
||||
set_voice_count( 8 );
|
||||
RETURN_ERR( resampler.setup( fm_rate / sample_rate(), rolloff, gain() ) );
|
||||
RETURN_ERR( resampler.reset( core.stereo_buf[0].length() * sample_rate() / 1000 ) );
|
||||
core.psg[0].volume( 0.135 * fm_gain * psg_gain * gain() );
|
||||
core.psg[1].volume( 0.135 * fm_gain * psg_gain * gain() );
|
||||
core.ay[0].volume( 0.135 * fm_gain * gain() );
|
||||
core.ay[1].volume( 0.135 * fm_gain * gain() );
|
||||
core.huc6280[0].volume( 0.135 * fm_gain * gain() );
|
||||
core.huc6280[1].volume( 0.135 * fm_gain * gain() );
|
||||
core.gbdmg[0].volume( 0.135 * fm_gain * gain() );
|
||||
core.gbdmg[1].volume( 0.135 * fm_gain * gain() );
|
||||
}
|
||||
else
|
||||
{
|
||||
core.psg[0].volume( psg_gain * gain() );
|
||||
core.psg[1].volume( psg_gain * gain() );
|
||||
}
|
||||
|
||||
static const char* const fm_names [] = {
|
||||
"FM 1", "FM 2", "FM 3", "FM 4", "FM 5", "FM 6", "PCM", "PSG"
|
||||
};
|
||||
static const char* const psg_names [] = { "Square 1", "Square 2", "Square 3", "Noise" };
|
||||
set_voice_names( core.uses_fm() ? fm_names : psg_names );
|
||||
|
||||
static int const types [8] = {
|
||||
wave_type+1, wave_type+2, wave_type+3, noise_type+1,
|
||||
0, 0, 0, 0
|
||||
};
|
||||
set_voice_types( types );
|
||||
|
||||
return Classic_Emu::setup_buffer( core.stereo_buf[0].center()->clock_rate() );
|
||||
}
|
||||
|
||||
// Emulation
|
||||
|
||||
blargg_err_t Vgm_Emu::start_track_( int track )
|
||||
{
|
||||
RETURN_ERR( Classic_Emu::start_track_( track ) );
|
||||
|
||||
core.start_track();
|
||||
|
||||
mute_voices_(muted_voices);
|
||||
|
||||
if ( core.uses_fm() )
|
||||
resampler.clear();
|
||||
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
|
@ -498,54 +448,86 @@ inline void Vgm_Emu::check_end()
|
|||
set_track_ended();
|
||||
}
|
||||
|
||||
inline void Vgm_Emu::check_warning()
|
||||
{
|
||||
const char* w = core.warning();
|
||||
if ( w )
|
||||
set_warning( w );
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::run_clocks( blip_time_t& time_io, int msec )
|
||||
{
|
||||
check_end();
|
||||
time_io = core.run_psg( msec );
|
||||
check_warning();
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
inline int Vgm_Emu::play_frame( blip_time_t blip_time, int sample_count, sample_t buf [] )
|
||||
{
|
||||
check_end();
|
||||
int result = core.play_frame( blip_time, sample_count, buf );
|
||||
check_warning();
|
||||
return result;
|
||||
}
|
||||
|
||||
int Vgm_Emu::play_frame_( void* p, blip_time_t a, int b, sample_t c [] )
|
||||
{
|
||||
return STATIC_CAST(Vgm_Emu*,p)->play_frame( a, b, c );
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::play_( int count, sample_t out [] )
|
||||
{
|
||||
if ( !core.uses_fm() )
|
||||
return Classic_Emu::play_( count, out );
|
||||
|
||||
Stereo_Buffer * secondaries[] = { &core.stereo_buf[1], &core.stereo_buf[2], &core.stereo_buf[3] };
|
||||
resampler.dual_play( count, out, core.stereo_buf[0], secondaries, 3 );
|
||||
return blargg_ok;
|
||||
core.play_(count, out);
|
||||
check_end();
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::hash_( Hash_Function& out ) const
|
||||
{
|
||||
byte const* p = file_begin() + header().size();
|
||||
byte const* p = file_begin();
|
||||
byte const* e = file_end();
|
||||
int data_offset = get_le32( header().data_offset );
|
||||
int data_offset = header().lngDataOffset;
|
||||
if ( data_offset )
|
||||
p += data_offset + offsetof( header_t, data_offset ) - header().size();
|
||||
int gd3_offset = get_le32( header().gd3_offset );
|
||||
if ( gd3_offset > 0 && gd3_offset + offsetof( header_t, gd3_offset ) > data_offset + offsetof( header_t, data_offset ) )
|
||||
e = file_begin() + gd3_offset + offsetof( header_t, gd3_offset );
|
||||
hash_vgm_file( header(), p, e - p, out );
|
||||
p += data_offset;
|
||||
int gd3_offset = header().lngGD3Offset;
|
||||
if ( gd3_offset > 0 && gd3_offset > data_offset )
|
||||
e = file_begin() + gd3_offset;
|
||||
hash_vgm_file( header(), p, (int)(e - p), out );
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::load_mem_( const byte* in, int file_size )
|
||||
{
|
||||
RETURN_ERR( core.load_mem(in, file_size) );
|
||||
|
||||
get_vgm_length( header(), &metadata );
|
||||
|
||||
int data_offset = header().lngDataOffset;
|
||||
int gd3_offset = header().lngGD3Offset;
|
||||
int data_size = file_size - data_offset;
|
||||
|
||||
if (gd3_offset > 0)
|
||||
{
|
||||
if (gd3_offset > data_offset)
|
||||
data_size = gd3_offset - data_offset;
|
||||
byte const* gd3 = core.file_begin() + gd3_offset;
|
||||
int gd3_size = check_gd3_header( gd3, (int)(core.file_end() - gd3) );
|
||||
if ( gd3_size )
|
||||
{
|
||||
byte const* gd3_data = gd3 + gd3_header_size;
|
||||
parse_gd3( gd3_data, gd3_data + gd3_size, &metadata, &metadata_j );
|
||||
}
|
||||
}
|
||||
|
||||
int header_size = data_offset;
|
||||
if ( gd3_offset && data_offset > gd3_offset )
|
||||
header_size = gd3_offset;
|
||||
RETURN_ERR( original_header.resize( header_size ) );
|
||||
memcpy( original_header.begin(), in, header_size );
|
||||
|
||||
RETURN_ERR( data.resize(data_size) );
|
||||
memcpy( data.begin(), in + data_offset, data_size );
|
||||
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::skip_( int count )
|
||||
{
|
||||
core.skip_(count);
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::set_track_info_( const track_info_t* in, int )
|
||||
{
|
||||
metadata = *in;
|
||||
|
||||
return blargg_ok;
|
||||
}
|
||||
|
||||
blargg_err_t Vgm_Emu::save_(gme_writer_t writer, void* your_data)
|
||||
{
|
||||
byte buffer[4];
|
||||
int data_size = (int)(data.end() - data.begin());
|
||||
int gd3_offset = (int)(original_header.end() - original_header.begin()) + data_size;
|
||||
|
||||
RETURN_ERR( writer( your_data, original_header.begin(), 0x14 ) );
|
||||
set_le32(buffer, gd3_offset - 0x14);
|
||||
RETURN_ERR( writer( your_data, buffer, 4 ) );
|
||||
RETURN_ERR( writer( your_data, original_header.begin() + 0x18, original_header.end() - original_header.begin() - 0x18 ) );
|
||||
RETURN_ERR( writer( your_data, data.begin(), data_size ) );
|
||||
|
||||
return write_gd3( writer, your_data, &metadata, &metadata_j );
|
||||
}
|
||||
|
|
|
@ -12,17 +12,9 @@
|
|||
Supports custom sound buffer and frequency equalization when VGM uses just the PSG. FM
|
||||
sound chips can be run at their proper rates, or slightly higher to reduce aliasing on
|
||||
high notes. A YM2413 is supported but not provided separately from the library. */
|
||||
class Vgm_Emu : public Classic_Emu {
|
||||
class Vgm_Emu : public Music_Emu {
|
||||
public:
|
||||
|
||||
// True if custom buffer and custom equalization are supported
|
||||
// TODO: move into Music_Emu and rename to something like supports_custom_buffer()
|
||||
bool is_classic_emu() const { return !core.uses_fm(); }
|
||||
|
||||
// Disables running FM chips at higher than normal rate. Will result in slightly
|
||||
// more aliasing of high notes.
|
||||
void disable_oversampling( bool disable = true ) { disable_oversampling_ = disable; }
|
||||
|
||||
// VGM file header (see Vgm_Core.h)
|
||||
typedef Vgm_Core::header_t header_t;
|
||||
|
||||
|
@ -43,27 +35,27 @@ public:
|
|||
|
||||
protected:
|
||||
blargg_err_t track_info_( track_info_t*, int track ) const;
|
||||
blargg_err_t set_track_info_( const track_info_t*, int track );
|
||||
blargg_err_t load_mem_( byte const [], int );
|
||||
blargg_err_t set_sample_rate_( int sample_rate );
|
||||
blargg_err_t start_track_( int );
|
||||
blargg_err_t play_( int count, sample_t []);
|
||||
blargg_err_t run_clocks( blip_time_t&, int );
|
||||
blargg_err_t skip_( int count );
|
||||
blargg_err_t save_( gme_writer_t, void* );
|
||||
virtual void set_tempo_( double );
|
||||
virtual void mute_voices_( int mask );
|
||||
virtual void set_voice( int, Blip_Buffer*, Blip_Buffer*, Blip_Buffer* );
|
||||
virtual void update_eq( blip_eq_t const& );
|
||||
virtual void unload();
|
||||
|
||||
private:
|
||||
bool disable_oversampling_;
|
||||
unsigned muted_voices;
|
||||
Dual_Resampler resampler;
|
||||
Vgm_Core core;
|
||||
|
||||
blargg_vector<byte> original_header;
|
||||
blargg_vector<byte> data;
|
||||
track_info_t metadata;
|
||||
track_info_t metadata_j;
|
||||
|
||||
void check_end();
|
||||
void check_warning();
|
||||
int play_frame( blip_time_t blip_time, int sample_count, sample_t buf [] );
|
||||
static int play_frame_( void*, blip_time_t, int, sample_t [] );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ym2151_Emu.h"
|
||||
#include "ym2151.h"
|
||||
|
||||
Ym2151_Emu::Ym2151_Emu() { PSG = 0; }
|
||||
|
||||
Ym2151_Emu::~Ym2151_Emu()
|
||||
{
|
||||
if ( PSG ) ym2151_shutdown( PSG );
|
||||
}
|
||||
|
||||
int Ym2151_Emu::set_rate( double sample_rate, double clock_rate )
|
||||
{
|
||||
if ( PSG )
|
||||
{
|
||||
ym2151_shutdown( PSG );
|
||||
PSG = 0;
|
||||
}
|
||||
|
||||
PSG = ym2151_init( clock_rate, sample_rate );
|
||||
if ( !PSG )
|
||||
return 1;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ym2151_Emu::reset()
|
||||
{
|
||||
ym2151_reset_chip( PSG );
|
||||
ym2151_set_mask( PSG, 0 );
|
||||
}
|
||||
|
||||
static stream_sample_t* DUMMYBUF[0x02] = {(stream_sample_t*)NULL, (stream_sample_t*)NULL};
|
||||
|
||||
void Ym2151_Emu::write( int addr, int data )
|
||||
{
|
||||
ym2151_update_one( PSG, DUMMYBUF, 0 );
|
||||
ym2151_write_reg( PSG, addr, data );
|
||||
}
|
||||
|
||||
void Ym2151_Emu::mute_voices( int mask )
|
||||
{
|
||||
ym2151_set_mask( PSG, mask );
|
||||
}
|
||||
|
||||
void Ym2151_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
SAMP bufL[ 1024 ];
|
||||
SAMP bufR[ 1024 ];
|
||||
SAMP * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
ym2151_update_one( PSG, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
// YM2151 FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef YM2151_EMU_H
|
||||
#define YM2151_EMU_H
|
||||
|
||||
class Ym2151_Emu {
|
||||
void* PSG;
|
||||
public:
|
||||
Ym2151_Emu();
|
||||
~Ym2151_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( double sample_rate, double clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 8 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,155 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ym2203_Emu.h"
|
||||
#include "fm.h"
|
||||
#include <string.h>
|
||||
|
||||
static void psg_set_clock(void *param, int clock)
|
||||
{
|
||||
Ym2203_Emu *info = (Ym2203_Emu *)param;
|
||||
info->psg_set_clock( clock );
|
||||
}
|
||||
|
||||
static void psg_write(void *param, int address, int data)
|
||||
{
|
||||
Ym2203_Emu *info = (Ym2203_Emu *)param;
|
||||
info->psg_write( address, data );
|
||||
}
|
||||
|
||||
static int psg_read(void *param)
|
||||
{
|
||||
Ym2203_Emu *info = (Ym2203_Emu *)param;
|
||||
return info->psg_read();
|
||||
}
|
||||
|
||||
static void psg_reset(void *param)
|
||||
{
|
||||
Ym2203_Emu *info = (Ym2203_Emu *)param;
|
||||
info->psg_reset();
|
||||
}
|
||||
|
||||
static const ssg_callbacks psgintf =
|
||||
{
|
||||
psg_set_clock,
|
||||
psg_write,
|
||||
psg_read,
|
||||
psg_reset
|
||||
};
|
||||
|
||||
Ym2203_Emu::Ym2203_Emu() { opn = 0; psg.set_type( Ay_Apu::Ym2203 ); }
|
||||
|
||||
Ym2203_Emu::~Ym2203_Emu()
|
||||
{
|
||||
if ( opn ) ym2203_shutdown( opn );
|
||||
}
|
||||
|
||||
int Ym2203_Emu::set_rate( int sample_rate, int clock_rate )
|
||||
{
|
||||
if ( opn )
|
||||
{
|
||||
ym2203_shutdown( opn );
|
||||
opn = 0;
|
||||
}
|
||||
|
||||
opn = ym2203_init( this, clock_rate, sample_rate, &psgintf );
|
||||
if ( !opn )
|
||||
return 1;
|
||||
|
||||
this->sample_rate = sample_rate;
|
||||
psg_clock = clock_rate * 2;
|
||||
|
||||
buffer.set_sample_rate( sample_rate );
|
||||
buffer.clock_rate( psg_clock );
|
||||
|
||||
psg.volume( 1.0 );
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ym2203_Emu::reset()
|
||||
{
|
||||
psg.reset();
|
||||
ym2203_reset_chip( opn );
|
||||
mute_voices( 0 );
|
||||
}
|
||||
|
||||
static stream_sample_t* DUMMYBUF[0x02] = {(stream_sample_t*)NULL, (stream_sample_t*)NULL};
|
||||
|
||||
void Ym2203_Emu::write( int addr, int data )
|
||||
{
|
||||
ym2203_update_one( opn, DUMMYBUF, 0 );
|
||||
ym2203_write( opn, 0, addr );
|
||||
ym2203_write( opn, 1, data );
|
||||
}
|
||||
|
||||
void Ym2203_Emu::mute_voices( int mask )
|
||||
{
|
||||
ym2203_set_mutemask( opn, mask );
|
||||
for ( unsigned i = 0, j = 1 << 3; i < 3; i++, j <<= 1)
|
||||
{
|
||||
Blip_Buffer * buf = ( mask & j ) ? NULL : &buffer;
|
||||
psg.set_output( i, buf );
|
||||
}
|
||||
}
|
||||
|
||||
void Ym2203_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
blip_sample_t buf[ 1024 ];
|
||||
FMSAMPLE bufL[ 1024 ];
|
||||
FMSAMPLE bufR[ 1024 ];
|
||||
FMSAMPLE * buffers[2] = { bufL, bufR };
|
||||
|
||||
blip_time_t psg_end_time = pair_count * psg_clock / sample_rate;
|
||||
psg.end_frame( psg_end_time );
|
||||
buffer.end_frame( psg_end_time );
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
ym2203_update_one( opn, buffers, todo );
|
||||
|
||||
int sample_count = buffer.read_samples( buf, todo );
|
||||
memset( buf + sample_count, 0, ( todo - sample_count ) * sizeof( blip_sample_t ) );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l, output_r;
|
||||
int output = buf [i];
|
||||
output_l = output + bufL [i];
|
||||
output_r = output + bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
||||
|
||||
void Ym2203_Emu::psg_set_clock( int clock )
|
||||
{
|
||||
psg_clock = clock * 2;
|
||||
buffer.clock_rate( psg_clock );
|
||||
}
|
||||
|
||||
void Ym2203_Emu::psg_write( int addr, int data )
|
||||
{
|
||||
if ( !(addr & 1) ) psg.write_addr( data );
|
||||
else psg.write_data( 0, data );
|
||||
}
|
||||
|
||||
int Ym2203_Emu::psg_read()
|
||||
{
|
||||
return psg.read();
|
||||
}
|
||||
|
||||
void Ym2203_Emu::psg_reset()
|
||||
{
|
||||
psg.reset();
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
// YM2203 FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef YM2203_EMU_H
|
||||
#define YM2203_EMU_H
|
||||
|
||||
#include "Ay_Apu.h"
|
||||
|
||||
class Ym2203_Emu {
|
||||
void* opn;
|
||||
Ay_Apu psg;
|
||||
Blip_Buffer buffer;
|
||||
unsigned sample_rate;
|
||||
unsigned psg_clock;
|
||||
public:
|
||||
Ym2203_Emu();
|
||||
~Ym2203_Emu();
|
||||
|
||||
// Sets output chip clock rate, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int sample_rate, int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 6 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
|
||||
// SSG interface
|
||||
inline void psg_set_clock( int clock );
|
||||
inline void psg_write( int addr, int data );
|
||||
inline int psg_read();
|
||||
inline void psg_reset();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,62 +1,64 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ym2413_Emu.h"
|
||||
#include "ym2413.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../vgmplay/chips/emu2413.h"
|
||||
}
|
||||
|
||||
Ym2413_Emu::Ym2413_Emu() { opll = 0; }
|
||||
|
||||
Ym2413_Emu::~Ym2413_Emu()
|
||||
{
|
||||
if ( opll ) ym2413_shutdown( opll );
|
||||
if ( opll ) OPLL_delete( (OPLL *) opll );
|
||||
}
|
||||
|
||||
int Ym2413_Emu::set_rate( int sample_rate, int clock_rate )
|
||||
{
|
||||
if ( opll )
|
||||
{
|
||||
ym2413_shutdown( opll );
|
||||
OPLL_delete( (OPLL *) opll );
|
||||
opll = 0;
|
||||
}
|
||||
|
||||
opll = ym2413_init( clock_rate, sample_rate, 0 );
|
||||
opll = OPLL_new( clock_rate, sample_rate );
|
||||
if ( !opll )
|
||||
return 1;
|
||||
|
||||
OPLL_SetChipMode( (OPLL *) opll, 0 );
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ym2413_Emu::reset()
|
||||
{
|
||||
ym2413_reset_chip( opll );
|
||||
ym2413_set_mask( opll, 0 );
|
||||
OPLL_reset( (OPLL *) opll );
|
||||
OPLL_SetMuteMask( (OPLL *) opll, 0 );
|
||||
}
|
||||
|
||||
static stream_sample_t* DUMMYBUF[0x02] = {(stream_sample_t*)NULL, (stream_sample_t*)NULL};
|
||||
|
||||
void Ym2413_Emu::write( int addr, int data )
|
||||
{
|
||||
ym2413_update_one( opll, DUMMYBUF, 0 );
|
||||
ym2413_write( opll, 0, addr );
|
||||
ym2413_write( opll, 1, data );
|
||||
OPLL_writeIO( (OPLL *) opll, 0, addr );
|
||||
OPLL_writeIO( (OPLL *) opll, 1, data );
|
||||
}
|
||||
|
||||
void Ym2413_Emu::mute_voices( int mask )
|
||||
{
|
||||
ym2413_set_mask( opll, mask );
|
||||
OPLL_SetMuteMask( (OPLL *) opll, mask );
|
||||
}
|
||||
|
||||
void Ym2413_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
SAMP bufMO[ 1024 ];
|
||||
SAMP bufRO[ 1024 ];
|
||||
SAMP * buffers[2] = { bufMO, bufRO };
|
||||
e_int32 bufMO[ 1024 ];
|
||||
e_int32 bufRO[ 1024 ];
|
||||
e_int32 * buffers[2] = { bufMO, bufRO };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
ym2413_update_one( opll, buffers, todo );
|
||||
OPLL_calc_stereo( (OPLL *) opll, buffers, todo, -1 );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#ifndef YM2413_EMU_H
|
||||
#define YM2413_EMU_H
|
||||
|
||||
struct OPLL;
|
||||
|
||||
class Ym2413_Emu {
|
||||
void* opll;
|
||||
public:
|
||||
|
|
|
@ -1,167 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ym2608_Emu.h"
|
||||
#include "fm.h"
|
||||
#include <string.h>
|
||||
|
||||
static void psg_set_clock(void *param, int clock)
|
||||
{
|
||||
Ym2608_Emu *info = (Ym2608_Emu *)param;
|
||||
info->psg_set_clock( clock );
|
||||
}
|
||||
|
||||
static void psg_write(void *param, int address, int data)
|
||||
{
|
||||
Ym2608_Emu *info = (Ym2608_Emu *)param;
|
||||
info->psg_write( address, data );
|
||||
}
|
||||
|
||||
static int psg_read(void *param)
|
||||
{
|
||||
Ym2608_Emu *info = (Ym2608_Emu *)param;
|
||||
return info->psg_read();
|
||||
}
|
||||
|
||||
static void psg_reset(void *param)
|
||||
{
|
||||
Ym2608_Emu *info = (Ym2608_Emu *)param;
|
||||
info->psg_reset();
|
||||
}
|
||||
|
||||
static const ssg_callbacks psgintf =
|
||||
{
|
||||
psg_set_clock,
|
||||
psg_write,
|
||||
psg_read,
|
||||
psg_reset
|
||||
};
|
||||
|
||||
Ym2608_Emu::Ym2608_Emu() { opn = 0; psg.set_type( Ay_Apu::Ym2608 ); }
|
||||
|
||||
Ym2608_Emu::~Ym2608_Emu()
|
||||
{
|
||||
if ( opn ) ym2608_shutdown( opn );
|
||||
}
|
||||
|
||||
int Ym2608_Emu::set_rate( int sample_rate, int clock_rate )
|
||||
{
|
||||
if ( opn )
|
||||
{
|
||||
ym2608_shutdown( opn );
|
||||
opn = 0;
|
||||
}
|
||||
|
||||
opn = ym2608_init( this, clock_rate, sample_rate, &psgintf );
|
||||
if ( !opn )
|
||||
return 1;
|
||||
|
||||
this->sample_rate = sample_rate;
|
||||
psg_clock = clock_rate * 2;
|
||||
|
||||
buffer.set_sample_rate( sample_rate );
|
||||
buffer.clock_rate( psg_clock );
|
||||
|
||||
psg.volume( 1.0 );
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ym2608_Emu::reset()
|
||||
{
|
||||
psg.reset();
|
||||
ym2608_reset_chip( opn );
|
||||
mute_voices( 0 );
|
||||
}
|
||||
|
||||
static stream_sample_t* DUMMYBUF[0x02] = {(stream_sample_t*)NULL, (stream_sample_t*)NULL};
|
||||
|
||||
void Ym2608_Emu::write0( int addr, int data )
|
||||
{
|
||||
ym2608_update_one( opn, DUMMYBUF, 0 );
|
||||
ym2608_write( opn, 0, addr );
|
||||
ym2608_write( opn, 1, data );
|
||||
}
|
||||
|
||||
void Ym2608_Emu::write1( int addr, int data )
|
||||
{
|
||||
ym2608_update_one( opn, DUMMYBUF, 0 );
|
||||
ym2608_write( opn, 2, addr );
|
||||
ym2608_write( opn, 3, data );
|
||||
}
|
||||
|
||||
void Ym2608_Emu::write_rom( int rom_id, int size, int start, int length, void * data )
|
||||
{
|
||||
ym2608_write_pcmrom( opn, rom_id, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void Ym2608_Emu::mute_voices( int mask )
|
||||
{
|
||||
ym2608_set_mutemask( opn, mask );
|
||||
for ( unsigned i = 0, j = 1 << 6; i < 3; i++, j <<= 1)
|
||||
{
|
||||
Blip_Buffer * buf = ( mask & j ) ? NULL : &buffer;
|
||||
psg.set_output( i, buf );
|
||||
}
|
||||
}
|
||||
|
||||
void Ym2608_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
blip_sample_t buf[ 1024 ];
|
||||
FMSAMPLE bufL[ 1024 ];
|
||||
FMSAMPLE bufR[ 1024 ];
|
||||
FMSAMPLE * buffers[2] = { bufL, bufR };
|
||||
|
||||
blip_time_t psg_end_time = pair_count * psg_clock / sample_rate;
|
||||
psg.end_frame( psg_end_time );
|
||||
buffer.end_frame( psg_end_time );
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
ym2608_update_one( opn, buffers, todo );
|
||||
|
||||
int sample_count = buffer.read_samples( buf, todo );
|
||||
memset( buf + sample_count, 0, ( todo - sample_count ) * sizeof( blip_sample_t ) );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l, output_r;
|
||||
int output = buf [i];
|
||||
output_l = output + bufL [i];
|
||||
output_r = output + bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
||||
|
||||
void Ym2608_Emu::psg_set_clock( int clock )
|
||||
{
|
||||
psg_clock = clock * 2;
|
||||
buffer.clock_rate( psg_clock );
|
||||
}
|
||||
|
||||
void Ym2608_Emu::psg_write( int addr, int data )
|
||||
{
|
||||
if ( !(addr & 1) ) psg.write_addr( data );
|
||||
else psg.write_data( 0, data );
|
||||
}
|
||||
|
||||
int Ym2608_Emu::psg_read()
|
||||
{
|
||||
return psg.read();
|
||||
}
|
||||
|
||||
void Ym2608_Emu::psg_reset()
|
||||
{
|
||||
psg.reset();
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
// YM2608 FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef YM2608_EMU_H
|
||||
#define YM2608_EMU_H
|
||||
|
||||
#include "Ay_Apu.h"
|
||||
|
||||
class Ym2608_Emu {
|
||||
void* opn;
|
||||
Ay_Apu psg;
|
||||
Blip_Buffer buffer;
|
||||
unsigned sample_rate;
|
||||
unsigned psg_clock;
|
||||
public:
|
||||
Ym2608_Emu();
|
||||
~Ym2608_Emu();
|
||||
|
||||
// Sets output chip clock rate, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int sample_rate, int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 9 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write0( int addr, int data );
|
||||
void write1( int addr, int data );
|
||||
|
||||
// Sets ROM type, scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int rom_id, int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
|
||||
// SSG interface
|
||||
inline void psg_set_clock( int clock );
|
||||
inline void psg_write( int addr, int data );
|
||||
inline int psg_read();
|
||||
inline void psg_reset();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,173 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ym2610b_Emu.h"
|
||||
#include "fm.h"
|
||||
#include <string.h>
|
||||
|
||||
static void psg_set_clock(void *param, int clock)
|
||||
{
|
||||
Ym2610b_Emu *info = (Ym2610b_Emu *)param;
|
||||
info->psg_set_clock( clock );
|
||||
}
|
||||
|
||||
static void psg_write(void *param, int address, int data)
|
||||
{
|
||||
Ym2610b_Emu *info = (Ym2610b_Emu *)param;
|
||||
info->psg_write( address, data );
|
||||
}
|
||||
|
||||
static int psg_read(void *param)
|
||||
{
|
||||
Ym2610b_Emu *info = (Ym2610b_Emu *)param;
|
||||
return info->psg_read();
|
||||
}
|
||||
|
||||
static void psg_reset(void *param)
|
||||
{
|
||||
Ym2610b_Emu *info = (Ym2610b_Emu *)param;
|
||||
info->psg_reset();
|
||||
}
|
||||
|
||||
static const ssg_callbacks psgintf =
|
||||
{
|
||||
psg_set_clock,
|
||||
psg_write,
|
||||
psg_read,
|
||||
psg_reset
|
||||
};
|
||||
|
||||
Ym2610b_Emu::Ym2610b_Emu() { opn = 0; }
|
||||
|
||||
Ym2610b_Emu::~Ym2610b_Emu()
|
||||
{
|
||||
if ( opn ) ym2610_shutdown( opn );
|
||||
}
|
||||
|
||||
int Ym2610b_Emu::set_rate( int sample_rate, int clock_rate, bool is_2610b )
|
||||
{
|
||||
if ( opn )
|
||||
{
|
||||
ym2610_shutdown( opn );
|
||||
opn = 0;
|
||||
}
|
||||
|
||||
psg.set_type( is_2610b ? Ay_Apu::Ym2610b : Ay_Apu::Ym2610 );
|
||||
|
||||
opn = ym2610_init( this, clock_rate, sample_rate, &psgintf );
|
||||
if ( !opn )
|
||||
return 1;
|
||||
|
||||
this->sample_rate = sample_rate;
|
||||
psg_clock = clock_rate * 2;
|
||||
this->is_2610b = is_2610b;
|
||||
|
||||
buffer.set_sample_rate( sample_rate );
|
||||
buffer.clock_rate( psg_clock );
|
||||
|
||||
psg.volume( 1.0 );
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::reset()
|
||||
{
|
||||
psg.reset();
|
||||
ym2610_reset_chip( opn );
|
||||
mute_voices( 0 );
|
||||
}
|
||||
|
||||
static stream_sample_t* DUMMYBUF[0x02] = {(stream_sample_t*)NULL, (stream_sample_t*)NULL};
|
||||
|
||||
void Ym2610b_Emu::write0( int addr, int data )
|
||||
{
|
||||
if ( is_2610b ) ym2610b_update_one( opn, DUMMYBUF, 0 );
|
||||
else ym2610_update_one( opn, DUMMYBUF, 0 );
|
||||
ym2610_write( opn, 0, addr );
|
||||
ym2610_write( opn, 1, data );
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::write1( int addr, int data )
|
||||
{
|
||||
if ( is_2610b ) ym2610b_update_one( opn, DUMMYBUF, 0 );
|
||||
else ym2610_update_one( opn, DUMMYBUF, 0 );
|
||||
ym2610_write( opn, 2, addr );
|
||||
ym2610_write( opn, 3, data );
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::write_rom( int rom_id, int size, int start, int length, void * data )
|
||||
{
|
||||
ym2610_write_pcmrom( opn, rom_id, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::mute_voices( int mask )
|
||||
{
|
||||
ym2610_set_mutemask( opn, mask );
|
||||
for ( unsigned i = 0, j = 1 << 6; i < 3; i++, j <<= 1)
|
||||
{
|
||||
Blip_Buffer * buf = ( mask & j ) ? NULL : &buffer;
|
||||
psg.set_output( i, buf );
|
||||
}
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
blip_sample_t buf[ 1024 ];
|
||||
FMSAMPLE bufL[ 1024 ];
|
||||
FMSAMPLE bufR[ 1024 ];
|
||||
FMSAMPLE * buffers[2] = { bufL, bufR };
|
||||
|
||||
blip_time_t psg_end_time = pair_count * psg_clock / sample_rate;
|
||||
psg.end_frame( psg_end_time );
|
||||
buffer.end_frame( psg_end_time );
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
if ( is_2610b ) ym2610b_update_one( opn, buffers, todo );
|
||||
else ym2610_update_one( opn, buffers, todo );
|
||||
|
||||
int sample_count = buffer.read_samples( buf, todo );
|
||||
memset( buf + sample_count, 0, ( todo - sample_count ) * sizeof( blip_sample_t ) );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l, output_r;
|
||||
int output = buf [i];
|
||||
output_l = output + bufL [i];
|
||||
output_r = output + bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::psg_set_clock( int clock )
|
||||
{
|
||||
psg_clock = clock * 2;
|
||||
buffer.clock_rate( psg_clock );
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::psg_write( int addr, int data )
|
||||
{
|
||||
if ( !(addr & 1) ) psg.write_addr( data );
|
||||
else psg.write_data( 0, data );
|
||||
}
|
||||
|
||||
int Ym2610b_Emu::psg_read()
|
||||
{
|
||||
return psg.read();
|
||||
}
|
||||
|
||||
void Ym2610b_Emu::psg_reset()
|
||||
{
|
||||
psg.reset();
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
// YM2610B FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef YM2610B_EMU_H
|
||||
#define YM2610B_EMU_H
|
||||
|
||||
#include "Ay_Apu.h"
|
||||
|
||||
class Ym2610b_Emu {
|
||||
void* opn;
|
||||
Ay_Apu psg;
|
||||
Blip_Buffer buffer;
|
||||
unsigned sample_rate;
|
||||
unsigned psg_clock;
|
||||
bool is_2610b;
|
||||
public:
|
||||
Ym2610b_Emu();
|
||||
~Ym2610b_Emu();
|
||||
|
||||
// Sets output chip clock rate, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int sample_rate, int clock_rate, bool is_2610b );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 9 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write0( int addr, int data );
|
||||
void write1( int addr, int data );
|
||||
|
||||
// Sets ROM type, scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int rom_id, int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
|
||||
// SSG interface
|
||||
inline void psg_set_clock( int clock );
|
||||
inline void psg_write( int addr, int data );
|
||||
inline int psg_read();
|
||||
inline void psg_reset();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||
#include "Ym2612_Emu.h"
|
||||
|
||||
#define YM2612_EMU_CPP
|
||||
#ifdef USE_GENS
|
||||
#include "Ym2612_Emu_Gens.cpp"
|
||||
#else
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
// Based on Gens 2.10 ym2612.c
|
||||
|
||||
#ifdef YM2612_EMU_CPP
|
||||
|
||||
#include "Ym2612_Emu.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
@ -1297,3 +1299,5 @@ void Ym2612_Impl::run( int pair_count, Ym2612_Emu::sample_t out [] )
|
|||
}
|
||||
|
||||
void Ym2612_Emu::run( int pair_count, sample_t out [] ) { impl->run( pair_count, out ); }
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#ifdef YM2612_EMU_CPP
|
||||
|
||||
#include "Ym2612_Emu.h"
|
||||
#include "fm.h"
|
||||
|
||||
extern "C" {
|
||||
#include "../vgmplay/chips/mamedef.h"
|
||||
#include "../vgmplay/chips/fm.h"
|
||||
}
|
||||
|
||||
#include "blargg_errors.h"
|
||||
|
||||
|
@ -13,6 +19,8 @@ Ym2612_Emu::~Ym2612_Emu()
|
|||
ym2612_shutdown( impl );
|
||||
}
|
||||
|
||||
static BOOST::uint8_t dummy = 0;
|
||||
|
||||
const char* Ym2612_Emu::set_rate( double sample_rate, double clock_rate )
|
||||
{
|
||||
if ( impl )
|
||||
|
@ -24,7 +32,7 @@ const char* Ym2612_Emu::set_rate( double sample_rate, double clock_rate )
|
|||
if ( !clock_rate )
|
||||
clock_rate = sample_rate * 144.;
|
||||
|
||||
impl = ym2612_init( (long) (clock_rate + 0.5), (long) (sample_rate + 0.5) );
|
||||
impl = ym2612_init( 0, (int) (clock_rate + 0.5), (int) (sample_rate + 0.5), 0, 0, &dummy, 0 );
|
||||
if ( !impl )
|
||||
return blargg_err_memory;
|
||||
|
||||
|
@ -85,3 +93,5 @@ void Ym2612_Emu::run( int pair_count, sample_t* out )
|
|||
pair_count -= todo;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ym3812_Emu.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "dbopl.h"
|
||||
|
||||
Ym3812_Emu::Ym3812_Emu() { opl = 0; }
|
||||
|
||||
Ym3812_Emu::~Ym3812_Emu()
|
||||
{
|
||||
delete opl;
|
||||
}
|
||||
|
||||
int Ym3812_Emu::set_rate( int sample_rate, int clock_rate )
|
||||
{
|
||||
delete opl;
|
||||
opl = 0;
|
||||
|
||||
opl = new DBOPL::Chip;
|
||||
if ( !opl )
|
||||
return 1;
|
||||
|
||||
this->sample_rate = sample_rate;
|
||||
this->clock_rate = clock_rate * 4;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ym3812_Emu::reset()
|
||||
{
|
||||
opl->Setup( clock_rate, sample_rate );
|
||||
}
|
||||
|
||||
void Ym3812_Emu::write( int addr, int data )
|
||||
{
|
||||
opl->WriteReg( addr, data );
|
||||
}
|
||||
|
||||
void Ym3812_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
Bit32s buf[ 1024 ];
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
opl->GenerateBlock2( todo, buf );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l, output_r;
|
||||
int output = buf [i];
|
||||
output_l = output + out [0];
|
||||
output_r = output + out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// YM3812 FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef YM3812_EMU_H
|
||||
#define YM3812_EMU_H
|
||||
|
||||
namespace DBOPL {
|
||||
struct Chip;
|
||||
}
|
||||
|
||||
class Ym3812_Emu {
|
||||
DBOPL::Chip * opl;
|
||||
unsigned sample_rate;
|
||||
unsigned clock_rate;
|
||||
public:
|
||||
Ym3812_Emu();
|
||||
~Ym3812_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int sample_rate, int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,93 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ymf262_Emu.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "dbopl.h"
|
||||
|
||||
Ymf262_Emu::Ymf262_Emu() { opl = 0; }
|
||||
|
||||
Ymf262_Emu::~Ymf262_Emu()
|
||||
{
|
||||
delete opl;
|
||||
}
|
||||
|
||||
int Ymf262_Emu::set_rate( int sample_rate, int clock_rate )
|
||||
{
|
||||
delete opl;
|
||||
opl = 0;
|
||||
|
||||
opl = new DBOPL::Chip;
|
||||
if ( !opl )
|
||||
return 1;
|
||||
|
||||
this->sample_rate = sample_rate;
|
||||
this->clock_rate = clock_rate;
|
||||
|
||||
reset();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Ymf262_Emu::reset()
|
||||
{
|
||||
opl->Setup( clock_rate, sample_rate );
|
||||
}
|
||||
|
||||
void Ymf262_Emu::write0( int addr, int data )
|
||||
{
|
||||
opl->WriteReg( addr, data );
|
||||
}
|
||||
|
||||
void Ymf262_Emu::write1( int addr, int data )
|
||||
{
|
||||
opl->WriteReg( 0x100 + addr, data );
|
||||
}
|
||||
|
||||
void Ymf262_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
Bit32s buf[ 2048 ];
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
|
||||
if ( opl->opl3Active )
|
||||
{
|
||||
opl->GenerateBlock3( todo, buf );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l, output_r;
|
||||
output_l = buf [i * 2];
|
||||
output_r = buf [i * 2 + 1];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
opl->GenerateBlock2( todo, buf );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l, output_r;
|
||||
int output = buf [i];
|
||||
output_l = output + out [0];
|
||||
output_r = output + out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// YMF262 FM sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef YMF262_EMU_H
|
||||
#define YMF262_EMU_H
|
||||
|
||||
namespace DBOPL {
|
||||
struct Chip;
|
||||
}
|
||||
|
||||
class Ymf262_Emu {
|
||||
DBOPL::Chip * opl;
|
||||
unsigned sample_rate;
|
||||
unsigned clock_rate;
|
||||
public:
|
||||
Ymf262_Emu();
|
||||
~Ymf262_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int sample_rate, int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Writes data to addr
|
||||
void write0( int addr, int data );
|
||||
void write1( int addr, int data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,78 +0,0 @@
|
|||
// Game_Music_Emu $vers. http://www.slack.net/~ant/
|
||||
|
||||
#include "Ymz280b_Emu.h"
|
||||
#include "ymz280b.h"
|
||||
|
||||
Ymz280b_Emu::Ymz280b_Emu() { chip = 0; }
|
||||
|
||||
Ymz280b_Emu::~Ymz280b_Emu()
|
||||
{
|
||||
if ( chip ) device_stop_ymz280b( chip );
|
||||
}
|
||||
|
||||
int Ymz280b_Emu::set_rate( int clock_rate )
|
||||
{
|
||||
if ( chip )
|
||||
{
|
||||
device_stop_ymz280b( chip );
|
||||
chip = 0;
|
||||
}
|
||||
|
||||
chip = device_start_ymz280b( clock_rate );
|
||||
if ( !chip )
|
||||
return 0;
|
||||
|
||||
reset();
|
||||
return clock_rate * 2 / 384;
|
||||
}
|
||||
|
||||
void Ymz280b_Emu::reset()
|
||||
{
|
||||
device_reset_ymz280b( chip );
|
||||
ymz280b_set_mute_mask( chip, 0 );
|
||||
}
|
||||
|
||||
void Ymz280b_Emu::write( int addr, int data )
|
||||
{
|
||||
ymz280b_w( chip, 0, addr );
|
||||
ymz280b_w( chip, 1, data );
|
||||
}
|
||||
|
||||
void Ymz280b_Emu::write_rom( int size, int start, int length, void * data )
|
||||
{
|
||||
ymz280b_write_rom( chip, size, start, length, (const UINT8 *) data );
|
||||
}
|
||||
|
||||
void Ymz280b_Emu::mute_voices( int mask )
|
||||
{
|
||||
ymz280b_set_mute_mask( chip, mask );
|
||||
}
|
||||
|
||||
void Ymz280b_Emu::run( int pair_count, sample_t* out )
|
||||
{
|
||||
stream_sample_t bufL[ 1024 ];
|
||||
stream_sample_t bufR[ 1024 ];
|
||||
stream_sample_t * buffers[2] = { bufL, bufR };
|
||||
|
||||
while (pair_count > 0)
|
||||
{
|
||||
int todo = pair_count;
|
||||
if (todo > 1024) todo = 1024;
|
||||
ymz280b_update( chip, buffers, todo );
|
||||
|
||||
for (int i = 0; i < todo; i++)
|
||||
{
|
||||
int output_l = bufL [i];
|
||||
int output_r = bufR [i];
|
||||
output_l += out [0];
|
||||
output_r += out [1];
|
||||
if ( (short)output_l != output_l ) output_l = 0x7FFF ^ ( output_l >> 31 );
|
||||
if ( (short)output_r != output_r ) output_r = 0x7FFF ^ ( output_r >> 31 );
|
||||
out [0] = output_l;
|
||||
out [1] = output_r;
|
||||
out += 2;
|
||||
}
|
||||
|
||||
pair_count -= todo;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
// YMZ280B sound chip emulator interface
|
||||
|
||||
// Game_Music_Emu $vers
|
||||
#ifndef YMZ280B_EMU_H
|
||||
#define YMZ280B_EMU_H
|
||||
|
||||
class Ymz280b_Emu {
|
||||
void* chip;
|
||||
public:
|
||||
Ymz280b_Emu();
|
||||
~Ymz280b_Emu();
|
||||
|
||||
// Sets output sample rate and chip clock rates, in Hz. Returns non-zero
|
||||
// if error.
|
||||
int set_rate( int clock_rate );
|
||||
|
||||
// Resets to power-up state
|
||||
void reset();
|
||||
|
||||
// Mutes voice n if bit n (1 << n) of mask is set
|
||||
enum { channel_count = 8 };
|
||||
void mute_voices( int mask );
|
||||
|
||||
// Writes data to addr
|
||||
void write( int addr, int data );
|
||||
|
||||
// Scales ROM size, then writes length bytes from data at start offset
|
||||
void write_rom( int size, int start, int length, void * data );
|
||||
|
||||
// Runs and writes pair_count*2 samples to output
|
||||
typedef short sample_t;
|
||||
enum { out_chan_count = 2 }; // stereo
|
||||
void run( int pair_count, sample_t* out );
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2009 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: adlib.h,v 1.4 2009/04/26 10:33:53 harekiet Exp $ */
|
||||
|
||||
#ifndef DOSBOX_ADLIB_H
|
||||
#define DOSBOX_ADLIB_H
|
||||
|
||||
/*#include "dosbox.h"
|
||||
#include "mixer.h"
|
||||
#include "inout.h"
|
||||
#include "mixer.h"
|
||||
#include "setup.h"
|
||||
#include "pic.h"
|
||||
#include "hardware.h"*/
|
||||
|
||||
|
||||
namespace Adlib {
|
||||
|
||||
struct Timer {
|
||||
double start;
|
||||
double delay;
|
||||
bool enabled, overflow, masked;
|
||||
Bit8u counter;
|
||||
Timer() {
|
||||
masked = false;
|
||||
overflow = false;
|
||||
enabled = false;
|
||||
counter = 0;
|
||||
delay = 0;
|
||||
}
|
||||
//Call update before making any further changes
|
||||
void Update( double time ) {
|
||||
if ( !enabled || !delay )
|
||||
return;
|
||||
double deltaStart = time - start;
|
||||
//Only set the overflow flag when not masked
|
||||
if ( deltaStart >= 0 && !masked ) {
|
||||
overflow = 1;
|
||||
}
|
||||
}
|
||||
//On a reset make sure the start is in sync with the next cycle
|
||||
void Reset(const double& time ) {
|
||||
overflow = false;
|
||||
if ( !delay || !enabled )
|
||||
return;
|
||||
double delta = (time - start);
|
||||
double rem = fmod( delta, delay );
|
||||
double next = delay - rem;
|
||||
start = time + next;
|
||||
}
|
||||
void Stop( ) {
|
||||
enabled = false;
|
||||
}
|
||||
void Start( const double& time, Bits scale ) {
|
||||
//Don't enable again
|
||||
if ( enabled ) {
|
||||
return;
|
||||
}
|
||||
enabled = true;
|
||||
delay = 0.001 * (256 - counter ) * scale;
|
||||
start = time + delay;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Chip {
|
||||
//Last selected register
|
||||
Timer timer[2];
|
||||
//Check for it being a write to the timer
|
||||
bool Write( Bit32u addr, Bit8u val );
|
||||
//Read the current timer state, will use current double
|
||||
Bit8u Read( );
|
||||
};
|
||||
|
||||
//The type of handler this is
|
||||
typedef enum {
|
||||
MODE_OPL2,
|
||||
MODE_DUALOPL2,
|
||||
MODE_OPL3
|
||||
} Mode;
|
||||
|
||||
/*class Handler {
|
||||
public:
|
||||
//Write an address to a chip, returns the address the chip sets
|
||||
virtual Bit32u WriteAddr( Bit32u port, Bit8u val ) = 0;
|
||||
//Write to a specific register in the chip
|
||||
virtual void WriteReg( Bit32u addr, Bit8u val ) = 0;
|
||||
//Generate a certain amount of samples
|
||||
virtual void Generate( MixerChannel* chan, Bitu samples ) = 0;
|
||||
//Initialize at a specific sample rate and mode
|
||||
virtual void Init( Bitu rate ) = 0;
|
||||
virtual ~Handler() {
|
||||
}
|
||||
};*/
|
||||
|
||||
//The cache for 2 chips or an opl3
|
||||
typedef Bit8u RegisterCache[512];
|
||||
|
||||
//Internal class used for dro capturing
|
||||
class Capture;
|
||||
|
||||
/*class Module: public Module_base {
|
||||
IO_ReadHandleObject ReadHandler[3];
|
||||
IO_WriteHandleObject WriteHandler[3];
|
||||
MixerObject mixerObject;
|
||||
|
||||
//Mode we're running in
|
||||
Mode mode;
|
||||
//Last selected address in the chip for the different modes
|
||||
union {
|
||||
Bit32u normal;
|
||||
Bit8u dual[2];
|
||||
} reg;
|
||||
void CacheWrite( Bit32u reg, Bit8u val );
|
||||
void DualWrite( Bit8u index, Bit8u reg, Bit8u val );
|
||||
public:
|
||||
static OPL_Mode oplmode;
|
||||
MixerChannel* mixerChan;
|
||||
Bit32u lastUsed; //Ticks when adlib was last used to turn of mixing after a few second
|
||||
|
||||
Handler* handler; //Handler that will generate the sound
|
||||
RegisterCache cache;
|
||||
Capture* capture;
|
||||
Chip chip[2];
|
||||
|
||||
//Handle port writes
|
||||
void PortWrite( Bitu port, Bitu val, Bitu iolen );
|
||||
Bitu PortRead( Bitu port, Bitu iolen );
|
||||
void Init( Mode m );
|
||||
|
||||
Module( Section* configuration);
|
||||
~Module();
|
||||
};*/
|
||||
|
||||
|
||||
} //Adlib namespace
|
||||
|
||||
#endif
|
|
@ -55,4 +55,270 @@ blargg_err_t blargg_vector_::resize_( size_t n, size_t elem_size )
|
|||
return blargg_ok;
|
||||
}
|
||||
|
||||
static const BOOST::uint8_t mask_tab[6]={0x80,0xE0,0xF0,0xF8,0xFC,0xFE};
|
||||
|
||||
static const BOOST::uint8_t val_tab[6]={0,0xC0,0xE0,0xF0,0xF8,0xFC};
|
||||
|
||||
size_t utf8_char_len_from_header( char p_c )
|
||||
{
|
||||
size_t cnt = 0;
|
||||
for(;;)
|
||||
{
|
||||
if ( ( p_c & mask_tab[cnt] ) == val_tab[cnt] ) break;
|
||||
if ( ++cnt >= 6 ) return 0;
|
||||
}
|
||||
|
||||
return cnt + 1;
|
||||
}
|
||||
|
||||
size_t utf8_decode_char( const char *p_utf8, unsigned & wide, size_t mmax )
|
||||
{
|
||||
const BOOST::uint8_t * utf8 = ( const BOOST::uint8_t* )p_utf8;
|
||||
|
||||
if ( mmax == 0 )
|
||||
{
|
||||
wide = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( utf8[0] < 0x80 )
|
||||
{
|
||||
wide = utf8[0];
|
||||
return utf8[0]>0 ? 1 : 0;
|
||||
}
|
||||
if ( mmax > 6 ) mmax = 6;
|
||||
wide = 0;
|
||||
|
||||
unsigned res=0;
|
||||
unsigned n;
|
||||
unsigned cnt=0;
|
||||
for(;;)
|
||||
{
|
||||
if ( ( *utf8 & mask_tab[cnt] ) == val_tab[cnt] ) break;
|
||||
if ( ++cnt >= mmax ) return 0;
|
||||
}
|
||||
cnt++;
|
||||
|
||||
if ( cnt==2 && !( *utf8 & 0x1E ) ) return 0;
|
||||
|
||||
if ( cnt == 1 )
|
||||
res = *utf8;
|
||||
else
|
||||
res = ( 0xFF >> ( cnt + 1 ) ) & *utf8;
|
||||
|
||||
for ( n = 1; n < cnt; n++ )
|
||||
{
|
||||
if ( ( utf8[n] & 0xC0 ) != 0x80 )
|
||||
return 0;
|
||||
if ( !res && n == 2 && !( ( utf8[n] & 0x7F ) >> ( 7 - cnt ) ) )
|
||||
return 0;
|
||||
|
||||
res = ( res << 6 ) | ( utf8[n] & 0x3F );
|
||||
}
|
||||
|
||||
wide = res;
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
size_t utf8_encode_char( unsigned wide, char * target )
|
||||
{
|
||||
size_t count;
|
||||
|
||||
if ( wide < 0x80 )
|
||||
count = 1;
|
||||
else if ( wide < 0x800 )
|
||||
count = 2;
|
||||
else if ( wide < 0x10000 )
|
||||
count = 3;
|
||||
else if ( wide < 0x200000 )
|
||||
count = 4;
|
||||
else if ( wide < 0x4000000 )
|
||||
count = 5;
|
||||
else if ( wide <= 0x7FFFFFFF )
|
||||
count = 6;
|
||||
else
|
||||
return 0;
|
||||
|
||||
if ( target == 0 )
|
||||
return count;
|
||||
|
||||
switch ( count )
|
||||
{
|
||||
case 6:
|
||||
target[5] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x4000000;
|
||||
case 5:
|
||||
target[4] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x200000;
|
||||
case 4:
|
||||
target[3] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x10000;
|
||||
case 3:
|
||||
target[2] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0x800;
|
||||
case 2:
|
||||
target[1] = 0x80 | ( wide & 0x3F );
|
||||
wide = wide >> 6;
|
||||
wide |= 0xC0;
|
||||
case 1:
|
||||
target[0] = wide;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t utf16_encode_char( unsigned cur_wchar, blargg_wchar_t * out )
|
||||
{
|
||||
if ( cur_wchar < 0x10000 )
|
||||
{
|
||||
if ( out ) *out = (blargg_wchar_t) cur_wchar; return 1;
|
||||
}
|
||||
else if ( cur_wchar < ( 1 << 20 ) )
|
||||
{
|
||||
unsigned c = cur_wchar - 0x10000;
|
||||
//MSDN:
|
||||
//The first (high) surrogate is a 16-bit code value in the range U+D800 to U+DBFF. The second (low) surrogate is a 16-bit code value in the range U+DC00 to U+DFFF. Using surrogates, Unicode can support over one million characters. For more details about surrogates, refer to The Unicode Standard, version 2.0.
|
||||
if ( out )
|
||||
{
|
||||
out[0] = ( blargg_wchar_t )( 0xD800 | ( 0x3FF & ( c >> 10 ) ) );
|
||||
out[1] = ( blargg_wchar_t )( 0xDC00 | ( 0x3FF & c ) ) ;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( out ) *out = '?'; return 1;
|
||||
}
|
||||
}
|
||||
|
||||
size_t utf16_decode_char( const blargg_wchar_t * p_source, unsigned * p_out, size_t p_source_length )
|
||||
{
|
||||
if ( p_source_length == 0 ) return 0;
|
||||
else if ( p_source_length == 1 )
|
||||
{
|
||||
*p_out = p_source[0];
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t retval = 0;
|
||||
unsigned decoded = p_source[0];
|
||||
if ( decoded != 0 )
|
||||
{
|
||||
retval = 1;
|
||||
if ( ( decoded & 0xFC00 ) == 0xD800 )
|
||||
{
|
||||
unsigned low = p_source[1];
|
||||
if ( ( low & 0xFC00 ) == 0xDC00 )
|
||||
{
|
||||
decoded = 0x10000 + ( ( ( decoded & 0x3FF ) << 10 ) | ( low & 0x3FF ) );
|
||||
retval = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
*p_out = decoded;
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
// Converts wide-character path to UTF-8. Free result with free(). Only supported on Windows.
|
||||
char* blargg_to_utf8( const blargg_wchar_t* wpath )
|
||||
{
|
||||
if ( wpath == NULL )
|
||||
return NULL;
|
||||
|
||||
size_t needed = 0;
|
||||
size_t mmax = blargg_wcslen( wpath );
|
||||
if ( mmax <= 0 )
|
||||
return NULL;
|
||||
|
||||
size_t ptr = 0;
|
||||
while ( ptr < mmax )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf16_decode_char( wpath + ptr, &wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
needed += utf8_encode_char( wide, 0 );
|
||||
}
|
||||
if ( needed <= 0 )
|
||||
return NULL;
|
||||
|
||||
char* path = (char*) calloc( needed + 1, 1 );
|
||||
if ( path == NULL )
|
||||
return NULL;
|
||||
|
||||
ptr = 0;
|
||||
size_t actual = 0;
|
||||
while ( ptr < mmax && actual < needed )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf16_decode_char( wpath + ptr, &wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
actual += utf8_encode_char( wide, path + actual );
|
||||
}
|
||||
|
||||
if ( actual == 0 )
|
||||
{
|
||||
free( path );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert( actual == needed );
|
||||
return path;
|
||||
}
|
||||
|
||||
// Converts UTF-8 path to wide-character. Free result with free() Only supported on Windows.
|
||||
blargg_wchar_t* blargg_to_wide( const char* path )
|
||||
{
|
||||
if ( path == NULL )
|
||||
return NULL;
|
||||
|
||||
size_t mmax = strlen( path );
|
||||
if ( mmax <= 0 )
|
||||
return NULL;
|
||||
|
||||
size_t needed = 0;
|
||||
size_t ptr = 0;
|
||||
while ( ptr < mmax )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf8_decode_char( path + ptr, wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
needed += utf16_encode_char( wide, 0 );
|
||||
}
|
||||
if ( needed <= 0 )
|
||||
return NULL;
|
||||
|
||||
blargg_wchar_t* wpath = (blargg_wchar_t*) calloc( needed + 1, sizeof *wpath );
|
||||
if ( wpath == NULL )
|
||||
return NULL;
|
||||
|
||||
ptr = 0;
|
||||
size_t actual = 0;
|
||||
while ( ptr < mmax && actual < needed )
|
||||
{
|
||||
unsigned wide = 0;
|
||||
size_t char_len = utf8_decode_char( path + ptr, wide, mmax - ptr );
|
||||
if ( !char_len ) break;
|
||||
ptr += char_len;
|
||||
actual += utf16_encode_char( wide, wpath + actual );
|
||||
}
|
||||
if ( actual == 0 )
|
||||
{
|
||||
free( wpath );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert( actual == needed );
|
||||
return wpath;
|
||||
}
|
||||
|
||||
BLARGG_NAMESPACE_END
|
||||
|
|
|
@ -219,6 +219,25 @@ BLARGG_DEPRECATED( typedef unsigned int blargg_ulong; )
|
|||
#define BOOST_STATIC_ASSERT BLARGG_STATIC_ASSERT
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef wchar_t blargg_wchar_t;
|
||||
#elif defined(HAVE_STDINT_H)
|
||||
#include <stdint.h>
|
||||
typedef uint16_t blargg_wchar_t;
|
||||
#else
|
||||
typedef unsigned short blargg_wchar_t;
|
||||
#endif
|
||||
|
||||
inline size_t blargg_wcslen( const blargg_wchar_t* str )
|
||||
{
|
||||
size_t length = 0;
|
||||
while ( *str++ ) length++;
|
||||
return length;
|
||||
}
|
||||
|
||||
char* blargg_to_utf8( const blargg_wchar_t* );
|
||||
blargg_wchar_t* blargg_to_wide( const char* );
|
||||
|
||||
BLARGG_NAMESPACE_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -130,6 +130,8 @@ BLARGG_DEF_MIN_MAX( int )
|
|||
BLARGG_DEF_MIN_MAX( unsigned )
|
||||
BLARGG_DEF_MIN_MAX( long )
|
||||
BLARGG_DEF_MIN_MAX( unsigned long )
|
||||
BLARGG_DEF_MIN_MAX( BOOST::int64_t )
|
||||
BLARGG_DEF_MIN_MAX( BOOST::uint64_t )
|
||||
BLARGG_DEF_MIN_MAX( float )
|
||||
BLARGG_DEF_MIN_MAX( double )
|
||||
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
/* C140.h */
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __OSDCOMM_H__
|
||||
#define __OSDCOMM_H__
|
||||
typedef unsigned char UINT8; /* unsigned 8bit */
|
||||
typedef unsigned short UINT16; /* unsigned 16bit */
|
||||
typedef unsigned int UINT32; /* unsigned 32bit */
|
||||
typedef signed char INT8; /* signed 8bit */
|
||||
typedef signed short INT16; /* signed 16bit */
|
||||
typedef signed int INT32; /* signed 32bit */
|
||||
|
||||
typedef INT32 stream_sample_t;
|
||||
typedef UINT32 offs_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void c140_update(void * chip, stream_sample_t **outputs, int samples);
|
||||
void * device_start_c140(int sample_rate, int clock, int banking_type);
|
||||
void device_stop_c140(void * chip);
|
||||
void device_reset_c140(void * chip);
|
||||
|
||||
//READ8_DEVICE_HANDLER( c140_r );
|
||||
//WRITE8_DEVICE_HANDLER( c140_w );
|
||||
UINT8 c140_r(void * chip, offs_t offset);
|
||||
void c140_w(void * chip, offs_t offset, UINT8 data);
|
||||
|
||||
//void c140_set_base(device_t *device, void *base);
|
||||
void c140_set_base(void *chip, void *base);
|
||||
|
||||
enum
|
||||
{
|
||||
C140_TYPE_SYSTEM2,
|
||||
C140_TYPE_SYSTEM21_A,
|
||||
C140_TYPE_SYSTEM21_B,
|
||||
C140_TYPE_ASIC219
|
||||
};
|
||||
|
||||
/*typedef struct _c140_interface c140_interface;
|
||||
struct _c140_interface {
|
||||
int banking_type;
|
||||
};*/
|
||||
|
||||
|
||||
void c140_write_rom(void * chip, offs_t ROMSize, offs_t DataStart, offs_t DataLength,
|
||||
const UINT8* ROMData);
|
||||
|
||||
void c140_set_mute_mask(void * chip, UINT32 MuteMask);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
//DECLARE_LEGACY_SOUND_DEVICE(C140, c140);
|
|
@ -1,44 +0,0 @@
|
|||
#ifndef _DAC_CONTROL_H_
|
||||
#define _DAC_CONTROL_H_
|
||||
|
||||
#ifndef __OSDCOMM_H__
|
||||
#define __OSDCOMM_H__
|
||||
typedef unsigned char UINT8; /* unsigned 8bit */
|
||||
typedef unsigned short UINT16; /* unsigned 16bit */
|
||||
typedef unsigned int UINT32; /* unsigned 32bit */
|
||||
typedef unsigned long long UINT64; /* unsigned 64bit */
|
||||
typedef signed char INT8; /* signed 8bit */
|
||||
typedef signed short INT16; /* signed 16bit */
|
||||
typedef signed int INT32; /* signed 32bit */
|
||||
typedef signed long long INT64; /* signed 64bit */
|
||||
|
||||
typedef INT32 stream_sample_t;
|
||||
typedef UINT32 offs_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void * device_start_daccontrol(UINT32 samplerate, void *context);
|
||||
void device_stop_daccontrol(void * chip);
|
||||
|
||||
void daccontrol_update(void * chip, UINT32 base_clock, UINT32 samples);
|
||||
void device_reset_daccontrol(void * chip);
|
||||
void daccontrol_setup_chip(void * chip, UINT8 ChType, UINT8 ChNum, UINT16 Command);
|
||||
void daccontrol_set_data(void *chip, const UINT8* Data, UINT32 DataLen, UINT8 StepSize, UINT8 StepBase);
|
||||
void daccontrol_set_frequency(void *chip, UINT32 Frequency);
|
||||
void daccontrol_start(void *chip, UINT32 DataPos, UINT8 LenMode, UINT32 Length);
|
||||
void daccontrol_stop(void *chip);
|
||||
|
||||
#define DCTRL_LMODE_IGNORE 0x00
|
||||
#define DCTRL_LMODE_CMDS 0x01
|
||||
#define DCTRL_LMODE_MSEC 0x02
|
||||
#define DCTRL_LMODE_TOEND 0x03
|
||||
#define DCTRL_LMODE_BYTES 0x0F
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -1,292 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2009 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
#define INLINE __forceinline
|
||||
#define DB_FASTCALL __fastcall
|
||||
#else
|
||||
#define INLINE inline
|
||||
#define DB_FASTCALL __attribute__((fastcall))
|
||||
#endif
|
||||
|
||||
typedef double Real64;
|
||||
/* The internal types */
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t Bit8u;
|
||||
typedef int8_t Bit8s;
|
||||
typedef uint16_t Bit16u;
|
||||
typedef int16_t Bit16s;
|
||||
typedef uint32_t Bit32u;
|
||||
typedef int32_t Bit32s;
|
||||
typedef uint64_t Bit64u;
|
||||
typedef int64_t Bit64s;
|
||||
#else
|
||||
typedef unsigned char Bit8u;
|
||||
typedef signed char Bit8s;
|
||||
typedef unsigned short Bit16u;
|
||||
typedef signed short Bit16s;
|
||||
typedef unsigned long Bit32u;
|
||||
typedef signed long Bit32s;
|
||||
typedef unsigned __int64 Bit64u;
|
||||
typedef signed __int64 Bit64s;
|
||||
#endif
|
||||
|
||||
typedef unsigned int Bitu;
|
||||
typedef signed int Bits;
|
||||
|
||||
#include "adlib.h"
|
||||
//#include "dosbox.h"
|
||||
|
||||
//Use 8 handlers based on a small logatirmic wavetabe and an exponential table for volume
|
||||
#define WAVE_HANDLER 10
|
||||
//Use a logarithmic wavetable with an exponential table for volume
|
||||
#define WAVE_TABLELOG 11
|
||||
//Use a linear wavetable with a multiply table for volume
|
||||
#define WAVE_TABLEMUL 12
|
||||
|
||||
//Select the type of wave generator routine
|
||||
#define DBOPL_WAVE WAVE_TABLEMUL
|
||||
|
||||
namespace DBOPL {
|
||||
|
||||
struct Chip;
|
||||
struct Operator;
|
||||
struct Channel;
|
||||
|
||||
#if (DBOPL_WAVE == WAVE_HANDLER)
|
||||
typedef Bits ( DB_FASTCALL *WaveHandler) ( Bitu i, Bitu volume );
|
||||
#endif
|
||||
|
||||
typedef Bits ( DBOPL::Operator::*VolumeHandler) ( );
|
||||
typedef Channel* ( DBOPL::Channel::*SynthHandler) ( Chip* chip, Bit32u samples, Bit32s* output );
|
||||
|
||||
//Different synth modes that can generate blocks of data
|
||||
typedef enum {
|
||||
sm2AM,
|
||||
sm2FM,
|
||||
sm3AM,
|
||||
sm3FM,
|
||||
sm4Start,
|
||||
sm3FMFM,
|
||||
sm3AMFM,
|
||||
sm3FMAM,
|
||||
sm3AMAM,
|
||||
sm6Start,
|
||||
sm2Percussion,
|
||||
sm3Percussion
|
||||
} SynthMode;
|
||||
|
||||
//Shifts for the values contained in chandata variable
|
||||
enum {
|
||||
SHIFT_KSLBASE = 16,
|
||||
SHIFT_KEYCODE = 24
|
||||
};
|
||||
|
||||
struct Operator {
|
||||
public:
|
||||
//Masks for operator 20 values
|
||||
enum {
|
||||
MASK_KSR = 0x10,
|
||||
MASK_SUSTAIN = 0x20,
|
||||
MASK_VIBRATO = 0x40,
|
||||
MASK_TREMOLO = 0x80
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
OFF,
|
||||
RELEASE,
|
||||
SUSTAIN,
|
||||
DECAY,
|
||||
ATTACK
|
||||
} State;
|
||||
|
||||
VolumeHandler volHandler;
|
||||
|
||||
#if (DBOPL_WAVE == WAVE_HANDLER)
|
||||
WaveHandler waveHandler; //Routine that generate a wave
|
||||
#else
|
||||
Bit16s* waveBase;
|
||||
Bit32u waveMask;
|
||||
Bit32u waveStart;
|
||||
#endif
|
||||
Bit32u waveIndex; //WAVE_BITS shifted counter of the frequency index
|
||||
Bit32u waveAdd; //The base frequency without vibrato
|
||||
Bit32u waveCurrent; //waveAdd + vibratao
|
||||
|
||||
Bit32u chanData; //Frequency/octave and derived data coming from whatever channel controls this
|
||||
Bit32u freqMul; //Scale channel frequency with this, TODO maybe remove?
|
||||
Bit32u vibrato; //Scaled up vibrato strength
|
||||
Bit32s sustainLevel; //When stopping at sustain level stop here
|
||||
Bit32s totalLevel; //totalLevel is added to every generated volume
|
||||
Bit32u currentLevel; //totalLevel + tremolo
|
||||
Bit32s volume; //The currently active volume
|
||||
|
||||
Bit32u attackAdd; //Timers for the different states of the envelope
|
||||
Bit32u decayAdd;
|
||||
Bit32u releaseAdd;
|
||||
Bit32u rateIndex; //Current position of the evenlope
|
||||
|
||||
Bit8u rateZero; //Bits for the different states of the envelope having no changes
|
||||
Bit8u keyOn; //Bitmask of different values that can generate keyon
|
||||
//Registers, also used to check for changes
|
||||
Bit8u reg20, reg40, reg60, reg80, regE0;
|
||||
//Active part of the envelope we're in
|
||||
Bit8u state;
|
||||
//0xff when tremolo is enabled
|
||||
Bit8u tremoloMask;
|
||||
//Strength of the vibrato
|
||||
Bit8u vibStrength;
|
||||
//Keep track of the calculated KSR so we can check for changes
|
||||
Bit8u ksr;
|
||||
private:
|
||||
void SetState( Bit8u s );
|
||||
void UpdateAttack( const Chip* chip );
|
||||
void UpdateRelease( const Chip* chip );
|
||||
void UpdateDecay( const Chip* chip );
|
||||
public:
|
||||
void UpdateAttenuation();
|
||||
void UpdateRates( const Chip* chip );
|
||||
void UpdateFrequency( );
|
||||
|
||||
void Write20( const Chip* chip, Bit8u val );
|
||||
void Write40( const Chip* chip, Bit8u val );
|
||||
void Write60( const Chip* chip, Bit8u val );
|
||||
void Write80( const Chip* chip, Bit8u val );
|
||||
void WriteE0( const Chip* chip, Bit8u val );
|
||||
|
||||
bool Silent() const;
|
||||
void Prepare( const Chip* chip );
|
||||
|
||||
void KeyOn( Bit8u mask);
|
||||
void KeyOff( Bit8u mask);
|
||||
|
||||
template< State state>
|
||||
Bits TemplateVolume( );
|
||||
|
||||
Bit32s RateForward( Bit32u add );
|
||||
Bitu ForwardWave();
|
||||
Bitu ForwardVolume();
|
||||
|
||||
Bits GetSample( Bits modulation );
|
||||
Bits GetWave( Bitu index, Bitu vol );
|
||||
public:
|
||||
Operator();
|
||||
};
|
||||
|
||||
struct Channel {
|
||||
Operator op[2];
|
||||
inline Operator* Op( Bitu index ) {
|
||||
return &( ( this + (index >> 1) )->op[ index & 1 ]);
|
||||
}
|
||||
SynthHandler synthHandler;
|
||||
Bit32u chanData; //Frequency/octave and derived values
|
||||
Bit32s old[2]; //Old data for feedback
|
||||
|
||||
Bit8u feedback; //Feedback shift
|
||||
Bit8u regB0; //Register values to check for changes
|
||||
Bit8u regC0;
|
||||
//This should correspond with reg104, bit 6 indicates a Percussion channel, bit 7 indicates a silent channel
|
||||
Bit8u fourMask;
|
||||
Bit8s maskLeft; //Sign extended values for both channel's panning
|
||||
Bit8s maskRight;
|
||||
|
||||
//Forward the channel data to the operators of the channel
|
||||
void SetChanData( const Chip* chip, Bit32u data );
|
||||
//Change in the chandata, check for new values and if we have to forward to operators
|
||||
void UpdateFrequency( const Chip* chip, Bit8u fourOp );
|
||||
void WriteA0( const Chip* chip, Bit8u val );
|
||||
void WriteB0( const Chip* chip, Bit8u val );
|
||||
void WriteC0( const Chip* chip, Bit8u val );
|
||||
void ResetC0( const Chip* chip );
|
||||
|
||||
//call this for the first channel
|
||||
template< bool opl3Mode >
|
||||
void GeneratePercussion( Chip* chip, Bit32s* output );
|
||||
|
||||
//Generate blocks of data in specific modes
|
||||
template<SynthMode mode>
|
||||
Channel* BlockTemplate( Chip* chip, Bit32u samples, Bit32s* output );
|
||||
Channel();
|
||||
};
|
||||
|
||||
struct Chip {
|
||||
//This is used as the base counter for vibrato and tremolo
|
||||
Bit32u lfoCounter;
|
||||
Bit32u lfoAdd;
|
||||
|
||||
|
||||
Bit32u noiseCounter;
|
||||
Bit32u noiseAdd;
|
||||
Bit32u noiseValue;
|
||||
|
||||
//Frequency scales for the different multiplications
|
||||
Bit32u freqMul[16];
|
||||
//Rates for decay and release for rate of this chip
|
||||
Bit32u linearRates[76];
|
||||
//Best match attack rates for the rate of this chip
|
||||
Bit32u attackRates[76];
|
||||
|
||||
//18 channels with 2 operators each
|
||||
Channel chan[18];
|
||||
|
||||
Bit8u reg104;
|
||||
Bit8u reg08;
|
||||
Bit8u reg04;
|
||||
Bit8u regBD;
|
||||
Bit8u vibratoIndex;
|
||||
Bit8u tremoloIndex;
|
||||
Bit8s vibratoSign;
|
||||
Bit8u vibratoShift;
|
||||
Bit8u tremoloValue;
|
||||
Bit8u vibratoStrength;
|
||||
Bit8u tremoloStrength;
|
||||
//Mask for allowed wave forms
|
||||
Bit8u waveFormMask;
|
||||
//0 or -1 when enabled
|
||||
Bit8s opl3Active;
|
||||
|
||||
//Return the maximum amount of samples before and LFO change
|
||||
Bit32u ForwardLFO( Bit32u samples );
|
||||
Bit32u ForwardNoise();
|
||||
|
||||
void WriteBD( Bit8u val );
|
||||
void WriteReg(Bit32u reg, Bit8u val );
|
||||
|
||||
Bit32u WriteAddr( Bit32u port, Bit8u val );
|
||||
|
||||
void GenerateBlock2( Bitu samples, Bit32s* output );
|
||||
void GenerateBlock3( Bitu samples, Bit32s* output );
|
||||
|
||||
void Setup( Bit32u c, Bit32u r );
|
||||
|
||||
Chip();
|
||||
};
|
||||
|
||||
/*struct Handler : public Adlib::Handler {
|
||||
DBOPL::Chip chip;
|
||||
virtual Bit32u WriteAddr( Bit32u port, Bit8u val );
|
||||
virtual void WriteReg( Bit32u addr, Bit8u val );
|
||||
virtual void Generate( MixerChannel* chan, Bitu samples );
|
||||
virtual void Init( Bitu rate );
|
||||
};*/
|
||||
|
||||
|
||||
} //Namespace
|
|
@ -1,18 +0,0 @@
|
|||
|
||||
static Uint32 DivFix(Uint32 p1, Uint32 p2, Uint32 fix)
|
||||
{
|
||||
Uint32 ret;
|
||||
ret = p1 / p2;
|
||||
p1 = p1 % p2;/* p1 = p1 - p2 * ret; */
|
||||
while (fix--)
|
||||
{
|
||||
p1 += p1;
|
||||
ret += ret;
|
||||
if (p1 >= p2)
|
||||
{
|
||||
p1 -= p2;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Configuration for emulation libraries
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __EMUCONFIG_H__
|
||||
#define __EMUCONFIG_H__
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// WIN32 native project definitions
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(WIN32) && !defined(__GNUC__)
|
||||
|
||||
#define EMU_CALL __fastcall
|
||||
#define EMU_CALL_ __cdecl
|
||||
#define EMU_INLINE __inline
|
||||
|
||||
#define uint8 unsigned char
|
||||
#define uint16 unsigned short
|
||||
#define uint32 unsigned int
|
||||
#define uint64 unsigned __int64
|
||||
#define sint8 signed char
|
||||
#define sint16 signed short
|
||||
#define sint32 signed int
|
||||
#define sint64 signed __int64
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LINUX / other platform definitions
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#else
|
||||
|
||||
//#if defined(__GNUC__) && defined(__i386__)
|
||||
//#define EMU_CALL __attribute__((__regparm__(2)))
|
||||
//#else
|
||||
#define EMU_CALL
|
||||
//#endif
|
||||
|
||||
#define EMU_CALL_
|
||||
#define EMU_INLINE __inline
|
||||
|
||||
#ifdef HAVE_STDINT_H
|
||||
#include <stdint.h>
|
||||
#define uint8 uint8_t
|
||||
#define uint16 uint16_t
|
||||
#define uint32 uint32_t
|
||||
#define uint64 uint64_t
|
||||
#define sint8 int8_t
|
||||
#define sint16 int16_t
|
||||
#define sint32 int32_t
|
||||
#define sint64 int64_t
|
||||
#else
|
||||
#define uint8 unsigned char
|
||||
#define uint16 unsigned short
|
||||
#define uint32 unsigned int
|
||||
#define uint64 unsigned long long
|
||||
#define sint8 signed char
|
||||
#define sint16 signed short
|
||||
#define sint32 signed int
|
||||
#define sint64 signed long long
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||
0x49, 0x4C, 0x4C, 0x32, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x33, 0x21, 0x09, 0x0E, 0x94, 0x90, 0x48, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x13, 0x41, 0x0F, 0x0D, 0xCE, 0xD3, 0x43, 0x13,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x12, 0x1B, 0x06, 0xFF, 0xD2, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x61, 0x1B, 0x07, 0xAF, 0x63, 0x20, 0x28,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x66, 0x21, 0x15, 0x00, 0x93, 0x94, 0x20, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x21, 0x61, 0x1C, 0x07, 0x82, 0x81, 0x10, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x23, 0x21, 0x20, 0x1F, 0xC0, 0x71, 0x07, 0x47,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x25, 0x31, 0x26, 0x05, 0x64, 0x41, 0x18, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x17, 0x21, 0x28, 0x07, 0xFF, 0x83, 0x02, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x97, 0x81, 0x25, 0x07, 0xCF, 0xC8, 0x02, 0x14,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x21, 0x21, 0x54, 0x0F, 0x80, 0x7F, 0x07, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x56, 0x03, 0xD3, 0xB2, 0x43, 0x58,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x31, 0x21, 0x0C, 0x03, 0x82, 0xC0, 0x40, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x21, 0x01, 0x0C, 0x03, 0xD4, 0xD3, 0x40, 0x84,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x21, 0x28, 0x00, 0xDF, 0xF8, 0xFF, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x23, 0x22, 0x00, 0x00, 0xA8, 0xF8, 0xF8, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x25, 0x18, 0x00, 0x00, 0xF8, 0xA9, 0xF8, 0x55,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
@ -1,38 +0,0 @@
|
|||
0x49, 0x4C, 0x4C, 0x32, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x61, 0x1E, 0x07, 0xF0, 0x7E, 0x07, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x13, 0x41, 0x0F, 0x1D, 0xCE, 0xD2, 0x43, 0x13,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x01, 0x99, 0x04, 0xFF, 0xC3, 0x03, 0x73,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x21, 0x61, 0x1B, 0x07, 0xAF, 0x63, 0x40, 0x28,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x31, 0x61, 0x1D, 0x07, 0x32, 0x81, 0x10, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x23, 0x21, 0x2D, 0x16, 0xC0, 0x70, 0x07, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x21, 0x1B, 0x06, 0x64, 0x65, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x61, 0x0C, 0x18, 0x85, 0xA0, 0x79, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x23, 0x21, 0x87, 0x11, 0xF0, 0xA4, 0x00, 0xF7,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x97, 0xE1, 0x28, 0x07, 0xFF, 0xF3, 0x02, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x10, 0x0C, 0x05, 0xF2, 0xC4, 0x40, 0xC8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x56, 0x03, 0xB4, 0xB2, 0x23, 0x58,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x41, 0x89, 0x03, 0xF1, 0xF4, 0xF0, 0x13,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x21, 0x28, 0x00, 0xDF, 0xF8, 0xFF, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0F, 0x02, 0x00, 0x00, 0xA7, 0xF7, 0x07, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x1F, 0x00, 0x00, 0xF8, 0xA9, 0x08, 0x05,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
@ -1,38 +0,0 @@
|
|||
0x49, 0x4C, 0x4C, 0x32, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x61, 0x1E, 0x07, 0xF0, 0x7E, 0x07, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x13, 0x41, 0x0F, 0x1D, 0xCE, 0xD2, 0x43, 0x13,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x01, 0x99, 0x04, 0xFF, 0xC3, 0x03, 0x73,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x21, 0x61, 0x1B, 0x07, 0xAF, 0x63, 0x40, 0x28,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x22, 0x21, 0x1E, 0x06, 0xF0, 0x76, 0x08, 0x28,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x31, 0x22, 0x16, 0x05, 0x90, 0x71, 0x00, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x31, 0x61, 0x1D, 0x07, 0x32, 0x81, 0x10, 0x17,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x23, 0x21, 0x2D, 0x16, 0xC0, 0x70, 0x07, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x21, 0x1B, 0x06, 0x64, 0x65, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x61, 0x0C, 0x18, 0x85, 0xA0, 0x79, 0x07,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x23, 0x21, 0x87, 0x11, 0xF0, 0xA4, 0x00, 0xF7,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x97, 0xE1, 0x28, 0x07, 0xFF, 0xF3, 0x02, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x10, 0x0C, 0x05, 0xF2, 0xC4, 0x40, 0xC8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x56, 0x03, 0xB4, 0xB2, 0x23, 0x58,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x61, 0x41, 0x89, 0x03, 0xF1, 0xF4, 0xF0, 0x13,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x21, 0x28, 0x00, 0xDF, 0xF8, 0xFF, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x21, 0x00, 0x00, 0xA8, 0xF8, 0xF8, 0xF8,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x25, 0x18, 0x00, 0x00, 0xF8, 0xA9, 0xF8, 0x55,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
@ -1,298 +0,0 @@
|
|||
/***************************************************************************
|
||||
|
||||
Konami 051649 - SCC1 sound as used in Haunted Castle, City Bomber
|
||||
|
||||
This file is pieced together by Bryan McPhail from a combination of
|
||||
Namco Sound, Amuse by Cab, Haunted Castle schematics and whoever first
|
||||
figured out SCC!
|
||||
|
||||
The 051649 is a 5 channel sound generator, each channel gets it's
|
||||
waveform from RAM (32 bytes per waveform, 8 bit signed data).
|
||||
|
||||
This sound chip is the same as the sound chip in some Konami
|
||||
megaROM cartridges for the MSX. It is actually well researched
|
||||
and documented:
|
||||
|
||||
http://www.msxnet.org/tech/scc
|
||||
|
||||
Thanks to Sean Young (sean@mess.org) for some bugfixes.
|
||||
|
||||
K052539 is equivalent to this chip except channel 5 does not share
|
||||
waveforms with channel 4.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "mamedef.h"
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
//#include "emu.h"
|
||||
//#include "streams.h"
|
||||
#include "k051649.h"
|
||||
|
||||
#define FREQBASEBITS 16
|
||||
|
||||
/* this structure defines the parameters for a channel */
|
||||
typedef struct
|
||||
{
|
||||
unsigned long counter;
|
||||
int frequency;
|
||||
int volume;
|
||||
int key;
|
||||
signed char waveform[32]; /* 19991207.CAB */
|
||||
UINT8 Muted;
|
||||
} k051649_sound_channel;
|
||||
|
||||
typedef struct _k051649_state k051649_state;
|
||||
struct _k051649_state
|
||||
{
|
||||
k051649_sound_channel channel_list[5];
|
||||
|
||||
/* global sound parameters */
|
||||
//sound_stream * stream;
|
||||
int mclock,rate;
|
||||
|
||||
/* mixer tables and internal buffers */
|
||||
INT16 *mixer_table;
|
||||
INT16 *mixer_lookup;
|
||||
short *mixer_buffer;
|
||||
|
||||
int f[10];
|
||||
int cur_reg;
|
||||
};
|
||||
|
||||
/*INLINE k051649_state *get_safe_token(running_device *device)
|
||||
{
|
||||
assert(device != NULL);
|
||||
assert(device->type() == K051649);
|
||||
return (k051649_state *)downcast<legacy_device_base *>(device)->token();
|
||||
}*/
|
||||
|
||||
/* build a table to divide by the number of voices */
|
||||
static void make_mixer_table(/*running_machine *machine,*/ k051649_state *info, int voices)
|
||||
{
|
||||
int count = voices * 256;
|
||||
int i;
|
||||
int gain = 8;
|
||||
|
||||
/* allocate memory */
|
||||
//info->mixer_table = auto_alloc_array(machine, INT16, 512 * voices);
|
||||
info->mixer_table = (INT16*)malloc(sizeof(INT16) * 512 * voices);
|
||||
|
||||
/* find the middle of the table */
|
||||
info->mixer_lookup = info->mixer_table + (256 * voices);
|
||||
|
||||
/* fill in the table - 16 bit case */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
int val = i * gain * 16 / voices;
|
||||
if (val > 32767) val = 32767;
|
||||
info->mixer_lookup[ i] = val;
|
||||
info->mixer_lookup[-i] = -val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* generate sound to the mix buffer */
|
||||
//static STREAM_UPDATE( k051649_update )
|
||||
void k051649_update(void *chip, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
k051649_sound_channel *voice=info->channel_list;
|
||||
stream_sample_t *buffer = outputs[0];
|
||||
stream_sample_t *buffer2 = outputs[1];
|
||||
short *mix;
|
||||
int i,v,f,j,k;
|
||||
|
||||
/* zap the contents of the mixer buffer */
|
||||
memset(info->mixer_buffer, 0, samples * sizeof(short));
|
||||
|
||||
for (j=0; j<5; j++) {
|
||||
v=voice[j].volume;
|
||||
f=voice[j].frequency;
|
||||
k=voice[j].key;
|
||||
/* SY 20040109: the SCC produces no sound for freq < 9 */
|
||||
if (v && f > 8 && k && ! voice[j].Muted)
|
||||
{
|
||||
const signed char *w = voice[j].waveform; /* 19991207.CAB */
|
||||
int c=voice[j].counter;
|
||||
|
||||
mix = info->mixer_buffer;
|
||||
|
||||
/* add our contribution */
|
||||
for (i = 0; i < samples; i++)
|
||||
{
|
||||
int offs;
|
||||
|
||||
/* Amuse source: Cab suggests this method gives greater resolution */
|
||||
/* Sean Young 20010417: the formula is really: f = clock/(16*(f+1))*/
|
||||
c+=(long)((((float)info->mclock / (float)((f+1) * 16))*(float)(1<<FREQBASEBITS)) / (float)(info->rate / 32));
|
||||
offs = (c >> 16) & 0x1f;
|
||||
*mix++ += (w[offs] * v)>>3;
|
||||
}
|
||||
|
||||
/* update the counter for this voice */
|
||||
voice[j].counter = c;
|
||||
}
|
||||
}
|
||||
|
||||
/* mix it down */
|
||||
mix = info->mixer_buffer;
|
||||
for (i = 0; i < samples; i++)
|
||||
*buffer++ = *buffer2++ = info->mixer_lookup[*mix++];
|
||||
}
|
||||
|
||||
//static DEVICE_START( k051649 )
|
||||
void * device_start_k051649(int clock)
|
||||
{
|
||||
//k051649_state *info = get_safe_token(device);
|
||||
k051649_state *info;
|
||||
UINT8 CurChn;
|
||||
|
||||
info = (k051649_state *) calloc(1, sizeof(k051649_state));
|
||||
/* get stream channels */
|
||||
//info->rate = device->clock()/16;
|
||||
info->rate = clock/16;
|
||||
//info->stream = stream_create(device, 0, 1, info->rate, info, k051649_update);
|
||||
//info->mclock = device->clock();
|
||||
info->mclock = clock;
|
||||
|
||||
/* allocate a buffer to mix into - 1 second's worth should be more than enough */
|
||||
//info->mixer_buffer = auto_alloc_array(device->machine, short, 2 * info->rate);
|
||||
info->mixer_buffer = (short*)malloc(sizeof(short) * info->rate);
|
||||
|
||||
/* build the mixer table */
|
||||
//make_mixer_table(device->machine, info, 5);
|
||||
make_mixer_table(info, 5);
|
||||
|
||||
for (CurChn = 0; CurChn < 5; CurChn ++)
|
||||
info->channel_list[CurChn].Muted = 0x00;
|
||||
|
||||
return info; //return info->rate;
|
||||
}
|
||||
|
||||
void device_stop_k051649(void *chip)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
|
||||
free(info->mixer_buffer);
|
||||
free(info->mixer_table);
|
||||
free(info);
|
||||
}
|
||||
|
||||
//static DEVICE_RESET( k051649 )
|
||||
void device_reset_k051649(void *chip)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
k051649_sound_channel *voice = info->channel_list;
|
||||
int i;
|
||||
|
||||
/* reset all the voices */
|
||||
for (i = 0; i < 5; i++) {
|
||||
voice[i].frequency = 0;
|
||||
voice[i].volume = 0;
|
||||
voice[i].counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************/
|
||||
|
||||
//WRITE8_DEVICE_HANDLER( k051649_waveform_w )
|
||||
void k051649_waveform_w(void *chip, offs_t offset, UINT8 data)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
//stream_update(info->stream);
|
||||
info->channel_list[offset>>5].waveform[offset&0x1f]=data;
|
||||
/* SY 20001114: Channel 5 shares the waveform with channel 4 */
|
||||
if (offset >= 0x60)
|
||||
info->channel_list[4].waveform[offset&0x1f]=data;
|
||||
}
|
||||
|
||||
//READ8_DEVICE_HANDLER ( k051649_waveform_r )
|
||||
UINT8 k051649_waveform_r(void *chip, offs_t offset)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
return info->channel_list[offset>>5].waveform[offset&0x1f];
|
||||
}
|
||||
|
||||
/* SY 20001114: Channel 5 doesn't share the waveform with channel 4 on this chip */
|
||||
//WRITE8_DEVICE_HANDLER( k052539_waveform_w )
|
||||
void k052539_waveform_w(void *chip, offs_t offset, UINT8 data)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
//stream_update(info->stream);
|
||||
info->channel_list[offset>>5].waveform[offset&0x1f]=data;
|
||||
}
|
||||
|
||||
//WRITE8_DEVICE_HANDLER( k051649_volume_w )
|
||||
void k051649_volume_w(void *chip, offs_t offset, UINT8 data)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
//stream_update(info->stream);
|
||||
info->channel_list[offset&0x7].volume=data&0xf;
|
||||
}
|
||||
|
||||
//WRITE8_DEVICE_HANDLER( k051649_frequency_w )
|
||||
void k051649_frequency_w(void *chip, offs_t offset, UINT8 data)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
info->f[offset]=data;
|
||||
|
||||
//stream_update(info->stream);
|
||||
info->channel_list[offset>>1].frequency=(info->f[offset&0xe] + (info->f[offset|1]<<8))&0xfff;
|
||||
}
|
||||
|
||||
//WRITE8_DEVICE_HANDLER( k051649_keyonoff_w )
|
||||
void k051649_keyonoff_w(void *chip, offs_t offset, UINT8 data)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
//stream_update(info->stream);
|
||||
info->channel_list[0].key=data&1;
|
||||
info->channel_list[1].key=data&2;
|
||||
info->channel_list[2].key=data&4;
|
||||
info->channel_list[3].key=data&8;
|
||||
info->channel_list[4].key=data&16;
|
||||
}
|
||||
|
||||
void k051649_w(void *chip, offs_t offset, UINT8 data)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
|
||||
switch(offset & 1)
|
||||
{
|
||||
case 0x00:
|
||||
info->cur_reg = data;
|
||||
break;
|
||||
case 0x01:
|
||||
switch(offset >> 1)
|
||||
{
|
||||
case 0x00:
|
||||
k051649_waveform_w(info, info->cur_reg, data);
|
||||
break;
|
||||
case 0x01:
|
||||
k051649_frequency_w(info, info->cur_reg, data);
|
||||
break;
|
||||
case 0x02:
|
||||
k051649_volume_w(info, info->cur_reg, data);
|
||||
break;
|
||||
case 0x03:
|
||||
k051649_keyonoff_w(info, info->cur_reg, data);
|
||||
break;
|
||||
case 0x04:
|
||||
k052539_waveform_w(info, info->cur_reg, data);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void k051649_set_mute_mask(void *chip, UINT32 MuteMask)
|
||||
{
|
||||
k051649_state *info = (k051649_state *) chip;
|
||||
UINT8 CurChn;
|
||||
|
||||
for (CurChn = 0; CurChn < 5; CurChn ++)
|
||||
info->channel_list[CurChn].Muted = (MuteMask >> CurChn) & 0x01;
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "mamedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//#ifndef __K051649_H__
|
||||
//#define __K051649_H__
|
||||
|
||||
//#include "devlegcy.h"
|
||||
|
||||
/*WRITE8_DEVICE_HANDLER( k051649_waveform_w );
|
||||
READ8_DEVICE_HANDLER( k051649_waveform_r );
|
||||
WRITE8_DEVICE_HANDLER( k051649_volume_w );
|
||||
WRITE8_DEVICE_HANDLER( k051649_frequency_w );
|
||||
WRITE8_DEVICE_HANDLER( k051649_keyonoff_w );
|
||||
|
||||
WRITE8_DEVICE_HANDLER( k052539_waveform_w );
|
||||
|
||||
DECLARE_LEGACY_SOUND_DEVICE(K051649, k051649);*/
|
||||
|
||||
void k051649_update(void *, stream_sample_t **outputs, int samples);
|
||||
void * device_start_k051649(int clock);
|
||||
void device_stop_k051649(void *);
|
||||
void device_reset_k051649(void *);
|
||||
|
||||
void k051649_waveform_w(void *, offs_t offset, UINT8 data);
|
||||
UINT8 k051649_waveform_r(void *, offs_t offset);
|
||||
void k051649_volume_w(void *, offs_t offset, UINT8 data);
|
||||
void k051649_frequency_w(void *, offs_t offset, UINT8 data);
|
||||
void k051649_keyonoff_w(void *, offs_t offset, UINT8 data);
|
||||
|
||||
void k052539_waveform_w(void *, offs_t offset, UINT8 data);
|
||||
|
||||
void k051649_w(void *, offs_t offset, UINT8 data);
|
||||
|
||||
void k051649_set_mute_mask(void *, UINT32 MuteMask);
|
||||
|
||||
//#endif /* __K051649_H__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
|
@ -1,31 +0,0 @@
|
|||
/* libnezp by Mamiya */
|
||||
|
||||
#ifndef KMSNDDEV_H__
|
||||
#define KMSNDDEV_H__
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "nestypes.h"
|
||||
|
||||
typedef struct KMIF_SOUND_DEVICE {
|
||||
void *ctx;
|
||||
void (*release)(void *ctx);
|
||||
void (*reset)(void *ctx, Uint32 clock, Uint32 freq);
|
||||
int (*synth)(void *ctx);
|
||||
void (*volume)(void *ctx, Int32 v);
|
||||
void (*write)(void *ctx, Uint32 a, Uint32 v);
|
||||
Uint32 (*read)(void *ctx, Uint32 a);
|
||||
void (*setinst)(void *ctx, Uint32 n, void *p, Uint32 l);
|
||||
#if 0
|
||||
void (*setrate)(void *ctx, Uint32 clock, Uint32 freq);
|
||||
void (*getinfo)(void *ctx, KMCH_INFO *cip, );
|
||||
void (*volume2)(void *ctx, Uint8 *volp, Uint32 numch);
|
||||
/* 0x00(mute),0x70(x1/2),0x80(x1),0x90(x2) */
|
||||
#endif
|
||||
} KMIF_SOUND_DEVICE;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* KMSNDDEV_H__ */
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef MATHDEFS_H
|
||||
#define MATHDEFS_H
|
||||
|
||||
|
||||
#ifndef _USE_MATH_DEFINES
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef NESTYPES_H__
|
||||
#define NESTYPES_H__
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define NEVER_REACH __assume(0);
|
||||
#define inline __inline
|
||||
#elif defined(__BORLANDC__)
|
||||
#define __fastcall __msfastcall
|
||||
#elif defined(__GNUC__)
|
||||
#define __inline __inline__
|
||||
#define __fastcall
|
||||
#else
|
||||
#define __inline
|
||||
#define __fastcall
|
||||
#endif
|
||||
#ifndef NEVER_REACH
|
||||
#define NEVER_REACH
|
||||
#endif
|
||||
|
||||
typedef int Int;
|
||||
typedef unsigned int Uint;
|
||||
typedef signed int Int32;
|
||||
typedef unsigned int Uint32;
|
||||
typedef signed short Int16;
|
||||
typedef unsigned short Uint16;
|
||||
typedef signed char Int8;
|
||||
typedef unsigned char Uint8;
|
||||
typedef char Char;
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define XSLEEP(n) ((void)0)
|
||||
#define XMALLOC(s) malloc(s)
|
||||
#define XREALLOC(p,s) realloc(p,s)
|
||||
#define XFREE(p) free(p)
|
||||
#define XMEMCPY(d,s,n) memcpy(d,s,n)
|
||||
#define XMEMSET(d,c,n) memset(d,c,n)
|
||||
|
||||
#endif /* NESTYPES_H__ */
|
|
@ -1,462 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// qmix - QSound mixer
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "qmix.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define ANTICLICK_TIME (64)
|
||||
#define ANTICLICK_THRESHHOLD (32)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define RENDERMAX (200)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static const sint32 gauss_shuffled_reverse_table[1024] = {
|
||||
366,1305, 374, 0, 362,1304, 378, 0, 358,1304, 381, 0, 354,1304, 385, 0, 351,1304, 389, 0, 347,1304, 393, 0, 343,1303, 397, 0, 339,1303, 401, 0,
|
||||
336,1303, 405, 0, 332,1302, 410, 0, 328,1302, 414, 0, 325,1301, 418, 0, 321,1300, 422, 0, 318,1300, 426, 0, 314,1299, 430, 0, 311,1298, 434, 0,
|
||||
307,1297, 439, 1, 304,1297, 443, 1, 300,1296, 447, 1, 297,1295, 451, 1, 293,1294, 456, 1, 290,1293, 460, 1, 286,1292, 464, 1, 283,1291, 469, 1,
|
||||
280,1290, 473, 1, 276,1288, 477, 1, 273,1287, 482, 1, 270,1286, 486, 2, 267,1284, 491, 2, 263,1283, 495, 2, 260,1282, 499, 2, 257,1280, 504, 2,
|
||||
254,1279, 508, 2, 251,1277, 513, 2, 248,1275, 517, 3, 245,1274, 522, 3, 242,1272, 527, 3, 239,1270, 531, 3, 236,1269, 536, 3, 233,1267, 540, 4,
|
||||
230,1265, 545, 4, 227,1263, 550, 4, 224,1261, 554, 4, 221,1259, 559, 4, 218,1257, 563, 5, 215,1255, 568, 5, 212,1253, 573, 5, 210,1251, 577, 5,
|
||||
207,1248, 582, 6, 204,1246, 587, 6, 201,1244, 592, 6, 199,1241, 596, 6, 196,1239, 601, 7, 193,1237, 606, 7, 191,1234, 611, 7, 188,1232, 615, 8,
|
||||
186,1229, 620, 8, 183,1227, 625, 8, 180,1224, 630, 9, 178,1221, 635, 9, 175,1219, 640, 9, 173,1216, 644, 10, 171,1213, 649, 10, 168,1210, 654, 10,
|
||||
166,1207, 659, 11, 163,1205, 664, 11, 161,1202, 669, 11, 159,1199, 674, 12, 156,1196, 678, 12, 154,1193, 683, 13, 152,1190, 688, 13, 150,1186, 693, 14,
|
||||
147,1183, 698, 14, 145,1180, 703, 15, 143,1177, 708, 15, 141,1174, 713, 15, 139,1170, 718, 16, 137,1167, 723, 16, 134,1164, 728, 17, 132,1160, 732, 17,
|
||||
130,1157, 737, 18, 128,1153, 742, 19, 126,1150, 747, 19, 124,1146, 752, 20, 122,1143, 757, 20, 120,1139, 762, 21, 118,1136, 767, 21, 117,1132, 772, 22,
|
||||
115,1128, 777, 23, 113,1125, 782, 23, 111,1121, 787, 24, 109,1117, 792, 24, 107,1113, 797, 25, 106,1109, 802, 26, 104,1106, 806, 27, 102,1102, 811, 27,
|
||||
100,1098, 816, 28, 99,1094, 821, 29, 97,1090, 826, 29, 95,1086, 831, 30, 94,1082, 836, 31, 92,1078, 841, 32, 90,1074, 846, 32, 89,1070, 851, 33,
|
||||
87,1066, 855, 34, 86,1061, 860, 35, 84,1057, 865, 36, 83,1053, 870, 36, 81,1049, 875, 37, 80,1045, 880, 38, 78,1040, 884, 39, 77,1036, 889, 40,
|
||||
76,1032, 894, 41, 74,1027, 899, 42, 73,1023, 904, 43, 71,1019, 908, 44, 70,1014, 913, 45, 69,1010, 918, 46, 67,1005, 923, 47, 66,1001, 927, 48,
|
||||
65, 997, 932, 49, 64, 992, 937, 50, 62, 988, 941, 51, 61, 983, 946, 52, 60, 978, 951, 53, 59, 974, 955, 54, 58, 969, 960, 55, 56, 965, 965, 56,
|
||||
55, 960, 969, 58, 54, 955, 974, 59, 53, 951, 978, 60, 52, 946, 983, 61, 51, 941, 988, 62, 50, 937, 992, 64, 49, 932, 997, 65, 48, 927,1001, 66,
|
||||
47, 923,1005, 67, 46, 918,1010, 69, 45, 913,1014, 70, 44, 908,1019, 71, 43, 904,1023, 73, 42, 899,1027, 74, 41, 894,1032, 76, 40, 889,1036, 77,
|
||||
39, 884,1040, 78, 38, 880,1045, 80, 37, 875,1049, 81, 36, 870,1053, 83, 36, 865,1057, 84, 35, 860,1061, 86, 34, 855,1066, 87, 33, 851,1070, 89,
|
||||
32, 846,1074, 90, 32, 841,1078, 92, 31, 836,1082, 94, 30, 831,1086, 95, 29, 826,1090, 97, 29, 821,1094, 99, 28, 816,1098, 100, 27, 811,1102, 102,
|
||||
27, 806,1106, 104, 26, 802,1109, 106, 25, 797,1113, 107, 24, 792,1117, 109, 24, 787,1121, 111, 23, 782,1125, 113, 23, 777,1128, 115, 22, 772,1132, 117,
|
||||
21, 767,1136, 118, 21, 762,1139, 120, 20, 757,1143, 122, 20, 752,1146, 124, 19, 747,1150, 126, 19, 742,1153, 128, 18, 737,1157, 130, 17, 732,1160, 132,
|
||||
17, 728,1164, 134, 16, 723,1167, 137, 16, 718,1170, 139, 15, 713,1174, 141, 15, 708,1177, 143, 15, 703,1180, 145, 14, 698,1183, 147, 14, 693,1186, 150,
|
||||
13, 688,1190, 152, 13, 683,1193, 154, 12, 678,1196, 156, 12, 674,1199, 159, 11, 669,1202, 161, 11, 664,1205, 163, 11, 659,1207, 166, 10, 654,1210, 168,
|
||||
10, 649,1213, 171, 10, 644,1216, 173, 9, 640,1219, 175, 9, 635,1221, 178, 9, 630,1224, 180, 8, 625,1227, 183, 8, 620,1229, 186, 8, 615,1232, 188,
|
||||
7, 611,1234, 191, 7, 606,1237, 193, 7, 601,1239, 196, 6, 596,1241, 199, 6, 592,1244, 201, 6, 587,1246, 204, 6, 582,1248, 207, 5, 577,1251, 210,
|
||||
5, 573,1253, 212, 5, 568,1255, 215, 5, 563,1257, 218, 4, 559,1259, 221, 4, 554,1261, 224, 4, 550,1263, 227, 4, 545,1265, 230, 4, 540,1267, 233,
|
||||
3, 536,1269, 236, 3, 531,1270, 239, 3, 527,1272, 242, 3, 522,1274, 245, 3, 517,1275, 248, 2, 513,1277, 251, 2, 508,1279, 254, 2, 504,1280, 257,
|
||||
2, 499,1282, 260, 2, 495,1283, 263, 2, 491,1284, 267, 2, 486,1286, 270, 1, 482,1287, 273, 1, 477,1288, 276, 1, 473,1290, 280, 1, 469,1291, 283,
|
||||
1, 464,1292, 286, 1, 460,1293, 290, 1, 456,1294, 293, 1, 451,1295, 297, 1, 447,1296, 300, 1, 443,1297, 304, 1, 439,1297, 307, 0, 434,1298, 311,
|
||||
0, 430,1299, 314, 0, 426,1300, 318, 0, 422,1300, 321, 0, 418,1301, 325, 0, 414,1302, 328, 0, 410,1302, 332, 0, 405,1303, 336, 0, 401,1303, 339,
|
||||
0, 397,1303, 343, 0, 393,1304, 347, 0, 389,1304, 351, 0, 385,1304, 354, 0, 381,1304, 358, 0, 378,1304, 362, 0, 374,1305, 366, 0, 370,1305, 370,
|
||||
};
|
||||
|
||||
static const sint32 pan_table[33] = {
|
||||
0, 724,1024,1254,1448,1619,1774,1916,
|
||||
2048,2172,2290,2401,2508,2611,2709,2804,
|
||||
2896,2985,3072,3156,3238,3318,3396,3473,
|
||||
3547,3620,3692,3762,3831,3899,3966,4031,
|
||||
4096};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Static information
|
||||
//
|
||||
sint32 EMU_CALL _qmix_init(void) { return 0; }
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// State information
|
||||
//
|
||||
#define QMIXSTATE ((struct QMIX_STATE*)(state))
|
||||
|
||||
struct QMIX_CHAN {
|
||||
uint32 on;
|
||||
uint32 startbank;
|
||||
uint32 startaddr;
|
||||
uint32 curbank;
|
||||
uint32 curaddr;
|
||||
uint32 startloop;
|
||||
uint32 startend;
|
||||
uint32 curloop;
|
||||
uint32 curend;
|
||||
uint32 phase;
|
||||
uint32 pitch;
|
||||
uint32 vol;
|
||||
uint32 pan;
|
||||
sint32 current_mix_l;
|
||||
sint32 current_mix_r;
|
||||
sint32 sample[4];
|
||||
sint32 sample_last_l;
|
||||
sint32 sample_last_r;
|
||||
sint32 sample_anticlick_l;
|
||||
sint32 sample_anticlick_r;
|
||||
sint32 sample_anticlick_remaining_l;
|
||||
sint32 sample_anticlick_remaining_r;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static EMU_INLINE void get_anticlicked_samples(
|
||||
struct QMIX_CHAN *chan, sint32 *l, sint32 *r
|
||||
) {
|
||||
sint32 out, remain;
|
||||
remain = chan->sample_anticlick_remaining_l;
|
||||
if(remain) {
|
||||
sint32 diff = chan->sample_last_l - chan->sample_anticlick_l;
|
||||
if(diff < 0) { diff = -diff; }
|
||||
if(diff < ANTICLICK_THRESHHOLD) {
|
||||
out = chan->sample_last_l;
|
||||
chan->sample_anticlick_remaining_l = 0;
|
||||
} else {
|
||||
out = (
|
||||
chan->sample_last_l * (ANTICLICK_TIME-remain) +
|
||||
chan->sample_anticlick_l * (remain)
|
||||
) / ANTICLICK_TIME;
|
||||
chan->sample_anticlick_remaining_l--;
|
||||
}
|
||||
} else {
|
||||
out = chan->sample_last_l;
|
||||
}
|
||||
*l = out;
|
||||
|
||||
remain = chan->sample_anticlick_remaining_r;
|
||||
if(remain) {
|
||||
sint32 diff = chan->sample_last_r - chan->sample_anticlick_r;
|
||||
if(diff < 0) { diff = -diff; }
|
||||
if(diff < ANTICLICK_THRESHHOLD) {
|
||||
out = chan->sample_last_r;
|
||||
chan->sample_anticlick_remaining_r = 0;
|
||||
} else {
|
||||
out = (
|
||||
chan->sample_last_r * (ANTICLICK_TIME-remain) +
|
||||
chan->sample_anticlick_r * (remain)
|
||||
) / ANTICLICK_TIME;
|
||||
chan->sample_anticlick_remaining_r--;
|
||||
}
|
||||
} else {
|
||||
out = chan->sample_last_r;
|
||||
}
|
||||
*r = out;
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static EMU_INLINE void anticlick(struct QMIX_CHAN *chan) {
|
||||
sint32 l, r;
|
||||
get_anticlicked_samples(chan, &l, &r);
|
||||
chan->sample_anticlick_l = l;
|
||||
chan->sample_anticlick_r = r;
|
||||
chan->sample_anticlick_remaining_l = ANTICLICK_TIME;
|
||||
chan->sample_anticlick_remaining_r = ANTICLICK_TIME;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct QMIX_STATE {
|
||||
uint8 *sample_rom;
|
||||
uint32 sample_rom_size;
|
||||
uint32 pitchscaler;
|
||||
struct QMIX_CHAN chan[16];
|
||||
sint32 last_in_l;
|
||||
sint32 last_in_r;
|
||||
sint32 last_out_l;
|
||||
sint32 last_out_r;
|
||||
sint32 acc_l;
|
||||
sint32 acc_r;
|
||||
};
|
||||
|
||||
uint32 EMU_CALL _qmix_get_state_size(void) {
|
||||
return sizeof(struct QMIX_STATE);
|
||||
}
|
||||
|
||||
void EMU_CALL _qmix_clear_state(void *state) {
|
||||
memset(state, 0, sizeof(struct QMIX_STATE));
|
||||
|
||||
|
||||
}
|
||||
|
||||
void EMU_CALL _qmix_set_sample_rom(void *state, void *rom, uint32 size) {
|
||||
QMIXSTATE->sample_rom = rom;
|
||||
QMIXSTATE->sample_rom_size = size;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static EMU_INLINE void chan_advance(
|
||||
struct QMIX_STATE *state,
|
||||
struct QMIX_CHAN *chan
|
||||
) {
|
||||
uint32 rom_addr = chan->curbank + chan->curaddr;
|
||||
if(rom_addr >= state->sample_rom_size) rom_addr = 0;
|
||||
chan->sample[0] = chan->sample[1];
|
||||
chan->sample[1] = chan->sample[2];
|
||||
chan->sample[2] = chan->sample[3];
|
||||
chan->sample[3] = (sint32)((sint8)(state->sample_rom[rom_addr]));
|
||||
chan->curaddr++;
|
||||
// FIXME: MAME thinks this is >=, but is it > ?
|
||||
if(chan->curaddr >= chan->curend) {
|
||||
// if(!chan->curloop) {
|
||||
// chan->on = 0;
|
||||
// chan->curaddr--;
|
||||
// } else {
|
||||
chan->curaddr = chan->curend - chan->curloop;
|
||||
// chan->curaddr -= 1 + chan->curloop;
|
||||
// }
|
||||
}
|
||||
chan->curaddr &= 0xFFFF;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static EMU_INLINE sint32 chan_get_resampled(
|
||||
struct QMIX_STATE *state,
|
||||
struct QMIX_CHAN *chan
|
||||
) {
|
||||
sint32 sum;
|
||||
sint32 phase = chan->phase & 0xFFF;
|
||||
|
||||
// sum = chan->sample[2];
|
||||
// sum <<= 8;
|
||||
|
||||
const sint32 *gauss = (sint32*)
|
||||
(((sint8*)gauss_shuffled_reverse_table) + (phase & 0x0FF0));
|
||||
sum = chan->sample[0] * gauss[0];
|
||||
sum += chan->sample[1] * gauss[1];
|
||||
sum += chan->sample[2] * gauss[2];
|
||||
sum += chan->sample[3] * gauss[3];
|
||||
sum /= 8;
|
||||
|
||||
// sum = chan->sample[1] * (0x1000-phase);
|
||||
// sum += chan->sample[2] * ( phase);
|
||||
// sum >>= 4;
|
||||
|
||||
chan->phase += chan->pitch;
|
||||
while(chan->phase >= 0x1000) {
|
||||
chan_advance(state, chan);
|
||||
chan->phase -= 0x1000;
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static EMU_INLINE void chan_get_stereo_anticlicked(
|
||||
struct QMIX_STATE *state,
|
||||
struct QMIX_CHAN *chan,
|
||||
sint32 *l,
|
||||
sint32 *r
|
||||
) {
|
||||
if(!chan->on) {
|
||||
chan->sample_last_l = 0;
|
||||
chan->sample_last_r = 0;
|
||||
} else {
|
||||
sint32 out = chan_get_resampled(state, chan);
|
||||
chan->sample_last_l = (out * chan->current_mix_l) / 0x8000;
|
||||
chan->sample_last_r = (out * chan->current_mix_r) / 0x8000;
|
||||
// if we suddenly keyed off, perform an anticlick here
|
||||
if(!chan->on) { anticlick(chan); }
|
||||
}
|
||||
get_anticlicked_samples(chan, l, r);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void recalc_mix(struct QMIX_CHAN *chan) {
|
||||
sint32 realpan = (chan->pan & 0x3F) - 0x10;
|
||||
sint32 realvol = chan->vol & 0xFFFF;
|
||||
if(realpan < 0x00) realpan = 0x00;
|
||||
if(realpan > 0x20) realpan = 0x20;
|
||||
|
||||
// chan->current_mix_l = realvol << 3;
|
||||
// chan->current_mix_r = realvol << 3;
|
||||
// if(realpan < 0x10) {
|
||||
// chan->current_mix_r *= realpan;
|
||||
// chan->current_mix_r >>= 4;
|
||||
// }
|
||||
// if(realpan > 0x10) {
|
||||
// chan->current_mix_l *= (0x20-realpan);
|
||||
// chan->current_mix_l >>= 4;
|
||||
// }
|
||||
|
||||
// chan->current_mix_l = ((0x20-realpan) * realvol) >> 1;
|
||||
// chan->current_mix_r = (( realpan) * realvol) >> 1;
|
||||
|
||||
chan->current_mix_l = (realvol * pan_table[0x20-realpan]) / 0x2000;
|
||||
chan->current_mix_r = (realvol * pan_table[ realpan]) / 0x2000;
|
||||
|
||||
// perform anticlick
|
||||
//anticlick(chan);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Command handling
|
||||
//
|
||||
//#include <stdio.h>
|
||||
|
||||
void EMU_CALL _qmix_command(void *state, uint8 cmd, uint16 data) {
|
||||
struct QMIX_CHAN *chan;
|
||||
uint32 ch = 0;
|
||||
uint32 reg = 99;
|
||||
//printf("qmix command 0x%02X:0x%04X\n",cmd,data);
|
||||
if(cmd < 0x80) {
|
||||
reg = cmd & 7;
|
||||
ch = cmd >> 3;
|
||||
} else if(cmd < 0x90) {
|
||||
reg = 8;
|
||||
ch = cmd - 0x80;
|
||||
} else if(cmd >= 0xBA && cmd < 0xCA) {
|
||||
reg = 9;
|
||||
ch = cmd - 0xBA;
|
||||
} else {
|
||||
reg = 99;
|
||||
ch = 0;
|
||||
}
|
||||
chan = QMIXSTATE->chan + ch;
|
||||
switch(reg) {
|
||||
case 0: // bank
|
||||
ch = (ch+1) & 0xF; chan = QMIXSTATE->chan + ch;
|
||||
//printf("qmix: bank ch%X = %04X\n",ch,data);
|
||||
chan->startbank = (((uint32)data) & 0x7F) << 16;
|
||||
break;
|
||||
case 1: // start
|
||||
//printf("qmix: start ch%X = %04X\n",ch,data);
|
||||
chan->startaddr = ((uint32)data) & 0xFFFF;
|
||||
break;
|
||||
case 2: // pitch
|
||||
//printf("qmix: pitch ch%X = %04X\n",ch,data);
|
||||
chan->pitch = (((uint32)(data & 0xFFFF)) * QMIXSTATE->pitchscaler) / 0x10000;
|
||||
if (chan->pitch == 0) {
|
||||
chan->on = 0;
|
||||
anticlick(chan);
|
||||
}
|
||||
break;
|
||||
case 3: // unknown
|
||||
break;
|
||||
case 4: // loop start
|
||||
//printf("qmix: loop ch%X = %04X\n",ch,data);
|
||||
chan->startloop = data;
|
||||
break;
|
||||
case 5: // end
|
||||
//printf("qmix: end ch%X = %04X\n",ch,data);
|
||||
chan->startend = data;
|
||||
break;
|
||||
case 6: // volume
|
||||
//printf("qmix: vol ch%X = %04X\n",ch,data);
|
||||
//printf("volume=%04X\n",data);
|
||||
// if(!data) {
|
||||
// chan->on = 0;
|
||||
// } else {
|
||||
// chan->on = 1;
|
||||
// chan->address = chan->start;
|
||||
// chan->phase = 0;
|
||||
// }
|
||||
//printf("qmix: unknown reg3 ch%X = %04X\n",ch,data);
|
||||
if(data == 0) {
|
||||
chan->on = 0;
|
||||
anticlick(chan);
|
||||
} else if (chan->on == 0) {
|
||||
chan->on = 1;
|
||||
chan->curbank = chan->startbank;
|
||||
chan->curaddr = chan->startaddr;
|
||||
chan->curloop = chan->startloop;
|
||||
chan->curend = chan->startend;
|
||||
chan->phase = 0;
|
||||
chan->sample[0] = 0;
|
||||
chan->sample[1] = 0;
|
||||
chan->sample[2] = 0;
|
||||
chan->sample[3] = 0;
|
||||
anticlick(chan);
|
||||
}
|
||||
|
||||
chan->vol = data;
|
||||
recalc_mix(chan);
|
||||
break;
|
||||
case 7: // unknown
|
||||
//printf("qmix: unknown reg7 ch%X = %04X\n",ch,data);
|
||||
break;
|
||||
case 8: // pan (0x110-0x130)
|
||||
//printf("qmix: pan ch%X = %04X\n",ch,data);
|
||||
//printf("pan=%04X\n",data);
|
||||
chan->pan = data;
|
||||
recalc_mix(chan);
|
||||
break;
|
||||
case 9: // ADSR?
|
||||
//printf("qmix: unknown reg9 ch%X = %04X\n",ch,data);
|
||||
break;
|
||||
default:
|
||||
//printf("qmix: unknown reg %02X = %04X\n",cmd,data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Rendering
|
||||
//
|
||||
static void render(
|
||||
struct QMIX_STATE *state,
|
||||
sint16 *buf,
|
||||
uint32 samples
|
||||
) {
|
||||
sint32 buf_l[RENDERMAX];
|
||||
sint32 buf_r[RENDERMAX];
|
||||
sint32 l, r;
|
||||
uint32 s;
|
||||
int ch;
|
||||
memset(buf_l, 0, 4 * samples);
|
||||
memset(buf_r, 0, 4 * samples);
|
||||
for(ch = 0; ch < 16; ch++) {
|
||||
struct QMIX_CHAN *chan = state->chan + ch;
|
||||
for(s = 0; s < samples; s++) {
|
||||
chan_get_stereo_anticlicked(state, chan, &l, &r);
|
||||
buf_l[s] += l;
|
||||
buf_r[s] += r;
|
||||
}
|
||||
}
|
||||
if(!buf) return;
|
||||
for(s = 0; s < samples; s++) {
|
||||
sint32 diff_l = buf_l[s] - state->last_in_l;
|
||||
sint32 diff_r = buf_r[s] - state->last_in_r;
|
||||
state->last_in_l = buf_l[s];
|
||||
state->last_in_r = buf_r[s];
|
||||
l = ((state->last_out_l * 255) / 256) + diff_l;
|
||||
r = ((state->last_out_r * 255) / 256) + diff_r;
|
||||
state->last_out_l = l;
|
||||
state->last_out_r = r;
|
||||
// l /= 2;
|
||||
// r /= 2;
|
||||
l *= 8;
|
||||
r *= 8;
|
||||
if(l > ( 32767)) l = ( 32767);
|
||||
if(l < (-32768)) l = (-32768);
|
||||
if(r > ( 32767)) r = ( 32767);
|
||||
if(r < (-32768)) r = (-32768);
|
||||
*buf++ = l;
|
||||
*buf++ = r;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EMU_CALL _qmix_render(void *state, sint16 *buf, uint32 samples) {
|
||||
//printf("qmix render %u samples\n",samples);
|
||||
for(; samples >= RENDERMAX; samples -= RENDERMAX) {
|
||||
render(QMIXSTATE, buf, RENDERMAX);
|
||||
if(buf) buf += 2 * RENDERMAX;
|
||||
}
|
||||
if(samples) {
|
||||
render(QMIXSTATE, buf, samples);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EMU_CALL _qmix_set_sample_rate(void *state, uint32 rate) {
|
||||
if(rate < 1) rate = 1;
|
||||
QMIXSTATE->pitchscaler = (65536 * 24000) / rate;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
|
@ -1,29 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// qmix - QSound mixer
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __Q_QMIX_H__
|
||||
#define __Q_QMIX_H__
|
||||
|
||||
#include "emuconfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
sint32 EMU_CALL _qmix_init(void);
|
||||
uint32 EMU_CALL _qmix_get_state_size(void);
|
||||
void EMU_CALL _qmix_clear_state(void *state);
|
||||
|
||||
void EMU_CALL _qmix_set_sample_rate(void *state, uint32 rate);
|
||||
void EMU_CALL _qmix_set_sample_rom(void *state, void *rom, uint32 size);
|
||||
void EMU_CALL _qmix_command(void *state, uint8 cmd, uint16 data);
|
||||
void EMU_CALL _qmix_render(void *state, sint16 *buf, uint32 samples);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,281 +0,0 @@
|
|||
#include "kmsnddev.h"
|
||||
#include "divfix.h"
|
||||
#include "s_logtbl.h"
|
||||
#include "s_deltat.h"
|
||||
#include <string.h>
|
||||
|
||||
#define CPS_SHIFT 16
|
||||
#define PHASE_SHIFT 16 /* 16(fix) */
|
||||
|
||||
typedef struct {
|
||||
KMIF_SOUND_DEVICE kmif;
|
||||
KMIF_LOGTABLE *logtbl;
|
||||
struct YMDELTATPCMSOUND_COMMON_TAG {
|
||||
Int32 mastervolume;
|
||||
Int32 step;
|
||||
Int32 output;
|
||||
Uint32 cnt;
|
||||
Uint32 cps;
|
||||
Uint32 phase;
|
||||
Uint32 deltan;
|
||||
Uint32 scale;
|
||||
Uint32 mem;
|
||||
Uint32 play;
|
||||
Uint32 start;
|
||||
Uint32 stop;
|
||||
Int32 level32;
|
||||
Uint8 key;
|
||||
Uint8 level;
|
||||
Uint8 granuality;
|
||||
Uint8 pad4_3;
|
||||
Uint8 regs[0x10];
|
||||
} common;
|
||||
Uint8 *romrambuf;
|
||||
Uint32 romrammask;
|
||||
Uint8 *rambuf;
|
||||
Uint32 rammask;
|
||||
Uint8 *rombuf;
|
||||
Uint32 rommask;
|
||||
Uint8 ymdeltatpcm_type;
|
||||
Uint8 memshift;
|
||||
} YMDELTATPCMSOUND;
|
||||
|
||||
static Uint8 const table_step[8] =
|
||||
{
|
||||
1, 3, 5, 7, 9, 11, 13, 15,
|
||||
};
|
||||
static Uint8 const table_scale[16] =
|
||||
{
|
||||
57, 57, 57, 57, 77, 102, 128, 153,
|
||||
57, 57, 57, 57, 77, 102, 128, 153,
|
||||
};
|
||||
|
||||
__inline static void writeram(YMDELTATPCMSOUND *sndp, Uint32 v)
|
||||
{
|
||||
sndp->rambuf[(sndp->common.mem >> 1) & sndp->rammask] = v;
|
||||
sndp->common.mem += 1 << 1;
|
||||
}
|
||||
|
||||
__inline static Uint32 readram(YMDELTATPCMSOUND *sndp)
|
||||
{
|
||||
Uint32 v;
|
||||
v = sndp->romrambuf[(sndp->common.play >> 1) & sndp->romrammask];
|
||||
if (sndp->common.play & 1)
|
||||
v &= 0x0F;
|
||||
else
|
||||
v >>= 4;
|
||||
sndp->common.play += 1;
|
||||
if (sndp->common.play >= sndp->common.stop)
|
||||
{
|
||||
if (sndp->common.regs[0] & 0x10)
|
||||
{
|
||||
sndp->common.play = sndp->common.start;
|
||||
sndp->common.step = 0;
|
||||
sndp->common.scale = 127;
|
||||
}
|
||||
else
|
||||
{
|
||||
sndp->common.key = 0;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
__inline static void DelrtatStep(YMDELTATPCMSOUND *sndp, Uint32 data)
|
||||
{
|
||||
if (data & 8)
|
||||
sndp->common.step -= (table_step[data & 7] * sndp->common.scale) >> 3;
|
||||
else
|
||||
sndp->common.step += (table_step[data & 7] * sndp->common.scale) >> 3;
|
||||
if (sndp->common.step > ((1 << 15) - 1)) sndp->common.step = ((1 << 15) - 1);
|
||||
if (sndp->common.step < -(1 << 15)) sndp->common.step = -(1 << 15);
|
||||
sndp->common.scale = (sndp->common.scale * table_scale[data]) >> 6;
|
||||
if (sndp->common.scale > 24576) sndp->common.scale = 24576;
|
||||
if (sndp->common.scale < 127) sndp->common.scale = 127;
|
||||
}
|
||||
|
||||
#if (((-1) >> 1) == -1)
|
||||
#define SSR(x, y) (((Int32)x) >> (y))
|
||||
#else
|
||||
#define SSR(x, y) (((x) >= 0) ? ((x) >> (y)) : (-((-(x) - 1) >> (y)) - 1))
|
||||
#endif
|
||||
|
||||
static int sndsynth(YMDELTATPCMSOUND *sndp )
|
||||
{
|
||||
if (!sndp->common.key)
|
||||
return 0;
|
||||
{
|
||||
Uint32 step;
|
||||
sndp->common.cnt += sndp->common.cps;
|
||||
step = sndp->common.cnt >> CPS_SHIFT;
|
||||
sndp->common.cnt &= (1 << CPS_SHIFT) - 1;
|
||||
sndp->common.phase += step * sndp->common.deltan;
|
||||
step = sndp->common.phase >> PHASE_SHIFT;
|
||||
sndp->common.phase &= (1 << PHASE_SHIFT) - 1;
|
||||
if (step)
|
||||
{
|
||||
do
|
||||
{
|
||||
DelrtatStep(sndp, readram(sndp));
|
||||
} while (--step);
|
||||
sndp->common.output = sndp->common.step * sndp->common.level32;
|
||||
sndp->common.output = SSR(sndp->common.output, 8 + 2);
|
||||
}
|
||||
}
|
||||
return sndp->common.output;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void sndwrite(YMDELTATPCMSOUND *sndp, Uint32 a, Uint32 v)
|
||||
{
|
||||
sndp->common.regs[a] = v;
|
||||
switch (a)
|
||||
{
|
||||
/* START,REC,MEMDATA,REPEAT,SPOFF,--,--,RESET */
|
||||
case 0x00: /* Control Register 1 */
|
||||
if ((v & 0x80) && !sndp->common.key)
|
||||
{
|
||||
sndp->common.key = 1;
|
||||
sndp->common.play = sndp->common.start;
|
||||
sndp->common.step = 0;
|
||||
sndp->common.scale = 127;
|
||||
}
|
||||
if (v & 1) sndp->common.key = 0;
|
||||
break;
|
||||
/* L,R,-,-,SAMPLE,DA/AD,RAMTYPE,ROM */
|
||||
case 0x01: /* Control Register 2 */
|
||||
sndp->romrambuf = (sndp->common.regs[1] & 1) ? sndp->rombuf : sndp->rambuf;
|
||||
sndp->romrammask = (sndp->common.regs[1] & 1) ? sndp->rommask : sndp->rammask;
|
||||
break;
|
||||
case 0x02: /* Start Address L */
|
||||
case 0x03: /* Start Address H */
|
||||
sndp->common.granuality = (v & 2) ? 1 : 4;
|
||||
sndp->common.start = ((sndp->common.regs[3] << 8) + sndp->common.regs[2]) << (sndp->memshift + 1);
|
||||
sndp->common.mem = sndp->common.start;
|
||||
break;
|
||||
case 0x04: /* Stop Address L */
|
||||
case 0x05: /* Stop Address H */
|
||||
sndp->common.stop = ((sndp->common.regs[5] << 8) + sndp->common.regs[4]) << (sndp->memshift + 1);
|
||||
break;
|
||||
case 0x06: /* Prescale L */
|
||||
case 0x07: /* Prescale H */
|
||||
break;
|
||||
case 0x08: /* Data */
|
||||
if ((sndp->common.regs[0] & 0x60) == 0x60) writeram(sndp, v);
|
||||
break;
|
||||
case 0x09: /* Delta-N L */
|
||||
case 0x0A: /* Delta-N H */
|
||||
sndp->common.deltan = (sndp->common.regs[0xA] << 8) + sndp->common.regs[0x9];
|
||||
if (sndp->common.deltan < 0x100) sndp->common.deltan = 0x100;
|
||||
break;
|
||||
case 0x0B: /* Level Control */
|
||||
sndp->common.level = v;
|
||||
sndp->common.level32 = ((Int32)(sndp->common.level * LogToLin(sndp->logtbl, sndp->common.mastervolume, LOG_LIN_BITS - 15))) >> 7;
|
||||
sndp->common.output = sndp->common.step * sndp->common.level32;
|
||||
sndp->common.output = SSR(sndp->common.output, 8 + 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static Uint32 sndread(YMDELTATPCMSOUND *sndp, Uint32 a)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sndreset(YMDELTATPCMSOUND *sndp, Uint32 clock, Uint32 freq)
|
||||
{
|
||||
XMEMSET(&sndp->common, 0, sizeof(sndp->common));
|
||||
sndp->common.cps = DivFix(clock, 72 * freq, CPS_SHIFT);
|
||||
sndp->romrambuf = (sndp->common.regs[1] & 1) ? sndp->rombuf : sndp->rambuf;
|
||||
sndp->romrammask = (sndp->common.regs[1] & 1) ? sndp->rommask : sndp->rammask;
|
||||
sndp->common.granuality = 4;
|
||||
}
|
||||
|
||||
static void sndvolume(YMDELTATPCMSOUND *sndp, Int32 volume)
|
||||
{
|
||||
volume = (volume << (LOG_BITS - 8)) << 1;
|
||||
sndp->common.mastervolume = volume;
|
||||
sndp->common.level32 = ((Int32)(sndp->common.level * LogToLin(sndp->logtbl, sndp->common.mastervolume, LOG_LIN_BITS - 15))) >> 7;
|
||||
sndp->common.output = sndp->common.step * sndp->common.level32;
|
||||
sndp->common.output = SSR(sndp->common.output, 8 + 2);
|
||||
}
|
||||
|
||||
static void sndrelease(YMDELTATPCMSOUND *sndp)
|
||||
{
|
||||
if (sndp->logtbl) sndp->logtbl->release(sndp->logtbl->ctx);
|
||||
XFREE(sndp);
|
||||
}
|
||||
|
||||
static void setinst(YMDELTATPCMSOUND *sndp, Uint32 n, void *p, Uint32 l)
|
||||
{
|
||||
if (n) return;
|
||||
if (p)
|
||||
{
|
||||
sndp->rombuf = (Uint8*) p;
|
||||
sndp->rommask = l - 1;
|
||||
sndp->romrambuf = (sndp->common.regs[1] & 1) ? sndp->rombuf : sndp->rambuf;
|
||||
sndp->romrammask = (sndp->common.regs[1] & 1) ? sndp->rommask : sndp->rammask;
|
||||
}
|
||||
else
|
||||
{
|
||||
sndp->rombuf = 0;
|
||||
sndp->rommask = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
KMIF_SOUND_DEVICE *YMDELTATPCMSoundAlloc(Uint32 ymdeltatpcm_type)
|
||||
{
|
||||
Uint32 ram_size;
|
||||
YMDELTATPCMSOUND *sndp;
|
||||
switch (ymdeltatpcm_type)
|
||||
{
|
||||
case YMDELTATPCM_TYPE_Y8950:
|
||||
ram_size = 32 * 1024;
|
||||
break;
|
||||
case YMDELTATPCM_TYPE_YM2608:
|
||||
ram_size = 256 * 1024;
|
||||
break;
|
||||
default:
|
||||
ram_size = 0;
|
||||
break;
|
||||
}
|
||||
sndp = (YMDELTATPCMSOUND*) XMALLOC(sizeof(YMDELTATPCMSOUND) + ram_size);
|
||||
if (!sndp) return 0;
|
||||
sndp->ymdeltatpcm_type = ymdeltatpcm_type;
|
||||
switch (ymdeltatpcm_type)
|
||||
{
|
||||
case YMDELTATPCM_TYPE_Y8950:
|
||||
sndp->memshift = 2;
|
||||
break;
|
||||
case YMDELTATPCM_TYPE_YM2608:
|
||||
/* OPNA */
|
||||
sndp->memshift = 6;
|
||||
break;
|
||||
case YMDELTATPCM_TYPE_YM2610:
|
||||
sndp->memshift = 9;
|
||||
break;
|
||||
}
|
||||
sndp->kmif.ctx = sndp;
|
||||
sndp->kmif.release = (void (*)( void* )) sndrelease;
|
||||
sndp->kmif.synth = (int (*)( void* )) sndsynth;
|
||||
sndp->kmif.volume = (void (*)( void*, int )) sndvolume;
|
||||
sndp->kmif.reset = (void (*)( void*, Uint32, Uint32 )) sndreset;
|
||||
sndp->kmif.write = (void (*)( void*, Uint32, Uint32 )) sndwrite;
|
||||
sndp->kmif.read = (Uint32 (*)( void*, Uint32 )) sndread;
|
||||
sndp->kmif.setinst = (void (*)( void*, Uint32, void*, Uint32 )) setinst;
|
||||
/* RAM */
|
||||
sndp->rambuf = ram_size ? (Uint8 *)(sndp + 1) : 0;
|
||||
sndp->rammask = ram_size ? (ram_size - 1) : 0;
|
||||
/* ROM */
|
||||
sndp->rombuf = 0;
|
||||
sndp->rommask = 0;
|
||||
sndp->logtbl = LogTableAddRef();
|
||||
if (!sndp->logtbl)
|
||||
{
|
||||
sndrelease(sndp);
|
||||
return 0;
|
||||
}
|
||||
return &sndp->kmif;
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef S_DELTAT_H__
|
||||
#define S_DELTAT_H__
|
||||
|
||||
#include "kmsnddev.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
/* MSX-AUDIO */ YMDELTATPCM_TYPE_Y8950,
|
||||
/* OPNA ADPCM */ YMDELTATPCM_TYPE_YM2608,
|
||||
/* OPNB ADPCMB */ YMDELTATPCM_TYPE_YM2610
|
||||
};
|
||||
|
||||
KMIF_SOUND_DEVICE *YMDELTATPCMSoundAlloc(Uint32 ymdeltatpcm_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* S_DELTAT_H__ */
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
#include "nestypes.h"
|
||||
#include "s_logtbl.h"
|
||||
|
||||
#if STATIC_TABLES
|
||||
|
||||
static void LogTableRelease(void *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static KMIF_LOGTABLE log_static_tables = {
|
||||
&log_static_tables;
|
||||
LogTableRelease,
|
||||
#include "s_logt.h"
|
||||
};
|
||||
|
||||
|
||||
KMIF_LOGTABLE *LogTableAddRef(void)
|
||||
{
|
||||
log_static_tables.release = LogTableRelease;
|
||||
return &log_static_tables;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <math.h>
|
||||
|
||||
static volatile Uint32 log_tables_mutex = 0;
|
||||
static Uint32 log_tables_refcount = 0;
|
||||
static KMIF_LOGTABLE *log_tables = 0;
|
||||
|
||||
static void LogTableRelease(void *ctx)
|
||||
{
|
||||
++log_tables_mutex;
|
||||
while (log_tables_mutex != 1)
|
||||
{
|
||||
XSLEEP(0);
|
||||
}
|
||||
log_tables_refcount--;
|
||||
if (!log_tables_refcount)
|
||||
{
|
||||
XFREE(ctx);
|
||||
log_tables = 0;
|
||||
}
|
||||
--log_tables_mutex;
|
||||
}
|
||||
|
||||
static void LogTableCalc(KMIF_LOGTABLE *kmif_lt)
|
||||
{
|
||||
Uint32 i;
|
||||
double a;
|
||||
for (i = 0; i < (1 << LOG_BITS); i++)
|
||||
{
|
||||
a = (1 << LOG_LIN_BITS) / pow(2, i / (double)(1 << LOG_BITS));
|
||||
kmif_lt->logtbl[i] = (Uint32)a;
|
||||
}
|
||||
kmif_lt->lineartbl[0] = LOG_LIN_BITS << LOG_BITS;
|
||||
for (i = 1; i < (1 << LIN_BITS) + 1; i++)
|
||||
{
|
||||
Uint32 ua;
|
||||
a = i << (LOG_LIN_BITS - LIN_BITS);
|
||||
ua = (Uint32)((LOG_LIN_BITS - (log(a) / log(2))) * (1 << LOG_BITS));
|
||||
kmif_lt->lineartbl[i] = ua << 1;
|
||||
}
|
||||
}
|
||||
|
||||
KMIF_LOGTABLE *LogTableAddRef(void)
|
||||
{
|
||||
++log_tables_mutex;
|
||||
while (log_tables_mutex != 1)
|
||||
{
|
||||
XSLEEP(0);
|
||||
}
|
||||
if (!log_tables_refcount)
|
||||
{
|
||||
log_tables = (KMIF_LOGTABLE*) XMALLOC(sizeof(KMIF_LOGTABLE));
|
||||
if (log_tables)
|
||||
{
|
||||
log_tables->ctx = log_tables;
|
||||
log_tables->release = LogTableRelease;
|
||||
LogTableCalc(log_tables);
|
||||
}
|
||||
}
|
||||
if (log_tables) log_tables_refcount++;
|
||||
--log_tables_mutex;
|
||||
return log_tables;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,43 +0,0 @@
|
|||
#ifndef S_LOGTBL_H__
|
||||
#define S_LOGTBL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LOG_BITS 12
|
||||
#define LIN_BITS 7
|
||||
#define LOG_LIN_BITS 30
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *ctx;
|
||||
void (*release)(void *ctx);
|
||||
Uint32 lineartbl[(1 << LIN_BITS) + 1];
|
||||
Uint32 logtbl[1 << LOG_BITS];
|
||||
} KMIF_LOGTABLE;
|
||||
|
||||
KMIF_LOGTABLE *LogTableAddRef(void);
|
||||
|
||||
__inline static Uint32 LinToLog(KMIF_LOGTABLE *kmif_lt, Int32 l)
|
||||
{
|
||||
return (l < 0) ? (kmif_lt->lineartbl[-l] + 1) : kmif_lt->lineartbl[l];
|
||||
}
|
||||
|
||||
__inline static Int32 LogToLin(KMIF_LOGTABLE *kmif_lt, Int32 l, Uint32 sft)
|
||||
{
|
||||
Int32 ret;
|
||||
Uint32 ofs;
|
||||
ofs = l + (sft << (LOG_BITS + 1));
|
||||
sft = ofs >> (LOG_BITS + 1);
|
||||
if (sft >= LOG_LIN_BITS) return 0;
|
||||
ofs = (ofs >> 1) & ((1 << LOG_BITS) - 1);
|
||||
ret = kmif_lt->logtbl[ofs] >> sft;
|
||||
return (l & 1) ? -ret : ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* S_LOGTBL_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,26 +0,0 @@
|
|||
#ifndef S_OPL_H__
|
||||
#define S_OPL_H__
|
||||
|
||||
#include "kmsnddev.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
OPL_TYPE_OPLL = 0x10, /* YAMAHA YM2413 */
|
||||
OPL_TYPE_MSXMUSIC = 0x11, /* YAMAHA YM2413 */
|
||||
OPL_TYPE_SMSFMUNIT = 0x12, /* YAMAHA YM2413? */
|
||||
OPL_TYPE_VRC7 = 0x13, /* KONAMI 053982 VRV VII */
|
||||
OPL_TYPE_OPL = 0x20, /* YAMAHA YM3526 */
|
||||
OPL_TYPE_MSXAUDIO = 0x21, /* YAMAHA Y8950 */
|
||||
OPL_TYPE_OPL2 = 0x22 /* YAMAHA YM3812 */
|
||||
};
|
||||
|
||||
KMIF_SOUND_DEVICE *OPLSoundAlloc(Uint32 opl_type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* S_OPL_H__ */
|
|
@ -1,136 +0,0 @@
|
|||
#include "nestypes.h"
|
||||
#include "s_logtbl.h"
|
||||
#include "s_opltbl.h"
|
||||
|
||||
#if STATIC_TABLES
|
||||
|
||||
static void OplTableRelease(void *ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static KMIF_OPLTABLE opl_static_tables = {
|
||||
&opl_static_tables;
|
||||
OplTableRelease,
|
||||
#include "s_oplt.h"
|
||||
};
|
||||
|
||||
KMIF_OPLTABLE *OplTableAddRef(void)
|
||||
{
|
||||
opl_static_tables.release = OplTableRelease;
|
||||
return &opl_static_tables;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <math.h>
|
||||
#ifndef M_PI
|
||||
#ifdef PI
|
||||
#define M_PI PI
|
||||
#else
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define AM_DEPTH1 4.8 /* dB */
|
||||
#define AM_DEPTH2 1.0 /* dB */
|
||||
#define PM_DEPTH1 14.0 /* cent */
|
||||
#define PM_DEPTH2 7.0 /* cent */
|
||||
#define LOG_KEYOFF (15 << (LOG_BITS + 1))
|
||||
|
||||
#define DB0375_TO_LOG(x) ((Uint32)(0.375 * (1 << (LOG_BITS + x)) / 10))
|
||||
|
||||
#define AR_OFF (128 << ARTBL_SHIFT)
|
||||
#define AR_MAX (127 << ARTBL_SHIFT)
|
||||
|
||||
|
||||
static volatile Uint32 opl_tables_mutex = 0;
|
||||
static Uint32 opl_tables_refcount = 0;
|
||||
static KMIF_OPLTABLE *opl_tables = 0;
|
||||
|
||||
static void OplTableRelease(void *ctx)
|
||||
{
|
||||
++opl_tables_mutex;
|
||||
while (opl_tables_mutex != 1)
|
||||
{
|
||||
XSLEEP(0);
|
||||
}
|
||||
opl_tables_refcount--;
|
||||
if (!opl_tables_refcount)
|
||||
{
|
||||
XFREE(ctx);
|
||||
opl_tables = 0;
|
||||
}
|
||||
--opl_tables_mutex;
|
||||
}
|
||||
|
||||
static void OplTableCalc(KMIF_OPLTABLE *tbl)
|
||||
{
|
||||
Uint32 u, u2, i;
|
||||
tbl->sin_table[0][0] = tbl->sin_table[0][1 << (SINTBL_BITS - 1)] = LOG_KEYOFF;
|
||||
for (i = 1 ;i < (1 << (SINTBL_BITS - 1)); i++)
|
||||
{
|
||||
double d;
|
||||
d = (1 << LOG_BITS) * -(log(sin(2.0 * M_PI * ((double)i) / (1 << SINTBL_BITS))) / log(2));
|
||||
if (d > (LOG_KEYOFF >> 1)) d = (LOG_KEYOFF >> 1);
|
||||
tbl->sin_table[0][i] = ((Uint32)d) << 1;
|
||||
tbl->sin_table[0][i + (1 << (SINTBL_BITS - 1))] = (((Uint32)d) << 1) + 1;
|
||||
}
|
||||
for (i = 0 ;i < (1 << SINTBL_BITS); i++)
|
||||
{
|
||||
tbl->sin_table[1][i] = (tbl->sin_table[0][i] & 1) ? tbl->sin_table[0][0] : tbl->sin_table[0][i];
|
||||
tbl->sin_table[2][i] = tbl->sin_table[0][i] & ~1;
|
||||
tbl->sin_table[3][i] = (i & (1 << (SINTBL_BITS - 2))) ? LOG_KEYOFF : tbl->sin_table[2][i];
|
||||
}
|
||||
for (i = 0; i < (1 << TLLTBL_BITS); i++)
|
||||
{
|
||||
tbl->tll2log_table[i] = (i * DB0375_TO_LOG(0)) << 1;
|
||||
}
|
||||
for (i = 0; i < (1 << AMTBL_BITS); i++)
|
||||
{
|
||||
u = (Uint32)((1 + sin(2 * M_PI * ((double)i) / (1 << AMTBL_BITS))) * ((1 << LOG_BITS) * AM_DEPTH1 / 20.0));
|
||||
u2 = (Uint32)((1 + sin(2 * M_PI * ((double)i) / (1 << AMTBL_BITS))) * ((1 << LOG_BITS) * AM_DEPTH2 / 20.0));
|
||||
tbl->am_table1[i] = u << 1;
|
||||
tbl->am_table2[i] = u2 << 1;
|
||||
}
|
||||
for (i = 0; i < (1 << PMTBL_BITS); i++)
|
||||
{
|
||||
u = (Uint32)((1 << PM_SHIFT) * pow(2, sin(2 * M_PI * ((double)i) / (1 << PMTBL_BITS)) * PM_DEPTH1 / 1200.0));
|
||||
u2 = (Uint32)((1 << PM_SHIFT) * pow(2, sin(2 * M_PI * ((double)i) / (1 << PMTBL_BITS)) * PM_DEPTH2 / 1200.0));
|
||||
tbl->pm_table1[i] = u;
|
||||
tbl->pm_table2[i] = u2;
|
||||
}
|
||||
|
||||
for (i = 0; i < (1 << ARTBL_BITS); i++)
|
||||
{
|
||||
u = (Uint32)(((double)AR_MAX) * (1 - log(1 + i) / log(1 << ARTBL_BITS)));
|
||||
tbl->ar_tablelog[i] = u;
|
||||
#if 1
|
||||
u = (Uint32)(((double)AR_MAX) * (pow(1 - i / (double)(1 << ARTBL_BITS), 8)));
|
||||
tbl->ar_tablepow[i] = u;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
KMIF_OPLTABLE *OplTableAddRef(void)
|
||||
{
|
||||
++opl_tables_mutex;
|
||||
while (opl_tables_mutex != 1)
|
||||
{
|
||||
XSLEEP(0);
|
||||
}
|
||||
if (!opl_tables_refcount)
|
||||
{
|
||||
opl_tables = (KMIF_OPLTABLE*) XMALLOC(sizeof(KMIF_OPLTABLE));
|
||||
if (opl_tables)
|
||||
{
|
||||
opl_tables->ctx = opl_tables;
|
||||
opl_tables->release = OplTableRelease;
|
||||
OplTableCalc(opl_tables);
|
||||
}
|
||||
}
|
||||
if (opl_tables) opl_tables_refcount++;
|
||||
--opl_tables_mutex;
|
||||
return opl_tables;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef S_OPLTBL_H__
|
||||
#define S_OPLTBL_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SINTBL_BITS 11
|
||||
#define AMTBL_BITS 8
|
||||
#define PMTBL_BITS 8
|
||||
#define PM_SHIFT 9
|
||||
#define ARTBL_BITS 7
|
||||
#define ARTBL_SHIFT 20
|
||||
#define TLLTBL_BITS 7
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void *ctx;
|
||||
void (*release)(void *ctx);
|
||||
Uint32 sin_table[4][1 << SINTBL_BITS];
|
||||
Uint32 tll2log_table[1 << TLLTBL_BITS];
|
||||
Uint32 ar_tablelog[1 << ARTBL_BITS];
|
||||
Uint32 am_table1[1 << AMTBL_BITS];
|
||||
Uint32 pm_table1[1 << PMTBL_BITS];
|
||||
#if 1
|
||||
Uint32 ar_tablepow[1 << ARTBL_BITS];
|
||||
#endif
|
||||
Uint32 am_table2[1 << AMTBL_BITS];
|
||||
Uint32 pm_table2[1 << PMTBL_BITS];
|
||||
} KMIF_OPLTABLE;
|
||||
|
||||
KMIF_OPLTABLE *OplTableAddRef(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* S_OPLTBL_H__ */
|
|
@ -1,50 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef __YM2413_H__
|
||||
#define __YM2413_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* select output bits size of output : 8 or 16 */
|
||||
#define SAMPLE_BITS 16
|
||||
|
||||
#include "mamedef.h"
|
||||
|
||||
typedef stream_sample_t SAMP;
|
||||
/*
|
||||
#if (SAMPLE_BITS==16)
|
||||
typedef INT16 SAMP;
|
||||
#endif
|
||||
#if (SAMPLE_BITS==8)
|
||||
typedef INT8 SAMP;
|
||||
#endif
|
||||
*/
|
||||
|
||||
|
||||
|
||||
void *ym2413_init(int clock, int rate, int type);
|
||||
void ym2413_shutdown(void *chip);
|
||||
void ym2413_reset_chip(void *chip);
|
||||
void ym2413_write(void *chip, int a, int v);
|
||||
unsigned char ym2413_read(void *chip, int a);
|
||||
void ym2413_update_one(void *chip, SAMP **buffers, int length);
|
||||
|
||||
void ym2413_advance_lfo(void *chip); /* call this once */
|
||||
SAMP ym2413_calcch(void *chip, int ch); /* then call this for each channel */
|
||||
void ym2413_advance(void *chip); /* then call this */
|
||||
|
||||
void * ym2413_get_inst0(void *chip);
|
||||
|
||||
void ym2413_set_mask(void *chip, UINT32 mask);
|
||||
|
||||
typedef void (*OPLL_UPDATEHANDLER)(void *param,int min_interval_us);
|
||||
|
||||
void ym2413_set_update_handler(void *chip, OPLL_UPDATEHANDLER UpdateHandler, void *param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__YM2413_H__*/
|
3
Frameworks/GME/vgmplay/.gitignore
vendored
Normal file
3
Frameworks/GME/vgmplay/.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
/obj
|
||||
/vgm2pcm
|
||||
/vgmplay
|
170
Frameworks/GME/vgmplay/ChipMapper.c
Normal file
170
Frameworks/GME/vgmplay/ChipMapper.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
// ChipMapper.c - Handles Chip Write (including OPL Hardware Support)
|
||||
|
||||
#include <stdio.h>
|
||||
#include <memory.h>
|
||||
#include <math.h>
|
||||
#include <wchar.h>
|
||||
#include "stdbool.h"
|
||||
|
||||
#include "chips/mamedef.h"
|
||||
|
||||
#include "chips/ChipIncl.h"
|
||||
|
||||
#include "VGMPlay.h"
|
||||
|
||||
#include "ChipMapper.h"
|
||||
|
||||
void chip_reg_write(void *param, UINT8 ChipType, UINT8 ChipID,
|
||||
UINT8 Port, UINT8 Offset, UINT8 Data)
|
||||
{
|
||||
VGM_PLAYER* p = (VGM_PLAYER *) param;
|
||||
switch(ChipType)
|
||||
{
|
||||
case 0x00: // SN76496
|
||||
sn764xx_w(p->sn764xx[ChipID], Port, Data);
|
||||
break;
|
||||
case 0x01: // YM2413
|
||||
ym2413_w(p->ym2413[ChipID], 0x00, Offset);
|
||||
ym2413_w(p->ym2413[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x02: // YM2612
|
||||
ym2612_w(p->ym2612[ChipID], (Port << 1) | 0x00, Offset);
|
||||
ym2612_w(p->ym2612[ChipID], (Port << 1) | 0x01, Data);
|
||||
break;
|
||||
case 0x03: // YM2151
|
||||
ym2151_w(p->ym2151[ChipID], 0x00, Offset);
|
||||
ym2151_w(p->ym2151[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x04: // SegaPCM
|
||||
break;
|
||||
case 0x05: // RF5C68
|
||||
rf5c68_w(p->rf5c68, Offset, Data);
|
||||
break;
|
||||
case 0x06: // YM2203
|
||||
ym2203_w(p->ym2203[ChipID], 0x00, Offset);
|
||||
ym2203_w(p->ym2203[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x07: // YM2608
|
||||
ym2608_w(p->ym2608[ChipID], (Port << 1) | 0x00, Offset);
|
||||
ym2608_w(p->ym2608[ChipID], (Port << 1) | 0x01, Data);
|
||||
break;
|
||||
case 0x08: // YM2610/YM2610B
|
||||
ym2610_w(p->ym2610[ChipID], (Port << 1) | 0x00, Offset);
|
||||
ym2610_w(p->ym2610[ChipID], (Port << 1) | 0x01, Data);
|
||||
break;
|
||||
case 0x09: // YM3812
|
||||
ym3812_w(p->ym3812[ChipID], 0x00, Offset);
|
||||
ym3812_w(p->ym3812[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x0A: // YM3526
|
||||
ym3526_w(p->ym3526[ChipID], 0x00, Offset);
|
||||
ym3526_w(p->ym3526[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x0B: // Y8950
|
||||
y8950_w(p->y8950[ChipID], 0x00, Offset);
|
||||
y8950_w(p->y8950[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x0C: // YMF262
|
||||
ymf262_w(p->ymf262[ChipID], (Port << 1) | 0x00, Offset);
|
||||
ymf262_w(p->ymf262[ChipID], (Port << 1) | 0x01, Data);
|
||||
break;
|
||||
case 0x0D: // YMF278B
|
||||
ymf278b_w(p->ymf278b[ChipID], (Port << 1) | 0x00, Offset);
|
||||
ymf278b_w(p->ymf278b[ChipID], (Port << 1) | 0x01, Data);
|
||||
break;
|
||||
case 0x0E: // YMF271
|
||||
ymf271_w(p->ymf271[ChipID], (Port << 1) | 0x00, Offset);
|
||||
ymf271_w(p->ymf271[ChipID], (Port << 1) | 0x01, Data);
|
||||
break;
|
||||
case 0x0F: // YMZ280B
|
||||
ymz280b_w(p->ymz280b[ChipID], 0x00, Offset);
|
||||
ymz280b_w(p->ymz280b[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x10: // RF5C164
|
||||
rf5c164_w(p->rf5c164, Offset, Data);
|
||||
break;
|
||||
case 0x11: // PWM
|
||||
pwm_chn_w(p->pwm, Port, (Offset << 8) | (Data << 0));
|
||||
break;
|
||||
case 0x12: // AY8910
|
||||
ayxx_w(p->ay8910[ChipID], 0x00, Offset);
|
||||
ayxx_w(p->ay8910[ChipID], 0x01, Data);
|
||||
break;
|
||||
case 0x13: // GameBoy
|
||||
gb_sound_w(p->gbdmg[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x14: // NES APU
|
||||
nes_w(p->nesapu[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x15: // MultiPCM
|
||||
multipcm_w(p->multipcm[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x16: // UPD7759
|
||||
upd7759_write(p->upd7759[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x17: // OKIM6258
|
||||
okim6258_write(p->okim6258[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x18: // OKIM6295
|
||||
okim6295_w(p->okim6295[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x19: // K051649 / SCC1
|
||||
k051649_w(p->k051649[ChipID], (Port << 1) | 0x00, Offset);
|
||||
k051649_w(p->k051649[ChipID], (Port << 1) | 0x01, Data);
|
||||
break;
|
||||
case 0x1A: // K054539
|
||||
k054539_w(p->k054539[ChipID], (Port << 8) | (Offset << 0), Data);
|
||||
break;
|
||||
case 0x1B: // HuC6280
|
||||
c6280_w(p->huc6280[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x1C: // C140
|
||||
c140_w(p->c140[ChipID], (Port << 8) | (Offset << 0), Data);
|
||||
break;
|
||||
case 0x1D: // K053260
|
||||
k053260_w(p->k053260[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x1E: // Pokey
|
||||
pokey_w(p->pokey[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x1F: // QSound
|
||||
qsound_w(p->qsound[ChipID], 0x00, Port); // Data MSB
|
||||
qsound_w(p->qsound[ChipID], 0x01, Offset); // Data LSB
|
||||
qsound_w(p->qsound[ChipID], 0x02, Data); // Register
|
||||
break;
|
||||
case 0x20: // YMF292/SCSP
|
||||
scsp_w(p->scsp[ChipID], (Port << 8) | (Offset << 0), Data);
|
||||
break;
|
||||
case 0x21: // WonderSwan
|
||||
ws_audio_port_write(p->wswan[ChipID], 0x80 | Offset, Data);
|
||||
break;
|
||||
case 0x22: // VSU
|
||||
VSU_Write(p->vsu[ChipID], (Port << 8) | (Offset << 0), Data);
|
||||
break;
|
||||
case 0x23: // SAA1099
|
||||
saa1099_control_w(p->saa1099[ChipID], 0, Offset);
|
||||
saa1099_data_w(p->saa1099[ChipID], 0, Data);
|
||||
break;
|
||||
case 0x24: // ES5503
|
||||
es5503_w(p->es5503[ChipID], Offset, Data);
|
||||
break;
|
||||
case 0x25: // ES5506
|
||||
if (Port & 0x80)
|
||||
es550x_w16(p->es550x[ChipID], Port & 0x7F, (Offset << 8) | (Data << 0));
|
||||
else
|
||||
es550x_w(p->es550x[ChipID], Port, Data);
|
||||
break;
|
||||
case 0x26: // X1-010
|
||||
seta_sound_w(p->x1_010[ChipID], (Port << 8) | (Offset << 0), Data);
|
||||
break;
|
||||
case 0x27: // C352
|
||||
c352_w(p->c352[ChipID], Port, (Offset << 8) | (Data << 0));
|
||||
break;
|
||||
case 0x28: // GA20
|
||||
irem_ga20_w(p->ga20[ChipID], Offset, Data);
|
||||
break;
|
||||
// case 0x##: // OKIM6376
|
||||
// break;
|
||||
}
|
||||
return;
|
||||
}
|
1
Frameworks/GME/vgmplay/ChipMapper.h
Normal file
1
Frameworks/GME/vgmplay/ChipMapper.h
Normal file
|
@ -0,0 +1 @@
|
|||
void chip_reg_write(void *, UINT8 ChipType, UINT8 ChipID, UINT8 Port, UINT8 Offset, UINT8 Data);
|
202
Frameworks/GME/vgmplay/Makefile
Normal file
202
Frameworks/GME/vgmplay/Makefile
Normal file
|
@ -0,0 +1,202 @@
|
|||
########################
|
||||
#
|
||||
# VGMPlay Makefile
|
||||
# (for GNU Make 3.81)
|
||||
#
|
||||
########################
|
||||
|
||||
# TODO: Make this look less horrible.
|
||||
# TODO: Make it not include pt_ioctl.c when DISABLE_HW_SUPPORT is active.
|
||||
|
||||
# Uncomment if you build on Windows using MinGW.
|
||||
#WINDOWS = 1
|
||||
|
||||
# Uncomment if you want to use libao instead of OSS for sound streaming under Linux
|
||||
USE_LIBAO = 1
|
||||
|
||||
CC = gcc
|
||||
PREFIX = /usr/local
|
||||
MANPREFIX = $(PREFIX)/share/man
|
||||
|
||||
# -- VGMPlay specific Compile Flags --
|
||||
MAINFLAGS := -DCONSOLE_MODE -DADDITIONAL_FORMATS -DSET_CONSOLE_TITLE
|
||||
ifdef WINDOWS
|
||||
# MinGW defines __WINDOWS__, Visual Studio defines WIN32
|
||||
MAINFLAGS += -DWIN32
|
||||
else
|
||||
ifdef USE_LIBAO
|
||||
MAINFLAGS += -DUSE_LIBAO
|
||||
endif
|
||||
endif
|
||||
EMUFLAGS := -DENABLE_ALL_CORES
|
||||
|
||||
#MAINFLAGS := -DVGM_BIG_ENDIAN
|
||||
#EMUFLAGS := -DVGM_BIG_ENDIAN
|
||||
|
||||
#MAINFLAGS := -DDISABLE_HW_SUPPORT
|
||||
|
||||
|
||||
# -- General Compile Flags --
|
||||
CFLAGS := -O3 -g0 $(CFLAGS)
|
||||
# libm (math library) and libz (zlib)
|
||||
LDFLAGS := -lm -lz $(LDFLAGS)
|
||||
ifdef WINDOWS
|
||||
# for Windows, add kernel32 and winmm (Multimedia APIs)
|
||||
LDFLAGS += -lkernel32 -lwinmm
|
||||
else
|
||||
# for Linux, add librt (clock stuff) and libpthread (threads)
|
||||
LDFLAGS += -lrt -lpthread -pthread
|
||||
MAINFLAGS += -pthread -DSHARE_PREFIX=\"$(PREFIX)\"
|
||||
ifdef USE_LIBAO
|
||||
LDFLAGS += -lao
|
||||
endif
|
||||
endif
|
||||
# add Library Path, if defined
|
||||
ifdef LD_LIBRARY_PATH
|
||||
LDFLAGS += -L $(LD_LIBRARY_PATH)
|
||||
endif
|
||||
|
||||
SRC = .
|
||||
OBJ = obj
|
||||
EMUSRC = $(SRC)/chips
|
||||
EMUOBJ = $(OBJ)/chips
|
||||
|
||||
OBJDIRS = \
|
||||
$(OBJ) \
|
||||
$(EMUOBJ)
|
||||
MAINOBJS = \
|
||||
$(OBJ)/VGMPlay.o \
|
||||
$(OBJ)/VGMPlay_AddFmts.o \
|
||||
$(OBJ)/Stream.o \
|
||||
$(OBJ)/ChipMapper.o
|
||||
ifdef WINDOWS
|
||||
MAINOBJS += $(OBJ)/pt_ioctl.o
|
||||
endif
|
||||
EMUOBJS = \
|
||||
$(EMUOBJ)/262intf.o \
|
||||
$(EMUOBJ)/2151intf.o \
|
||||
$(EMUOBJ)/2203intf.o \
|
||||
$(EMUOBJ)/2413intf.o \
|
||||
$(EMUOBJ)/2608intf.o \
|
||||
$(EMUOBJ)/2610intf.o \
|
||||
$(EMUOBJ)/2612intf.o \
|
||||
$(EMUOBJ)/3526intf.o \
|
||||
$(EMUOBJ)/3812intf.o \
|
||||
$(EMUOBJ)/8950intf.o \
|
||||
$(EMUOBJ)/adlibemu_opl2.o \
|
||||
$(EMUOBJ)/adlibemu_opl3.o \
|
||||
$(EMUOBJ)/ay8910.o \
|
||||
$(EMUOBJ)/ay_intf.o \
|
||||
$(EMUOBJ)/c140.o \
|
||||
$(EMUOBJ)/c352.o \
|
||||
$(EMUOBJ)/c6280.o \
|
||||
$(EMUOBJ)/c6280intf.o \
|
||||
$(EMUOBJ)/dac_control.o \
|
||||
$(EMUOBJ)/es5503.o \
|
||||
$(EMUOBJ)/es5506.o \
|
||||
$(EMUOBJ)/emu2149.o \
|
||||
$(EMUOBJ)/emu2413.o \
|
||||
$(EMUOBJ)/fm2612.o \
|
||||
$(EMUOBJ)/fm.o \
|
||||
$(EMUOBJ)/fmopl.o \
|
||||
$(EMUOBJ)/gb.o \
|
||||
$(EMUOBJ)/iremga20.o \
|
||||
$(EMUOBJ)/k051649.o \
|
||||
$(EMUOBJ)/k053260.o \
|
||||
$(EMUOBJ)/k054539.o \
|
||||
$(EMUOBJ)/multipcm.o \
|
||||
$(EMUOBJ)/nes_apu.o \
|
||||
$(EMUOBJ)/nes_intf.o \
|
||||
$(EMUOBJ)/np_nes_apu.o \
|
||||
$(EMUOBJ)/np_nes_dmc.o \
|
||||
$(EMUOBJ)/np_nes_fds.o \
|
||||
$(EMUOBJ)/okim6258.o \
|
||||
$(EMUOBJ)/okim6295.o \
|
||||
$(EMUOBJ)/Ootake_PSG.o \
|
||||
$(EMUOBJ)/panning.o \
|
||||
$(EMUOBJ)/pokey.o \
|
||||
$(EMUOBJ)/pwm.o \
|
||||
$(EMUOBJ)/qsound.o \
|
||||
$(EMUOBJ)/rf5c68.o \
|
||||
$(EMUOBJ)/saa1099.o \
|
||||
$(EMUOBJ)/segapcm.o \
|
||||
$(EMUOBJ)/scd_pcm.o \
|
||||
$(EMUOBJ)/scsp.o \
|
||||
$(EMUOBJ)/scspdsp.o \
|
||||
$(EMUOBJ)/sn76489.o \
|
||||
$(EMUOBJ)/sn76496.o \
|
||||
$(EMUOBJ)/sn764intf.o \
|
||||
$(EMUOBJ)/upd7759.o \
|
||||
$(EMUOBJ)/vsu.o \
|
||||
$(EMUOBJ)/ws_audio.o \
|
||||
$(EMUOBJ)/x1_010.o \
|
||||
$(EMUOBJ)/ym2151.o \
|
||||
$(EMUOBJ)/ym2413.o \
|
||||
$(EMUOBJ)/ym2612.o \
|
||||
$(EMUOBJ)/ymdeltat.o \
|
||||
$(EMUOBJ)/ymf262.o \
|
||||
$(EMUOBJ)/ymf271.o \
|
||||
$(EMUOBJ)/ymf278b.o \
|
||||
$(EMUOBJ)/ymz280b.o \
|
||||
$(EMUOBJ)/ay8910_opl.o \
|
||||
$(EMUOBJ)/sn76496_opl.o \
|
||||
$(EMUOBJ)/ym2413hd.o \
|
||||
$(EMUOBJ)/ym2413_opl.o
|
||||
VGMPLAY_OBJS = \
|
||||
$(OBJ)/VGMPlayUI.o
|
||||
VGM2PCM_OBJS = \
|
||||
$(OBJ)/vgm2pcm.o
|
||||
EXTRA_OBJS = $(VGMPLAY_OBJS) $(VGM2PCM_OBJS)
|
||||
|
||||
|
||||
all: vgmplay vgm2pcm
|
||||
|
||||
vgmplay: $(EMUOBJS) $(MAINOBJS) $(VGMPLAY_OBJS)
|
||||
@echo Linking vgmplay ...
|
||||
@$(CC) $(VGMPLAY_OBJS) $(MAINOBJS) $(EMUOBJS) $(LDFLAGS) -o vgmplay
|
||||
@echo Done.
|
||||
|
||||
vgm2pcm: $(EMUOBJS) $(MAINOBJS) $(VGM2PCM_OBJS)
|
||||
@echo Linking vgm2pcm ...
|
||||
@$(CC) $(VGM2PCM_OBJS) $(MAINOBJS) $(EMUOBJS) $(LDFLAGS) -o vgm2pcm
|
||||
@echo Done.
|
||||
|
||||
# compile the chip-emulator c-files
|
||||
$(EMUOBJ)/%.o: $(EMUSRC)/%.c
|
||||
@echo Compiling $< ...
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) $(CFLAGS) $(EMUFLAGS) -c $< -o $@
|
||||
|
||||
# compile the main c-files
|
||||
$(OBJ)/%.o: $(SRC)/%.c
|
||||
@echo Compiling $< ...
|
||||
@mkdir -p $(@D)
|
||||
@$(CC) $(CFLAGS) $(MAINFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@echo Deleting object files ...
|
||||
@rm -f $(MAINOBJS) $(EMUOBJS) $(EXTRA_OBJS)
|
||||
@echo Deleting executable files ...
|
||||
@rm -f vgmplay vgm2pcm
|
||||
@echo Done.
|
||||
|
||||
# Thanks to ZekeSulastin and nextvolume for the install and uninstall routines.
|
||||
install: vgmplay
|
||||
install -m 755 vgmplay $(DESTDIR)$(PREFIX)/bin/vgmplay
|
||||
install -m 644 vgmplay.1 $(DESTDIR)$(MANPREFIX)/man1/vgmplay.1
|
||||
mkdir -m 755 -p $(DESTDIR)$(PREFIX)/share/vgmplay
|
||||
install -m 644 VGMPlay.ini $(DESTDIR)$(PREFIX)/share/vgmplay/vgmplay.ini
|
||||
-install -m 644 yrw801.rom $(DESTDIR)$(PREFIX)/share/vgmplay/yrw801.rom
|
||||
|
||||
|
||||
# Install the "vgm-player" wrapper
|
||||
play_inst: install
|
||||
install -m 755 vgm-player $(DESTDIR)$(PREFIX)/bin/vgm-player
|
||||
|
||||
uninstall:
|
||||
rm $(DESTDIR)$(PREFIX)/bin/vgmplay
|
||||
rm $(DESTDIR)$(PREFIX)/bin/vgm-player
|
||||
rm $(DESTDIR)$(MANPREFIX)/man1/vgmplay.1
|
||||
rm -rf $(DESTDIR)$(PREFIX)/share/vgmplay
|
||||
|
||||
.PHONY: all clean install uninstall
|
37
Frameworks/GME/vgmplay/PortTalk_IOCTL.h
Normal file
37
Frameworks/GME/vgmplay/PortTalk_IOCTL.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/******************************************************************************/
|
||||
/* */
|
||||
/* PortTalk Driver for Windows NT/2000/XP */
|
||||
/* Version 2.0, 12th January 2002 */
|
||||
/* http://www.beyondlogic.org */
|
||||
/* */
|
||||
/* Copyright © 2002 Craig Peacock. Craig.Peacock@beyondlogic.org */
|
||||
/* Any publication or distribution of this code in source form is prohibited */
|
||||
/* without prior written permission of the copyright holder. This source code */
|
||||
/* is provided "as is", without any guarantee made as to its suitability or */
|
||||
/* fitness for any particular use. Permission is herby granted to modify or */
|
||||
/* enhance this sample code to produce a derivative program which may only be */
|
||||
/* distributed in compiled object form only. */
|
||||
/******************************************************************************/
|
||||
|
||||
#define PORTTALK_TYPE 40000 /* 32768-65535 are reserved for customers */
|
||||
|
||||
// The IOCTL function codes from 0x800 to 0xFFF are for customer use.
|
||||
|
||||
#define IOCTL_IOPM_RESTRICT_ALL_ACCESS \
|
||||
CTL_CODE(PORTTALK_TYPE, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_IOPM_ALLOW_EXCUSIVE_ACCESS \
|
||||
CTL_CODE(PORTTALK_TYPE, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_SET_IOPM \
|
||||
CTL_CODE(PORTTALK_TYPE, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_ENABLE_IOPM_ON_PROCESSID \
|
||||
CTL_CODE(PORTTALK_TYPE, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_READ_PORT_UCHAR \
|
||||
CTL_CODE(PORTTALK_TYPE, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_WRITE_PORT_UCHAR \
|
||||
CTL_CODE(PORTTALK_TYPE, 0x905, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
31
Frameworks/GME/vgmplay/SourceReadme.txt
Normal file
31
Frameworks/GME/vgmplay/SourceReadme.txt
Normal file
|
@ -0,0 +1,31 @@
|
|||
VGMPlay Build Instructions
|
||||
--------------------------
|
||||
|
||||
Compile VGMPlay under Windows
|
||||
-----------------------------
|
||||
|
||||
using MS Visual Studio 6.0:
|
||||
1. Open VGMPlay.dsw.
|
||||
2. Build the project.
|
||||
3. Done.
|
||||
|
||||
using later versions of MS Visual Studio:
|
||||
1. Open VGMPlay.dsw.
|
||||
2. It will ask you to convert the project to the current project format. Click "Yes".
|
||||
3. Build the project.
|
||||
4. Done.
|
||||
|
||||
using MinGW/MSYS:
|
||||
1. edit the Makefile and enable the line "WINDOWS = 1" (remove the #)
|
||||
2. open MSYS and run the "make" command in VGMPlay's folder.
|
||||
3. Done.
|
||||
|
||||
Note: You can compile it without MSYS, but you need to manually create the OBJDIRS paths (or make them use the backslash '\'), because mkdir fails at paths with a forward slash.
|
||||
|
||||
|
||||
|
||||
Compile VGMPlay under Linux
|
||||
---------------------------
|
||||
1. [optional step] If you have libao installed, you can edit the Makefile to make VGMPlay use libao instead of OSS.
|
||||
2. run "make" in VGMPlay's folder
|
||||
3. Done.
|
147
Frameworks/GME/vgmplay/VGMFile.h
Normal file
147
Frameworks/GME/vgmplay/VGMFile.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
// Header file for VGM file handling
|
||||
|
||||
typedef struct _vgm_file_header
|
||||
{
|
||||
UINT32 fccVGM;
|
||||
UINT32 lngEOFOffset;
|
||||
UINT32 lngVersion;
|
||||
UINT32 lngHzPSG;
|
||||
UINT32 lngHzYM2413;
|
||||
UINT32 lngGD3Offset;
|
||||
UINT32 lngTotalSamples;
|
||||
UINT32 lngLoopOffset;
|
||||
UINT32 lngLoopSamples;
|
||||
UINT32 lngRate;
|
||||
UINT16 shtPSG_Feedback;
|
||||
UINT8 bytPSG_SRWidth;
|
||||
UINT8 bytPSG_Flags;
|
||||
UINT32 lngHzYM2612;
|
||||
UINT32 lngHzYM2151;
|
||||
UINT32 lngDataOffset;
|
||||
UINT32 lngHzSPCM;
|
||||
UINT32 lngSPCMIntf;
|
||||
UINT32 lngHzRF5C68;
|
||||
UINT32 lngHzYM2203;
|
||||
UINT32 lngHzYM2608;
|
||||
UINT32 lngHzYM2610;
|
||||
UINT32 lngHzYM3812;
|
||||
UINT32 lngHzYM3526;
|
||||
UINT32 lngHzY8950;
|
||||
UINT32 lngHzYMF262;
|
||||
UINT32 lngHzYMF278B;
|
||||
UINT32 lngHzYMF271;
|
||||
UINT32 lngHzYMZ280B;
|
||||
UINT32 lngHzRF5C164;
|
||||
UINT32 lngHzPWM;
|
||||
UINT32 lngHzAY8910;
|
||||
UINT8 bytAYType;
|
||||
UINT8 bytAYFlag;
|
||||
UINT8 bytAYFlagYM2203;
|
||||
UINT8 bytAYFlagYM2608;
|
||||
UINT8 bytVolumeModifier;
|
||||
UINT8 bytReserved2;
|
||||
INT8 bytLoopBase;
|
||||
UINT8 bytLoopModifier;
|
||||
UINT32 lngHzGBDMG;
|
||||
UINT32 lngHzNESAPU;
|
||||
UINT32 lngHzMultiPCM;
|
||||
UINT32 lngHzUPD7759;
|
||||
UINT32 lngHzOKIM6258;
|
||||
UINT8 bytOKI6258Flags;
|
||||
UINT8 bytK054539Flags;
|
||||
UINT8 bytC140Type;
|
||||
UINT8 bytReservedFlags;
|
||||
UINT32 lngHzOKIM6295;
|
||||
UINT32 lngHzK051649;
|
||||
UINT32 lngHzK054539;
|
||||
UINT32 lngHzHuC6280;
|
||||
UINT32 lngHzC140;
|
||||
UINT32 lngHzK053260;
|
||||
UINT32 lngHzPokey;
|
||||
UINT32 lngHzQSound;
|
||||
UINT32 lngHzSCSP;
|
||||
// UINT32 lngHzOKIM6376;
|
||||
//UINT8 bytReserved[0x04];
|
||||
UINT32 lngExtraOffset;
|
||||
UINT32 lngHzWSwan;
|
||||
UINT32 lngHzVSU;
|
||||
UINT32 lngHzSAA1099;
|
||||
UINT32 lngHzES5503;
|
||||
UINT32 lngHzES5506;
|
||||
UINT8 bytES5503Chns;
|
||||
UINT8 bytES5506Chns;
|
||||
UINT8 bytC352ClkDiv;
|
||||
UINT8 bytESReserved;
|
||||
UINT32 lngHzX1_010;
|
||||
UINT32 lngHzC352;
|
||||
UINT32 lngHzGA20;
|
||||
} VGM_HEADER;
|
||||
typedef struct _vgm_header_extra
|
||||
{
|
||||
UINT32 DataSize;
|
||||
UINT32 Chp2ClkOffset;
|
||||
UINT32 ChpVolOffset;
|
||||
} VGM_HDR_EXTRA;
|
||||
typedef struct _vgm_extra_chip_data32
|
||||
{
|
||||
UINT8 Type;
|
||||
UINT32 Data;
|
||||
} VGMX_CHIP_DATA32;
|
||||
typedef struct _vgm_extra_chip_data16
|
||||
{
|
||||
UINT8 Type;
|
||||
UINT8 Flags;
|
||||
UINT16 Data;
|
||||
} VGMX_CHIP_DATA16;
|
||||
typedef struct _vgm_extra_chip_extra32
|
||||
{
|
||||
UINT8 ChipCnt;
|
||||
VGMX_CHIP_DATA32* CCData;
|
||||
} VGMX_CHP_EXTRA32;
|
||||
typedef struct _vgm_extra_chip_extra16
|
||||
{
|
||||
UINT8 ChipCnt;
|
||||
VGMX_CHIP_DATA16* CCData;
|
||||
} VGMX_CHP_EXTRA16;
|
||||
typedef struct _vgm_header_extra_data
|
||||
{
|
||||
VGMX_CHP_EXTRA32 Clocks;
|
||||
VGMX_CHP_EXTRA16 Volumes;
|
||||
} VGM_EXTRA;
|
||||
|
||||
#define VOLUME_MODIF_WRAP 0xC0
|
||||
typedef struct _vgm_gd3_tag
|
||||
{
|
||||
UINT32 fccGD3;
|
||||
UINT32 lngVersion;
|
||||
UINT32 lngTagLength;
|
||||
wchar_t* strTrackNameE;
|
||||
wchar_t* strTrackNameJ;
|
||||
wchar_t* strGameNameE;
|
||||
wchar_t* strGameNameJ;
|
||||
wchar_t* strSystemNameE;
|
||||
wchar_t* strSystemNameJ;
|
||||
wchar_t* strAuthorNameE;
|
||||
wchar_t* strAuthorNameJ;
|
||||
wchar_t* strReleaseDate;
|
||||
wchar_t* strCreator;
|
||||
wchar_t* strNotes;
|
||||
} GD3_TAG;
|
||||
typedef struct _vgm_pcm_bank_data
|
||||
{
|
||||
UINT32 DataSize;
|
||||
UINT8* Data;
|
||||
UINT32 DataStart;
|
||||
} VGM_PCM_DATA;
|
||||
typedef struct _vgm_pcm_bank
|
||||
{
|
||||
UINT32 BankCount;
|
||||
VGM_PCM_DATA* Bank;
|
||||
UINT32 DataSize;
|
||||
UINT8* Data;
|
||||
UINT32 DataPos;
|
||||
UINT32 BnkPos;
|
||||
} VGM_PCM_BANK;
|
||||
|
||||
#define FCC_VGM 0x206D6756 // 'Vgm '
|
||||
#define FCC_GD3 0x20336447 // 'Gd3 '
|
5150
Frameworks/GME/vgmplay/VGMPlay.c
Normal file
5150
Frameworks/GME/vgmplay/VGMPlay.c
Normal file
File diff suppressed because it is too large
Load diff
1096
Frameworks/GME/vgmplay/VGMPlay.dsp
Normal file
1096
Frameworks/GME/vgmplay/VGMPlay.dsp
Normal file
File diff suppressed because it is too large
Load diff
29
Frameworks/GME/vgmplay/VGMPlay.dsw
Normal file
29
Frameworks/GME/vgmplay/VGMPlay.dsw
Normal file
|
@ -0,0 +1,29 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNUNG: DIESE ARBEITSBEREICHSDATEI DARF NICHT BEARBEITET ODER GELÖSCHT WERDEN!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "VGMPlay"=".\VGMPlay.dsp" - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
295
Frameworks/GME/vgmplay/VGMPlay.h
Normal file
295
Frameworks/GME/vgmplay/VGMPlay.h
Normal file
|
@ -0,0 +1,295 @@
|
|||
// Header File for structures and constants used within VGMPlay.c
|
||||
|
||||
#include "chips/mamedef.h"
|
||||
|
||||
#include "VGMFile.h"
|
||||
|
||||
#include "VGMPlay_Intf.h"
|
||||
|
||||
#define VGMPLAY_VER_STR "0.40.6"
|
||||
//#define APLHA
|
||||
//#define BETA
|
||||
#define VGM_VER_STR "1.71b"
|
||||
#define VGM_VER_NUM 0x170
|
||||
|
||||
#define CHIP_COUNT 0x29
|
||||
typedef struct chip_options
|
||||
{
|
||||
bool Disabled;
|
||||
UINT8 EmuCore;
|
||||
UINT8 ChnCnt;
|
||||
// Special Flags:
|
||||
// YM2612: Bit 0 - DAC Highpass Enable, Bit 1 - SSG-EG Enable
|
||||
// YM-OPN: Bit 0 - Disable AY8910-Part
|
||||
UINT16 SpecialFlags;
|
||||
|
||||
// Channel Mute Mask - 1 Channel is represented by 1 bit
|
||||
UINT32 ChnMute1;
|
||||
// Mask 2 - used by YMF287B for OPL4 Wavetable Synth and by YM2608/YM2610 for PCM
|
||||
UINT32 ChnMute2;
|
||||
// Mask 3 - used for the AY-part of some OPN-chips
|
||||
UINT32 ChnMute3;
|
||||
|
||||
INT16* Panning;
|
||||
} CHIP_OPTS;
|
||||
typedef struct chips_options
|
||||
{
|
||||
CHIP_OPTS SN76496;
|
||||
CHIP_OPTS YM2413;
|
||||
CHIP_OPTS YM2612;
|
||||
CHIP_OPTS YM2151;
|
||||
CHIP_OPTS SegaPCM;
|
||||
CHIP_OPTS RF5C68;
|
||||
CHIP_OPTS YM2203;
|
||||
CHIP_OPTS YM2608;
|
||||
CHIP_OPTS YM2610;
|
||||
CHIP_OPTS YM3812;
|
||||
CHIP_OPTS YM3526;
|
||||
CHIP_OPTS Y8950;
|
||||
CHIP_OPTS YMF262;
|
||||
CHIP_OPTS YMF278B;
|
||||
CHIP_OPTS YMF271;
|
||||
CHIP_OPTS YMZ280B;
|
||||
CHIP_OPTS RF5C164;
|
||||
CHIP_OPTS PWM;
|
||||
CHIP_OPTS AY8910;
|
||||
CHIP_OPTS GameBoy;
|
||||
CHIP_OPTS NES;
|
||||
CHIP_OPTS MultiPCM;
|
||||
CHIP_OPTS UPD7759;
|
||||
CHIP_OPTS OKIM6258;
|
||||
CHIP_OPTS OKIM6295;
|
||||
CHIP_OPTS K051649;
|
||||
CHIP_OPTS K054539;
|
||||
CHIP_OPTS HuC6280;
|
||||
CHIP_OPTS C140;
|
||||
CHIP_OPTS K053260;
|
||||
CHIP_OPTS Pokey;
|
||||
CHIP_OPTS QSound;
|
||||
CHIP_OPTS SCSP;
|
||||
CHIP_OPTS WSwan;
|
||||
CHIP_OPTS VSU;
|
||||
CHIP_OPTS SAA1099;
|
||||
CHIP_OPTS ES5503;
|
||||
CHIP_OPTS ES5506;
|
||||
CHIP_OPTS X1_010;
|
||||
CHIP_OPTS C352;
|
||||
CHIP_OPTS GA20;
|
||||
// CHIP_OPTS OKIM6376;
|
||||
} CHIPS_OPTION;
|
||||
|
||||
typedef void (*strm_func)(void *, stream_sample_t **outputs, int samples);
|
||||
|
||||
typedef struct chip_audio_attributes CAUD_ATTR;
|
||||
struct chip_audio_attributes
|
||||
{
|
||||
UINT32 TargetSmpRate;
|
||||
UINT32 SmpRate;
|
||||
UINT32 LastSmpRate;
|
||||
UINT16 Volume;
|
||||
UINT8 ChipType;
|
||||
UINT8 ChipID; // 0 - 1st chip, 1 - 2nd chip, etc.
|
||||
void* Resampler;
|
||||
strm_func StreamUpdate;
|
||||
void* StreamUpdateParam;
|
||||
CAUD_ATTR* Paired;
|
||||
};
|
||||
|
||||
typedef struct chip_audio_struct
|
||||
{
|
||||
CAUD_ATTR SN76496;
|
||||
CAUD_ATTR YM2413;
|
||||
CAUD_ATTR YM2612;
|
||||
CAUD_ATTR YM2151;
|
||||
CAUD_ATTR SegaPCM;
|
||||
CAUD_ATTR RF5C68;
|
||||
CAUD_ATTR YM2203;
|
||||
CAUD_ATTR YM2608;
|
||||
CAUD_ATTR YM2610;
|
||||
CAUD_ATTR YM3812;
|
||||
CAUD_ATTR YM3526;
|
||||
CAUD_ATTR Y8950;
|
||||
CAUD_ATTR YMF262;
|
||||
CAUD_ATTR YMF278B;
|
||||
CAUD_ATTR YMF271;
|
||||
CAUD_ATTR YMZ280B;
|
||||
CAUD_ATTR RF5C164;
|
||||
CAUD_ATTR PWM;
|
||||
CAUD_ATTR AY8910;
|
||||
CAUD_ATTR GameBoy;
|
||||
CAUD_ATTR NES;
|
||||
CAUD_ATTR MultiPCM;
|
||||
CAUD_ATTR UPD7759;
|
||||
CAUD_ATTR OKIM6258;
|
||||
CAUD_ATTR OKIM6295;
|
||||
CAUD_ATTR K051649;
|
||||
CAUD_ATTR K054539;
|
||||
CAUD_ATTR HuC6280;
|
||||
CAUD_ATTR C140;
|
||||
CAUD_ATTR K053260;
|
||||
CAUD_ATTR Pokey;
|
||||
CAUD_ATTR QSound;
|
||||
CAUD_ATTR SCSP;
|
||||
CAUD_ATTR WSwan;
|
||||
CAUD_ATTR VSU;
|
||||
CAUD_ATTR SAA1099;
|
||||
CAUD_ATTR ES5503;
|
||||
CAUD_ATTR ES5506;
|
||||
CAUD_ATTR X1_010;
|
||||
CAUD_ATTR C352;
|
||||
CAUD_ATTR GA20;
|
||||
// CAUD_ATTR OKIM6376;
|
||||
} CHIP_AUDIO;
|
||||
|
||||
typedef struct chip_aud_list CA_LIST;
|
||||
struct chip_aud_list
|
||||
{
|
||||
CAUD_ATTR* CAud;
|
||||
CHIP_OPTS* COpts;
|
||||
CA_LIST* next;
|
||||
};
|
||||
|
||||
typedef struct daccontrol_data
|
||||
{
|
||||
bool Enable;
|
||||
UINT8 Bank;
|
||||
} DACCTRL_DATA;
|
||||
|
||||
typedef struct pcmbank_table
|
||||
{
|
||||
UINT8 ComprType;
|
||||
UINT8 CmpSubType;
|
||||
UINT8 BitDec;
|
||||
UINT8 BitCmp;
|
||||
UINT16 EntryCount;
|
||||
void* Entries;
|
||||
} PCMBANK_TBL;
|
||||
|
||||
typedef struct vgm_player
|
||||
{
|
||||
// Options Variables
|
||||
UINT32 SampleRate; // Note: also used by some sound cores to determinate the chip sample rate
|
||||
|
||||
UINT32 VGMMaxLoop;
|
||||
UINT32 VGMPbRate; // in Hz, ignored if this value or VGM's lngRate Header value is 0
|
||||
#ifdef ADDITIONAL_FORMATS
|
||||
UINT32 CMFMaxLoop;
|
||||
#endif
|
||||
UINT32 FadeTime;
|
||||
|
||||
float VolumeLevel;
|
||||
bool SurroundSound;
|
||||
bool FadeRAWLog;
|
||||
//bool FullBufFill; // Fill Buffer until it's full
|
||||
|
||||
bool DoubleSSGVol;
|
||||
|
||||
UINT8 ResampleMode; // 00 - HQ both, 01 - LQ downsampling, 02 - LQ both
|
||||
UINT8 CHIP_SAMPLING_MODE;
|
||||
INT32 CHIP_SAMPLE_RATE;
|
||||
|
||||
CHIPS_OPTION ChipOpts[0x02];
|
||||
|
||||
stream_sample_t* DUMMYBUF[0x02];
|
||||
|
||||
char* AppPaths[8];
|
||||
|
||||
UINT8 FileMode;
|
||||
VGM_HEADER VGMHead;
|
||||
VGM_HDR_EXTRA VGMHeadX;
|
||||
VGM_EXTRA VGMH_Extra;
|
||||
UINT32 VGMDataLen;
|
||||
UINT8* VGMData;
|
||||
GD3_TAG VGMTag;
|
||||
|
||||
#define PCM_BANK_COUNT 0x40
|
||||
VGM_PCM_BANK PCMBank[PCM_BANK_COUNT];
|
||||
PCMBANK_TBL PCMTbl;
|
||||
UINT8 DacCtrlUsed;
|
||||
UINT8 DacCtrlUsg[0xFF];
|
||||
DACCTRL_DATA DacCtrl[0xFF];
|
||||
|
||||
CHIP_AUDIO ChipAudio[0x02];
|
||||
CAUD_ATTR CA_Paired[0x02][0x03];
|
||||
float MasterVol;
|
||||
|
||||
CA_LIST ChipListBuffer[0x200];
|
||||
CA_LIST* ChipListAll; // all chips needed for playback (in general)
|
||||
//CA_LIST* ChipListOpt; // ChipListAll minus muted chips
|
||||
|
||||
#define SMPL_BUFSIZE 0x100
|
||||
INT32* StreamBufs[0x02];
|
||||
|
||||
UINT32 VGMPos;
|
||||
INT32 VGMSmplPos;
|
||||
INT32 VGMSmplPlayed;
|
||||
INT32 VGMSampleRate;
|
||||
UINT32 VGMPbRateMul;
|
||||
UINT32 VGMPbRateDiv;
|
||||
UINT32 VGMSmplRateMul;
|
||||
UINT32 VGMSmplRateDiv;
|
||||
bool VGMEnd;
|
||||
bool EndPlay;
|
||||
bool FadePlay;
|
||||
bool ForceVGMExec;
|
||||
UINT8 PlayingMode;
|
||||
UINT32 PlayingTime;
|
||||
UINT32 FadeStart;
|
||||
UINT32 VGMMaxLoopM;
|
||||
UINT32 VGMCurLoop;
|
||||
float VolumeLevelM;
|
||||
float FinalVol;
|
||||
bool ResetPBTimer;
|
||||
|
||||
UINT8 IsVGMInit;
|
||||
UINT16 Last95Drum; // for optvgm debugging
|
||||
UINT16 Last95Max; // for optvgm debugging
|
||||
UINT32 Last95Freq; // for optvgm debugging
|
||||
|
||||
bool ErrorHappened;
|
||||
|
||||
// the chips' states
|
||||
void * sn764xx[2];
|
||||
void * ym2413[2];
|
||||
void * ym2612[2];
|
||||
void * ym2151[2];
|
||||
void * segapcm[2];
|
||||
void * rf5c68;
|
||||
void * ym2203[2];
|
||||
void * ym2608[2];
|
||||
void * ym2610[2];
|
||||
void * ym3812[2];
|
||||
void * ym3812_dual_data[2];
|
||||
void * ym3526[2];
|
||||
void * y8950[2];
|
||||
void * ymf262[2];
|
||||
void * ymf278b[2];
|
||||
void * ymf271[2];
|
||||
void * ymz280b[2];
|
||||
void * rf5c164;
|
||||
void * pwm;
|
||||
void * ay8910[2];
|
||||
void * gbdmg[2];
|
||||
void * nesapu[2];
|
||||
void * multipcm[2];
|
||||
void * upd7759[2];
|
||||
void * okim6258[2];
|
||||
void * okim6295[2];
|
||||
void * k051649[2];
|
||||
void * k054539[2];
|
||||
void * huc6280[2];
|
||||
void * c140[2];
|
||||
void * k053260[2];
|
||||
void * pokey[2];
|
||||
void * qsound[2];
|
||||
void * scsp[2];
|
||||
void * wswan[2];
|
||||
void * vsu[2];
|
||||
void * saa1099[2];
|
||||
void * es5503[2];
|
||||
void * es550x[2];
|
||||
void * x1_010[2];
|
||||
void * c352[2];
|
||||
void * ga20[2];
|
||||
void * daccontrol[255];
|
||||
} VGM_PLAYER;
|
344
Frameworks/GME/vgmplay/VGMPlay.ini
Normal file
344
Frameworks/GME/vgmplay/VGMPlay.ini
Normal file
|
@ -0,0 +1,344 @@
|
|||
; VGMPlay Configuration File
|
||||
; --------------------------
|
||||
;
|
||||
; Default Values are usually 0 (False for boolean ones)
|
||||
; Boolean Values are:
|
||||
; False / 0
|
||||
; True / 1
|
||||
|
||||
[General]
|
||||
; Default Sample Rate: 44100
|
||||
SampleRate = 48000
|
||||
; If you set PlaybackRate to 50, some songs will play slower, like on a PAL console.
|
||||
; If you set it to 60, some songs may play faster, like PAL games on a NTSC console.
|
||||
PlaybackRate = 0
|
||||
|
||||
; double the volume of the YM2xxx SSG, if it gets overridden by a VGM's header.
|
||||
; This option will be removed once all VGMs on vgmrips are fixed.
|
||||
DoubleSSGVol = True
|
||||
|
||||
; Display Japanese GD3 Tag if available
|
||||
; Most western Windows systems won't be able to display Japanese characters in the normal console,
|
||||
; so use at own risk. (Linux doesn't have this problem.)
|
||||
PreferJapTag = False
|
||||
|
||||
; Default Fade Time: 5000
|
||||
FadeTime = 8000
|
||||
; In-Playlist Fade Time: for all looping tracks in a playlist (except the last one)
|
||||
; Setting this to 0 simulate a Song-Medley without gaps.
|
||||
; Default Fade Time in Playlist: 2000
|
||||
FadeTimePL = 0
|
||||
JinglePause = 1000
|
||||
|
||||
; Fade RAW logs from emulators (VGMs without Creator-Tag) so that they don't
|
||||
; end abruptly at the full volume level but at 33%
|
||||
;FadeRAWLogs = True
|
||||
; Default Volume: 1.0 (of course)
|
||||
Volume = 1.0
|
||||
|
||||
; Log Sound to Wave: 0 - no logging, 1 - log only, 2 - play and log
|
||||
LogSound = 0
|
||||
|
||||
; Maximum Loops before fading
|
||||
; Default: 0x02 (0x01 for CMF)
|
||||
MaxLoops = 0x02
|
||||
MaxLoopsCMF = 0x01
|
||||
|
||||
; Resampling Mode:
|
||||
; 0 - always high quality resampler (default)
|
||||
; 1 - HQ resampler for upsampling, LQ resampler for downsampling (recommend for slow machines)
|
||||
; 2 - always low quality resampler (very fast)
|
||||
ResamplingMode = 0
|
||||
; Chip Sample Mode:
|
||||
; 0 - Native (default)
|
||||
; 1 - use highest sampling rate (native or the one below)
|
||||
; 2 - use always the sampling rate below (CPU friendly)
|
||||
; 3 - use native sample rate for FM chips and highest sampling rate for all others
|
||||
ChipSmplMode = 3
|
||||
; Default Chip Sample Rate: 0 (results in value of Playback SampleRate)
|
||||
ChipSmplRate = 0
|
||||
|
||||
; Force Audio Buffer Number (1 Buffer = 10 ms, Minimum is 4, Maximum is 200)
|
||||
; higher values result in greater delays while seeking (and pausing with EmulatePause On)
|
||||
; set this to 50 or 100 if the sound is choppy
|
||||
; 0 results in 10 for Windows 98/ME/2000/XP/7,
|
||||
; 50 for Windows 95 and 20 for Windows Vista
|
||||
AudioBuffers = 0
|
||||
; "Surround" Sound - inverts the waveform of the right channel to create a pseudo surround effect
|
||||
; use only with headphones!!
|
||||
SurroundSound = False
|
||||
; Emulate during Pause: continue to generate sound while playback is paused
|
||||
EmulatePause = False
|
||||
; Shows the last data block played with DAC Stream Command 95. Useful for debugging.
|
||||
; 0 - don't show
|
||||
; 1 - show data block ID only
|
||||
; 2 - show data block ID + frequency
|
||||
; 3 - show data block ID + frequency in KHz
|
||||
ShowStreamCmds = 3
|
||||
|
||||
; --- FM Hardware Section Start ---
|
||||
; Hardware FM Port (in hex, usually 220 or 388)
|
||||
FMPort = 0
|
||||
; Force FM Mode, even if only the SN76496 is used, also enables Mixed Mode (Hardware FM + Software Emulator)
|
||||
FMForce = False
|
||||
; Makes some FM-Voices fading on track-end instead of instant silencing them
|
||||
FMSoftStop = True
|
||||
; Overrides Volume setting, if FM hardware is used
|
||||
; Possible values:
|
||||
; = 0 - don't override (default)
|
||||
; > 0 - override Volume setting and VGM Volume Modifier
|
||||
; < 0 - multiply with volume
|
||||
FMVolume = 0.0
|
||||
; --- FM Hardware Section End ---
|
||||
|
||||
|
||||
; Chip Options
|
||||
; ------------
|
||||
; - Disabled = False/True
|
||||
; disable the emulation of the current chip
|
||||
; - EmulatorType = 0 / 1 / ...
|
||||
; 0 is recommend/default, 1+ are alternative emulation cores
|
||||
; - MuteMask = 0
|
||||
; mute channels by setting the muting bitmask
|
||||
; - MuteCh? = False/True
|
||||
; mute channel ?
|
||||
; - Mutexxx = False/True
|
||||
; mute channel with the name xxx (e.g. DAC, DT, BD, ...)
|
||||
|
||||
[SN76496]
|
||||
Disabled = False
|
||||
; EmulatorType: 0 - MAME, 1 - Maxim
|
||||
EmulatorType = 0x00
|
||||
; Channels: 4 (0-3)
|
||||
|
||||
[YM2413]
|
||||
Disabled = False
|
||||
; FMPort = 0:
|
||||
; EmulatorType: 0 - EMU2413, 1 - MAME
|
||||
; FMPort != 0:
|
||||
; EmulatorType: 0 - Valley Bell Custom, 1 - Meka
|
||||
EmulatorType = 0x00
|
||||
; Channels: 14 (0-8, BD, SD, TOM, TC, HH)
|
||||
|
||||
[YM2612]
|
||||
Disabled = False
|
||||
; EmulatorType: 0 - MAME (Genesis Plus GX), 1 - Gens
|
||||
EmulatorType = 0x00
|
||||
; MAME: if on, the chip updates its left/right channel alternatively, creating a nice pseudo-stereo effect
|
||||
; Note: If you emulate at a set sample rate, this option halves it.
|
||||
PseudoStereo = False
|
||||
; Gens: DAC Highpass-Filter (sometimes sounds good, but sometimes it generates a terrible noise)
|
||||
DACHighpass = False
|
||||
; Gens: SSG-EG Enable (very buggy)
|
||||
SSG-EG = False
|
||||
; Channels: 7 (0-5, DAC)
|
||||
|
||||
[YM2151]
|
||||
Disabled = False
|
||||
; Channels: 8 (0-7)
|
||||
|
||||
[SegaPCM]
|
||||
Disabled = False
|
||||
; Channels: 16 (0-15)
|
||||
|
||||
[RF5C68]
|
||||
Disabled = False
|
||||
; Channels: 8 (0-7)
|
||||
|
||||
[YM2203]
|
||||
Disabled = False
|
||||
; AY/YM2149 EmulatorType: 0 - EMU2149, 1 - MAME
|
||||
EmulatorType = 0x00
|
||||
; disable the AY8910-part to speed up loading
|
||||
DisableAY = False
|
||||
; Channels: 3 (0-2)
|
||||
|
||||
[YM2608]
|
||||
Disabled = False
|
||||
EmulatorType = 0x00
|
||||
DisableAY = False
|
||||
; Channels: 6 FM (0-5) + 6 ADPCM (0-5) + 1 Delta-T
|
||||
; Use MuteMask_FM, MuteMask_PCM (Delta-T is Ch6), MuteFMCh, MutePCMCh and MuteDT
|
||||
|
||||
[YM2610]
|
||||
Disabled = False
|
||||
EmulatorType = 0x00
|
||||
DisableAY = False
|
||||
; Channels: 6 FM (0-5) + 6 ADPCM (0-5) + 1 Delta-T
|
||||
; Use MuteMask_FM, MuteMask_PCM (Delta-T is Ch6), MuteFMCh, MutePCMCh and MuteDT
|
||||
|
||||
[YM3812]
|
||||
Disabled = False
|
||||
; EmulatorType: 0 - DOSBox (AdLibEmu), 1 - MAME
|
||||
EmulatorType = 0x00
|
||||
; Channels: 14 (0-8, BD, SD, TOM, TC, HH)
|
||||
|
||||
[YM3526]
|
||||
Disabled = False
|
||||
; Channels: 14 (0-8, BD, SD, TOM, TC, HH)
|
||||
|
||||
[Y8950]
|
||||
Disabled = False
|
||||
; Channels: 15 (0-8, BD, SD, TOM, TC, HH, DT)
|
||||
|
||||
[YMF262]
|
||||
Disabled = False
|
||||
; EmulatorType: 0 - DOSBox (AdLibEmu), 1 - MAME
|
||||
EmulatorType = 0x00
|
||||
; Channels: 23 (0-17, BD, SD, TOM, TC, HH)
|
||||
|
||||
[YMF278B]
|
||||
Disabled = False
|
||||
; Channels: 23 FM (0-17, BD, SD, TOM, TC, HH) + 24 WaveTable (0-23)
|
||||
; Use MuteMask_FM, MuteMask_WT, MuteFMCh and MuteWTCh
|
||||
|
||||
[YMF271]
|
||||
Disabled = False
|
||||
; Channels: 12 (0-11)
|
||||
|
||||
[YMZ280B]
|
||||
Disabled = False
|
||||
; Channels: 8 (0-7)
|
||||
|
||||
[RF5C164]
|
||||
Disabled = False
|
||||
; Channels: 8 (0-7)
|
||||
|
||||
[PWM]
|
||||
Disabled = False
|
||||
; Channels: none (it just has left and right)
|
||||
|
||||
[AY8910]
|
||||
Disabled = False
|
||||
; EmulatorType: 0 - EMU2149, 1 - MAME
|
||||
EmulatorType = 0x00
|
||||
; Channels: 3 (0-2)
|
||||
|
||||
[GameBoy]
|
||||
Disabled = False
|
||||
; double the volume of the Wave Channel (sounds better, but may be less accurate and seems to sound distorted sometimes, like nezplay++)
|
||||
BoostWaveChn = True
|
||||
; don't double volume of the Noise Channel (like MESS and nezplay++, False is like VisualBoy Advance and sounds better for some games)
|
||||
LowerNoiseChn = True
|
||||
; disable the accuracy hacks (expect some slightly off-tune notes and a very distorted Wave Channel)
|
||||
Inaccurate = False
|
||||
; Channels: 4 (0-3)
|
||||
|
||||
[NES APU]
|
||||
Disabled = False
|
||||
; EmulatorType: 0 - NSFPlay, 1 - MAME
|
||||
EmulatorType = 0x00
|
||||
; Channels: 6 (0-5 = Square 1, Square 2, Triangle, Noise, DPCM, FDS)
|
||||
|
||||
; Options (NSFPlay cores only)
|
||||
; -------
|
||||
; APU/DMC Options (2 bits, default: 0x03)
|
||||
; 0x01 - OPT_UNMUTE_ON_RESET (enable all channels by default after reset)
|
||||
; 0x02 - OPT_NONLINEAR_MIXER
|
||||
SharedOpts = 0x03
|
||||
; APU Options (2 bits, default: 0x01)
|
||||
; 0x01 - OPT_PHASE_REFRESH
|
||||
; 0x02 - OPT_DUTY_SWAP
|
||||
APUOpts = 0x01
|
||||
; DMC Options (6 bits, default: 0x3B)
|
||||
; 0x01 - OPT_ENABLE_4011
|
||||
; 0x02 - OPT_ENABLE_PNOISE
|
||||
; 0x04 - OPT_DPCM_ANTI_CLICK (nullify register 4011 writes, keeps DPCM limits correctly)
|
||||
; 0x08 - OPT_RANDOMIZE_NOISE
|
||||
; 0x10 - OPT_TRI_MUTE (stops Triangle wave if set to freq = 0, processes it at a very high rate else)
|
||||
; 0x20 - OPT_TRI_NULL (VB custom, always makes Triangle return to null-level when stopping)
|
||||
DMCOpts = 0x3B
|
||||
; FDS Options (1 bit, default: 0x00)
|
||||
; 0x01 - OPT_4085_RESET (reset modulation phase on 4085 writes)
|
||||
FDSOpts = 0x00
|
||||
|
||||
[MultiPCM]
|
||||
Disabled = False
|
||||
; Channels: 28 (0-27)
|
||||
|
||||
[uPD7759]
|
||||
Disabled = False
|
||||
; Channels: none (actually 1)
|
||||
|
||||
[OKIM6258]
|
||||
Disabled = False
|
||||
; enables internal 10-bit processing (original MESS behaviour)
|
||||
; The comments in the code say something about 10-bit and 12-bit DAC, but that's not what the code does.
|
||||
Enable10Bit = False
|
||||
; Remove the DC offset by resetting the ADPCM signal everytime a Play command is issued.
|
||||
; Note: This causes lots of clicks with polyphonic ADPCM drivers, so the option is False by default.
|
||||
RemoveDCOfs = True
|
||||
; Channels: none (actually 1)
|
||||
|
||||
[OKIM6295]
|
||||
Disabled = False
|
||||
; Channels: 4 (0-3)
|
||||
|
||||
[K051649]
|
||||
; also known as SCC1
|
||||
Disabled = False
|
||||
; Channels: 5 (0-4)
|
||||
|
||||
[K054539]
|
||||
Disabled = False
|
||||
; Channels: 8 (0-7)
|
||||
|
||||
[HuC6280]
|
||||
Disabled = False
|
||||
; EmulatorType: 0 - Ootake, 1 - MAME (sounds brighter, lacks LFO)
|
||||
EmulatorType = 0x00
|
||||
; Channels: 6 (0-5)
|
||||
|
||||
[C140]
|
||||
Disabled = False
|
||||
; Channels: 24 (0-23)
|
||||
|
||||
[K053260]
|
||||
Disabled = False
|
||||
; Channels: 4 (0-3)
|
||||
|
||||
[Pokey]
|
||||
Disabled = False
|
||||
; Channels: 4 (0-3)
|
||||
|
||||
[QSound]
|
||||
Disabled = False
|
||||
; Channels: 16 (0-15)
|
||||
|
||||
[SCSP]
|
||||
Disabled = False
|
||||
; Skip all DSP calculations, huge speedup (the DSP doesn't work correctly right now anyway)
|
||||
BypassDSP = True
|
||||
; Channels: 32 (0-31)
|
||||
|
||||
[WSwan]
|
||||
Disabled = False
|
||||
; Channels: 4 (0-3)
|
||||
|
||||
[VSU]
|
||||
Disabled = False
|
||||
; Channels: 6 (0-5)
|
||||
|
||||
[SAA1099]
|
||||
Disabled = False
|
||||
; Channels: 6 (0-5)
|
||||
|
||||
[ES5503]
|
||||
Disabled = False
|
||||
; Channels: 32 (0-31)
|
||||
|
||||
[ES5506]
|
||||
Disabled = False
|
||||
; Channels: 32 (0-31)
|
||||
|
||||
[X1-010]
|
||||
Disabled = False
|
||||
; Channels: 16 (0-15)
|
||||
|
||||
[C352]
|
||||
Disabled = False
|
||||
; Channels: 32 (0-31)
|
||||
|
||||
[GA20]
|
||||
Disabled = False
|
||||
; Channels: 4 (0-3)
|
159
Frameworks/GME/vgmplay/VGMPlay.txt
Normal file
159
Frameworks/GME/vgmplay/VGMPlay.txt
Normal file
|
@ -0,0 +1,159 @@
|
|||
VGM Player - Readme
|
||||
==========
|
||||
|
||||
General
|
||||
=======
|
||||
Usage: Drop a file on the executable or open the program and type the filename.
|
||||
|
||||
Supported files types are:
|
||||
- Video Game Music Files (*.vgm, *.vgz)
|
||||
- Creative Music Files (*.cmf)
|
||||
- DosBox RAW OPL Log Files (*.dro)
|
||||
- Playlist files (*.m3u)
|
||||
|
||||
Supported chips
|
||||
---------------
|
||||
- SN76496** (Sega PSG) and T6W28** (NeoGeo Pocket custom)
|
||||
- YM2413* (OPLL)
|
||||
- YM2612 (OPN2)
|
||||
- YM2151 (OPM)
|
||||
- SegaPCM
|
||||
- RF5C68
|
||||
- YM2203 (OPN)
|
||||
- YM2608 (OPNA)
|
||||
- YM2610/B (OPNB)
|
||||
- YM3812* (OPL2)
|
||||
- YM3526* (OPL)
|
||||
- Y8950* (MSX AUDIO)
|
||||
- YMF262* (OP3)
|
||||
- YMF278B (OPL4) !
|
||||
- YMF271 (OPLX)
|
||||
- YMZ280B
|
||||
- RF5C164 (Sega MegaCD PCM)
|
||||
- PWM (from Sega 32x)
|
||||
- AY8910 (MSX PSG)
|
||||
- GameBoy DMG
|
||||
- NES APU (incl. FDS)
|
||||
- MultiPCM
|
||||
- UPD7759
|
||||
- OKI6258 (Sharp X68000 ADPCM)
|
||||
- OKI6295
|
||||
- K051649
|
||||
- K054539
|
||||
- HuC6280 (PC Engine)
|
||||
- Namco C140
|
||||
- K053260
|
||||
- Pokey (Atari)
|
||||
- QSound
|
||||
- SCSP (Saturn Custom Sound Processor, YMF292-F)
|
||||
- WonderSwan
|
||||
- Virtual Boy VSU
|
||||
- SAA1099
|
||||
- ESS5503
|
||||
- ESS5505/6
|
||||
- Seta X1-010
|
||||
- Namco C352
|
||||
- Irem GA20
|
||||
|
||||
|
||||
* This chip can be emulated via OPL Hardware (like Soundblaster sound cards).
|
||||
** OPL hardware emulation is available, but software emulation is prefered. Hardware emulation is used if another chip activates HW emulation or FMForce is True.
|
||||
! You need a sample ROM, called yrw801.rom, to make playback work. Place it in the directory where VGMPlay.exe lies.
|
||||
|
||||
OPL hardware emulation can be enabled by setting the "FMPort"-entry in the ini-file.
|
||||
If you want to use FM Hardware under Windows NT/2000/XP/... you have to install PortTalk.
|
||||
PortTalk Website: http://www.beyondlogic.org/porttalk/porttalk.htm
|
||||
Under Linux the program must have root rights to use Hardware FM.
|
||||
|
||||
It's possible to write Wave-Files by editing the "LogSound"-line in the ini-file.
|
||||
Batch conversions are possible by opening a playlist.
|
||||
FM Hardware can't be logged to Wave files.
|
||||
|
||||
Keys
|
||||
----
|
||||
You can use the following keys during playback:
|
||||
Space - Pause
|
||||
Cursor Left/Right - Seek 5 seconds backward/forward
|
||||
Ctrl + Cursor Left/Right - Seek 1 minute backward/forward
|
||||
ESC/Q - Quit the program
|
||||
F - Fade out
|
||||
R - Restart current Track
|
||||
PageUp/B - Previous Track
|
||||
PageDown/N - Next Track
|
||||
|
||||
Note: All keys also work during silent sound logging.
|
||||
|
||||
|
||||
System Reqiurements
|
||||
===================
|
||||
It depends on the files you want to play.
|
||||
|
||||
Minimum Reqiurements
|
||||
--------------------
|
||||
Software Emulation:
|
||||
|
||||
166 MHz should be enough for SN76496 + YM2612.
|
||||
For chips with 12+ FM channels you need probably need at least 700 MHz.
|
||||
16 MB RAM (plus a size of the VGM you want to play, so for a 100 MB vgm, you need ~110 MB RAM)
|
||||
|
||||
That allows you to play VGMs with up to 2x FM, 2x PSG or FM + PSG + PCM.
|
||||
It's NOT enough for YMF271 emulation.
|
||||
The YMF262 is equal to 2x FM. The YMF278B is Wavetable + YMF262 (with the latter one disabled if unused).
|
||||
|
||||
Hardware FM Playback:
|
||||
|
||||
486 with 33 MHz? - I dunno
|
||||
On my PII 233 MHz FM Playback takes 3.5% CPU at a maximum.
|
||||
|
||||
|
||||
Bugs
|
||||
====
|
||||
PauseEmulation is disabled under Linux unless FM Hardware is used.
|
||||
|
||||
Under Linux you have to double-tap ESC to quit the program (or just press Q). I haven't yet found a way around it.
|
||||
|
||||
Sometimes MAME's sound cores tend to sound strange. I already fixed some, but it's not my fault.
|
||||
|
||||
Ubuntu refuses to run (or maybe compile) VGMPlay correctly. It either crashes upon opening a vgm file or doesn't open the sound device. (and the ini-file, too. VGMs are opened for some reason.)
|
||||
Using Wine with the Windows-version of VGMPlay should work.
|
||||
|
||||
It runs fine on openSUSE. (I compile and test it regularly with 12.3 64-bit. Older version were successfully tested with 11.1 32-bit and 11.4 64-bit)
|
||||
It also ran fine on the Debian system at university.
|
||||
|
||||
|
||||
Comments
|
||||
========
|
||||
If you want to set some options, open the ini-file. It's well commented.
|
||||
|
||||
The T6W28 doesn't use MAME's T6W28 core. Instead I modified the SN76496 core to emulate the T6W28 with 2 SN76496 chips.
|
||||
|
||||
The SN76496 OPL emulation is okay, but it's impossible to get the noise sound right.
|
||||
|
||||
EMU2413 Emulator was added, because sometimes the one of MAME sounds strange.
|
||||
I added the Gens YM2612 core for the same reason (before I fixed MAME's YM2612 core).
|
||||
|
||||
I haven't yet found a player that supports all three version of dro files.
|
||||
P.S.: AdPlug now seems to support them.
|
||||
|
||||
Some may be wondering, how someone can have the idea to implement OPL Hardware support. Here a more or less small story:
|
||||
I like CMF MIDI files, but I was unable to listen to them while doing other things on my computer in Windows 95. It was impossible to listen to them unter Windows 2000. When I found AdPlug, the CMF support was bad and I started to make my VGM Player play CMF files. Debugging wasn't nice - a Pentium2 233MHz isn't stong enough for a Software OPL Emulator in Debug Mode. The OPL2-Port option in AdPlug was interesting (I have a Soundblaster 16) and showed me the power of PortTalk.
|
||||
My MIDI-FM Player that got OPL-Hardware-Support earlier than my VGM Player, because playing usual MIDI files requires a lot more debugging than playing simple VGM files. When it was working in my MIDI player, I implemented OPL-Hardware-Support into VGMPlay. Of course the first working chips were OPL/OPL2/OPL3. I remembered that Meka had OPL-Support, too and wrote my OPLL->OPL-Mapper. It sounded quite good, but I was unable to get the PSG and the YM2413 of Space Harrier Theme in sync. So a PSG->OPL-Mapper followed. Later I ported Meka's OPL Mapper, because I liked the bass of some Phantasy Star tunes.
|
||||
|
||||
|
||||
Credits
|
||||
=======
|
||||
This program was written by Valley Bell.
|
||||
|
||||
- almost all software emulators are from MAME (http://mamedev.org)
|
||||
- EMU2413 and Gens YM2612 were ported from Maxim's in_vgm
|
||||
- the YMF278B core was ported from openMSX
|
||||
- zlib compression by Jean-loup Gailly and Mark Adler is used
|
||||
- all custom OPL Mappers were written using MAME software emulators and the OPL2/3 programming guides by Jeffrey S. Lee and Vladimir Arnost
|
||||
- one YM2413 OPL Mapper was ported from MEKA.
|
||||
- the RF5C164 and PWM cores were ported from Gens/GS
|
||||
- the MAME YM2612 core was fixed with the help of Blargg's MAME YM2612 fix and Genesis Plus GX' YM2612 core
|
||||
- AdLibEmu (OPL2 and OPL3 core) was ported from DOSBox
|
||||
- The default HuC6280 core is from Ootake.
|
||||
- EMU2149, the alternative NES APU core and the NES FDS core were ported from rainwarrior's NSFPlay.
|
||||
- the WonderSwan core was ported from in_wsr
|
||||
- Virtual Boy VSU core was ported from vbjin and originates from mednafen
|
2672
Frameworks/GME/vgmplay/VGMPlayUI.c
Normal file
2672
Frameworks/GME/vgmplay/VGMPlayUI.c
Normal file
File diff suppressed because it is too large
Load diff
1155
Frameworks/GME/vgmplay/VGMPlay_AddFmts.c
Normal file
1155
Frameworks/GME/vgmplay/VGMPlay_AddFmts.c
Normal file
File diff suppressed because it is too large
Load diff
75
Frameworks/GME/vgmplay/VGMPlay_Intf.h
Normal file
75
Frameworks/GME/vgmplay/VGMPlay_Intf.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
// VGMPlay_Intf.h: VGMPlay Interface Header File
|
||||
//
|
||||
|
||||
//#define NO_WCHAR_FILENAMES
|
||||
#ifndef WIN32
|
||||
// Linux uses UTF-8 Unicode and has no special wide-character file routines.
|
||||
#define NO_WCHAR_FILENAMES
|
||||
#endif
|
||||
|
||||
typedef struct waveform_16bit_stereo
|
||||
{
|
||||
INT16 Left;
|
||||
INT16 Right;
|
||||
} WAVE_16BS;
|
||||
|
||||
typedef struct waveform_32bit_stereo
|
||||
{
|
||||
INT32 Left;
|
||||
INT32 Right;
|
||||
} WAVE_32BS;
|
||||
|
||||
typedef struct vgm_file VGM_FILE;
|
||||
struct vgm_file
|
||||
{
|
||||
int (*Read)(VGM_FILE*, void*, UINT32);
|
||||
int (*Seek)(VGM_FILE*, UINT32);
|
||||
UINT32 (*GetSize)(VGM_FILE*);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void * VGMPlay_Init(void);
|
||||
void VGMPlay_Init2(void* vgmp);
|
||||
void VGMPlay_Deinit(void* vgmp);
|
||||
|
||||
UINT32 GetGZFileLength(const char* FileName);
|
||||
|
||||
bool OpenVGMFile(void* vgmp, const char* FileName);
|
||||
bool OpenVGMFile_Handle(void* vgmp, VGM_FILE*);
|
||||
void CloseVGMFile(void* vgmp);
|
||||
|
||||
void FreeGD3Tag(GD3_TAG* TagData);
|
||||
UINT32 GetVGMFileInfo(const char* FileName, VGM_HEADER* RetVGMHead, GD3_TAG* RetGD3Tag);
|
||||
UINT32 GetVGMFileInfo_Handle(VGM_FILE*, VGM_HEADER* RetVGMHead, GD3_TAG* RetGD3Tag);
|
||||
UINT32 CalcSampleMSec(void* vgmp, UINT64 Value, UINT8 Mode);
|
||||
UINT32 CalcSampleMSecExt(void* vgmp, UINT64 Value, UINT8 Mode, VGM_HEADER* FileHead);
|
||||
const char* GetChipName(UINT8 ChipID);
|
||||
const char* GetAccurateChipName(UINT8 ChipID, UINT8 SubType);
|
||||
UINT32 GetChipClock(void* vgmp, UINT8 ChipID, UINT8* RetSubType);
|
||||
|
||||
#ifndef NO_WCHAR_FILENAMES
|
||||
UINT32 GetGZFileLengthW(const wchar_t* FileName);
|
||||
bool OpenVGMFileW(void* vgmp, const wchar_t* FileName);
|
||||
UINT32 GetVGMFileInfoW(const wchar_t* FileName, VGM_HEADER* RetVGMHead, GD3_TAG* RetGD3Tag);
|
||||
#endif
|
||||
|
||||
INT32 SampleVGM2Playback(void* vgmp, INT32 SampleVal);
|
||||
INT32 SamplePlayback2VGM(void* vgmp, INT32 SampleVal);
|
||||
|
||||
void PlayVGM(void* vgmp);
|
||||
void StopVGM(void* vgmp);
|
||||
void RestartVGM(void* vgmp);
|
||||
void SeekVGM(void* vgmp, bool Relative, INT32 PlayBkSamples);
|
||||
void RefreshMuting(void* vgmp);
|
||||
void RefreshPanning(void* vgmp);
|
||||
void RefreshPlaybackOptions(void* vgmp);
|
||||
|
||||
UINT32 FillBuffer(void* vgmp, WAVE_16BS* Buffer, UINT32 BufferSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
130
Frameworks/GME/vgmplay/VGMPlay_Updates.txt
Normal file
130
Frameworks/GME/vgmplay/VGMPlay_Updates.txt
Normal file
|
@ -0,0 +1,130 @@
|
|||
Update list since 0.4.0u3 (03.12.2012)
|
||||
- replaced some larger swich statements with function pointers (small speed up)
|
||||
- fixed Stereo flag in SN76496 OPL mapper
|
||||
- optimized playback routine (huge speed up, >20% for single-chip VGMs)
|
||||
- writing to a second chip if only the first one is defined doesn't cause crashes anymore
|
||||
- shortened the Chip Reset, Chip Mute and Chip Panning routines
|
||||
- added OKIM6295, OKIM6258 and UPD7759 to DAC Stream Control
|
||||
- slight improvements on OPL Hardware Playback
|
||||
- fixed bug where [VGMPlay Linux] was unable to show Unicode characters
|
||||
- added multiple paths for VGMPlay.ini and OPL4 ROM
|
||||
- [VGMPlay Linux] is now checking for "vgmplay.ini" as well as "VGMPlay.ini"
|
||||
- cleaned the code a bit
|
||||
- [VGMPlay] now frees its memory properly when quitting
|
||||
|
||||
17.04.2013 and later:
|
||||
- improved skipping code for OPL hardware (to hopefully reduce noise after seeking)
|
||||
- made Makefile print short information instead of full gcc command lines
|
||||
- added possibility to override volume (+gain) of VGMs when using OPL hardware
|
||||
- [VGMPlay] made it use stderr for error messages
|
||||
- added optional debug output for DAC stream control (current data block, frequency)
|
||||
- fixed a bug with data blocks being re-read when restarting playback (wasted memory)
|
||||
- [VGMPlay] fixed bug when alternating between OPL hardware playback and emulation without restarting VGMPlay (e.g. via playlist with OPL and non-OPL VGMs)
|
||||
- fixed crash where the NES ROM could be written to invalid offsets
|
||||
- added alternative AY8910 core (EMU2149)
|
||||
- added NES DPCM address overflow behaviour, added alternative DPCM range (based on NSFPlay)
|
||||
- [VGMPlay] prevented it from writing too quickly to the OPL chip on fast computers
|
||||
|
||||
15.06.2013 and later:
|
||||
- [VGMPlay] console title now changes to "Song (Game) - VGM Player" while playing
|
||||
- [VGMPlay] made it fall back to Japanese tags if English ones are empty
|
||||
- [VGMPlay] made Console title use Unicode (yes, that works - not like the in-Console text)
|
||||
- [in_vgm] made ANSI GetFileInfo function fall back to Japanese tags if English ones are not present
|
||||
- [in_vgm] fixed Unicode -> ANSI filename conversion bug (caused Unicode Tag function to fail with some non-ANSI filenames)
|
||||
- [in_vgm] fixed File Info Dialog falling back to tags of the other language (it isn't supposed to do that)
|
||||
- [VGMPlay] some Codepage fixes for Windows version, hopefully it now behaves correctly in all cases.
|
||||
The Linux version should now be able to print non-ANSI Unicode characters in tags.
|
||||
- [VGMPlay Windows] now writes Unicode to the console (via WinAPI), so with the non-raster-fonts Japanese characters should work now. (although I only saw square boxes in WinXP, copying and pasting into Notepad worked at least)
|
||||
- [in_vgm] Fixed bug where "Chip Rate" == 0 didn't work and would get reset to 44100 when loading the plugin.
|
||||
- fixed bug where YM2612 Database Block caused DAC Stream Control to malfunction or crash (The MAME devs were right - realloc IS evil.)
|
||||
- [VGMPlay Linux] added support for libao
|
||||
|
||||
09.09.2013 and later:
|
||||
- added WonderSwan support
|
||||
- added better SN-PSG name display
|
||||
- made it work on Big Endian machines (Thanks to nextvolume for sending me a patch that helped to find the critical spots)
|
||||
- cleaned code that loads VGMs a bit
|
||||
- shortened the Chip Stop routine
|
||||
- applied MAME fixes to YM2413/YMF262 (thread safe now), K051649 (added test register, changed sound generation code a bit), K054539 (replaced sound generation code, might improve reverb), YMZ280B (minor stuff), YMF271 (FM code replaced, sounds different now!)
|
||||
- added NES APU database block type
|
||||
- added NES APU to 0x68 command (RAM write from database) and fixed its dual chip support
|
||||
- ported NES APU/DMC emulator from NSFPlay 2.2
|
||||
- ported NES FDS emulator from NSFPlay 2.3
|
||||
- fixed MAME NES emulator reset
|
||||
- fixed MAME NES (and maybe others?) unmuting all channels when restarting a song or seeking back
|
||||
- added EMU2149 to YM2203, YM2608 and YM2610, fixes wrong AY-PSG tones in some VGMs (bug is still present with MAME's AY core)
|
||||
- [VGMPlay] modified makefile to make it easier to compile VGMPlay using MSYS/MinGW
|
||||
- [in_vgm] fixed crash when trying to mute channels after opening Winamp, but before any song was played
|
||||
- [in_vgm] added options from VGMPlay.ini to in_vgm.ini
|
||||
- [in_vgm] fixed track length display bug after changing the playback rate
|
||||
- [VGMPlay Linux] fixed warnings that are printed from ym2612.c
|
||||
- added VRC7 mode for YM2413 (reducing features and using separate instrument set)
|
||||
- [in_vgm] made OK button of File Dialog return another error code to Winamp to prevent a playlist bug
|
||||
|
||||
Updates since 0.4.0u4 (02.11.2013)
|
||||
- added code for muting channels to K053260 (looks like I forgot that one) and K054539 (lost when applying MAME fixes)
|
||||
- made K054539 use a proper clock (with a fallback for older VGMs)
|
||||
- added a small hack that allows mid-song sample rate changes for the OKIM6258 chip (I'll make a proper implementation for 0.41)
|
||||
- [VGMPlay] fixed absolute paths in m3u files
|
||||
- [VGMPlay] fixed path handling, makes paths that contain / and \ work in both Windows and Unix, fixes m3u Windows paths under Unix
|
||||
- fixed pitch of YM2608 ADPCM Tom Tom and Rim Shot (reported by MaliceX)
|
||||
- fixed YM2612 Timer A (there are still tiny rounding errors though), this fixed the CSM mode
|
||||
- fixed probable YM2612 bug (CSM mode was able to prevent KeyOn/Off commands on channels other than FM3)
|
||||
- fixed noise calculation in MAME's AY8910 (applied latest MAME update)
|
||||
- fixed a few crashes related to corrupted VGM headers with invalid offsets and insane clock values (though not all)
|
||||
- [VGMPlay] MuteWTCh# now works in VGMPlay.ini
|
||||
- fixed clicks in YMF278B core (introduced when porting it from openMSX)
|
||||
- [VGMPlay] fixed length display when VGMs play slower/faster after using the PlaybackRate option
|
||||
- fixed bug where VGZs with additional 00s at the end won't play (because VGMPlay will read an unpacked size of 0 bytes)
|
||||
- changed Endianess of SCSP RAM data to Big Endian (as it should be)
|
||||
- applied MAME QSound fixes (key on register, chip initialization)
|
||||
- removed last A from AY-3-8910A and variants
|
||||
- added an option to force OKIM6258 into 12-bit mode (makes it louder sometimes, but an internal 12-bit calculation seems to be more correct)
|
||||
- VGMs using the OKIM6258 or OKIM6295 are now half as loud (affects global volume only, not chip-relative volume)
|
||||
- [VGMPlay] fixed crash that happened on Linux when trying to display a large Notes tag (thanks to vampi-the-frog for the report)
|
||||
- OKIM6258 lowers its output signal faster if there's no incoming data (reduces clicks)
|
||||
|
||||
Updates since 0.4.0u5 (13.04.2014)
|
||||
- fixed panning in AdLibEmu with 4-op instruments (it used the bits from Channel+0 instead of Channel+3)
|
||||
- fixed panning in AdLibEmu for rhythm channels
|
||||
- [VGMPlay] fixed YM2608/YM2610 DeltaT-channel not being muteable via MuteMask_PCM
|
||||
- [VGMPlay] fixed muting of YM278B's FM drums
|
||||
- applied MAME YM2612 Timer fix (said to fix SFX in Streets of Rage 2, see MAME Testers 05049)
|
||||
- fixed C140 sub chip type and C140/System 21 banking (using current MAME code)
|
||||
- added code to handle "real" C140 clock
|
||||
- [VGMPlay] fixed "make install" (the share/vgmplay/ folder was created without "execute" rights for users)
|
||||
- improved OKIM6258 data cache (should reduce clicks a bit)
|
||||
- YMF278B: fixed OPL3 register writes and OPL3 chip clock
|
||||
- applied MAME K053260 DPCM decoding fix
|
||||
- applied MAME OPLx Key Scale Level fix
|
||||
- added 40h-byte-FIFO to UPD7759 chip when in Slave mode, based on how Sega Pico games work
|
||||
- fixed T6W28 muting (Noise channel muting was controlled by chip #2, affected in_vgm only)
|
||||
Thanks to the developers of foo_input_vgm for noticing this bug.
|
||||
- added NMK112 banking to OKIM6295 emulation
|
||||
- added callback function for chip sample rate change
|
||||
-> replaces OKIM6258 hack
|
||||
-> fixes OPN SSG with MAME AY emulation
|
||||
-> makes OKIM6295 clock changes work
|
||||
- added routines for wide-character file names (only used by in_vgm for now)
|
||||
- fixed RAM write range check for RF5C68 and RF5C164
|
||||
- made OKIM6258 FIFO queue larger, added RemoveDCOfs option
|
||||
- [VGMPlay] fixed tag display under Windows 95
|
||||
- fixed YM2151 internal sample clipping (works like YM2612 now, can reduce distortion)
|
||||
- fixed SegaPCM volume register bitmask [thanks ctr for finding the bug]
|
||||
- fix potential crash in MultiPCM chip when playing invalid instruments
|
||||
- fixed buggy frequency writes in K051649 by backporting some MAME changes
|
||||
- added VSU, SAA1099 support
|
||||
- fixed high beep in NSFPlay NES core with triangle at frequency 0 and OPT_TRI_NULL option
|
||||
- [VGMPlay] fixed YM2612 DAC not being muteable via MuteMask
|
||||
- added ES5503, ES5506, Seta X1-010, Namco C352, Irem GA20 support
|
||||
- [VGMPlay] fixed Loop Length (is now adjusted for changed playback rates)
|
||||
|
||||
Updates since 0.4.0u6 (30.05.2015)
|
||||
- fixed SAA1099 muting (muting channel 1 or 4 prevented the envelope generator from running, thus muting 0-2 or 3-5 respectively)
|
||||
- made SAA1099 output bipolar
|
||||
- [VGMPlay] fix compiling under Linux (broken since Wide-Charcter file name support)
|
||||
- fixed ES5503 sample rate (divider was off by one)
|
||||
- applied fix from VOGONS that makes the SAA1099 core actually use the chip clock
|
||||
- fixed YMF278B's FM part being emulated at wrong sample rate
|
||||
- fixed Irem GA20 channel muting
|
||||
- fixed playing non-NMK banked OKIM6295 VGMs after NMK-banked ones
|
403
Frameworks/GME/vgmplay/XMasFiles/SWJ-SQRC01_1C.h
Normal file
403
Frameworks/GME/vgmplay/XMasFiles/SWJ-SQRC01_1C.h
Normal file
|
@ -0,0 +1,403 @@
|
|||
// SWJ-SQRC01_1C.vgz
|
||||
UINT8 FF1ws_1C[0x1908] =
|
||||
{ 0x1F, 0x8B, 0x08, 0x00, 0xD4, 0x7A, 0x2F, 0x52, 0x02, 0x00, 0xD4, 0x98, 0x57, 0xCC, 0x0E, 0x51,
|
||||
0x10, 0x86, 0xC7, 0xFA, 0x7D, 0x7A, 0x0D, 0x42, 0x5C, 0x10, 0x12, 0x2E, 0x08, 0xA2, 0x25, 0x7A,
|
||||
0xFB, 0x95, 0x04, 0x21, 0xD1, 0xE2, 0x42, 0x39, 0x21, 0x24, 0x12, 0xD1, 0xAD, 0x16, 0xBD, 0xF7,
|
||||
0xDE, 0x7B, 0xEF, 0xBD, 0x1B, 0xDC, 0x6D, 0x24, 0x88, 0x1E, 0xA2, 0x04, 0x97, 0x6E, 0x48, 0x5C,
|
||||
0x48, 0x44, 0x94, 0x67, 0x8F, 0xC3, 0xE2, 0x60, 0xD5, 0xE0, 0x4B, 0x26, 0xF1, 0xAD, 0x9D, 0x77,
|
||||
0xDE, 0x77, 0x66, 0xCE, 0x9C, 0xF9, 0xFE, 0x2E, 0xFD, 0x06, 0x94, 0xEB, 0xDA, 0x4B, 0x64, 0x70,
|
||||
0x0E, 0xF9, 0xF0, 0x69, 0xDA, 0x53, 0xE4, 0x71, 0xC9, 0x72, 0x72, 0xB5, 0x80, 0x48, 0xA5, 0x1E,
|
||||
0x65, 0xE4, 0xF3, 0xCF, 0x1A, 0xF9, 0x87, 0x3E, 0x0F, 0xAB, 0x7E, 0xF2, 0x75, 0x90, 0xE6, 0x11,
|
||||
0xCD, 0x27, 0x9A, 0x5F, 0x54, 0x44, 0x73, 0x88, 0x06, 0xA2, 0x39, 0x45, 0xB3, 0x44, 0x73, 0x89,
|
||||
0x66, 0x44, 0x73, 0xF3, 0x46, 0x01, 0xD1, 0x82, 0xA2, 0x79, 0x45, 0x8B, 0x34, 0xD1, 0xE2, 0xA2,
|
||||
0x45, 0x33, 0x83, 0xB4, 0x50, 0x29, 0x2D, 0x1C, 0x98, 0xD6, 0x41, 0x24, 0x13, 0xDE, 0x44, 0x32,
|
||||
0x11, 0x9B, 0x84, 0x4D, 0xC6, 0xA6, 0x60, 0x53, 0xB1, 0x69, 0xD8, 0x74, 0x6C, 0x86, 0x44, 0x32,
|
||||
0x13, 0x9B, 0x85, 0xCD, 0xC6, 0xE6, 0x60, 0x73, 0xB1, 0x79, 0xD8, 0x7C, 0x19, 0x1A, 0xC9, 0x02,
|
||||
0x5E, 0x5A, 0x88, 0x2D, 0xC2, 0x16, 0x63, 0x4B, 0xB0, 0xA5, 0xD8, 0x32, 0x6C, 0x39, 0xB6, 0x82,
|
||||
0x17, 0x57, 0x62, 0xAB, 0xB0, 0xD5, 0xD8, 0x1A, 0x6C, 0x2D, 0xB6, 0x0E, 0x5B, 0x2F, 0xC3, 0x22,
|
||||
0xD9, 0xF0, 0x2A, 0x92, 0x8D, 0xCB, 0x22, 0xD9, 0x54, 0x3D, 0x92, 0xCD, 0x2F, 0x23, 0xD9, 0x32,
|
||||
0x35, 0x92, 0xAD, 0xCD, 0x22, 0xD9, 0x56, 0x2C, 0x92, 0xED, 0x2D, 0x22, 0xD9, 0xD1, 0x27, 0x92,
|
||||
0x9D, 0xE5, 0x23, 0xD9, 0x55, 0x3B, 0x92, 0xDD, 0xFB, 0x22, 0xD9, 0xC3, 0xFB, 0x7B, 0x4F, 0x44,
|
||||
0xB2, 0x6F, 0x78, 0x24, 0xFB, 0x6B, 0x8C, 0x00, 0xA0, 0x39, 0x00, 0xE5, 0x01, 0x78, 0x03, 0xC0,
|
||||
0x13, 0x00, 0xEA, 0x00, 0xB0, 0x06, 0x80, 0x0C, 0x00, 0x97, 0x01, 0x78, 0x03, 0x00, 0xB6, 0x0B,
|
||||
0xDB, 0x1D, 0x00, 0xD0, 0x0F, 0x80, 0x0D, 0x00, 0x08, 0x00, 0xC5, 0x06, 0x6B, 0x56, 0x69, 0xCD,
|
||||
0x95, 0x7B, 0x70, 0x24, 0x07, 0x00, 0x3E, 0x08, 0x91, 0x43, 0x10, 0x39, 0x0C, 0x91, 0x23, 0x10,
|
||||
0x39, 0x0A, 0x91, 0x63, 0x10, 0x39, 0x0E, 0x91, 0x13, 0x10, 0x39, 0x49, 0x9C, 0x53, 0x10, 0x39,
|
||||
0x0D, 0x11, 0xE5, 0xFD, 0x33, 0x10, 0x39, 0x0B, 0x91, 0x73, 0x35, 0x86, 0x03, 0xD0, 0x1C, 0x80,
|
||||
0xF2, 0x00, 0xBC, 0x01, 0xE0, 0x09, 0x00, 0x75, 0x00, 0x58, 0x03, 0x40, 0x06, 0x80, 0xCB, 0x00,
|
||||
0xBC, 0x01, 0x00, 0x3B, 0x85, 0x9D, 0x86, 0x88, 0xF6, 0x03, 0x60, 0x03, 0x00, 0x02, 0x00, 0x44,
|
||||
0x32, 0xBD, 0x35, 0x77, 0xD6, 0x20, 0x2D, 0xD2, 0xD6, 0x54, 0x0D, 0x34, 0x6F, 0xCD, 0xA1, 0x9A,
|
||||
0x0F, 0xCB, 0x5F, 0xD3, 0xDC, 0xC8, 0x68, 0xBE, 0xEC, 0x21, 0x9A, 0x3F, 0xDB, 0xCC, 0xCC, 0xD2,
|
||||
0xBC, 0xD9, 0xA6, 0x6C, 0x5E, 0xCD, 0xDB, 0xD9, 0xDC, 0xE5, 0x69, 0x27, 0xFE, 0xBF, 0x85, 0xB9,
|
||||
0x96, 0x51, 0x69, 0xA8, 0x39, 0x72, 0x8F, 0xD4, 0xE0, 0xB9, 0xE6, 0xCC, 0x0A, 0xB5, 0x48, 0x7B,
|
||||
0x53, 0x23, 0xD0, 0x3C, 0xD9, 0x43, 0x41, 0x31, 0xF3, 0x63, 0x1F, 0xB0, 0xFA, 0x80, 0xD0, 0xD2,
|
||||
0x34, 0xE2, 0x79, 0x67, 0x73, 0x2B, 0xA3, 0x79, 0xFA, 0x0E, 0x8D, 0x51, 0x96, 0x67, 0x69, 0xFE,
|
||||
0xF2, 0xA6, 0x21, 0x4F, 0xC3, 0x21, 0x9A, 0xB7, 0xAF, 0x39, 0x50, 0x50, 0xA5, 0xC6, 0x08, 0x0D,
|
||||
0xCE, 0xDB, 0x67, 0x44, 0x05, 0x61, 0x81, 0x8D, 0x9A, 0x6D, 0x3D, 0x6F, 0xC7, 0x9E, 0x43, 0x62,
|
||||
0xCF, 0x0E, 0x41, 0xCC, 0x6D, 0x4A, 0x16, 0x9E, 0x43, 0x63, 0xCF, 0xFD, 0x78, 0x36, 0xC4, 0xF3,
|
||||
0x39, 0x9E, 0x2E, 0xF6, 0x50, 0x18, 0x9A, 0xD9, 0x2E, 0x7E, 0xB6, 0x69, 0xFA, 0x69, 0xEC, 0x21,
|
||||
0xE8, 0x33, 0x57, 0x33, 0xCE, 0x9F, 0x6F, 0xE5, 0x63, 0xF4, 0x7C, 0x45, 0xCD, 0xCD, 0x0C, 0x1C,
|
||||
0x46, 0xC2, 0x81, 0x67, 0x12, 0x6A, 0xA6, 0xB2, 0xA9, 0x86, 0x67, 0x11, 0xA2, 0xE6, 0x30, 0x0F,
|
||||
0x32, 0x71, 0x1E, 0x2E, 0xE1, 0x55, 0x8E, 0xEF, 0x81, 0x39, 0x5E, 0xF0, 0x7D, 0x06, 0x3A, 0x86,
|
||||
0x1A, 0xB4, 0xD1, 0x9C, 0xB9, 0x4C, 0xBD, 0x4F, 0xA5, 0x8F, 0xF8, 0x92, 0xEC, 0xC5, 0x59, 0x04,
|
||||
0xB2, 0x84, 0x12, 0xF2, 0xDD, 0x21, 0x3F, 0x04, 0xF2, 0x9F, 0x78, 0xC7, 0x14, 0x1C, 0xF1, 0x44,
|
||||
0x3A, 0x04, 0x49, 0xD7, 0x7B, 0xBF, 0x81, 0xF8, 0x9D, 0xFA, 0xDC, 0xCF, 0xB4, 0xF8, 0xCC, 0xE7,
|
||||
0x86, 0x13, 0x4A, 0x8A, 0xE3, 0x58, 0xC8, 0x1B, 0x32, 0x5A, 0x33, 0xCF, 0x34, 0x77, 0xCE, 0x77,
|
||||
0xEA, 0x86, 0xA2, 0x0E, 0xAA, 0xD6, 0x1D, 0x85, 0x25, 0xF2, 0xBE, 0x57, 0xB8, 0x22, 0x0B, 0x85,
|
||||
0xD4, 0x1C, 0x19, 0xE8, 0x24, 0x5C, 0x18, 0x87, 0xAB, 0xEF, 0x55, 0xC7, 0x0F, 0x97, 0x48, 0xEB,
|
||||
0x0B, 0xC5, 0xE5, 0x3E, 0x45, 0x97, 0x14, 0x5F, 0xD6, 0xC1, 0x82, 0x2E, 0x0E, 0x14, 0x8F, 0x98,
|
||||
0xEA, 0xEF, 0xB3, 0x1F, 0xC6, 0xFC, 0xE6, 0x59, 0x7E, 0x25, 0x3F, 0xF0, 0x5B, 0x6E, 0xF9, 0x95,
|
||||
0xB3, 0xFC, 0xA8, 0xA6, 0x84, 0x48, 0xBB, 0x93, 0x14, 0xC1, 0x8F, 0x35, 0xD4, 0xF1, 0xFB, 0xA8,
|
||||
0xE3, 0xC6, 0xC3, 0xEF, 0x05, 0xFC, 0x7E, 0x44, 0xD3, 0x34, 0x7C, 0x4A, 0x6A, 0xCE, 0x0C, 0x6E,
|
||||
0xDF, 0x1B, 0xEA, 0xA0, 0x0B, 0x75, 0x7F, 0xA4, 0x66, 0x9D, 0xD2, 0x5C, 0xB9, 0x46, 0x68, 0x26,
|
||||
0x5B, 0x73, 0x07, 0xA6, 0x8A, 0x13, 0x98, 0x1C, 0xB9, 0x19, 0xAE, 0xF6, 0x58, 0x22, 0xD6, 0xB6,
|
||||
0x6C, 0x27, 0xB3, 0x24, 0x16, 0x4C, 0x4F, 0x80, 0x18, 0x1F, 0x2B, 0x0E, 0xE2, 0xFB, 0xD2, 0xAC,
|
||||
0x07, 0x7B, 0x0C, 0xA5, 0x49, 0xE7, 0x93, 0xC8, 0x58, 0x89, 0x4F, 0x9F, 0x71, 0x9A, 0x59, 0xC6,
|
||||
0xA1, 0xC7, 0xCF, 0xB1, 0x28, 0x9F, 0xB0, 0x18, 0x01, 0x03, 0x34, 0xC6, 0x18, 0xED, 0x03, 0xBA,
|
||||
0x96, 0x21, 0xE0, 0x12, 0xE2, 0x5A, 0xA3, 0x41, 0xE0, 0xF0, 0xEC, 0x48, 0x90, 0xA1, 0x31, 0x9B,
|
||||
0x2B, 0xB0, 0x99, 0x3B, 0x12, 0x36, 0x23, 0x34, 0xAB, 0x86, 0xE6, 0xCA, 0x98, 0x5A, 0x8E, 0x54,
|
||||
0x0E, 0x4B, 0x19, 0x62, 0x08, 0x41, 0x82, 0x03, 0xCD, 0x26, 0x94, 0xA5, 0x47, 0x3D, 0xDB, 0x04,
|
||||
0x24, 0xC1, 0x06, 0x09, 0x47, 0x24, 0x67, 0x32, 0xF6, 0x10, 0xD3, 0x2D, 0x78, 0x37, 0xA4, 0xDE,
|
||||
0xB5, 0xC4, 0x08, 0x97, 0x2D, 0xD7, 0xB2, 0xE8, 0x72, 0x87, 0xBC, 0x9C, 0x59, 0xFD, 0x59, 0xD3,
|
||||
0xAE, 0x0C, 0x51, 0xE9, 0x37, 0x85, 0x23, 0x00, 0x19, 0x08, 0xF8, 0xF9, 0xE9, 0x9F, 0x1F, 0xB2,
|
||||
0xBC, 0xE5, 0x32, 0xEB, 0x55, 0x3A, 0xFB, 0x9B, 0xE7, 0x72, 0x17, 0x3E, 0x5B, 0x4D, 0xA3, 0xEF,
|
||||
0x6E, 0xAA, 0x93, 0x05, 0xDF, 0xE5, 0xAB, 0x24, 0x6D, 0x51, 0x99, 0x9E, 0x70, 0x87, 0x72, 0xC8,
|
||||
0xD7, 0x54, 0xFA, 0xC7, 0xF3, 0x3A, 0x4A, 0xB7, 0xA2, 0x74, 0xA1, 0x55, 0x1A, 0xDA, 0xA8, 0x73,
|
||||
0x9C, 0xAE, 0x6C, 0xFE, 0x45, 0xE4, 0x11, 0x68, 0x25, 0xB9, 0x70, 0x8A, 0xA3, 0xDB, 0x67, 0x35,
|
||||
0x4D, 0xDB, 0x00, 0xB6, 0x7C, 0xE7, 0x3D, 0x18, 0xA3, 0xD2, 0xF9, 0xCE, 0x75, 0x95, 0x4E, 0x7C,
|
||||
0xFB, 0xBC, 0xF3, 0x05, 0xCF, 0xF9, 0x52, 0x2E, 0xFC, 0xAC, 0x2A, 0x7A, 0x46, 0xF6, 0xA3, 0xF9,
|
||||
0x24, 0x08, 0x56, 0x93, 0x1F, 0x3D, 0xD6, 0xE0, 0x7B, 0x93, 0x61, 0xBC, 0xC7, 0x12, 0x1B, 0xF5,
|
||||
0x2F, 0x38, 0x17, 0xA1, 0x1B, 0x4C, 0x55, 0x9C, 0xCA, 0x1C, 0xF6, 0x5C, 0x24, 0x87, 0x7F, 0x1A,
|
||||
0xBE, 0x45, 0x5C, 0xE3, 0x64, 0x07, 0xC9, 0x10, 0x68, 0x86, 0x8E, 0x13, 0x74, 0xDD, 0x7D, 0xF4,
|
||||
0x7B, 0x1A, 0xC2, 0x38, 0x43, 0x53, 0x2C, 0x8B, 0x05, 0x5F, 0x67, 0x31, 0x44, 0xE5, 0x30, 0x1A,
|
||||
0x2E, 0xD8, 0xAB, 0xA3, 0xEE, 0x8F, 0xE9, 0xB0, 0xAD, 0xDD, 0xD4, 0x69, 0xB9, 0x8F, 0x96, 0x3B,
|
||||
0x08, 0x39, 0xF2, 0x53, 0x2A, 0x56, 0xA2, 0x82, 0x7E, 0xF5, 0xE3, 0xDB, 0xDB, 0x64, 0xAA, 0xC7,
|
||||
0xC1, 0x57, 0x71, 0x22, 0x9E, 0x33, 0x56, 0xC5, 0xD7, 0x7A, 0xC1, 0xE5, 0x61, 0xC8, 0x57, 0x55,
|
||||
0x8C, 0x50, 0xB9, 0x34, 0x92, 0xED, 0xEA, 0x09, 0xDB, 0xD5, 0x7D, 0xB6, 0xAB, 0x8B, 0x6C, 0x57,
|
||||
0xA7, 0xD9, 0xAE, 0x76, 0xB1, 0x5D, 0xAD, 0x64, 0xBB, 0x9A, 0xC1, 0x76, 0x15, 0xB2, 0x5D, 0xF5,
|
||||
0x65, 0xBB, 0xEA, 0xCC, 0x76, 0x95, 0xCD, 0x76, 0x55, 0x93, 0xED, 0xAA, 0x3C, 0xDB, 0x55, 0xD1,
|
||||
0xC1, 0x94, 0x73, 0x94, 0x3D, 0xFC, 0xB9, 0x47, 0xB3, 0x9A, 0x5C, 0x60, 0x35, 0xB9, 0xC7, 0x6A,
|
||||
0xF2, 0x9A, 0xD5, 0xE4, 0x0D, 0xAB, 0x09, 0x76, 0xF4, 0x29, 0xAB, 0xC9, 0x25, 0x56, 0x13, 0x65,
|
||||
0x35, 0xA9, 0xC5, 0x6A, 0x52, 0x81, 0xD5, 0x24, 0x07, 0xAB, 0x89, 0x44, 0xA2, 0xD8, 0x99, 0x22,
|
||||
0xAC, 0x26, 0x35, 0x58, 0x4D, 0x9A, 0xB3, 0x9A, 0x9C, 0x8F, 0x4F, 0x7D, 0x59, 0xA7, 0x64, 0x25,
|
||||
0x1C, 0xB1, 0xFC, 0x2B, 0x4D, 0x13, 0x18, 0xCF, 0xA0, 0xB2, 0x33, 0x98, 0x42, 0x68, 0x0B, 0x35,
|
||||
0xDF, 0x0C, 0x9B, 0xCB, 0x90, 0x3C, 0x85, 0x6E, 0x6A, 0xB5, 0x8B, 0x55, 0xF1, 0x4E, 0x5F, 0x37,
|
||||
0x19, 0xDF, 0xCD, 0xD1, 0x10, 0xFF, 0xCE, 0x64, 0x12, 0xDD, 0xAE, 0x3B, 0xB2, 0xE9, 0x0E, 0x54,
|
||||
0xBB, 0xC5, 0x81, 0x9E, 0xA1, 0x52, 0x31, 0x16, 0x4F, 0x82, 0x85, 0xE0, 0x95, 0x37, 0x75, 0xF0,
|
||||
0x97, 0xA1, 0xC4, 0xC7, 0xBF, 0xB3, 0xC9, 0x76, 0xB1, 0x8B, 0x32, 0x3B, 0xDE, 0x45, 0x14, 0xD3,
|
||||
0xC2, 0x55, 0x93, 0x88, 0xAC, 0xB7, 0x44, 0xFA, 0xB0, 0xFE, 0xC4, 0xD9, 0x77, 0xB3, 0xD5, 0x34,
|
||||
0x0F, 0x58, 0x7A, 0xC9, 0xEA, 0x24, 0xB2, 0x3A, 0x99, 0xAC, 0x4E, 0x21, 0xAB, 0x53, 0xC9, 0xEA,
|
||||
0x34, 0xB2, 0x3A, 0x9D, 0xAC, 0xCE, 0x08, 0x59, 0x7A, 0xC9, 0xEA, 0x2C, 0xB2, 0x3A, 0x9B, 0xAC,
|
||||
0xCE, 0x21, 0xAB, 0x73, 0xC9, 0xEA, 0x3C, 0xB2, 0x2A, 0x0B, 0x35, 0x47, 0x66, 0xC8, 0x3B, 0x56,
|
||||
0x77, 0x58, 0x37, 0xAC, 0xF0, 0xC0, 0x91, 0x2A, 0x0A, 0x01, 0x48, 0xD9, 0xA0, 0xA1, 0x3D, 0x94,
|
||||
0x39, 0x48, 0x89, 0xF8, 0x84, 0x28, 0x3D, 0x64, 0xE2, 0x27, 0x72, 0x47, 0x73, 0xE4, 0x72, 0x78,
|
||||
0x5B, 0xED, 0x75, 0xF6, 0x1E, 0xCF, 0xB4, 0x4E, 0xB0, 0xC0, 0x05, 0xCB, 0xB4, 0x49, 0x70, 0xDC,
|
||||
0x38, 0x9B, 0xFF, 0x01, 0x67, 0xEB, 0xA7, 0xBC, 0x12, 0x1C, 0x24, 0x0B, 0xC9, 0x94, 0xC1, 0xF1,
|
||||
0x5E, 0xD8, 0xD8, 0x62, 0x2E, 0x70, 0xFC, 0x52, 0x30, 0x2D, 0x37, 0x20, 0xE8, 0xE7, 0xA0, 0x0F,
|
||||
0xDC, 0xEC, 0x30, 0x0D, 0x86, 0x38, 0x6E, 0xA9, 0x38, 0x89, 0xC6, 0x3E, 0x09, 0xB7, 0x85, 0x10,
|
||||
0xFB, 0x3A, 0x48, 0x5B, 0x0B, 0xD2, 0xEA, 0x8B, 0x20, 0x0B, 0xBF, 0xA8, 0x8E, 0x97, 0x3D, 0x90,
|
||||
0xEF, 0xCF, 0xF6, 0xCF, 0xE1, 0xF8, 0xD9, 0xFE, 0xF1, 0xAA, 0xF9, 0x7C, 0x2E, 0xFC, 0x4A, 0xF5,
|
||||
0x2F, 0xC0, 0xC7, 0x56, 0xCA, 0xE3, 0x93, 0x52, 0xA9, 0xB4, 0xFC, 0xFC, 0x64, 0xC5, 0xB7, 0xFE,
|
||||
0x07, 0x15, 0x77, 0x19, 0xFE, 0x7B, 0x15, 0xEF, 0xE3, 0xF1, 0xF9, 0x81, 0xB3, 0xD9, 0x27, 0xA9,
|
||||
0xF8, 0xC2, 0x9F, 0x3E, 0x98, 0x7E, 0x86, 0x87, 0xFC, 0xB9, 0x9E, 0xF1, 0xCB, 0xED, 0x67, 0xF8,
|
||||
0x37, 0x57, 0xFC, 0x42, 0x6A, 0xC5, 0x53, 0xCE, 0xD4, 0xEF, 0xAA, 0xF8, 0xD0, 0x24, 0x3F, 0xA3,
|
||||
0x35, 0xEB, 0xBC, 0xE6, 0xCA, 0xD2, 0x02, 0x32, 0x8A, 0xF5, 0x84, 0x3D, 0x8B, 0x3F, 0xC7, 0xF0,
|
||||
0xAB, 0xFF, 0xB2, 0xA9, 0xF8, 0xD1, 0xC4, 0x0E, 0x99, 0xD8, 0xBB, 0x58, 0x03, 0x88, 0xC3, 0xC5,
|
||||
0x66, 0x71, 0xB8, 0xE8, 0xF8, 0xFE, 0x9E, 0x39, 0xCB, 0x20, 0x6B, 0x5F, 0x12, 0xD5, 0x5E, 0x7F,
|
||||
0x33, 0xDD, 0xCF, 0x16, 0x16, 0x0A, 0x1B, 0xBD, 0xED, 0xE7, 0x27, 0xB1, 0x9E, 0x2D, 0x8D, 0x0B,
|
||||
0x81, 0x7B, 0x92, 0x56, 0x0F, 0x34, 0x91, 0xC2, 0xBB, 0x0E, 0xD0, 0xEB, 0x99, 0xF1, 0x83, 0x34,
|
||||
0xF3, 0x48, 0x73, 0xE7, 0x46, 0x02, 0x7B, 0x56, 0x82, 0x5D, 0xCE, 0xEE, 0x59, 0x76, 0x3B, 0x70,
|
||||
0xC4, 0xBE, 0xD1, 0x02, 0xBC, 0x5F, 0x04, 0xFC, 0xD4, 0x03, 0x3B, 0xE4, 0x8B, 0x9C, 0xC3, 0xCF,
|
||||
0x39, 0xCF, 0xF7, 0x38, 0x7B, 0xAD, 0xC5, 0xEF, 0xAD, 0xBE, 0x31, 0xE5, 0xAA, 0x1F, 0x43, 0x7B,
|
||||
0x77, 0x77, 0x0A, 0x74, 0xCA, 0x79, 0x4E, 0x52, 0x9C, 0x74, 0xCA, 0xD7, 0x52, 0x9C, 0xD4, 0xCC,
|
||||
0xBF, 0x2F, 0xD9, 0x63, 0x97, 0xB3, 0x93, 0x8F, 0x7C, 0xD7, 0x2B, 0x83, 0x6C, 0xA6, 0x3F, 0x6B,
|
||||
0x94, 0xD3, 0x1F, 0x1A, 0x25, 0xDB, 0x35, 0x0A, 0x99, 0x77, 0x01, 0x53, 0x1B, 0x25, 0xA9, 0xEB,
|
||||
0xC7, 0xF7, 0x47, 0xA3, 0x8F, 0x8B, 0x89, 0x7B, 0xCA, 0x3C, 0x48, 0x2B, 0x62, 0xA8, 0x59, 0x6D,
|
||||
0x50, 0xE0, 0xB7, 0x8A, 0x5D, 0x04, 0xA1, 0x6D, 0x5B, 0x65, 0x78, 0x4C, 0x6D, 0xD6, 0x8F, 0xB5,
|
||||
0xA3, 0x3F, 0x35, 0x52, 0x98, 0xFF, 0x40, 0xFB, 0x5D, 0x78, 0xC7, 0xBC, 0x7C, 0x48, 0xBB, 0x7C,
|
||||
0x9A, 0xF8, 0x0F, 0x0B, 0xAC, 0xE5, 0x6D, 0x3A, 0x04, 0xEF, 0x35, 0x84, 0xF6, 0xB4, 0x36, 0xFC,
|
||||
0xB4, 0x7B, 0xEC, 0xF2, 0xDA, 0xD4, 0x46, 0x6C, 0xEF, 0xCA, 0xE3, 0x74, 0x80, 0x21, 0x66, 0x46,
|
||||
0xEA, 0xC4, 0x21, 0x1E, 0x5A, 0x5A, 0xA4, 0xDC, 0x57, 0xA9, 0x55, 0x18, 0xF9, 0x6E, 0xF2, 0x84,
|
||||
0x1F, 0xB5, 0x52, 0xE5, 0x3F, 0xD2, 0x4A, 0x5B, 0x3F, 0xBA, 0x9B, 0x9C, 0x88, 0x1F, 0x98, 0x39,
|
||||
0x29, 0xBD, 0x39, 0x7E, 0xF0, 0x57, 0x66, 0x8E, 0xD7, 0x48, 0x3F, 0xDD, 0xAE, 0x70, 0x4E, 0x9F,
|
||||
0x93, 0x2D, 0xBC, 0x46, 0xFA, 0xBE, 0x99, 0xF3, 0x27, 0x7B, 0xC8, 0x9F, 0x47, 0xBF, 0x3E, 0x3E,
|
||||
0xFD, 0x79, 0xF4, 0x96, 0x57, 0xAB, 0xC7, 0x69, 0x23, 0x0C, 0xA2, 0x52, 0xA2, 0xF4, 0x7B, 0x04,
|
||||
0x8B, 0x2A, 0x0A, 0x22, 0x48, 0xA6, 0x4B, 0x88, 0x44, 0xA4, 0xB5, 0x82, 0x65, 0x8A, 0x48, 0xC8,
|
||||
0x27, 0x88, 0xB4, 0x6D, 0xD0, 0x6E, 0xC2, 0x1A, 0x28, 0x68, 0x28, 0x42, 0x41, 0x91, 0x32, 0x07,
|
||||
0xC8, 0x2D, 0x72, 0x03, 0xCE, 0x92, 0x26, 0x27, 0xC8, 0x78, 0x3C, 0x9F, 0x9F, 0x9F, 0x9F, 0xF9,
|
||||
0x3E, 0x81, 0xA3, 0x34, 0xC8, 0x08, 0xF6, 0x9B, 0xBF, 0x37, 0x6F, 0xDE, 0x37, 0xEB, 0x3F, 0xBF,
|
||||
0x5E, 0x3C, 0x0F, 0x3E, 0x9A, 0x47, 0xB4, 0x47, 0x11, 0xFD, 0x33, 0x3A, 0xD2, 0x46, 0x40, 0x53,
|
||||
0x17, 0xC7, 0x6F, 0xAB, 0xF5, 0x0D, 0x08, 0x45, 0x23, 0x7C, 0xB2, 0x46, 0x98, 0x49, 0x07, 0xB8,
|
||||
0xF7, 0x47, 0xF0, 0xFE, 0x91, 0x53, 0xF7, 0x4E, 0x8B, 0x8F, 0x39, 0xD9, 0xE4, 0xE7, 0xA4, 0x95,
|
||||
0x35, 0x4A, 0xCC, 0xA8, 0xED, 0xCD, 0x85, 0xAF, 0xF3, 0xE7, 0xDE, 0xCC, 0x0D, 0xF6, 0xBE, 0x17,
|
||||
0x4C, 0x08, 0x6E, 0xE7, 0x4F, 0xDC, 0xE6, 0xA8, 0xCB, 0x26, 0x47, 0x67, 0x07, 0x7C, 0x41, 0xB5,
|
||||
0x60, 0x9E, 0xE2, 0xF5, 0x0B, 0xF8, 0x07, 0x8A, 0x97, 0x80, 0x7E, 0xB5, 0x08, 0xE0, 0x6C, 0xB3,
|
||||
0x27, 0x53, 0xF2, 0x44, 0x88, 0xEC, 0x2A, 0x62, 0x40, 0xB2, 0x5B, 0x8E, 0xFD, 0xA3, 0xC7, 0x6E,
|
||||
0x9F, 0x99, 0xDA, 0xCE, 0xD3, 0x73, 0x6F, 0x3D, 0xD9, 0x14, 0x7B, 0x67, 0x4F, 0x04, 0xEC, 0xC7,
|
||||
0xCB, 0x17, 0x59, 0x67, 0x4F, 0x7D, 0x93, 0x75, 0x66, 0xAF, 0x1C, 0xEC, 0x15, 0x8A, 0x63, 0x84,
|
||||
0xC8, 0xB2, 0x9D, 0xBB, 0x80, 0xEC, 0xBD, 0x8C, 0x95, 0x90, 0x60, 0x3D, 0x96, 0xB4, 0xCD, 0x25,
|
||||
0xF0, 0xEE, 0xAB, 0x46, 0xF4, 0x97, 0xFF, 0x5E, 0x77, 0x81, 0x9A, 0x58, 0x7D, 0x44, 0xFA, 0x7C,
|
||||
0xAD, 0x67, 0x96, 0x23, 0x7D, 0x3D, 0x5D, 0x9D, 0x7A, 0x26, 0x4F, 0x3F, 0xA7, 0x31, 0x70, 0x24,
|
||||
0xF8, 0xDB, 0x79, 0x6C, 0x03, 0x4B, 0xA9, 0xCE, 0x91, 0x49, 0xE7, 0x8F, 0xED, 0xFC, 0xCF, 0x0C,
|
||||
0x4D, 0x54, 0xF6, 0x95, 0x3F, 0x1E, 0xD8, 0x6C, 0xE7, 0xE4, 0xF4, 0x7E, 0x89, 0xCD, 0xDA, 0x3F,
|
||||
0x83, 0x9C, 0xA6, 0x09, 0x9F, 0x5E, 0x39, 0x10, 0x93, 0xA7, 0x21, 0x0C, 0x57, 0x44, 0x4E, 0x20,
|
||||
0x58, 0x33, 0x8A, 0x19, 0xB4, 0xEF, 0x6B, 0xA5, 0x72, 0x07, 0x9A, 0x39, 0xEE, 0xBE, 0xDE, 0x0F,
|
||||
0x67, 0xBE, 0x32, 0x0C, 0x23, 0x36, 0xFF, 0x67, 0xE6, 0x70, 0x1C, 0x54, 0xE2, 0xEF, 0xE1, 0xCA,
|
||||
0xE6, 0xC3, 0x3C, 0x20, 0x06, 0x8D, 0x55, 0x1E, 0x0E, 0xF3, 0x5D, 0x7A, 0x07, 0x12, 0xF2, 0x3A,
|
||||
0xD8, 0xDF, 0xE2, 0x58, 0x8B, 0x28, 0x16, 0xBD, 0xA8, 0x30, 0xCB, 0x3B, 0xF0, 0xC3, 0x1E, 0x41,
|
||||
0x8C, 0x6B, 0x10, 0x20, 0x6B, 0x53, 0x1D, 0x46, 0x6E, 0xFC, 0x28, 0x8C, 0xC7, 0x90, 0x80, 0x03,
|
||||
0x97, 0x3A, 0x28, 0xDE, 0xB9, 0x23, 0x93, 0xA5, 0x23, 0xD7, 0x2B, 0x50, 0xE8, 0x17, 0x90, 0x9F,
|
||||
0x91, 0x3E, 0x80, 0x33, 0x3B, 0x9B, 0xB8, 0x1D, 0x0E, 0x59, 0x4E, 0x28, 0x07, 0xE7, 0xC9, 0x5C,
|
||||
0x3D, 0x8F, 0xDB, 0xE1, 0xE0, 0x95, 0x24, 0xF3, 0x3D, 0xCB, 0x93, 0x89, 0xA7, 0x02, 0x76, 0xA1,
|
||||
0x4B, 0x32, 0x76, 0x4F, 0x50, 0x81, 0x36, 0x67, 0x7D, 0x2A, 0xD6, 0x1B, 0x5E, 0x99, 0xC0, 0xE4,
|
||||
0x40, 0xCA, 0xEC, 0xC1, 0xB5, 0x5C, 0x60, 0x1C, 0x5D, 0xC5, 0xD1, 0x28, 0xF0, 0xE9, 0x1A, 0x11,
|
||||
0xCF, 0x68, 0x00, 0x10, 0xDE, 0x1D, 0x1D, 0x5C, 0xE0, 0x2E, 0x15, 0xB8, 0xE6, 0xD8, 0xD0, 0x6C,
|
||||
0xDE, 0xF9, 0xF5, 0x45, 0x74, 0x47, 0x90, 0x30, 0x0A, 0x0C, 0x47, 0x8E, 0xB9, 0xD7, 0x83, 0xC9,
|
||||
0xD8, 0x8B, 0x81, 0xCE, 0x01, 0x34, 0x32, 0x2A, 0x9B, 0xDA, 0xA5, 0x77, 0x3B, 0x84, 0xF0, 0x0A,
|
||||
0x08, 0x0F, 0x8E, 0x19, 0x92, 0xFC, 0x77, 0x60, 0xC5, 0x5B, 0x28, 0xED, 0xA4, 0x69, 0x87, 0x3A,
|
||||
0x82, 0xC7, 0x9A, 0x8E, 0xF5, 0x88, 0xBF, 0xAE, 0x45, 0xF5, 0x82, 0x21, 0xEB, 0x67, 0x72, 0x7F,
|
||||
0xF3, 0xB3, 0xCA, 0xBA, 0x66, 0xF3, 0x78, 0x3E, 0x88, 0xF3, 0x06, 0xD2, 0x7A, 0xCE, 0xEA, 0x69,
|
||||
0xEC, 0xA9, 0x22, 0xB3, 0xCF, 0x42, 0x7A, 0xA8, 0x00, 0x94, 0x25, 0x18, 0x56, 0x53, 0x30, 0xD1,
|
||||
0x14, 0x40, 0xD1, 0x68, 0x0A, 0x10, 0x80, 0x79, 0x6E, 0xD9, 0x15, 0x4C, 0x09, 0x71, 0xD7, 0x30,
|
||||
0x40, 0xC4, 0xAD, 0x38, 0xBA, 0x0D, 0x36, 0x85, 0x94, 0xCC, 0xB0, 0x69, 0xF9, 0x9A, 0x76, 0x9A,
|
||||
0xD7, 0x8F, 0x35, 0xF1, 0xBF, 0x22, 0x91, 0x13, 0x34, 0xE2, 0x04, 0x9D, 0xA7, 0x7C, 0x83, 0x6B,
|
||||
0x0D, 0x01, 0x92, 0xA4, 0x04, 0x15, 0xBE, 0x16, 0xDA, 0xCF, 0xEC, 0x25, 0x0A, 0x20, 0x0E, 0xD1,
|
||||
0xA8, 0x50, 0xE9, 0x33, 0x50, 0x31, 0x4B, 0x8F, 0x96, 0xF0, 0xCD, 0xBA, 0xF4, 0xAD, 0x99, 0x96,
|
||||
0x82, 0x8C, 0xE0, 0xBC, 0x42, 0xA5, 0x12, 0xA8, 0x90, 0x2A, 0xE4, 0x7D, 0xC2, 0xF0, 0x99, 0x12,
|
||||
0xAD, 0x0E, 0xDF, 0xA2, 0x70, 0xE7, 0xC6, 0x57, 0x71, 0xF1, 0x3A, 0xCC, 0x0C, 0x80, 0xCF, 0x85,
|
||||
0xE7, 0x97, 0x79, 0x71, 0xE1, 0x19, 0x68, 0x59, 0x60, 0x1C, 0x74, 0x49, 0x02, 0x27, 0x2D, 0xB5,
|
||||
0xD3, 0x01, 0x6A, 0xC2, 0x3C, 0x33, 0xE1, 0xBD, 0x8D, 0x68, 0x3B, 0x74, 0x6F, 0x58, 0x03, 0x5B,
|
||||
0xA0, 0x84, 0xB8, 0xBA, 0x4D, 0x0C, 0x78, 0xE3, 0x0A, 0x2B, 0xA1, 0xEE, 0x1B, 0xF9, 0x70, 0xCC,
|
||||
0x0A, 0x6E, 0x8D, 0xF3, 0x46, 0x50, 0x70, 0xAC, 0x12, 0x55, 0xC1, 0xB5, 0x7A, 0xFE, 0x18, 0x31,
|
||||
0x0A, 0x7B, 0xED, 0x82, 0x61, 0x95, 0xC1, 0x16, 0x99, 0x5D, 0x8A, 0x87, 0xDB, 0xC4, 0x62, 0xC1,
|
||||
0xF4, 0x0A, 0xCC, 0x2A, 0x24, 0x03, 0x21, 0x49, 0x44, 0x5C, 0xB4, 0x42, 0xF1, 0xFE, 0x77, 0x52,
|
||||
0x86, 0x10, 0x2C, 0xA8, 0x7E, 0x63, 0x72, 0x57, 0xC6, 0x51, 0x1C, 0x82, 0xBA, 0xDC, 0x03, 0xD5,
|
||||
0xD0, 0x27, 0xD9, 0x2A, 0xDB, 0x61, 0xC5, 0x0A, 0x43, 0xC1, 0xF5, 0x2B, 0x48, 0xDF, 0x23, 0x8C,
|
||||
0x95, 0xD1, 0x0E, 0x05, 0x5F, 0x46, 0xFC, 0x34, 0x83, 0xF8, 0xC2, 0x8C, 0x2F, 0x63, 0xDD, 0x33,
|
||||
0xC2, 0x38, 0xE7, 0x9B, 0x4A, 0xB5, 0x96, 0x85, 0x66, 0x6D, 0xC9, 0x77, 0xC1, 0xA2, 0x91, 0x5B,
|
||||
0x6C, 0xCB, 0x4B, 0x12, 0x4C, 0x4B, 0xD0, 0xE8, 0x32, 0x6C, 0xCA, 0xE8, 0x9E, 0x24, 0xD1, 0xC9,
|
||||
0x1D, 0xA9, 0xC2, 0x1D, 0x89, 0xEA, 0x7B, 0xBF, 0x50, 0xA6, 0x3B, 0xA8, 0xAF, 0xA8, 0x53, 0xEF,
|
||||
0x32, 0xD4, 0x17, 0x03, 0x40, 0xEB, 0x8B, 0x7E, 0xAB, 0x3B, 0xAD, 0xAF, 0x43, 0xB8, 0xF3, 0xC0,
|
||||
0xC9, 0x97, 0x21, 0xAF, 0xBF, 0xA2, 0xBE, 0xEC, 0xC7, 0xA0, 0xD5, 0xDB, 0xA8, 0xD6, 0x77, 0xB2,
|
||||
0x29, 0xC9, 0x0F, 0x64, 0x61, 0xAC, 0xFA, 0x1C, 0x2A, 0x8E, 0x97, 0x63, 0xC8, 0x6F, 0x58, 0x6A,
|
||||
0x10, 0xB1, 0xB3, 0x5D, 0xDF, 0xAA, 0x30, 0x80, 0xBA, 0xF8, 0xBE, 0xF5, 0x45, 0x0D, 0xD9, 0x01,
|
||||
0x17, 0xEE, 0x93, 0x92, 0x3B, 0x02, 0xF3, 0x5E, 0x68, 0x07, 0x9A, 0xEF, 0xF9, 0xEA, 0xB4, 0xAB,
|
||||
0x8C, 0x78, 0x43, 0x5C, 0x7C, 0xBD, 0xAA, 0xEF, 0x0E, 0x49, 0xE2, 0x8E, 0x68, 0x5C, 0x17, 0x24,
|
||||
0x6E, 0x51, 0xDF, 0x6D, 0x21, 0x37, 0xA0, 0x4F, 0x21, 0x37, 0xA8, 0xC6, 0x4A, 0x94, 0xDB, 0x2F,
|
||||
0x1B, 0xF8, 0x92, 0xF5, 0x13, 0xCA, 0x8F, 0xDE, 0x64, 0xF4, 0xBC, 0x7C, 0xCB, 0x03, 0x98, 0x60,
|
||||
0x25, 0xC3, 0x18, 0x1E, 0x10, 0x53, 0xF4, 0xC2, 0x14, 0x89, 0x13, 0x79, 0x1A, 0x48, 0x9F, 0x8C,
|
||||
0x64, 0x12, 0x28, 0x07, 0xA2, 0xFE, 0xF7, 0x22, 0x12, 0x3D, 0xC4, 0x27, 0xCD, 0x82, 0x11, 0xA3,
|
||||
0x31, 0xBE, 0x71, 0x0B, 0x34, 0x3E, 0x3C, 0x0B, 0x7E, 0x3C, 0x48, 0x8B, 0x10, 0x1F, 0x25, 0x5A,
|
||||
0xCC, 0x10, 0xFE, 0x5D, 0x1C, 0xFF, 0x7B, 0xB3, 0x94, 0xDC, 0xFD, 0x5F, 0xFB, 0x31, 0x95, 0x98,
|
||||
0x42, 0x88, 0x25, 0x62, 0x46, 0xA1, 0x8B, 0xA4, 0x5C, 0x31, 0x29, 0xA3, 0xED, 0xFF, 0xF6, 0x72,
|
||||
0x25, 0xAF, 0x3F, 0x45, 0x51, 0xFC, 0x9A, 0x43, 0x8A, 0x94, 0x4C, 0xE5, 0x87, 0x42, 0x64, 0x9E,
|
||||
0xE7, 0x79, 0x26, 0x22, 0xAC, 0x2C, 0x9E, 0x29, 0x4A, 0x86, 0x2F, 0xBE, 0xCF, 0xAC, 0x64, 0xA1,
|
||||
0x64, 0x8A, 0x05, 0x52, 0x94, 0x58, 0xA0, 0xA4, 0x64, 0xCA, 0x7F, 0x80, 0x28, 0x0B, 0x0B, 0x2C,
|
||||
0x14, 0x76, 0xB2, 0xA6, 0x0C, 0x9F, 0xF7, 0xB9, 0xC3, 0xE7, 0xDD, 0x77, 0xCD, 0x13, 0x7D, 0xF9,
|
||||
0x0E, 0xF7, 0x9E, 0xF9, 0x9E, 0x73, 0xEE, 0xBD, 0xE7, 0xBC, 0xAD, 0xF7, 0x1A, 0xAF, 0xB9, 0xD7,
|
||||
0xA4, 0x45, 0x8E, 0x1C, 0x20, 0xE4, 0x98, 0x3A, 0x46, 0x53, 0x52, 0x0D, 0xAA, 0x95, 0x50, 0x93,
|
||||
0x24, 0xFA, 0x36, 0x0A, 0x77, 0x09, 0x08, 0x33, 0x10, 0x3A, 0xF8, 0xA4, 0xDE, 0x73, 0x14, 0x19,
|
||||
0x5A, 0x0F, 0xCA, 0x77, 0x90, 0x0C, 0xC7, 0x42, 0x06, 0xDE, 0x8F, 0x9E, 0xE4, 0xD8, 0xD7, 0xCD,
|
||||
0x0B, 0x5C, 0x23, 0x98, 0xAB, 0xF9, 0xF8, 0x3E, 0xB3, 0x84, 0xA7, 0x63, 0x4B, 0x90, 0x9A, 0x7B,
|
||||
0xD8, 0x6D, 0x6D, 0x31, 0x15, 0x3C, 0x28, 0x62, 0x1B, 0x8A, 0xD3, 0x7A, 0x69, 0x67, 0x51, 0xF3,
|
||||
0x98, 0x0E, 0x96, 0x30, 0xB1, 0x48, 0xBA, 0x65, 0x5E, 0x48, 0x7F, 0xE5, 0x4A, 0x99, 0xF3, 0x30,
|
||||
0xE7, 0xDC, 0x65, 0xCA, 0x6B, 0x4A, 0x57, 0x17, 0x4B, 0x74, 0x2A, 0x05, 0x50, 0xA1, 0xB4, 0x3C,
|
||||
0x5B, 0xFC, 0x95, 0xFD, 0x4E, 0x97, 0x96, 0xDE, 0x43, 0x0E, 0x45, 0x75, 0x2C, 0x15, 0x8A, 0x59,
|
||||
0xDD, 0x5A, 0xFA, 0xDA, 0xAE, 0x76, 0xD9, 0x71, 0x90, 0x8A, 0x84, 0xA8, 0xF1, 0x47, 0xD8, 0x5A,
|
||||
0xBA, 0x6D, 0xEC, 0xF7, 0x75, 0x21, 0x07, 0x83, 0x6B, 0x47, 0x7D, 0x71, 0x39, 0x31, 0x58, 0xE4,
|
||||
0xDE, 0xAC, 0x40, 0xBF, 0x0F, 0x20, 0xFC, 0x85, 0x16, 0xB3, 0x84, 0xEE, 0x00, 0x34, 0xE1, 0xEA,
|
||||
0xBE, 0xA1, 0x10, 0x5C, 0xB8, 0x41, 0xE8, 0x61, 0x13, 0x6E, 0x88, 0xAC, 0x13, 0x35, 0xCD, 0x43,
|
||||
0xAA, 0xCA, 0x65, 0xE6, 0xB4, 0xE8, 0x32, 0x73, 0x46, 0xE3, 0x02, 0xD3, 0x14, 0xF9, 0x7E, 0xD1,
|
||||
0xC0, 0xCF, 0xE0, 0x29, 0xC6, 0x5F, 0xF3, 0xF8, 0xBB, 0x12, 0x3F, 0x64, 0x80, 0x4A, 0x35, 0xE1,
|
||||
0x07, 0x5F, 0x56, 0x65, 0xFE, 0x32, 0x32, 0xEC, 0x9A, 0x4B, 0x2B, 0x8D, 0xE9, 0x91, 0x76, 0xCD,
|
||||
0xDE, 0xC0, 0x73, 0xA9, 0x82, 0x7E, 0x46, 0xC6, 0x0D, 0x31, 0x28, 0x16, 0x44, 0xA2, 0xA0, 0x3D,
|
||||
0x90, 0x14, 0xAA, 0xA4, 0x8B, 0x23, 0x67, 0x49, 0x49, 0x1C, 0x43, 0x72, 0xEB, 0x02, 0xB6, 0x69,
|
||||
0x7F, 0xA5, 0xE3, 0xDC, 0x58, 0x27, 0xE9, 0xD2, 0x3F, 0x18, 0x45, 0x12, 0xF0, 0xC6, 0xF5, 0x99,
|
||||
0xEF, 0x8C, 0xF5, 0x33, 0x4D, 0x31, 0x07, 0x0C, 0x40, 0x03, 0x76, 0x54, 0x0E, 0xC8, 0xB6, 0x5A,
|
||||
0x58, 0x7E, 0xAB, 0x04, 0xCB, 0x7E, 0xCE, 0x83, 0x1F, 0x23, 0x2C, 0x18, 0xB4, 0x87, 0x02, 0x2C,
|
||||
0x4D, 0x57, 0xF2, 0x88, 0x71, 0x30, 0x1D, 0xB3, 0x65, 0x32, 0xD7, 0xE2, 0x11, 0xAD, 0xA4, 0x45,
|
||||
0x90, 0xF7, 0x85, 0x44, 0x66, 0x68, 0x88, 0x38, 0xD4, 0xA4, 0x5D, 0x58, 0xF2, 0xA5, 0xD0, 0x95,
|
||||
0xA2, 0x1D, 0xD6, 0xA7, 0xFC, 0xBF, 0x08, 0xA7, 0x53, 0x92, 0xB7, 0x17, 0x7B, 0xD9, 0x51, 0x81,
|
||||
0x8D, 0x5C, 0x34, 0x58, 0xDB, 0xE1, 0x85, 0x2D, 0x87, 0x37, 0xA8, 0x98, 0x53, 0x57, 0x39, 0x65,
|
||||
0x39, 0xBB, 0x59, 0x93, 0xC6, 0x14, 0x93, 0xEF, 0x28, 0x2C, 0x61, 0x8C, 0x17, 0x51, 0x6A, 0x0D,
|
||||
0x64, 0xCC, 0x63, 0xDC, 0x07, 0x8C, 0x2B, 0xFD, 0x68, 0x3A, 0xC2, 0xDC, 0x96, 0x9F, 0x83, 0x4A,
|
||||
0xF9, 0x6E, 0x04, 0x85, 0x20, 0xF4, 0xA1, 0x12, 0xBA, 0xC4, 0xC2, 0x22, 0x50, 0x57, 0xEA, 0x5E,
|
||||
0x07, 0x0F, 0x95, 0xDD, 0xB8, 0xAC, 0xB8, 0xE2, 0x29, 0xC3, 0x7E, 0xF5, 0xA0, 0x4B, 0x9C, 0x28,
|
||||
0x3D, 0x79, 0x4B, 0x9B, 0x2E, 0x31, 0xB1, 0x7A, 0xDE, 0xBC, 0xA0, 0xED, 0x09, 0xBD, 0x25, 0xC7,
|
||||
0x62, 0x04, 0x1B, 0x3D, 0x38, 0xEE, 0x4D, 0xF3, 0xB0, 0x5C, 0xE5, 0x2F, 0x6B, 0x7E, 0xA5, 0x98,
|
||||
0x2C, 0x6B, 0x0D, 0xCA, 0x39, 0xB6, 0x2D, 0x1D, 0x52, 0x0F, 0xF0, 0x07, 0x59, 0x81, 0xDE, 0xC5,
|
||||
0x58, 0xF2, 0xD9, 0x84, 0x28, 0xE1, 0x7D, 0xDC, 0x9C, 0x87, 0x51, 0x91, 0xB3, 0x5C, 0x83, 0xDA,
|
||||
0xE1, 0x70, 0xF4, 0xC4, 0x83, 0xAA, 0x73, 0x4D, 0xED, 0x3A, 0x45, 0x42, 0xE8, 0xB4, 0x03, 0x98,
|
||||
0xD2, 0x8C, 0x72, 0xB5, 0x79, 0xEE, 0xEA, 0x4B, 0x11, 0x1E, 0xDF, 0xDB, 0xC8, 0x4E, 0x0F, 0x4E,
|
||||
0xF3, 0xA4, 0x5B, 0x5C, 0xE3, 0xEE, 0x17, 0xC9, 0x93, 0xBC, 0x39, 0x5D, 0xD3, 0x90, 0x7D, 0xD1,
|
||||
0x79, 0xDA, 0x5F, 0x91, 0xE9, 0xB3, 0xE6, 0x8C, 0x0B, 0x7F, 0x55, 0xA6, 0x74, 0x63, 0xFF, 0x47,
|
||||
0xA0, 0x32, 0xEF, 0xE9, 0xDF, 0x12, 0xA8, 0xDB, 0x44, 0x9C, 0xAC, 0x08, 0x74, 0x48, 0xDD, 0x3A,
|
||||
0xB7, 0x9F, 0x95, 0x29, 0x48, 0x22, 0x07, 0x7F, 0x2E, 0x53, 0x45, 0x74, 0xBB, 0x6F, 0x11, 0x1E,
|
||||
0x45, 0xF4, 0xFA, 0x37, 0x22, 0x3A, 0xC3, 0x93, 0x82, 0x7A, 0x2A, 0x5A, 0x12, 0x26, 0xD1, 0x4E,
|
||||
0x0E, 0xA2, 0x3D, 0xDF, 0x54, 0xF1, 0x7D, 0xEC, 0x3F, 0x97, 0xAE, 0x22, 0x3A, 0xCF, 0x4D, 0x7E,
|
||||
0xEC, 0x0C, 0x82, 0xC9, 0x2A, 0xAA, 0x83, 0x22, 0x1A, 0x8A, 0xE3, 0xC0, 0x89, 0x44, 0x51, 0x15,
|
||||
0x78, 0x10, 0xC6, 0xBE, 0x17, 0x51, 0xE3, 0x88, 0x2E, 0x97, 0x1A, 0x1F, 0xA1, 0xC9, 0xAD, 0x12,
|
||||
0x7F, 0xEE, 0x55, 0x31, 0xD4, 0xBB, 0xCC, 0x38, 0xCF, 0xD9, 0xA2, 0x00, 0x0B, 0x7E, 0x15, 0x5C,
|
||||
0x49, 0xD1, 0x8F, 0x73, 0x8C, 0x7D, 0x39, 0xB2, 0xC9, 0xEF, 0xA5, 0x92, 0x8A, 0x52, 0x5A, 0xCC,
|
||||
0xE9, 0xD2, 0xA1, 0xE1, 0x1D, 0x8A, 0x74, 0x1C, 0x1B, 0xDE, 0x5C, 0x19, 0x1E, 0xB4, 0x23, 0xC3,
|
||||
0x1B, 0x1E, 0x52, 0x49, 0xC9, 0x7E, 0xE6, 0x8F, 0x52, 0xC9, 0x1C, 0x0B, 0x3A, 0xDA, 0xF5, 0xD2,
|
||||
0xEA, 0xD2, 0xE5, 0xE0, 0xD2, 0x49, 0xED, 0x72, 0x2F, 0x34, 0x8D, 0x4B, 0x0A, 0xB4, 0xAF, 0x05,
|
||||
0x89, 0x0B, 0x94, 0x52, 0x6A, 0x5F, 0x4B, 0x51, 0x13, 0xED, 0xFF, 0x4A, 0x26, 0x25, 0xE0, 0xC8,
|
||||
0xF4, 0xC8, 0x52, 0x6A, 0x7A, 0x3F, 0x50, 0xF4, 0x61, 0x99, 0x9E, 0x8B, 0x2C, 0xDB, 0x93, 0x64,
|
||||
0xB2, 0x5F, 0x92, 0x4C, 0xD2, 0x9B, 0x8A, 0x0E, 0x60, 0x91, 0xF9, 0x7B, 0xAF, 0x72, 0x52, 0xF8,
|
||||
0xB1, 0x6C, 0x7F, 0x2E, 0x99, 0x9C, 0x95, 0x26, 0x93, 0xA9, 0xCD, 0xA7, 0x09, 0x25, 0x44, 0xF8,
|
||||
0x0B, 0x36, 0xFF, 0x93, 0xC9, 0x24, 0xC8, 0xC1, 0xAB, 0x7A, 0x52, 0x3F, 0xE8, 0x5B, 0x89, 0x64,
|
||||
0xA4, 0x8F, 0x24, 0x8D, 0xC4, 0xAF, 0xED, 0x94, 0xEA, 0x57, 0xD2, 0xBF, 0xC5, 0x61, 0x8C, 0x51,
|
||||
0x3E, 0x06, 0x42, 0xA3, 0x14, 0x72, 0xDB, 0x9F, 0xB6, 0x35, 0x6F, 0x86, 0x78, 0xC3, 0x41, 0x43,
|
||||
0x8F, 0x6A, 0x1E, 0x5A, 0x10, 0x58, 0x48, 0xD4, 0xE4, 0x39, 0xCC, 0x60, 0x1B, 0x52, 0xAC, 0x1D,
|
||||
0xD4, 0x81, 0x1F, 0xFF, 0xDD, 0x7C, 0x94, 0xB3, 0x6B, 0x2E, 0x9D, 0x63, 0x37, 0xE3, 0x1A, 0x61,
|
||||
0xAA, 0xE4, 0xA5, 0x07, 0xFD, 0xF8, 0xA0, 0xF4, 0x5C, 0x59, 0xA9, 0x90, 0x49, 0x0A, 0x15, 0xF0,
|
||||
0xB4, 0xD3, 0x7D, 0x4E, 0xCD, 0x62, 0x24, 0x05, 0xBD, 0xA6, 0xB0, 0x27, 0x29, 0xB0, 0x5A, 0xC9,
|
||||
0xD0, 0xA3, 0x6C, 0x55, 0xE4, 0x45, 0x16, 0xE5, 0xC0, 0x6C, 0xF1, 0xC2, 0x67, 0xD2, 0x15, 0xBA,
|
||||
0x7D, 0x38, 0xFB, 0x9B, 0x49, 0xAA, 0x08, 0xA0, 0x1C, 0xEA, 0x90, 0xA4, 0x66, 0x45, 0xC9, 0x6A,
|
||||
0x15, 0xCB, 0xE1, 0x42, 0x16, 0x62, 0xAC, 0xAA, 0xA1, 0x5A, 0x01, 0x77, 0xB6, 0x4B, 0x59, 0xF7,
|
||||
0x25, 0x29, 0xAB, 0x9B, 0x95, 0x6E, 0xEE, 0xD9, 0x8B, 0xE4, 0xF1, 0xE0, 0x73, 0xE3, 0xC3, 0x4C,
|
||||
0x60, 0x78, 0x02, 0x16, 0x3B, 0x0A, 0xC0, 0x9F, 0x8F, 0xDF, 0x4F, 0x67, 0x13, 0x9D, 0x04, 0x7A,
|
||||
0x28, 0x6E, 0x52, 0xB8, 0xD3, 0xB0, 0xA8, 0xAD, 0x2A, 0xD8, 0xD7, 0xC8, 0x8A, 0xAA, 0x7D, 0x5B,
|
||||
0xE5, 0x28, 0x06, 0xBA, 0xC4, 0xBF, 0x41, 0x3B, 0x4E, 0xA6, 0x55, 0xC0, 0x5B, 0x40, 0xE4, 0xBF,
|
||||
0xA0, 0xC9, 0x1E, 0x16, 0x99, 0xB7, 0x50, 0xA7, 0x36, 0x17, 0xBC, 0xAE, 0xAF, 0x8E, 0x42, 0xF7,
|
||||
0xE0, 0xC7, 0xBA, 0x2A, 0xE6, 0x63, 0xEB, 0x88, 0xC1, 0x72, 0xA5, 0x4C, 0x76, 0x93, 0x3A, 0xA1,
|
||||
0x6C, 0xAA, 0xC8, 0x97, 0xEC, 0x24, 0x6D, 0x5F, 0xBE, 0x8A, 0xA1, 0x17, 0x46, 0x7E, 0xDC, 0x2B,
|
||||
0x59, 0x0E, 0x20, 0x17, 0x8A, 0xF6, 0xF1, 0xC5, 0xC4, 0xF8, 0x6F, 0xA0, 0x1C, 0xA2, 0x64, 0x27,
|
||||
0xDD, 0x36, 0xA6, 0x68, 0x5D, 0xD6, 0x29, 0xF3, 0xA8, 0xCB, 0x34, 0x66, 0x6A, 0x74, 0xCE, 0x52,
|
||||
0x1A, 0xCE, 0x70, 0x39, 0xB5, 0x63, 0xE9, 0x98, 0x87, 0xED, 0x3A, 0x66, 0x31, 0x47, 0xB0, 0x65,
|
||||
0xFB, 0x55, 0xC3, 0xAF, 0xA7, 0x46, 0x4F, 0x86, 0xF0, 0x6E, 0x28, 0x98, 0x8C, 0x31, 0x26, 0x86,
|
||||
0x9F, 0x2D, 0x4E, 0x8D, 0xBE, 0x2C, 0x10, 0x50, 0x21, 0xDE, 0x30, 0x82, 0x27, 0x71, 0x76, 0x6A,
|
||||
0xFE, 0x2D, 0xA5, 0xC5, 0xEC, 0xE5, 0x29, 0x7B, 0x89, 0xE5, 0xC4, 0x4B, 0x3B, 0x39, 0xB9, 0xCD,
|
||||
0x13, 0xE7, 0xFC, 0x3D, 0xCD, 0xD5, 0x1C, 0x93, 0xD9, 0x84, 0xA0, 0xB6, 0x03, 0xDF, 0xC5, 0xCD,
|
||||
0x7C, 0x08, 0xFE, 0xF1, 0x4C, 0x36, 0x92, 0x02, 0xFD, 0xB1, 0x31, 0x72, 0x5D, 0xFF, 0xD8, 0x12,
|
||||
0xB7, 0xA2, 0x5E, 0xF0, 0x3E, 0xEA, 0x05, 0x9F, 0xA3, 0x5C, 0xF0, 0x13, 0xCA, 0x04, 0xDF, 0xA1,
|
||||
0x4C, 0xF0, 0x21, 0xCA, 0x04, 0xEF, 0xA1, 0x4C, 0x70, 0x18, 0xCA, 0x04, 0x7B, 0xA2, 0x4C, 0xB0,
|
||||
0x11, 0xCA, 0x03, 0xDB, 0xA2, 0x3C, 0x70, 0x08, 0xCA, 0x03, 0xA7, 0xA2, 0x3C, 0xF0, 0x44, 0xFE,
|
||||
0xBD, 0x56, 0xCC, 0x4D, 0xDF, 0xEB, 0xC5, 0xDC, 0x74, 0xAF, 0xF1, 0x46, 0x88, 0xF0, 0xD5, 0xBD,
|
||||
0x66, 0x8D, 0xB7, 0xA3, 0x17, 0x13, 0xE1, 0xE3, 0xFA, 0x67, 0x3E, 0x26, 0x42, 0xBD, 0x98, 0x78,
|
||||
0xDD, 0xC4, 0xEB, 0x16, 0x5E, 0xB7, 0x0D, 0x7A, 0x31, 0xF1, 0xBA, 0x6B, 0x4A, 0xBD, 0x98, 0xC6,
|
||||
0x3D, 0x26, 0xC2, 0xE0, 0x7E, 0x63, 0xDE, 0xBD, 0x16, 0xCD, 0x37, 0x15, 0xCD, 0x7C, 0x7D, 0x98,
|
||||
0x02, 0x79, 0x33, 0x7B, 0xD0, 0xDC, 0x56, 0x7C, 0xC1, 0xC3, 0x29, 0xBF, 0x43, 0x44, 0xC8, 0xAD,
|
||||
0xD7, 0x41, 0x0E, 0xE7, 0x8A, 0x78, 0xDC, 0xD6, 0xE2, 0x20, 0x12, 0xA5, 0xA2, 0x87, 0xF3, 0xA1,
|
||||
0xEB, 0x4C, 0xCF, 0xED, 0x66, 0x8D, 0xB1, 0xFD, 0x72, 0x76, 0x1A, 0xD9, 0x19, 0x17, 0x00, 0x20,
|
||||
0x63, 0x1C, 0xA0, 0xA2, 0x67, 0x1A, 0xB0, 0xAE, 0xB4, 0x01, 0x3E, 0xCE, 0x7E, 0xCE, 0xD9, 0x93,
|
||||
0x0A, 0x5C, 0x90, 0x35, 0x60, 0xF2, 0x9B, 0xCB, 0x80, 0x02, 0x12, 0x41, 0x03, 0x66, 0xBA, 0x6C,
|
||||
0x11, 0x59, 0x20, 0xE6, 0x3F, 0xE5, 0xFC, 0x4B, 0x6D, 0x54, 0xAB, 0x76, 0x90, 0x30, 0x4F, 0xEB,
|
||||
0xE4, 0x95, 0x14, 0x18, 0x52, 0x3E, 0x8D, 0x5E, 0xFF, 0xB2, 0xCA, 0x99, 0xCC, 0x39, 0x58, 0xC3,
|
||||
0x72, 0x6C, 0xC9, 0x76, 0xE1, 0xB2, 0xF9, 0x97, 0x78, 0xB6, 0x9D, 0xD5, 0x29, 0xCF, 0x2E, 0x75,
|
||||
0x8A, 0x79, 0x9E, 0xF7, 0x0D, 0x9E, 0x4D, 0x89, 0xE7, 0x47, 0xCC, 0xA5, 0xC9, 0xAD, 0xC3, 0x0B,
|
||||
0x5A, 0x41, 0x97, 0x78, 0x5E, 0xE2, 0x78, 0x7E, 0x82, 0x91, 0xD3, 0x30, 0x93, 0x19, 0x50, 0x2B,
|
||||
0xF6, 0xA0, 0x63, 0x93, 0x2C, 0xCE, 0x57, 0xB6, 0xA6, 0x7C, 0x88, 0xFD, 0x2C, 0xB0, 0x5F, 0xCC,
|
||||
0x46, 0x35, 0x76, 0x57, 0x8A, 0x18, 0x21, 0xBE, 0xFC, 0xBC, 0x1C, 0x8F, 0x4B, 0xC0, 0x6C, 0x2B,
|
||||
0x57, 0x4A, 0xE8, 0x34, 0xA8, 0xF3, 0xB4, 0xBF, 0xBF, 0xD7, 0xA2, 0x99, 0x36, 0x70, 0x60, 0x41,
|
||||
0x00, 0xC0, 0x26, 0x26, 0x1F, 0xF9, 0xAE, 0x21, 0x48, 0x0D, 0xDD, 0x98, 0xAE, 0x89, 0xB4, 0x71,
|
||||
0x54, 0x02, 0x02, 0x16, 0x9B, 0xEA, 0x17, 0x43, 0x09, 0x77, 0x60, 0x83, 0xD2, 0x03, 0xE5, 0x99,
|
||||
0xE8, 0xA1, 0x9E, 0xDA, 0x1E, 0xF5, 0x20, 0xFE, 0xA1, 0x3F, 0xD9, 0x9E, 0xD0, 0x9D, 0xA6, 0x24,
|
||||
0x80, 0x94, 0x52, 0x90, 0xED, 0x5C, 0x2D, 0x6C, 0x4F, 0xB3, 0xCB, 0xB2, 0xC9, 0x9E, 0x51, 0x1B,
|
||||
0xA7, 0x30, 0xF3, 0x4E, 0x36, 0x49, 0xB6, 0x07, 0xCD, 0x4A, 0x8F, 0xD7, 0x28, 0xBB, 0x67, 0x9C,
|
||||
0xFB, 0x18, 0x9A, 0x31, 0x78, 0xEF, 0xF1, 0xBD, 0x48, 0x04, 0x67, 0x4F, 0xB1, 0x4F, 0x7C, 0x57,
|
||||
0x70, 0xA4, 0x43, 0x57, 0x34, 0x4C, 0xF6, 0xF1, 0x2E, 0x70, 0x22, 0xEB, 0xBD, 0x06, 0xEB, 0x3D,
|
||||
0xB1, 0xA3, 0xA0, 0x6E, 0x38, 0xAF, 0x7B, 0x62, 0xA9, 0xF1, 0x1C, 0x9D, 0xFD, 0xE7, 0x0C, 0x4C,
|
||||
0x80, 0xD4, 0x95, 0x96, 0x6B, 0xD5, 0x60, 0xC4, 0x33, 0xB7, 0x47, 0x3A, 0x64, 0xA3, 0x7C, 0x99,
|
||||
0x21, 0x05, 0x5B, 0x64, 0xDE, 0xB1, 0x78, 0x67, 0xC1, 0xD1, 0x68, 0xDE, 0x75, 0xC8, 0x26, 0x29,
|
||||
0x0B, 0x42, 0x20, 0x5F, 0xCE, 0x32, 0x0F, 0x86, 0x03, 0x08, 0xC2, 0x05, 0x46, 0x99, 0x85, 0x30,
|
||||
0xC2, 0x24, 0x90, 0x0E, 0x68, 0xAD, 0xA0, 0xBB, 0x82, 0x3D, 0xEE, 0xE7, 0x10, 0xCD, 0x3F, 0x32,
|
||||
0xE0, 0x0D, 0x2D, 0xF4, 0x58, 0x8B, 0x2C, 0x62, 0x47, 0xC0, 0xB7, 0x25, 0x78, 0x89, 0x12, 0xCE,
|
||||
0x97, 0xCD, 0xEF, 0x35, 0x5D, 0x8C, 0x06, 0x75, 0x88, 0x1E, 0xCC, 0xFA, 0x13, 0x46, 0x09, 0x96,
|
||||
0x62, 0x01, 0x58, 0x97, 0x12, 0xD1, 0x8A, 0x99, 0xD8, 0x2D, 0x71, 0xE2, 0xC5, 0x8E, 0xAA, 0xF1,
|
||||
0x78, 0xE7, 0x59, 0xF1, 0xD4, 0x86, 0x4E, 0x08, 0xBF, 0x56, 0xBC, 0xFE, 0x5E, 0x9E, 0xC2, 0xE4,
|
||||
0xF2, 0x74, 0x42, 0x5E, 0x42, 0x68, 0x64, 0xB3, 0xEE, 0x85, 0x3D, 0xB4, 0x16, 0x6F, 0x47, 0x96,
|
||||
0xEF, 0xBD, 0xD7, 0xB4, 0x57, 0x41, 0xD6, 0x28, 0x4C, 0x68, 0xE2, 0x40, 0x1D, 0x44, 0x18, 0xF7,
|
||||
0x77, 0x65, 0xC0, 0x45, 0xAD, 0xBB, 0xE8, 0x03, 0x5B, 0xF2, 0xA5, 0x8F, 0x8D, 0x42, 0x95, 0x5E,
|
||||
0x8F, 0x9D, 0x20, 0x10, 0xE0, 0xE3, 0x47, 0x2C, 0xA9, 0x20, 0x7D, 0x53, 0x54, 0x91, 0x1E, 0x57,
|
||||
0xA2, 0xEF, 0xDB, 0x1E, 0x6D, 0x53, 0x77, 0x86, 0x7C, 0xA9, 0xE8, 0x12, 0xEC, 0xFD, 0xE3, 0x6A,
|
||||
0xE9, 0xE4, 0x16, 0x5E, 0x15, 0xD3, 0x4A, 0x9D, 0xD3, 0x7B, 0xF4, 0xCB, 0xDC, 0xAC, 0xB8, 0xB3,
|
||||
0x2A, 0x32, 0xDE, 0xC0, 0x03, 0x83, 0xC6, 0x16, 0x56, 0xD6, 0xE0, 0x4C, 0xB2, 0x51, 0x61, 0x06,
|
||||
0x4C, 0x4A, 0x2F, 0x66, 0x53, 0x43, 0x15, 0x28, 0xDD, 0xB6, 0x7F, 0xB4, 0x06, 0x1F, 0x77, 0x02,
|
||||
0xC7, 0xD9, 0x94, 0x07, 0xED, 0xBF, 0x5D, 0x1B, 0x74, 0xF0, 0x6B, 0x35, 0x9B, 0xFB, 0xB6, 0xE9,
|
||||
0xDC, 0x80, 0xB0, 0x9B, 0xF8, 0x3B, 0x7E, 0xB8, 0x02, 0x7F, 0x6A, 0xD0, 0x38, 0xB7, 0x8F, 0xEC,
|
||||
0x08, 0xE7, 0x05, 0xC4, 0xDB, 0x28, 0x5C, 0xE5, 0xBD, 0x68, 0x1E, 0x84, 0x8A, 0x8B, 0x1A, 0x4F,
|
||||
0x97, 0x11, 0x5D, 0x30, 0x78, 0x77, 0x8A, 0x69, 0xCE, 0x65, 0x33, 0x7F, 0x5C, 0x3D, 0xA4, 0x6B,
|
||||
0xE9, 0x9F, 0xAA, 0x1E, 0x3A, 0x51, 0x2B, 0x38, 0xA9, 0xBB, 0x13, 0x1E, 0x09, 0x3C, 0xDD, 0xF7,
|
||||
0x91, 0x74, 0xAF, 0x04, 0xB2, 0x48, 0x9F, 0xA1, 0x1B, 0xEF, 0x46, 0xBA, 0xA5, 0xB5, 0x87, 0xF6,
|
||||
0x1C, 0x99, 0x3B, 0xA5, 0x90, 0x54, 0xCC, 0x0A, 0x73, 0xF9, 0x2F, 0x44, 0x13, 0xC6, 0x1F, 0xDE,
|
||||
0xB7, 0x83, 0x64, 0xFC, 0x72, 0xD1, 0x8E, 0x6A, 0x33, 0xA6, 0xFE, 0x4C, 0xD1, 0x8E, 0xF8, 0x0E,
|
||||
0xC7, 0x52, 0xD4, 0x9C, 0xCB, 0xC4, 0xE7, 0x8A, 0xC9, 0x32, 0xA1, 0xB4, 0xB7, 0x50, 0x97, 0x82,
|
||||
0x51, 0x60, 0xD0, 0x55, 0x43, 0x30, 0x89, 0x94, 0xE6, 0xD2, 0xAD, 0x32, 0x98, 0xA4, 0xB0, 0x3C,
|
||||
0x4D, 0x80, 0xE8, 0x61, 0x9C, 0x00, 0xD3, 0xB4, 0x22, 0xB2, 0x9E, 0x96, 0xF3, 0xFC, 0x52, 0xB9,
|
||||
0xD6, 0xB8, 0x5F, 0x2C, 0xE7, 0x39, 0xB7, 0xC5, 0x9A, 0xB1, 0x4E, 0x9F, 0xFE, 0xA6, 0x09, 0x90,
|
||||
0xBB, 0xED, 0x51, 0x53, 0xC7, 0x6F, 0x56, 0x20, 0xF0, 0x8A, 0x7B, 0x4D, 0x3D, 0xDC, 0x18, 0xA9,
|
||||
0x0A, 0xC1, 0x6E, 0xD2, 0x92, 0x8A, 0xB4, 0x25, 0xE5, 0x92, 0x0B, 0xB1, 0x28, 0x2A, 0xB6, 0x68,
|
||||
0xB5, 0x46, 0x9B, 0x86, 0x1D, 0x15, 0x1E, 0xC9, 0xC5, 0xE2, 0xEA, 0xB5, 0x60, 0x2D, 0x70, 0xAA,
|
||||
0x1B, 0x2A, 0x19, 0xEF, 0xAF, 0x96, 0x1D, 0x34, 0x7C, 0xBF, 0xEC, 0x80, 0xCB, 0x57, 0x86, 0x7B,
|
||||
0x39, 0x31, 0xDC, 0xB6, 0x91, 0xE1, 0x42, 0x5C, 0xDE, 0xE0, 0xA8, 0x20, 0xAA, 0x85, 0x30, 0xA8,
|
||||
0x12, 0xEF, 0x2A, 0xE9, 0x34, 0x8C, 0x7D, 0x52, 0x93, 0x63, 0x63, 0x7F, 0x6B, 0x6E, 0x19, 0x29,
|
||||
0xD0, 0x5F, 0xAA, 0xC3, 0x55, 0x61, 0x95, 0x1A, 0x61, 0xD4, 0x86, 0x06, 0x13, 0xA2, 0x8B, 0x91,
|
||||
0x99, 0xD3, 0x57, 0xD2, 0xC2, 0xA2, 0xE3, 0x7D, 0x86, 0x33, 0xAE, 0x0D, 0xE8, 0xF9, 0xA8, 0x7C,
|
||||
0xA5, 0xAB, 0xAE, 0x95, 0xAF, 0xDC, 0x14, 0x9C, 0x25, 0x25, 0x69, 0x4A, 0x05, 0xDA, 0x0D, 0x91,
|
||||
0xB3, 0xFC, 0x9B, 0xC5, 0xAE, 0xA9, 0xB3, 0x4C, 0xAD, 0x28, 0x56, 0x72, 0xBA, 0x52, 0x54, 0xE3,
|
||||
0xC6, 0x08, 0x20, 0x5F, 0x22, 0x67, 0x39, 0x2F, 0x71, 0x96, 0x52, 0xA5, 0xFC, 0x46, 0xEA, 0x2C,
|
||||
0xA5, 0x2D, 0xD9, 0xDB, 0xCF, 0x16, 0x11, 0xCB, 0xDE, 0x54, 0xB7, 0x14, 0xF3, 0x9D, 0x06, 0x64,
|
||||
0x5D, 0x20, 0xC7, 0x4C, 0x92, 0xDC, 0xD4, 0x15, 0xA4, 0xCE, 0x72, 0xD2, 0xD7, 0x9D, 0x65, 0x2A,
|
||||
0x2C, 0x40, 0x4C, 0xDD, 0x49, 0xBA, 0xD6, 0x7E, 0x5C, 0x5A, 0x27, 0xDE, 0x7F, 0x5C, 0x5E, 0xA7,
|
||||
0xB3, 0x3D, 0x49, 0xE1, 0x5C, 0xE4, 0x4A, 0xFE, 0xD8, 0x08, 0x6A, 0x89, 0x8C, 0x14, 0x0C, 0x52,
|
||||
0xF6, 0x7E, 0xBA, 0xB6, 0x93, 0xDE, 0xD2, 0x07, 0x84, 0xD1, 0x5F, 0xBB, 0x5F, 0x4F, 0x02, 0xC2,
|
||||
0x92, 0x5A, 0xEC, 0x2D, 0xEB, 0x96, 0xC5, 0x88, 0x43, 0xEE, 0x97, 0xBE, 0xC9, 0x61, 0x5C, 0x1D,
|
||||
0xA1, 0xD3, 0x9C, 0xC8, 0xD0, 0xED, 0xE5, 0xFB, 0x7B, 0xF4, 0x86, 0x62, 0x0B, 0x32, 0x6F, 0xBB,
|
||||
0xCD, 0x96, 0xB3, 0xC1, 0x8C, 0x51, 0x3F, 0xDD, 0xCF, 0xA1, 0xFE, 0x13, 0xFA, 0x30, 0xF9, 0x97,
|
||||
0x1A, 0x36, 0xBE, 0xEE, 0x3C, 0x02, 0xF9, 0xB2, 0xF7, 0xAA, 0xED, 0x38, 0xC7, 0xB0, 0x90, 0x89,
|
||||
0x0F, 0x99, 0xA4, 0x2B, 0xE9, 0x5E, 0x7C, 0x6E, 0xFC, 0x3E, 0x14, 0x76, 0x13, 0xBC, 0xDA, 0x30,
|
||||
0xBE, 0xF9, 0x64, 0x10, 0x96, 0x0F, 0xCE, 0x2B, 0x2E, 0x64, 0x37, 0xDB, 0x24, 0x5F, 0xE5, 0xE6,
|
||||
0xA2, 0xDC, 0x27, 0x91, 0x35, 0xBF, 0xF2, 0xD2, 0xC6, 0x1F, 0xD5, 0x86, 0xEF, 0x52, 0x7F, 0xEA,
|
||||
0x9D, 0x7D, 0xEE, 0x48, 0xC5, 0xF6, 0x27, 0x84, 0xAD, 0x9D, 0xEA, 0x2B, 0x73, 0x05, 0x0E, 0xC7,
|
||||
0xBC, 0x72, 0xD4, 0x35, 0x21, 0x47, 0xA5, 0xB0, 0x69, 0x5E, 0x43, 0xEB, 0xB4, 0x1A, 0x5F, 0x29,
|
||||
0xBF, 0x03, 0x12, 0x42, 0xFC, 0x04, 0xEC, 0xFA, 0x57, 0xE1, 0x42, 0x89, 0xF4, 0x2E, 0x31, 0x5C,
|
||||
0x40, 0xF3, 0x41, 0xA8, 0x9D, 0x2B, 0x39, 0x59, 0x02, 0xE7, 0x6B, 0xCF, 0x5B, 0x69, 0x2E, 0xD8,
|
||||
0x23, 0xF3, 0x14, 0xF8, 0x60, 0xEE, 0x77, 0x28, 0xE3, 0xFD, 0xF5, 0x87, 0x05, 0x1F, 0x5A, 0xE4,
|
||||
0x4C, 0xB9, 0x45, 0x2E, 0x5B, 0xC4, 0xCD, 0x10, 0x57, 0x21, 0xC6, 0xA9, 0x2D, 0x6E, 0x71, 0xB1,
|
||||
0x6B, 0xE6, 0xF7, 0x10, 0x37, 0x4F, 0x6A, 0xA9, 0xA9, 0x09, 0x05, 0x8A, 0x52, 0x0D, 0xB9, 0x71,
|
||||
0x0F, 0x1C, 0xFC, 0xC9, 0xF6, 0xB8, 0xB4, 0x3B, 0xCC, 0x3D, 0xAC, 0x4E, 0x3D, 0xD2, 0x5B, 0xFD,
|
||||
0x73, 0x51, 0x20, 0xA7, 0xC1, 0x05, 0x36, 0xC0, 0x08, 0x07, 0x78, 0x9C, 0xD3, 0x2E, 0x75, 0x75,
|
||||
0x78, 0x6F, 0xA1, 0xDC, 0xA9, 0x43, 0x87, 0x7B, 0xA1, 0x42, 0xE8, 0x0F, 0x73, 0xC3, 0xD1, 0xFF,
|
||||
0xE4, 0x2A, 0x8C, 0x9A, 0x44, 0x80, 0xB9, 0x9E, 0x79, 0x52, 0x26, 0x68, 0x2F, 0x00, 0xED, 0x05,
|
||||
0x44, 0xDB, 0x01, 0x01, 0x59, 0xD0, 0x1A, 0x1C, 0xB4, 0x63, 0x36, 0xE0, 0x07, 0x8A, 0x04, 0x49,
|
||||
0x2D, 0x80, 0xC0, 0x28, 0xBA, 0xC0, 0x53, 0xAF, 0xC2, 0x5E, 0x87, 0x78, 0x60, 0x98, 0xF6, 0x1D,
|
||||
0x40, 0xFC, 0x57, 0x20, 0x7A, 0xD9, 0xA3, 0xF5, 0x5E, 0x3C, 0xEA, 0xF6, 0x10, 0xB8, 0x5E, 0x27,
|
||||
0x55, 0xA1, 0x6C, 0x11, 0x73, 0x98, 0x2D, 0xCD, 0x8A, 0xB9, 0x1A, 0x98, 0x83, 0xC0, 0x0B, 0xFE,
|
||||
0x20, 0xEC, 0x08, 0x5E, 0x43, 0x0A, 0x4F, 0xF9, 0x8C, 0xD8, 0x8B, 0x60, 0x8D, 0x07, 0x6D, 0x39,
|
||||
0x76, 0xDF, 0x81, 0xB6, 0x5A, 0x44, 0x5B, 0xAE, 0x58, 0x25, 0x05, 0x46, 0x41, 0xB5, 0x1E, 0x02,
|
||||
0xF1, 0x16, 0xFB, 0x0C, 0xD5, 0x8D, 0x82, 0x03, 0xEC, 0x3F, 0x6F, 0x00, 0x17, 0x5D, 0x29, 0x1A,
|
||||
0x3C, 0xDB, 0x0D, 0xEC, 0x96, 0xF9, 0xB0, 0x0E, 0xB7, 0x57, 0xEE, 0x6B, 0x99, 0x94, 0x2F, 0x77,
|
||||
0x37, 0x1B, 0x7A, 0xDE, 0x82, 0xCF, 0x63, 0xD3, 0x76, 0x5A, 0x1C, 0xD9, 0x28, 0xFB, 0x25, 0x1C,
|
||||
0x6F, 0xD7, 0x79, 0xDA, 0x56, 0x6B, 0xE1, 0xC8, 0xBE, 0x39, 0xFF, 0xA2, 0x0F, 0xDF, 0x9C, 0xDB,
|
||||
0xA4, 0x6A, 0x47, 0xF8, 0xB5, 0x31, 0xD7, 0x0D, 0x71, 0x61, 0x96, 0x2C, 0x7F, 0xAE, 0xCF, 0xBF,
|
||||
0x30, 0x5E, 0x17, 0x58, 0x80, 0x58, 0x1E, 0xB5, 0xC5, 0xED, 0xB9, 0xF5, 0xBB, 0xA0, 0x08, 0x8B,
|
||||
0xE6, 0x2A, 0x73, 0x39, 0x18, 0xED, 0x75, 0xBC, 0xD7, 0xF8, 0x71, 0x03, 0x2A, 0x10, 0x84, 0x2E,
|
||||
0xE3, 0xD1, 0x15, 0x91, 0xA4, 0x05, 0xE6, 0x84, 0x43, 0x56, 0x28, 0x58, 0xCE, 0xBF, 0xB8, 0x25,
|
||||
0x88, 0x84, 0x19, 0x4D, 0xC5, 0xF6, 0xB6, 0x78, 0x91, 0x10, 0x17, 0x67, 0x1D, 0xE4, 0x45, 0x47,
|
||||
0xEE, 0x4E, 0x57, 0x24, 0x92, 0x63, 0x62, 0x2B, 0x0E, 0x9B, 0x07, 0xA3, 0xB3, 0x91, 0x71, 0x24,
|
||||
0x2E, 0x2A, 0x0B, 0x75, 0x84, 0x2D, 0x70, 0x8C, 0x49, 0xD7, 0xB9, 0x25, 0x6C, 0x67, 0xDC, 0xF3,
|
||||
0xB4, 0x26, 0xF4, 0x14, 0xAE, 0xB1, 0x89, 0x6A, 0x40, 0x1C, 0x15, 0xC5, 0x12, 0x2F, 0x9F, 0x73,
|
||||
0x2C, 0x3B, 0xA3, 0xAB, 0x95, 0x40, 0x87, 0x06, 0x81, 0x0E, 0x15, 0x5E, 0xBA, 0xF2, 0x4D, 0x85,
|
||||
0x44, 0x07, 0x25, 0x86, 0x42, 0xA9, 0xAA, 0x00, 0xA0, 0xCC, 0x75, 0x61, 0x3C, 0xBB, 0xC5, 0x38,
|
||||
0x09, 0x60, 0x7E, 0x37, 0xDE, 0x33, 0x4C, 0x44, 0x6D, 0xB7, 0x70, 0xB3, 0xA6, 0xB9, 0x32, 0x12,
|
||||
0x3E, 0x70, 0x98, 0x90, 0xAB, 0xC6, 0xB2, 0x6F, 0x8F, 0x7D, 0xDE, 0x23, 0x42, 0x7A, 0x88, 0x89,
|
||||
0xB9, 0x0D, 0xFD, 0xC1, 0xEB, 0x0F, 0x55, 0x3B, 0x03, 0x65, 0xD3, 0xA3, 0xD2, 0xFB, 0xDE, 0xAE,
|
||||
0xD2, 0x75, 0x6D, 0xCA, 0x4D, 0x0D, 0xF8, 0xD7, 0x2B, 0xFF, 0x09, 0xCF, 0x97, 0xD6, 0xB6, 0xF6,
|
||||
0xCA, 0x5D, 0x85, 0x77, 0x26, 0xEB, 0xDC, 0xA9, 0xD8, 0x1E, 0xB5, 0xEF, 0x84, 0x07, 0x60, 0xE6,
|
||||
0x08, 0x0E, 0xB9, 0x7D, 0x8E, 0x25, 0xB8, 0x94, 0x7A, 0xD7, 0xB8, 0xBC, 0x38, 0x69, 0xC6, 0x27,
|
||||
0xC2, 0xA8, 0x5D, 0x99, 0x76, 0xA4, 0x56, 0xE5, 0x69, 0x69, 0x30, 0xAA, 0xAB, 0x59, 0x4F, 0x0E,
|
||||
0xE3, 0x27, 0x30, 0x88, 0xE5, 0x1F, 0x61, 0xC8, 0x55, 0xB0, 0x8E, 0x1F, 0x5D, 0x3F, 0x7D, 0x39,
|
||||
0x79, 0x91, 0xD4, 0x92, 0xC4, 0xA5, 0x9D, 0x4B, 0x5C, 0xE6, 0xFC, 0xF6, 0x63, 0x2B, 0x37, 0x25,
|
||||
0x4F, 0x40, 0xC9, 0xC6, 0xFC, 0xB5, 0xC7, 0x4C, 0xAE, 0x99, 0xB9, 0x6A, 0x68, 0x83, 0x69, 0x64,
|
||||
0xCC, 0x07, 0x63, 0xCC, 0x3C, 0x93, 0x99, 0x2D, 0x66, 0xAB, 0x69, 0x30, 0x53, 0xF0, 0x6E, 0x2B,
|
||||
0xFE, 0xAE, 0x37, 0xAB, 0x4D, 0xF1, 0x67, 0x86, 0x59, 0x67, 0x36, 0x98, 0x0C, 0x9F, 0x1B, 0xF0,
|
||||
0x3E, 0xC3, 0xFB, 0xAD, 0x1C, 0xBB, 0x83, 0xBF, 0x2E, 0x33, 0x1B, 0xF1, 0xCD, 0x2A, 0x8C, 0xAD,
|
||||
0x99, 0xC5, 0x26, 0xE7, 0xEF, 0x0D, 0x66, 0x2A, 0xBE, 0x5D, 0x8F, 0x57, 0xCD, 0xF8, 0x3F, 0x43,
|
||||
0xCC, 0x20, 0xFE, 0xED, 0x6F, 0x06, 0xE3, 0x7D, 0x7F, 0xBC, 0x1B, 0x8D, 0x6F, 0x97, 0x16, 0x70,
|
||||
0x89, 0x69, 0x07, 0x31, 0xAF, 0xE6, 0x27, 0x63, 0x16, 0x63, 0xEE, 0x36, 0xC2, 0x6D, 0x30, 0xB3,
|
||||
0xCD, 0x34, 0x33, 0x06, 0xFF, 0x0F, 0x06, 0xD4, 0x56, 0x66, 0x26, 0xC6, 0x6C, 0x28, 0xB0, 0x91,
|
||||
0xCA, 0xD5, 0x1C, 0xB1, 0x82, 0xB3, 0x97, 0x61, 0xD6, 0x22, 0xD3, 0x10, 0xCD, 0x5D, 0x08, 0x68,
|
||||
0x99, 0xD9, 0xC1, 0xF1, 0x0D, 0x8E, 0x86, 0x11, 0xC4, 0x3E, 0x9C, 0xFF, 0x0E, 0x01, 0xAE, 0x2F,
|
||||
0x11, 0x23, 0x48, 0xC8, 0x5B, 0x60, 0x00, 0x00};
|
Binary file not shown.
BIN
Frameworks/GME/vgmplay/XMasFiles/WEWISH.CMF
Normal file
BIN
Frameworks/GME/vgmplay/XMasFiles/WEWISH.CMF
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue