/src/vlc/contrib/contrib-build/game-music-emu/gme/Gme_File.cpp
Line | Count | Source |
1 | | // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/ |
2 | | |
3 | | #include "Gme_File.h" |
4 | | |
5 | | #include "blargg_endian.h" |
6 | | #include <string.h> |
7 | | |
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 |
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 |
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 |
14 | | FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more |
15 | | details. You should have received a copy of the GNU Lesser General Public |
16 | | License along with this module; if not, write to the Free Software Foundation, |
17 | | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ |
18 | | |
19 | | #include "blargg_source.h" |
20 | | |
21 | | const char* const gme_wrong_file_type = "Wrong file type for this emulator"; |
22 | | |
23 | | void Gme_File::clear_playlist() |
24 | 8.31k | { |
25 | 8.31k | playlist.clear(); |
26 | 8.31k | clear_playlist_(); |
27 | 8.31k | track_count_ = raw_track_count_; |
28 | 8.31k | } |
29 | | |
30 | | void Gme_File::unload() |
31 | 8.31k | { |
32 | 8.31k | clear_playlist(); // *before* clearing track count |
33 | 8.31k | track_count_ = 0; |
34 | 8.31k | raw_track_count_ = 0; |
35 | 8.31k | file_data.clear(); |
36 | 8.31k | } |
37 | | |
38 | | Gme_File::Gme_File() |
39 | 2.44k | { |
40 | 2.44k | type_ = 0; |
41 | 2.44k | user_data_ = 0; |
42 | 2.44k | user_cleanup_ = 0; |
43 | 2.44k | unload(); // clears fields |
44 | 2.44k | blargg_verify_byte_order(); // used by most emulator types, so save them the trouble |
45 | 2.44k | } |
46 | | |
47 | | Gme_File::~Gme_File() |
48 | 2.44k | { |
49 | 2.44k | if ( user_cleanup_ ) |
50 | 0 | user_cleanup_( user_data_ ); |
51 | 2.44k | } |
52 | | |
53 | | blargg_err_t Gme_File::load_mem_( byte const* data, long size ) |
54 | 0 | { |
55 | 0 | require( data != file_data.begin() ); // load_mem_() or load_() must be overridden |
56 | 0 | Mem_File_Reader in( data, size ); |
57 | 0 | return load_( in ); |
58 | 0 | } |
59 | | |
60 | | blargg_err_t Gme_File::load_( Data_Reader& in ) |
61 | 372 | { |
62 | 372 | RETURN_ERR( file_data.resize( in.remain() ) ); |
63 | 372 | RETURN_ERR( in.read( file_data.begin(), file_data.size() ) ); |
64 | 372 | if ( type()->track_count == 1 ) |
65 | 358 | { |
66 | 358 | RETURN_ERR( tracks.resize( 2 ) ); |
67 | 358 | tracks[0] = 0, tracks[1] = file_data.size(); |
68 | 358 | } |
69 | 372 | return load_mem_( file_data.begin(), file_data.size() ); |
70 | 372 | } |
71 | | |
72 | | // public load functions call this at beginning |
73 | 2.44k | void Gme_File::pre_load() { unload(); } |
74 | | |
75 | 0 | void Gme_File::post_load_() { } |
76 | | |
77 | | // public load functions call this at end |
78 | | blargg_err_t Gme_File::post_load( blargg_err_t err ) |
79 | 2.44k | { |
80 | 2.44k | if ( !track_count() ) |
81 | 396 | set_track_count( type()->track_count ); |
82 | 2.44k | if ( !err ) |
83 | 2.36k | post_load_(); |
84 | 81 | else |
85 | 81 | unload(); |
86 | | |
87 | 2.44k | return err; |
88 | 2.44k | } |
89 | | |
90 | | // Public load functions |
91 | | |
92 | | blargg_err_t Gme_File::load_mem( void const* in, long size ) |
93 | 0 | { |
94 | 0 | pre_load(); |
95 | 0 | return post_load( load_mem_( (byte const*) in, size ) ); |
96 | 0 | } |
97 | | |
98 | | blargg_err_t Gme_File::load_tracks( void const* in, long* sizes, int count ) |
99 | 0 | { |
100 | 0 | pre_load(); |
101 | 0 | if ( type()->track_count != 1 ) |
102 | 0 | return "File type must have a fixed track count of 1"; |
103 | 0 | set_track_count( count ); |
104 | 0 | RETURN_ERR( tracks.resize( count + 1 ) ); |
105 | 0 | long size = 0; |
106 | 0 | for ( int i = 0; i < count; size += sizes[i++] ) |
107 | 0 | tracks[i] = size; |
108 | 0 | tracks[count] = size; |
109 | 0 | RETURN_ERR( file_data.resize( size ) ); |
110 | 0 | memcpy( file_data.begin(), in, size ); |
111 | 0 | return post_load( load_mem_( file_data.begin(), tracks[1] ) ); |
112 | 0 | } |
113 | | |
114 | | blargg_err_t Gme_File::load( Data_Reader& in ) |
115 | 2.44k | { |
116 | 2.44k | pre_load(); |
117 | 2.44k | return post_load( load_( in ) ); |
118 | 2.44k | } |
119 | | |
120 | | blargg_err_t Gme_File::load_file( const char* path ) |
121 | 0 | { |
122 | 0 | pre_load(); |
123 | 0 | GME_FILE_READER in; |
124 | 0 | RETURN_ERR( in.open( path ) ); |
125 | 0 | return post_load( load_( in ) ); |
126 | 0 | } |
127 | | |
128 | | blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in ) |
129 | 0 | { |
130 | 0 | Remaining_Reader rem( h, s, &in ); |
131 | 0 | return load( rem ); |
132 | 0 | } |
133 | | |
134 | | // Track info |
135 | | |
136 | | void Gme_File::copy_field_( char* out, const char* in, int in_size ) |
137 | 40.0k | { |
138 | 40.0k | if ( !in || !*in ) |
139 | 15.2k | return; |
140 | | |
141 | | // remove spaces/junk from beginning |
142 | 31.7k | while ( in_size && unsigned (*in - 1) <= ' ' - 1 ) |
143 | 6.90k | { |
144 | 6.90k | in++; |
145 | 6.90k | in_size--; |
146 | 6.90k | } |
147 | | |
148 | | // truncate |
149 | 24.8k | if ( in_size > max_field_ ) |
150 | 3 | in_size = max_field_; |
151 | | |
152 | | // find terminator |
153 | 24.8k | int len = 0; |
154 | 342k | while ( len < in_size && in [len] ) |
155 | 317k | len++; |
156 | | |
157 | | // remove spaces/junk from end |
158 | 28.5k | while ( len && unsigned (in [len - 1]) <= ' ' ) |
159 | 3.67k | len--; |
160 | | |
161 | | // copy |
162 | 24.8k | out [len] = 0; |
163 | 24.8k | memcpy( out, in, len ); |
164 | | |
165 | | // strip out stupid fields that should have been left blank |
166 | 24.8k | if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) ) |
167 | 2 | out [0] = 0; |
168 | 24.8k | } |
169 | | |
170 | | void Gme_File::copy_field_( char* out, const char* in ) |
171 | 17.6k | { |
172 | 17.6k | copy_field_( out, in, max_field_ ); |
173 | 17.6k | } |
174 | | |
175 | | blargg_err_t Gme_File::remap_track_( int* track_io ) const |
176 | 19.9k | { |
177 | 19.9k | if ( (unsigned) *track_io >= (unsigned) track_count() ) |
178 | 86 | return "Invalid track"; |
179 | | |
180 | 19.8k | if ( (unsigned) *track_io < (unsigned) playlist.size() ) |
181 | 0 | { |
182 | 0 | M3u_Playlist::entry_t const& e = playlist [*track_io]; |
183 | 0 | *track_io = 0; |
184 | 0 | if ( e.track >= 0 ) |
185 | 0 | { |
186 | 0 | *track_io = e.track; |
187 | 0 | if ( !(type_->flags_ & 0x02) ) |
188 | 0 | *track_io -= e.decimal_track; |
189 | 0 | } |
190 | 0 | if ( *track_io >= raw_track_count_ ) |
191 | 0 | return "Invalid track in m3u playlist"; |
192 | 0 | } |
193 | 19.8k | else |
194 | 19.8k | { |
195 | 19.8k | check( !playlist.size() ); |
196 | 19.8k | } |
197 | 19.8k | return 0; |
198 | 19.8k | } |
199 | | |
200 | | blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const |
201 | 9.94k | { |
202 | 9.94k | out->track_count = track_count(); |
203 | 9.94k | out->length = -1; |
204 | 9.94k | out->loop_length = -1; |
205 | 9.94k | out->intro_length = -1; |
206 | 9.94k | out->fade_length = -1; |
207 | 9.94k | out->play_length = -1; |
208 | 9.94k | out->repeat_count = -1; |
209 | 9.94k | out->song [0] = 0; |
210 | | |
211 | 9.94k | out->game [0] = 0; |
212 | 9.94k | out->author [0] = 0; |
213 | 9.94k | out->composer [0] = 0; |
214 | 9.94k | out->engineer [0] = 0; |
215 | 9.94k | out->sequencer [0] = 0; |
216 | 9.94k | out->tagger [0] = 0; |
217 | 9.94k | out->copyright [0] = 0; |
218 | 9.94k | out->date [0] = 0; |
219 | 9.94k | out->comment [0] = 0; |
220 | 9.94k | out->dumper [0] = 0; |
221 | 9.94k | out->system [0] = 0; |
222 | 9.94k | out->disc [0] = 0; |
223 | 9.94k | out->track [0] = 0; |
224 | 9.94k | out->ost [0] = 0; |
225 | | |
226 | 9.94k | copy_field_( out->system, type()->system ); |
227 | | |
228 | 9.94k | int remapped = track; |
229 | 9.94k | RETURN_ERR( remap_track_( &remapped ) ); |
230 | 9.94k | RETURN_ERR( track_info_( out, remapped ) ); |
231 | | |
232 | | // override with m3u info |
233 | 9.94k | if ( playlist.size() ) |
234 | 0 | { |
235 | 0 | M3u_Playlist::info_t const& i = playlist.info(); |
236 | 0 | copy_field_( out->game , i.title ); |
237 | 0 | copy_field_( out->author, i.artist ); |
238 | 0 | copy_field_( out->engineer, i.engineer ); |
239 | 0 | copy_field_( out->composer, i.composer ); |
240 | 0 | copy_field_( out->sequencer, i.sequencer ); |
241 | 0 | copy_field_( out->copyright, i.copyright ); |
242 | 0 | copy_field_( out->dumper, i.ripping ); |
243 | 0 | copy_field_( out->tagger, i.tagging ); |
244 | 0 | copy_field_( out->date, i.date ); |
245 | |
|
246 | 0 | M3u_Playlist::entry_t const& e = playlist [track]; |
247 | 0 | copy_field_( out->song, e.name ); |
248 | 0 | if ( e.length >= 0 ) out->length = e.length; |
249 | 0 | if ( e.intro >= 0 ) out->intro_length = e.intro; |
250 | 0 | if ( e.loop >= 0 ) out->loop_length = e.loop; |
251 | 0 | if ( e.fade >= 0 ) out->fade_length = e.fade; |
252 | 0 | if ( e.repeat >= 0 ) out->repeat_count = e.repeat; |
253 | 0 | } |
254 | 9.94k | return 0; |
255 | 9.94k | } |