comparison src/console/Gme_File.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
children 986f098da058
comparison
equal deleted inserted replaced
315:2294f3a6f136 316:fb513e10174e
1 // Game_Music_Emu 0.5.1. http://www.slack.net/~ant/
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 gme_wrong_file_type [] = "Wrong file type for this emulator";
22
23 void Gme_File::clear_playlist()
24 {
25 playlist.clear();
26 clear_playlist_();
27 track_count_ = raw_track_count_;
28 }
29
30 void Gme_File::unload()
31 {
32 clear_playlist(); // *before* clearing track count
33 track_count_ = 0;
34 raw_track_count_ = 0;
35 file_data.clear();
36 }
37
38 Gme_File::Gme_File()
39 {
40 type_ = 0;
41 unload(); // clears fields
42 blargg_verify_byte_order(); // used by most emulator types, so save them the trouble
43 }
44
45 Gme_File::~Gme_File() { }
46
47 blargg_err_t Gme_File::load_mem_( byte const* data, long size )
48 {
49 require( data != file_data.begin() ); // load_mem_() or load_() must be overridden
50 Mem_File_Reader in( data, size );
51 return load_( in );
52 }
53
54 blargg_err_t Gme_File::load_( Data_Reader& in )
55 {
56 RETURN_ERR( file_data.resize( in.remain() ) );
57 RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
58 return load_mem_( file_data.begin(), file_data.size() );
59 }
60
61 // public load functions call this at beginning
62 void Gme_File::pre_load() { unload(); }
63
64 void Gme_File::post_load_() { }
65
66 // public load functions call this at end
67 blargg_err_t Gme_File::post_load( blargg_err_t err )
68 {
69 if ( !track_count() )
70 set_track_count( type()->track_count );
71 if ( !err )
72 post_load_();
73 else
74 unload();
75
76 return err;
77 }
78
79 // Public load functions
80
81 blargg_err_t Gme_File::load_mem( void const* in, long size )
82 {
83 pre_load();
84 return post_load( load_mem_( (byte const*) in, size ) );
85 }
86
87 blargg_err_t Gme_File::load( Data_Reader& in )
88 {
89 pre_load();
90 return post_load( load_( in ) );
91 }
92
93 blargg_err_t Gme_File::load_file( const char* path )
94 {
95 pre_load();
96 GME_FILE_READER in;
97 RETURN_ERR( in.open( path ) );
98 return post_load( load_( in ) );
99 }
100
101 blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in )
102 {
103 Remaining_Reader rem( h, s, &in );
104 return load( rem );
105 }
106
107 // Track info
108
109 void Gme_File::copy_field_( char* out, const char* in, int in_size )
110 {
111 if ( !in || !*in )
112 return;
113
114 // remove spaces/junk from beginning
115 while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
116 {
117 in++;
118 in_size--;
119 }
120
121 // truncate
122 if ( in_size > max_field_ )
123 in_size = max_field_;
124
125 // find terminator
126 int len = 0;
127 while ( len < in_size && in [len] )
128 len++;
129
130 // remove spaces/junk from end
131 while ( len && unsigned (in [len - 1]) <= ' ' )
132 len--;
133
134 // copy
135 out [len] = 0;
136 memcpy( out, in, len );
137
138 // strip out stupid fields that should have been left blank
139 if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
140 out [0] = 0;
141 }
142
143 void Gme_File::copy_field_( char* out, const char* in )
144 {
145 copy_field_( out, in, max_field_ );
146 }
147
148 blargg_err_t Gme_File::remap_track( int* track_io ) const
149 {
150 if ( (unsigned) *track_io >= (unsigned) track_count() )
151 return "Invalid track";
152
153 if ( (unsigned) *track_io < (unsigned) playlist.size() )
154 {
155 M3u_Playlist::entry_t const& e = playlist [*track_io];
156 *track_io = 0;
157 if ( e.track >= 0 )
158 {
159 *track_io = e.track;
160 if ( !(type_->flags_ & 0x02) )
161 *track_io -= e.decimal_track;
162 }
163 if ( *track_io >= raw_track_count_ )
164 return "Invalid track in m3u playlist";
165 }
166 else
167 {
168 check( !playlist.size() );
169 }
170 return 0;
171 }
172
173 blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
174 {
175 out->track_count = track_count();
176 out->length = -1;
177 out->loop_length = -1;
178 out->intro_length = -1;
179 out->song [0] = 0;
180
181 out->game [0] = 0;
182 out->author [0] = 0;
183 out->copyright [0] = 0;
184 out->comment [0] = 0;
185 out->dumper [0] = 0;
186 out->system [0] = 0;
187
188 copy_field_( out->system, type()->system );
189
190 int remapped = track;
191 RETURN_ERR( remap_track( &remapped ) );
192 RETURN_ERR( track_info_( out, remapped ) );
193
194 // override with m3u info
195 if ( playlist.size() )
196 {
197 M3u_Playlist::info_t const& i = playlist.info();
198 copy_field_( out->game , i.title );
199 copy_field_( out->author, i.engineer );
200 copy_field_( out->author, i.composer );
201 copy_field_( out->dumper, i.ripping );
202
203 M3u_Playlist::entry_t const& e = playlist [track];
204 copy_field_( out->song, e.name );
205 if ( e.length >= 0 ) out->length = e.length * 1000L;
206 if ( e.intro >= 0 ) out->intro_length = e.intro * 1000L;
207 if ( e.loop >= 0 ) out->loop_length = e.loop * 1000L;
208 }
209 return 0;
210 }