diff options
Diffstat (limited to 'apps/codecs/libgme/hes_emu.h')
-rw-r--r-- | apps/codecs/libgme/hes_emu.h | 156 |
1 files changed, 61 insertions, 95 deletions
diff --git a/apps/codecs/libgme/hes_emu.h b/apps/codecs/libgme/hes_emu.h index 0dcd29a9c6..a1dd048498 100644 --- a/apps/codecs/libgme/hes_emu.h +++ b/apps/codecs/libgme/hes_emu.h | |||
@@ -12,88 +12,67 @@ | |||
12 | #include "hes_apu_adpcm.h" | 12 | #include "hes_apu_adpcm.h" |
13 | #include "hes_cpu.h" | 13 | #include "hes_cpu.h" |
14 | #include "m3u_playlist.h" | 14 | #include "m3u_playlist.h" |
15 | 15 | #include "track_filter.h" | |
16 | typedef short sample_t; | ||
17 | |||
18 | enum { buf_size = 2048 }; | ||
19 | 16 | ||
20 | // HES file header | 17 | // HES file header |
18 | enum { info_offset = 0x20 }; | ||
21 | enum { header_size = 0x20 }; | 19 | enum { header_size = 0x20 }; |
22 | struct header_t | 20 | struct header_t |
23 | { | 21 | { |
24 | byte tag [4]; | 22 | byte tag [4]; |
25 | byte vers; | 23 | byte vers; |
26 | byte first_track; | 24 | byte first_track; |
27 | byte init_addr [2]; | 25 | byte init_addr [2]; |
28 | byte banks [8]; | 26 | byte banks [8]; |
29 | byte data_tag [4]; | 27 | byte data_tag [4]; |
30 | byte size [4]; | 28 | byte size [4]; |
31 | byte addr [4]; | 29 | byte addr [4]; |
32 | byte unused [4]; | 30 | byte unused [4]; |
33 | }; | 31 | }; |
34 | 32 | ||
35 | 33 | ||
36 | struct timer_t { | 34 | struct timer_t { |
37 | hes_time_t last_time; | 35 | hes_time_t last_time; |
38 | blargg_long count; | 36 | int count; |
39 | blargg_long load; | 37 | int load; |
40 | int raw_load; | 38 | int raw_load; |
41 | byte enabled; | 39 | byte enabled; |
42 | byte fired; | 40 | byte fired; |
43 | }; | 41 | }; |
44 | 42 | ||
45 | struct vdp_t { | 43 | struct vdp_t { |
46 | hes_time_t next_vbl; | 44 | hes_time_t next_vbl; |
47 | byte latch; | 45 | byte latch; |
48 | byte control; | 46 | byte control; |
49 | }; | 47 | }; |
50 | 48 | ||
51 | struct irq_t { | 49 | struct irq_t { |
52 | hes_time_t timer; | 50 | hes_time_t timer; |
53 | hes_time_t vdp; | 51 | hes_time_t vdp; |
54 | byte disables; | 52 | byte disables; |
55 | }; | 53 | }; |
56 | 54 | ||
57 | |||
58 | struct Hes_Emu { | 55 | struct Hes_Emu { |
59 | hes_time_t play_period; | 56 | hes_time_t play_period; |
60 | hes_time_t last_frame_hook; | ||
61 | int timer_base; | 57 | int timer_base; |
62 | 58 | ||
63 | struct timer_t timer; | 59 | struct timer_t timer; |
64 | struct vdp_t vdp; | 60 | struct vdp_t vdp; |
65 | struct irq_t irq; | 61 | struct irq_t irq; |
66 | 62 | ||
67 | // Sound | 63 | // Sound |
68 | long clock_rate_; | 64 | int clock_rate_; |
69 | long sample_rate_; | 65 | int sample_rate_; |
70 | unsigned buf_changed_count; | 66 | unsigned buf_changed_count; |
71 | int voice_count_; | 67 | int voice_count_; |
68 | int const* voice_types_; | ||
69 | int mute_mask_; | ||
72 | int tempo_; | 70 | int tempo_; |
73 | int gain_; | 71 | int gain_; |
74 | 72 | ||
75 | // track-specific | 73 | // track-specific |
76 | byte track_count; | 74 | byte track_count; |
77 | volatile bool track_ended; | ||
78 | int current_track_; | 75 | int current_track_; |
79 | blargg_long out_time; // number of samples played since start of track | ||
80 | blargg_long emu_time; // number of samples emulator has generated since start of track | ||
81 | bool emu_track_ended_; // emulator has reached end of track | ||
82 | |||
83 | // fading | ||
84 | blargg_long fade_start; | ||
85 | int fade_step; | ||
86 | |||
87 | // silence detection | ||
88 | // Disable automatic end-of-track detection and skipping of silence at beginning | ||
89 | bool ignore_silence; | ||
90 | |||
91 | int max_initial_silence; | ||
92 | int mute_mask_; | ||
93 | int silence_lookahead; // speed to run emulator when looking ahead for silence | ||
94 | long silence_time; // number of samples where most recent silence began | ||
95 | long silence_count; // number of samples of silence to play before using buf | ||
96 | long buf_remain; // number of samples left in silence buffer | ||
97 | 76 | ||
98 | // Larger files at the end | 77 | // Larger files at the end |
99 | // Header for currently loaded file | 78 | // Header for currently loaded file |
@@ -102,19 +81,22 @@ struct Hes_Emu { | |||
102 | // M3u Playlist | 81 | // M3u Playlist |
103 | struct M3u_Playlist m3u; | 82 | struct M3u_Playlist m3u; |
104 | 83 | ||
84 | struct setup_t tfilter; | ||
85 | struct Track_Filter track_filter; | ||
86 | |||
105 | // Hes Cpu | 87 | // Hes Cpu |
106 | byte* write_pages [page_count + 1]; // 0 if unmapped or I/O space | ||
107 | struct Hes_Cpu cpu; | 88 | struct Hes_Cpu cpu; |
89 | struct Rom_Data rom; | ||
108 | 90 | ||
109 | struct Hes_Apu apu; | 91 | struct Hes_Apu apu; |
110 | struct Hes_Apu_Adpcm adpcm; | 92 | struct Hes_Apu_Adpcm adpcm; |
111 | 93 | ||
112 | struct Stereo_Buffer stereo_buf; | 94 | struct Multi_Buffer stereo_buf; |
113 | sample_t buf [buf_size]; | ||
114 | 95 | ||
115 | // rom & ram | 96 | // rom & ram |
116 | struct Rom_Data rom; | 97 | byte* write_pages [page_count + 1]; // 0 if unmapped or I/O space |
117 | byte sgx [3 * page_size + cpu_padding]; | 98 | byte ram [page_size]; |
99 | byte sgx [3 * page_size + cpu_padding]; | ||
118 | }; | 100 | }; |
119 | 101 | ||
120 | 102 | ||
@@ -126,36 +108,48 @@ void Hes_init( struct Hes_Emu* this ); | |||
126 | void Hes_stop( struct Hes_Emu* this ); | 108 | void Hes_stop( struct Hes_Emu* this ); |
127 | 109 | ||
128 | // Loads a file from memory | 110 | // Loads a file from memory |
129 | blargg_err_t Hes_load( struct Hes_Emu* this, void* data, long size ); | 111 | blargg_err_t Hes_load_mem( struct Hes_Emu* this, void* data, long size ); |
130 | 112 | ||
131 | // Set output sample rate. Must be called only once before loading file. | 113 | // Set output sample rate. Must be called only once before loading file. |
132 | blargg_err_t Hes_set_sample_rate( struct Hes_Emu* this, long sample_rate ); | 114 | blargg_err_t Hes_set_sample_rate( struct Hes_Emu* this, int sample_rate ); |
133 | 115 | ||
134 | // Start a track, where 0 is the first track. Also clears warning string. | 116 | // Start a track, where 0 is the first track. Also clears warning string. |
135 | blargg_err_t Hes_start_track( struct Hes_Emu* this, int ); | 117 | blargg_err_t Hes_start_track( struct Hes_Emu* this, int ); |
136 | 118 | ||
137 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation | 119 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation |
138 | // errors set warning string, and major errors also end track. | 120 | // errors set warning string, and major errors also end track. |
139 | blargg_err_t Hes_play( struct Hes_Emu* this, long count, sample_t* buf ); | 121 | blargg_err_t Hes_play( struct Hes_Emu* this, int count, sample_t* buf ); |
140 | 122 | ||
141 | // Track status/control | 123 | // Track status/control |
142 | // Number of milliseconds (1000 msec = 1 second) played since ning of track | 124 | // Number of milliseconds (1000 msec = 1 second) played since ning of track |
143 | long Track_tell( struct Hes_Emu* this ); | 125 | int Track_tell( struct Hes_Emu* this ); |
144 | 126 | ||
145 | // Seek to new time in track. Seeking backwards or far forward can take a while. | 127 | // Seek to new time in track. Seeking backwards or far forward can take a while. |
146 | blargg_err_t Track_seek( struct Hes_Emu* this, long msec ); | 128 | blargg_err_t Track_seek( struct Hes_Emu* this, int msec ); |
147 | 129 | ||
148 | // Skip n samples | 130 | // Skip n samples |
149 | blargg_err_t Track_skip( struct Hes_Emu* this, long n ); | 131 | blargg_err_t Track_skip( struct Hes_Emu* this, int n ); |
150 | 132 | ||
151 | // Set start time and length of track fade out. Once fade ends track_ended() returns | 133 | // Set start time and length of track fade out. Once fade ends track_ended() returns |
152 | // true. Fade time can be changed while track is playing. | 134 | // true. Fade time can be changed while track is playing. |
153 | void Track_set_fade( struct Hes_Emu* this, long start_msec, long length_msec ); | 135 | void Track_set_fade( struct Hes_Emu* this, int start_msec, int length_msec ); |
136 | |||
137 | // True if a track has reached its end | ||
138 | static inline bool Track_ended( struct Hes_Emu* this ) | ||
139 | { | ||
140 | return track_ended( &this->track_filter ); | ||
141 | } | ||
142 | |||
143 | // Disables automatic end-of-track detection and skipping of silence at beginning | ||
144 | static inline void Track_ignore_silence( struct Hes_Emu* this, bool disable ) | ||
145 | { | ||
146 | this->track_filter.silence_ignored_ = disable; | ||
147 | } | ||
154 | 148 | ||
155 | // Get track length in milliseconds | 149 | // Get track length in milliseconds |
156 | static inline long Track_get_length( struct Hes_Emu* this, int n ) | 150 | static inline int Track_get_length( struct Hes_Emu* this, int n ) |
157 | { | 151 | { |
158 | long length = 120 * 1000; /* 2 minutes */ | 152 | int length = 120 * 1000; /* 2 minutes */ |
159 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { | 153 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { |
160 | struct entry_t* entry = &this->m3u.entries [n]; | 154 | struct entry_t* entry = &this->m3u.entries [n]; |
161 | length = entry->length; | 155 | length = entry->length; |
@@ -185,45 +179,17 @@ static inline void Sound_set_gain( struct Hes_Emu* this, int g ) | |||
185 | this->gain_ = g; | 179 | this->gain_ = g; |
186 | } | 180 | } |
187 | 181 | ||
188 | |||
189 | // Emulation (You shouldn't touch these) | 182 | // Emulation (You shouldn't touch these) |
190 | 183 | ||
191 | int Cpu_read( struct Hes_Emu* this, hes_addr_t ); | 184 | void irq_changed( struct Hes_Emu* this ); |
192 | void Cpu_write( struct Hes_Emu* this, hes_addr_t, int ); | 185 | void run_until( struct Hes_Emu* this, hes_time_t ); |
193 | void Cpu_write_vdp( struct Hes_Emu* this, int addr, int data ); | 186 | bool run_cpu( struct Hes_Emu* this, hes_time_t end ); |
194 | int Cpu_done( struct Hes_Emu* this ); | 187 | int read_mem_( struct Hes_Emu* this, hes_addr_t ); |
195 | 188 | int read_mem( struct Hes_Emu* this, hes_addr_t ); | |
196 | int Emu_cpu_read( struct Hes_Emu* this, hes_addr_t ); | 189 | void write_mem_( struct Hes_Emu* this, hes_addr_t, int data ); |
197 | void Emu_cpu_write( struct Hes_Emu* this, hes_addr_t, int data ); | 190 | void write_mem( struct Hes_Emu* this, hes_addr_t, int ); |
198 | 191 | void write_vdp( struct Hes_Emu* this, int addr, int data ); | |
199 | static inline byte const* Emu_cpu_set_mmr( struct Hes_Emu* this, int page, int bank ) | 192 | void set_mmr( struct Hes_Emu* this, int reg, int bank ); |
200 | { | 193 | int cpu_done( struct Hes_Emu* this ); |
201 | this->write_pages [page] = 0; | ||
202 | if ( bank < 0x80 ) | ||
203 | return Rom_at_addr( &this->rom, bank * (blargg_long) page_size ); | ||
204 | |||
205 | byte* data = 0; | ||
206 | switch ( bank ) | ||
207 | { | ||
208 | case 0xF8: | ||
209 | data = this->cpu.ram; | ||
210 | break; | ||
211 | |||
212 | case 0xF9: | ||
213 | case 0xFA: | ||
214 | case 0xFB: | ||
215 | data = &this->sgx [(bank - 0xF9) * page_size]; | ||
216 | break; | ||
217 | |||
218 | default: | ||
219 | if ( bank != 0xFF ) { | ||
220 | dprintf( "Unmapped bank $%02X\n", bank ); | ||
221 | } | ||
222 | return this->rom.unmapped; | ||
223 | } | ||
224 | |||
225 | this->write_pages [page] = data; | ||
226 | return data; | ||
227 | } | ||
228 | 194 | ||
229 | #endif | 195 | #endif |