diff options
Diffstat (limited to 'lib/rbcodec/codecs/libgme/gbs_emu.h')
-rw-r--r-- | lib/rbcodec/codecs/libgme/gbs_emu.h | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libgme/gbs_emu.h b/lib/rbcodec/codecs/libgme/gbs_emu.h new file mode 100644 index 0000000000..72671b4658 --- /dev/null +++ b/lib/rbcodec/codecs/libgme/gbs_emu.h | |||
@@ -0,0 +1,192 @@ | |||
1 | // Nintendo Game Boy GBS music file emulator | ||
2 | |||
3 | // Game_Music_Emu 0.5.2 | ||
4 | #ifndef GBS_EMU_H | ||
5 | #define GBS_EMU_H | ||
6 | |||
7 | #include "rom_data.h" | ||
8 | #include "multi_buffer.h" | ||
9 | #include "gb_apu.h" | ||
10 | #include "gb_cpu.h" | ||
11 | #include "m3u_playlist.h" | ||
12 | #include "track_filter.h" | ||
13 | |||
14 | enum { joypad_addr = 0xFF00 }; | ||
15 | enum { ram_addr = 0xA000 }; | ||
16 | enum { hi_page = 0xFF00 - ram_addr }; | ||
17 | enum { io_base = 0xFF00 }; | ||
18 | |||
19 | // Selects which sound hardware to use. AGB hardware is cleaner than the | ||
20 | // others. Doesn't take effect until next start_track(). | ||
21 | enum sound_t { | ||
22 | sound_dmg = mode_dmg, // Game Boy monochrome | ||
23 | sound_cgb = mode_cgb, // Game Boy Color | ||
24 | sound_agb = mode_agb, // Game Boy Advance | ||
25 | sound_gbs // Use DMG/CGB based on GBS (default) | ||
26 | }; | ||
27 | |||
28 | // GBS file header | ||
29 | enum { header_size = 112 }; | ||
30 | struct header_t | ||
31 | { | ||
32 | char tag [3]; | ||
33 | byte vers; | ||
34 | byte track_count; | ||
35 | byte first_track; | ||
36 | byte load_addr [2]; | ||
37 | byte init_addr [2]; | ||
38 | byte play_addr [2]; | ||
39 | byte stack_ptr [2]; | ||
40 | byte timer_modulo; | ||
41 | byte timer_mode; | ||
42 | char game [32]; | ||
43 | char author [32]; | ||
44 | char copyright [32]; | ||
45 | }; | ||
46 | |||
47 | struct Gbs_Emu { | ||
48 | enum sound_t sound_hardware; | ||
49 | |||
50 | int tempo; | ||
51 | |||
52 | // timer | ||
53 | blip_time_t cpu_time; | ||
54 | blip_time_t end_time; | ||
55 | blip_time_t play_period; | ||
56 | blip_time_t next_play; | ||
57 | |||
58 | // Sound | ||
59 | int clock_rate_; | ||
60 | int sample_rate_; | ||
61 | unsigned buf_changed_count; | ||
62 | int voice_count_; | ||
63 | int const* voice_types_; | ||
64 | int mute_mask_; | ||
65 | int gain_; | ||
66 | int tempo_; | ||
67 | |||
68 | // track-specific | ||
69 | byte track_count; | ||
70 | int current_track_; | ||
71 | |||
72 | // Larger items at the end | ||
73 | // Header for currently loaded file | ||
74 | struct header_t header; | ||
75 | |||
76 | // M3u Playlist | ||
77 | struct M3u_Playlist m3u; | ||
78 | |||
79 | struct setup_t tfilter; | ||
80 | struct Track_Filter track_filter; | ||
81 | |||
82 | struct Gb_Apu apu; | ||
83 | struct Gb_Cpu cpu; | ||
84 | struct Multi_Buffer stereo_buf; | ||
85 | |||
86 | // rom & ram | ||
87 | struct Rom_Data rom; | ||
88 | byte ram [0x4000 + 0x2000 + cpu_padding]; | ||
89 | }; | ||
90 | |||
91 | |||
92 | // Basic functionality | ||
93 | // Initializes Gbs_Emu structure | ||
94 | void Gbs_init( struct Gbs_Emu* this ); | ||
95 | |||
96 | // Stops (clear) Gbs_Emu structure | ||
97 | void Gbs_stop( struct Gbs_Emu* this ); | ||
98 | |||
99 | // Loads a file from memory | ||
100 | blargg_err_t Gbs_load_mem( struct Gbs_Emu* this, void* data, long size ); | ||
101 | |||
102 | // Set output sample rate. Must be called only once before loading file. | ||
103 | blargg_err_t Gbs_set_sample_rate( struct Gbs_Emu* this, int sample_rate ); | ||
104 | |||
105 | // Start a track, where 0 is the first track. Also clears warning string. | ||
106 | blargg_err_t Gbs_start_track( struct Gbs_Emu* this, int ); | ||
107 | |||
108 | // Generate 'count' samples info 'buf'. Output is in stereo. Any emulation | ||
109 | // errors set warning string, and major errors also end track. | ||
110 | blargg_err_t Gbs_play( struct Gbs_Emu* this, int count, sample_t* buf ); | ||
111 | |||
112 | // Track status/control | ||
113 | // Number of milliseconds (1000 msec = 1 second) played since beginning of track | ||
114 | int Track_tell( struct Gbs_Emu* this ); | ||
115 | |||
116 | // Seek to new time in track. Seeking backwards or far forward can take a while. | ||
117 | blargg_err_t Track_seek( struct Gbs_Emu* this, int msec ); | ||
118 | |||
119 | // Skip n samples | ||
120 | blargg_err_t Track_skip( struct Gbs_Emu* this, int n ); | ||
121 | |||
122 | // Set start time and length of track fade out. Once fade ends track_ended() returns | ||
123 | // true. Fade time can be changed while track is playing. | ||
124 | void Track_set_fade( struct Gbs_Emu* this, int start_msec, int length_msec ); | ||
125 | |||
126 | // True if a track has reached its end | ||
127 | static inline bool Track_ended( struct Gbs_Emu* this ) | ||
128 | { | ||
129 | return track_ended( &this->track_filter ); | ||
130 | } | ||
131 | |||
132 | // Disables automatic end-of-track detection and skipping of silence at beginning | ||
133 | static inline void Track_ignore_silence( struct Gbs_Emu* this, bool disable ) | ||
134 | { | ||
135 | this->track_filter.silence_ignored_ = disable; | ||
136 | } | ||
137 | |||
138 | // Get track length in milliseconds | ||
139 | static inline int Track_get_length( struct Gbs_Emu* this, int n ) | ||
140 | { | ||
141 | int length = 120 * 1000; /* 2 minutes */ | ||
142 | if ( (this->m3u.size > 0) && (n < this->m3u.size) ) { | ||
143 | struct entry_t* entry = &this->m3u.entries [n]; | ||
144 | length = entry->length; | ||
145 | } | ||
146 | |||
147 | return length; | ||
148 | } | ||
149 | |||
150 | |||
151 | // Sound customization | ||
152 | // Adjust song tempo, where 1.0 = normal, 0.5 = half speed, 2.0 = double speed. | ||
153 | // Track length as returned by track_info() assumes a tempo of 1.0. | ||
154 | void Sound_set_tempo( struct Gbs_Emu* this, int ); | ||
155 | |||
156 | // Mute/unmute voice i, where voice 0 is first voice | ||
157 | void Sound_mute_voice( struct Gbs_Emu* this, int index, bool mute ); | ||
158 | |||
159 | // Set muting state of all voices at once using a bit mask, where -1 mutes them all, | ||
160 | // 0 unmutes them all, 0x01 mutes just the first voice, etc. | ||
161 | void Sound_mute_voices( struct Gbs_Emu* this, int mask ); | ||
162 | |||
163 | // Change overall output amplitude, where 1.0 results in minimal clamping. | ||
164 | // Must be called before set_sample_rate(). | ||
165 | static inline void Sound_set_gain( struct Gbs_Emu* this, int g ) | ||
166 | { | ||
167 | assert( !this->sample_rate_ ); // you must set gain before setting sample rate | ||
168 | this->gain_ = g; | ||
169 | } | ||
170 | |||
171 | // Emulation (You shouldn't touch these) | ||
172 | |||
173 | blargg_err_t run_clocks( struct Gbs_Emu* this, blip_time_t duration ); | ||
174 | void set_bank( struct Gbs_Emu* this, int ); | ||
175 | void update_timer( struct Gbs_Emu* this ); | ||
176 | |||
177 | // Runs CPU until time becomes >= 0 | ||
178 | void run_cpu( struct Gbs_Emu* this ); | ||
179 | |||
180 | // Reads/writes memory and I/O | ||
181 | int read_mem( struct Gbs_Emu* this, addr_t addr ); | ||
182 | void write_mem( struct Gbs_Emu* this, addr_t addr, int data ); | ||
183 | |||
184 | // Current time | ||
185 | static inline blip_time_t Time( struct Gbs_Emu* this ) | ||
186 | { | ||
187 | return Cpu_time( &this->cpu ) + this->end_time; | ||
188 | } | ||
189 | |||
190 | void jsr_then_stop( struct Gbs_Emu* this, byte const [] ); | ||
191 | |||
192 | #endif | ||