diff options
Diffstat (limited to 'apps/codecs/libgme/sgc_emu.h')
-rw-r--r-- | apps/codecs/libgme/sgc_emu.h | 390 |
1 files changed, 195 insertions, 195 deletions
diff --git a/apps/codecs/libgme/sgc_emu.h b/apps/codecs/libgme/sgc_emu.h index 6595c02daf..83cde1e6ae 100644 --- a/apps/codecs/libgme/sgc_emu.h +++ b/apps/codecs/libgme/sgc_emu.h | |||
@@ -1,195 +1,195 @@ | |||
1 | // Sega/Game Gear/Coleco SGC music file emulator | 1 | // Sega/Game Gear/Coleco SGC music file emulator |
2 | 2 | ||
3 | // Game_Music_Emu 0.6-pre | 3 | // Game_Music_Emu 0.6-pre |
4 | #ifndef SGC_EMU_H | 4 | #ifndef SGC_EMU_H |
5 | #define SGC_EMU_H | 5 | #define SGC_EMU_H |
6 | 6 | ||
7 | #include "blargg_common.h" | 7 | #include "blargg_common.h" |
8 | #include "multi_buffer.h" | 8 | #include "multi_buffer.h" |
9 | 9 | ||
10 | #include "rom_data.h" | 10 | #include "rom_data.h" |
11 | #include "z80_cpu.h" | 11 | #include "z80_cpu.h" |
12 | #include "sms_fm_apu.h" | 12 | #include "sms_fm_apu.h" |
13 | #include "sms_apu.h" | 13 | #include "sms_apu.h" |
14 | #include "m3u_playlist.h" | 14 | #include "m3u_playlist.h" |
15 | #include "track_filter.h" | 15 | #include "track_filter.h" |
16 | 16 | ||
17 | typedef struct Z80_Cpu Sgc_Cpu; | 17 | typedef struct Z80_Cpu Sgc_Cpu; |
18 | 18 | ||
19 | // SGC file header | 19 | // SGC file header |
20 | enum { header_size = 0xA0 }; | 20 | enum { header_size = 0xA0 }; |
21 | struct header_t | 21 | struct header_t |
22 | { | 22 | { |
23 | char tag [4]; // "SGC\x1A" | 23 | char tag [4]; // "SGC\x1A" |
24 | byte vers; // 0x01 | 24 | byte vers; // 0x01 |
25 | byte rate; // 0=NTSC 1=PAL | 25 | byte rate; // 0=NTSC 1=PAL |
26 | byte reserved1 [2]; | 26 | byte reserved1 [2]; |
27 | byte load_addr [2]; | 27 | byte load_addr [2]; |
28 | byte init_addr [2]; | 28 | byte init_addr [2]; |
29 | byte play_addr [2]; | 29 | byte play_addr [2]; |
30 | byte stack_ptr [2]; | 30 | byte stack_ptr [2]; |
31 | byte reserved2 [2]; | 31 | byte reserved2 [2]; |
32 | byte rst_addrs [7*2]; | 32 | byte rst_addrs [7*2]; |
33 | byte mapping [4]; // Used by Sega only | 33 | byte mapping [4]; // Used by Sega only |
34 | byte first_song; // Song to start playing first | 34 | byte first_song; // Song to start playing first |
35 | byte song_count; | 35 | byte song_count; |
36 | byte first_effect; | 36 | byte first_effect; |
37 | byte last_effect; | 37 | byte last_effect; |
38 | byte system; // 0=Master System 1=Game Gear 2=Colecovision | 38 | byte system; // 0=Master System 1=Game Gear 2=Colecovision |
39 | byte reserved3 [23]; | 39 | byte reserved3 [23]; |
40 | char game [32]; // strings can be 32 chars, NOT terminated | 40 | char game [32]; // strings can be 32 chars, NOT terminated |
41 | char author [32]; | 41 | char author [32]; |
42 | char copyright [32]; | 42 | char copyright [32]; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | // True if header has valid file signature | 45 | // True if header has valid file signature |
46 | static inline bool valid_tag( struct header_t* h ) | 46 | static inline bool valid_tag( struct header_t* h ) |
47 | { | 47 | { |
48 | return 0 == memcmp( h->tag, "SGC\x1A", 4 ); | 48 | return 0 == memcmp( h->tag, "SGC\x1A", 4 ); |
49 | } | 49 | } |
50 | 50 | ||
51 | static inline int effect_count( struct header_t* h ) { return h->last_effect ? h->last_effect - h->first_effect + 1 : 0; } | 51 | static inline int effect_count( struct header_t* h ) { return h->last_effect ? h->last_effect - h->first_effect + 1 : 0; } |
52 | 52 | ||
53 | struct Sgc_Emu { | 53 | struct Sgc_Emu { |
54 | bool fm_accessed; | 54 | bool fm_accessed; |
55 | 55 | ||
56 | cpu_time_t play_period; | 56 | cpu_time_t play_period; |
57 | cpu_time_t next_play; | 57 | cpu_time_t next_play; |
58 | void const* bank2; // ROM selected for bank 2, in case RAM is currently hiding it | 58 | void const* bank2; // ROM selected for bank 2, in case RAM is currently hiding it |
59 | addr_t vectors_addr; // RST vectors start here | 59 | addr_t vectors_addr; // RST vectors start here |
60 | addr_t idle_addr; // return address for init/play routines | 60 | addr_t idle_addr; // return address for init/play routines |
61 | void* coleco_bios; | 61 | void* coleco_bios; |
62 | 62 | ||
63 | // general | 63 | // general |
64 | int voice_count; | 64 | int voice_count; |
65 | int const* voice_types; | 65 | int const* voice_types; |
66 | int mute_mask_; | 66 | int mute_mask_; |
67 | int tempo; | 67 | int tempo; |
68 | int gain; | 68 | int gain; |
69 | 69 | ||
70 | int sample_rate; | 70 | int sample_rate; |
71 | 71 | ||
72 | // track-specific | 72 | // track-specific |
73 | int current_track; | 73 | int current_track; |
74 | int track_count; | 74 | int track_count; |
75 | 75 | ||
76 | int clock_rate_; | 76 | int clock_rate_; |
77 | unsigned buf_changed_count; | 77 | unsigned buf_changed_count; |
78 | 78 | ||
79 | // M3u Playlist | 79 | // M3u Playlist |
80 | struct M3u_Playlist m3u; | 80 | struct M3u_Playlist m3u; |
81 | struct header_t header; | 81 | struct header_t header; |
82 | 82 | ||
83 | struct setup_t tfilter; | 83 | struct setup_t tfilter; |
84 | struct Track_Filter track_filter; | 84 | struct Track_Filter track_filter; |
85 | 85 | ||
86 | struct Multi_Buffer stereo_buf; | 86 | struct Multi_Buffer stereo_buf; |
87 | 87 | ||
88 | struct Sms_Apu apu; | 88 | struct Sms_Apu apu; |
89 | struct Sms_Fm_Apu fm_apu; | 89 | struct Sms_Fm_Apu fm_apu; |
90 | 90 | ||
91 | Sgc_Cpu cpu; | 91 | Sgc_Cpu cpu; |
92 | 92 | ||
93 | // large items | 93 | // large items |
94 | struct Rom_Data rom; | 94 | struct Rom_Data rom; |
95 | byte vectors [page_size + page_padding]; | 95 | byte vectors [page_size + page_padding]; |
96 | byte unmapped_write [0x4000]; | 96 | byte unmapped_write [0x4000]; |
97 | byte ram [0x2000 + page_padding]; | 97 | byte ram [0x2000 + page_padding]; |
98 | byte ram2 [0x4000 + page_padding]; | 98 | byte ram2 [0x4000 + page_padding]; |
99 | }; | 99 | }; |
100 | 100 | ||
101 | // Basic functionality (see Gme_File.h for file loading/track info functions) | 101 | // Basic functionality (see Gme_File.h for file loading/track info functions) |
102 | 102 | ||
103 | void Sgc_init( struct Sgc_Emu* this ); | 103 | void Sgc_init( struct Sgc_Emu* this ); |
104 | 104 | ||
105 | blargg_err_t Sgc_load_mem( struct Sgc_Emu* this, const void* data, long size ); | 105 | blargg_err_t Sgc_load_mem( struct Sgc_Emu* this, const void* data, long size ); |
106 | 106 | ||
107 | static inline int clock_rate( struct Sgc_Emu* this ) { return this->header.rate ? 3546893 : 3579545; } | 107 | static inline int clock_rate( struct Sgc_Emu* this ) { return this->header.rate ? 3546893 : 3579545; } |
108 | 108 | ||
109 | // 0x2000 bytes | 109 | // 0x2000 bytes |
110 | static inline void set_coleco_bios( struct Sgc_Emu* this, void* p ) { this->coleco_bios = p; } | 110 | static inline void set_coleco_bios( struct Sgc_Emu* this, void* p ) { this->coleco_bios = p; } |
111 | 111 | ||
112 | // Set output sample rate. Must be called only once before loading file. | 112 | // Set output sample rate. Must be called only once before loading file. |
113 | blargg_err_t Sgc_set_sample_rate( struct Sgc_Emu* this, int sample_rate ); | 113 | blargg_err_t Sgc_set_sample_rate( struct Sgc_Emu* this, int sample_rate ); |
114 | 114 | ||
115 | // Start a track, where 0 is the first track. Also clears warning string. | 115 | // Start a track, where 0 is the first track. Also clears warning string. |
116 | blargg_err_t Sgc_start_track( struct Sgc_Emu* this, int track ); | 116 | blargg_err_t Sgc_start_track( struct Sgc_Emu* this, int track ); |
117 | 117 | ||
118 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation | 118 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation |
119 | // errors set warning string, and major errors also end track. | 119 | // errors set warning string, and major errors also end track. |
120 | blargg_err_t Sgc_play( struct Sgc_Emu* this, int count, sample_t* buf ); | 120 | blargg_err_t Sgc_play( struct Sgc_Emu* this, int count, sample_t* buf ); |
121 | 121 | ||
122 | // Track status/control | 122 | // Track status/control |
123 | 123 | ||
124 | // Number of milliseconds (1000 msec = 1 second) played since beginning of track | 124 | // Number of milliseconds (1000 msec = 1 second) played since beginning of track |
125 | int Track_tell( struct Sgc_Emu* this ); | 125 | int Track_tell( struct Sgc_Emu* this ); |
126 | 126 | ||
127 | // 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. |
128 | blargg_err_t Track_seek( struct Sgc_Emu* this, int msec ); | 128 | blargg_err_t Track_seek( struct Sgc_Emu* this, int msec ); |
129 | 129 | ||
130 | // Skip n samples | 130 | // Skip n samples |
131 | blargg_err_t Track_skip( struct Sgc_Emu* this, int n ); | 131 | blargg_err_t Track_skip( struct Sgc_Emu* this, int n ); |
132 | 132 | ||
133 | // 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 |
134 | // true. Fade time can be changed while track is playing. | 134 | // true. Fade time can be changed while track is playing. |
135 | void Track_set_fade( struct Sgc_Emu* this, int start_msec, int length_msec ); | 135 | void Track_set_fade( struct Sgc_Emu* this, int start_msec, int length_msec ); |
136 | 136 | ||
137 | // True if a track has reached its end | 137 | // True if a track has reached its end |
138 | static inline bool Track_ended( struct Sgc_Emu* this ) | 138 | static inline bool Track_ended( struct Sgc_Emu* this ) |
139 | { | 139 | { |
140 | return track_ended( &this->track_filter ); | 140 | return track_ended( &this->track_filter ); |
141 | } | 141 | } |
142 | 142 | ||
143 | // Disables automatic end-of-track detection and skipping of silence at beginning | 143 | // Disables automatic end-of-track detection and skipping of silence at beginning |
144 | static inline void Track_ignore_silence( struct Sgc_Emu* this, bool disable ) | 144 | static inline void Track_ignore_silence( struct Sgc_Emu* this, bool disable ) |
145 | { | 145 | { |
146 | this->track_filter.silence_ignored_ = disable; | 146 | this->track_filter.silence_ignored_ = disable; |
147 | } | 147 | } |
148 | 148 | ||
149 | // Get track length in milliseconds | 149 | // Get track length in milliseconds |
150 | static inline int Track_get_length( struct Sgc_Emu* this, int n ) | 150 | static inline int Track_get_length( struct Sgc_Emu* this, int n ) |
151 | { | 151 | { |
152 | int length = 120 * 1000; /* 2 minutes */ | 152 | int length = 120 * 1000; /* 2 minutes */ |
153 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { | 153 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { |
154 | struct entry_t* entry = &this->m3u.entries [n]; | 154 | struct entry_t* entry = &this->m3u.entries [n]; |
155 | length = entry->length; | 155 | length = entry->length; |
156 | } | 156 | } |
157 | 157 | ||
158 | return length; | 158 | return length; |
159 | } | 159 | } |
160 | 160 | ||
161 | // Sound customization | 161 | // Sound customization |
162 | 162 | ||
163 | // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed. | 163 | // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed. |
164 | // Track length as returned by track_info() assumes a tempo of 1.0. | 164 | // Track length as returned by track_info() assumes a tempo of 1.0. |
165 | void Sound_set_tempo( struct Sgc_Emu* this, int t ); | 165 | void Sound_set_tempo( struct Sgc_Emu* this, int t ); |
166 | 166 | ||
167 | // Mute/unmute voice i, where voice 0 is first voice | 167 | // Mute/unmute voice i, where voice 0 is first voice |
168 | void Sound_mute_voice( struct Sgc_Emu* this, int index, bool mute ); | 168 | void Sound_mute_voice( struct Sgc_Emu* this, int index, bool mute ); |
169 | 169 | ||
170 | // Set muting state of all voices at once using a bit mask, where -1 mutes them all, | 170 | // Set muting state of all voices at once using a bit mask, where -1 mutes them all, |
171 | // 0 unmutes them all, 0x01 mutes just the first voice, etc. | 171 | // 0 unmutes them all, 0x01 mutes just the first voice, etc. |
172 | void Sound_mute_voices( struct Sgc_Emu* this, int mask ); | 172 | void Sound_mute_voices( struct Sgc_Emu* this, int mask ); |
173 | 173 | ||
174 | // Change overall output amplitude, where 1.0 results in minimal clamping. | 174 | // Change overall output amplitude, where 1.0 results in minimal clamping. |
175 | // Must be called before set_sample_rate(). | 175 | // Must be called before set_sample_rate(). |
176 | static inline void Sound_set_gain( struct Sgc_Emu* this, int g ) | 176 | static inline void Sound_set_gain( struct Sgc_Emu* this, int g ) |
177 | { | 177 | { |
178 | assert( !this->sample_rate ); // you must set gain before setting sample rate | 178 | assert( !this->sample_rate ); // you must set gain before setting sample rate |
179 | this->gain = g; | 179 | this->gain = g; |
180 | } | 180 | } |
181 | 181 | ||
182 | // True if Master System or Game Gear | 182 | // True if Master System or Game Gear |
183 | static inline bool sega_mapping( struct Sgc_Emu* this ) | 183 | static inline bool sega_mapping( struct Sgc_Emu* this ) |
184 | { | 184 | { |
185 | return this->header.system <= 1; | 185 | return this->header.system <= 1; |
186 | } | 186 | } |
187 | 187 | ||
188 | // Emulation (You shouldn't touch these) | 188 | // Emulation (You shouldn't touch these) |
189 | 189 | ||
190 | bool run_cpu( struct Sgc_Emu* this, cpu_time_t end_time ); | 190 | bool run_cpu( struct Sgc_Emu* this, cpu_time_t end_time ); |
191 | void cpu_out( struct Sgc_Emu* this, cpu_time_t time, addr_t addr, int data ); | 191 | void cpu_out( struct Sgc_Emu* this, cpu_time_t time, addr_t addr, int data ); |
192 | void cpu_write( struct Sgc_Emu* this, addr_t addr, int data ); | 192 | void cpu_write( struct Sgc_Emu* this, addr_t addr, int data ); |
193 | void jsr( struct Sgc_Emu* this, byte addr [2] ); | 193 | void jsr( struct Sgc_Emu* this, byte addr [2] ); |
194 | 194 | ||
195 | #endif | 195 | #endif |