comparison src/console/Classic_Emu.cxx @ 316:fb513e10174e trunk

[svn] - merge libconsole-blargg into mainline libconsole: + obsoletes plugins-ugly:sapplug
author nenolod
date Thu, 30 Nov 2006 19:54:33 -0800
parents 3da1b8942b8b
children 986f098da058
comparison
equal deleted inserted replaced
315:2294f3a6f136 316:fb513e10174e
1 1 // Game_Music_Emu 0.5.1. http://www.slack.net/~ant/
2 // Game_Music_Emu 0.3.0. http://www.slack.net/~ant/
3 2
4 #include "Classic_Emu.h" 3 #include "Classic_Emu.h"
5 4
6 #include "Multi_Buffer.h" 5 #include "Multi_Buffer.h"
6 #include <string.h>
7 7
8 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you 8 /* Copyright (C) 2003-2006 Shay Green. This module is free software; you
9 can redistribute it and/or modify it under the terms of the GNU Lesser 9 can redistribute it and/or modify it under the terms of the GNU Lesser
10 General Public License as published by the Free Software Foundation; either 10 General Public License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version. This 11 version 2.1 of the License, or (at your option) any later version. This
12 module is distributed in the hope that it will be useful, but WITHOUT ANY 12 module is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
15 more details. You should have received a copy of the GNU Lesser General 15 details. You should have received a copy of the GNU Lesser General Public
16 Public License along with this module; if not, write to the Free Software 16 License along with this module; if not, write to the Free Software Foundation,
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
18 18
19 #include BLARGG_SOURCE_BEGIN 19 #include "blargg_source.h"
20 20
21 Classic_Emu::Classic_Emu() 21 Classic_Emu::Classic_Emu()
22 { 22 {
23 buf = NULL; 23 buf = 0;
24 stereo_buffer = NULL; 24 stereo_buffer = 0;
25 voice_types = 0;
26
27 // avoid inconsistency in our duplicated constants
28 assert( (int) wave_type == (int) Multi_Buffer::wave_type );
29 assert( (int) noise_type == (int) Multi_Buffer::noise_type );
30 assert( (int) mixed_type == (int) Multi_Buffer::mixed_type );
25 } 31 }
26 32
27 Classic_Emu::~Classic_Emu() 33 Classic_Emu::~Classic_Emu()
28 { 34 {
29 delete stereo_buffer; 35 delete stereo_buffer;
30 } 36 }
31 37
32 void Classic_Emu::set_equalizer( equalizer_t const& eq ) 38 void Classic_Emu::set_equalizer_( equalizer_t const& eq )
33 { 39 {
34 Music_Emu::set_equalizer( eq ); 40 Music_Emu::set_equalizer_( eq );
35 update_eq( eq.treble ); 41 update_eq( eq.treble );
36 if ( buf ) 42 if ( buf )
37 buf->bass_freq( equalizer().bass ); 43 buf->bass_freq( equalizer().bass );
38 } 44 }
39 45
40 blargg_err_t Classic_Emu::set_sample_rate( long sample_rate ) 46 blargg_err_t Classic_Emu::set_sample_rate_( long sample_rate )
41 { 47 {
42 if ( !buf ) 48 if ( !buf )
43 { 49 {
44 if ( !stereo_buffer ) 50 if ( !stereo_buffer )
45 BLARGG_CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer ); 51 CHECK_ALLOC( stereo_buffer = BLARGG_NEW Stereo_Buffer );
46 buf = stereo_buffer; 52 buf = stereo_buffer;
47 } 53 }
48 54 return buf->set_sample_rate( sample_rate, 1000 / 20 );
49 BLARGG_RETURN_ERR( buf->set_sample_rate( sample_rate, 1000 / 20 ) );
50 return Music_Emu::set_sample_rate( sample_rate );
51 } 55 }
52 56
53 void Classic_Emu::mute_voices( int mask ) 57 void Classic_Emu::mute_voices_( int mask )
54 { 58 {
55 require( buf ); // set_sample_rate() must have been called 59 Music_Emu::mute_voices_( mask );
56
57 Music_Emu::mute_voices( mask );
58 for ( int i = voice_count(); i--; ) 60 for ( int i = voice_count(); i--; )
59 { 61 {
60 if ( mask & (1 << i) ) 62 if ( mask & (1 << i) )
61 { 63 {
62 set_voice( i, NULL, NULL, NULL ); 64 set_voice( i, 0, 0, 0 );
63 } 65 }
64 else 66 else
65 { 67 {
66 Multi_Buffer::channel_t ch = buf->channel( i ); 68 Multi_Buffer::channel_t ch = buf->channel( i, (voice_types ? voice_types [i] : 0) );
69 assert( (ch.center && ch.left && ch.right) ||
70 (!ch.center && !ch.left && !ch.right) ); // all or nothing
67 set_voice( i, ch.center, ch.left, ch.right ); 71 set_voice( i, ch.center, ch.left, ch.right );
68 } 72 }
69 } 73 }
70 } 74 }
71 75
72 blargg_err_t Classic_Emu::setup_buffer( long new_clock_rate ) 76 blargg_err_t Classic_Emu::setup_buffer( long rate )
73 { 77 {
74 require( sample_rate() ); // fails if set_sample_rate() hasn't been called yet 78 clock_rate_ = rate;
75 79 buf->clock_rate( rate );
76 clock_rate = new_clock_rate; 80 RETURN_ERR( buf->set_channel_count( voice_count() ) );
77 buf->clock_rate( clock_rate );
78 BLARGG_RETURN_ERR( buf->set_channel_count( voice_count() ) );
79 set_equalizer( equalizer() ); 81 set_equalizer( equalizer() );
80 remute_voices(); 82 buf_changed_count = buf->channels_changed_count();
81 return blargg_success; 83 return 0;
82 } 84 }
83 85
84 void Classic_Emu::start_track( int track ) 86 blargg_err_t Classic_Emu::start_track_( int track )
85 { 87 {
86 Music_Emu::start_track( track ); 88 RETURN_ERR( Music_Emu::start_track_( track ) );
87 buf->clear(); 89 buf->clear();
90 return 0;
88 } 91 }
89 92
90 blip_time_t Classic_Emu::run_clocks( blip_time_t t, bool* ) 93 blargg_err_t Classic_Emu::play_( long count, sample_t* out )
91 { 94 {
92 assert( false );
93 return t;
94 }
95
96 blip_time_t Classic_Emu::run( int msec, bool* added_stereo )
97 {
98 return run_clocks( (long) msec * clock_rate / 1000, added_stereo );
99 }
100
101 void Classic_Emu::play( long count, sample_t* out )
102 {
103 require( sample_rate() ); // fails if set_sample_rate() hasn't been called yet
104
105 long remain = count; 95 long remain = count;
106 while ( remain ) 96 while ( remain )
107 { 97 {
108 remain -= buf->read_samples( &out [count - remain], remain ); 98 remain -= buf->read_samples( &out [count - remain], remain );
109 if ( remain ) 99 if ( remain )
110 { 100 {
111 bool added_stereo = false; 101 if ( buf_changed_count != buf->channels_changed_count() )
112 blip_time_t clocks_emulated = run( buf->length(), &added_stereo ); 102 {
113 buf->end_frame( clocks_emulated, added_stereo ); 103 buf_changed_count = buf->channels_changed_count();
104 remute_voices();
105 }
106 int msec = buf->length();
107 blip_time_t clocks_emulated = (blargg_long) msec * clock_rate_ / 1000;
108 RETURN_ERR( run_clocks( clocks_emulated, msec ) );
109 assert( clocks_emulated );
110 buf->end_frame( clocks_emulated );
114 } 111 }
115 } 112 }
113 return 0;
116 } 114 }
117 115
116 // Rom_Data
117
118 blargg_err_t Rom_Data_::load_rom_data_( Data_Reader& in,
119 int header_size, void* header_out, int fill, long pad_size )
120 {
121 long file_offset = pad_size - header_size;
122
123 rom_addr = 0;
124 mask = 0;
125 size_ = 0;
126 rom.clear();
127
128 file_size_ = in.remain();
129 if ( file_size_ <= header_size ) // <= because there must be data after header
130 return gme_wrong_file_type;
131 blargg_err_t err = rom.resize( file_offset + file_size_ + pad_size );
132 if ( !err )
133 err = in.read( rom.begin() + file_offset, file_size_ );
134 if ( err )
135 {
136 rom.clear();
137 return err;
138 }
139
140 file_size_ -= header_size;
141 memcpy( header_out, &rom [file_offset], header_size );
142
143 memset( rom.begin() , fill, pad_size );
144 memset( rom.end() - pad_size, fill, pad_size );
145
146 return 0;
147 }
148
149 void Rom_Data_::set_addr_( long addr, int unit )
150 {
151 rom_addr = addr - unit - pad_extra;
152
153 long rounded = (addr + file_size_ + unit - 1) / unit * unit;
154 if ( rounded <= 0 )
155 {
156 rounded = 0;
157 }
158 else
159 {
160 int shift = 0;
161 unsigned long max_addr = (unsigned long) (rounded - 1);
162 while ( max_addr >> shift )
163 shift++;
164 mask = (1L << shift) - 1;
165 }
166
167 if ( addr < 0 )
168 addr = 0;
169 size_ = rounded;
170 if ( rom.resize( rounded - rom_addr + pad_extra ) ) { } // OK if shrink fails
171
172 if ( 0 )
173 {
174 dprintf( "addr: %X\n", addr );
175 dprintf( "file_size: %d\n", file_size_ );
176 dprintf( "rounded: %d\n", rounded );
177 dprintf( "mask: $%X\n", mask );
178 }
179 }