diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/console/Gme_File.cxx	Thu Nov 30 19:54:33 2006 -0800
@@ -0,0 +1,210 @@
+// Game_Music_Emu 0.5.1. http://www.slack.net/~ant/
+
+#include "Gme_File.h"
+
+#include "blargg_endian.h"
+#include <string.h>
+
+/* Copyright (C) 2003-2006 Shay Green. This module is free software; you
+can redistribute it and/or modify it under the terms of the GNU Lesser
+General Public License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version. This
+module is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details. You should have received a copy of the GNU Lesser General Public
+License along with this module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#include "blargg_source.h"
+
+const char gme_wrong_file_type [] = "Wrong file type for this emulator";
+
+void Gme_File::clear_playlist()
+{
+	playlist.clear();
+	clear_playlist_();
+	track_count_ = raw_track_count_;
+}
+
+void Gme_File::unload()
+{
+	clear_playlist(); // *before* clearing track count
+	track_count_     = 0;
+	raw_track_count_ = 0;
+	file_data.clear();
+}
+
+Gme_File::Gme_File()
+{
+	type_ = 0;
+	unload(); // clears fields
+	blargg_verify_byte_order(); // used by most emulator types, so save them the trouble
+}
+
+Gme_File::~Gme_File() { }
+
+blargg_err_t Gme_File::load_mem_( byte const* data, long size )
+{
+	require( data != file_data.begin() ); // load_mem_() or load_() must be overridden
+	Mem_File_Reader in( data, size );
+	return load_( in );
+}
+
+blargg_err_t Gme_File::load_( Data_Reader& in )
+{
+	RETURN_ERR( file_data.resize( in.remain() ) );
+	RETURN_ERR( in.read( file_data.begin(), file_data.size() ) );
+	return load_mem_( file_data.begin(), file_data.size() );
+}
+
+// public load functions call this at beginning
+void Gme_File::pre_load() { unload(); }
+
+void Gme_File::post_load_() { }
+
+// public load functions call this at end
+blargg_err_t Gme_File::post_load( blargg_err_t err )
+{
+	if ( !track_count() )
+		set_track_count( type()->track_count );
+	if ( !err )
+		post_load_();
+	else
+		unload();
+	
+	return err;
+}
+
+// Public load functions
+
+blargg_err_t Gme_File::load_mem( void const* in, long size )
+{
+	pre_load();
+	return post_load( load_mem_( (byte const*) in, size ) );
+}
+
+blargg_err_t Gme_File::load( Data_Reader& in )
+{
+	pre_load();
+	return post_load( load_( in ) );
+}
+
+blargg_err_t Gme_File::load_file( const char* path )
+{
+	pre_load();
+	GME_FILE_READER in;
+	RETURN_ERR( in.open( path ) );
+	return post_load( load_( in ) );
+}
+
+blargg_err_t Gme_File::load_remaining_( void const* h, long s, Data_Reader& in )
+{
+	Remaining_Reader rem( h, s, &in );
+	return load( rem );
+}
+
+// Track info
+
+void Gme_File::copy_field_( char* out, const char* in, int in_size )
+{
+	if ( !in || !*in )
+		return;
+	
+	// remove spaces/junk from beginning
+	while ( in_size && unsigned (*in - 1) <= ' ' - 1 )
+	{
+		in++;
+		in_size--;
+	}
+	
+	// truncate
+	if ( in_size > max_field_ )
+		in_size = max_field_;
+	
+	// find terminator
+	int len = 0;
+	while ( len < in_size && in [len] )
+		len++;
+	
+	// remove spaces/junk from end
+	while ( len && unsigned (in [len - 1]) <= ' ' )
+		len--;
+	
+	// copy
+	out [len] = 0;
+	memcpy( out, in, len );
+	
+	// strip out stupid fields that should have been left blank
+	if ( !strcmp( out, "?" ) || !strcmp( out, "<?>" ) || !strcmp( out, "< ? >" ) )
+		out [0] = 0;
+}
+
+void Gme_File::copy_field_( char* out, const char* in )
+{
+	copy_field_( out, in, max_field_ );
+}
+
+blargg_err_t Gme_File::remap_track( int* track_io ) const
+{
+	if ( (unsigned) *track_io >= (unsigned) track_count() )
+		return "Invalid track";
+	
+	if ( (unsigned) *track_io < (unsigned) playlist.size() )
+	{
+		M3u_Playlist::entry_t const& e = playlist [*track_io];
+		*track_io = 0;
+		if ( e.track >= 0 )
+		{
+			*track_io = e.track;
+			if ( !(type_->flags_ & 0x02) )
+				*track_io -= e.decimal_track;
+		}
+		if ( *track_io >= raw_track_count_ )
+			return "Invalid track in m3u playlist";
+	}
+	else
+	{
+		check( !playlist.size() );
+	}
+	return 0;
+}
+
+blargg_err_t Gme_File::track_info( track_info_t* out, int track ) const
+{
+	out->track_count = track_count();
+	out->length        = -1;
+	out->loop_length   = -1;
+	out->intro_length  = -1;
+	out->song [0]      = 0;
+	
+	out->game [0]      = 0;
+	out->author [0]    = 0;
+	out->copyright [0] = 0;
+	out->comment [0]   = 0;
+	out->dumper [0]    = 0;
+	out->system [0]    = 0;
+	
+	copy_field_( out->system, type()->system );
+	
+	int remapped = track;
+	RETURN_ERR( remap_track( &remapped ) );
+	RETURN_ERR( track_info_( out, remapped ) );
+	
+	// override with m3u info
+	if ( playlist.size() )
+	{
+		M3u_Playlist::info_t const& i = playlist.info();
+		copy_field_( out->game  , i.title );
+		copy_field_( out->author, i.engineer );
+		copy_field_( out->author, i.composer );
+		copy_field_( out->dumper, i.ripping );
+		
+		M3u_Playlist::entry_t const& e = playlist [track];
+		copy_field_( out->song, e.name );
+		if ( e.length >= 0 ) out->length       = e.length * 1000L;
+		if ( e.intro  >= 0 ) out->intro_length = e.intro  * 1000L;
+		if ( e.loop   >= 0 ) out->loop_length  = e.loop   * 1000L;
+	}
+	return 0;
+}