1 // Common interface to game music file loading and information
2 
3 // Game_Music_Emu https://bitbucket.org/mpyne/game-music-emu/
4 #ifndef GME_FILE_H
5 #define GME_FILE_H
6 
7 #include "gme.h"
8 #include "blargg_common.h"
9 #include "Data_Reader.h"
10 #include "M3u_Playlist.h"
11 
12 // Error returned if file is wrong type
13 //extern const char gme_wrong_file_type []; // declared in gme.h
14 
15 struct gme_type_t_
16 {
17 	const char* system;         /* name of system this music file type is generally for */
18 	int track_count;            /* non-zero for formats with a fixed number of tracks */
19 	Music_Emu* (*new_emu)();    /* Create new emulator for this type (useful in C++ only) */
20 	Music_Emu* (*new_info)();   /* Create new info reader for this type */
21 
22 	/* internal */
23 	const char* extension_;
24 	int flags_;
25 };
26 
27 struct track_info_t
28 {
29 	long track_count;
30 
31 	/* times in milliseconds; -1 if unknown */
32 	long length;
33 	long intro_length;
34 	long loop_length;
35 
36 	/* empty string if not available */
37 	char system    [256];
38 	char game      [256];
39 	char song      [256];
40 	char author    [256];
41 	char copyright [256];
42 	char comment   [256];
43 	char dumper    [256];
44 };
45 enum { gme_max_field = 255 };
46 
47 struct Gme_File {
48 public:
49 // File loading
50 
51 	// Each loads game music data from a file and returns an error if
52 	// file is wrong type or is seriously corrupt. They also set warning
53 	// string for minor problems.
54 
55 	// Load from file on disk
56 	blargg_err_t load_file( const char* path );
57 
58 	// Load from custom data source (see Data_Reader.h)
59 	blargg_err_t load( Data_Reader& );
60 
61 	// Load from file already read into memory. Keeps pointer to data, so you
62 	// must not free it until you're done with the file.
63 	blargg_err_t load_mem( void const* data, long size );
64 
65 	// Load an m3u playlist. Must be done after loading main music file.
66 	blargg_err_t load_m3u( const char* path );
67 	blargg_err_t load_m3u( Data_Reader& in );
68 
69 	// Clears any loaded m3u playlist and any internal playlist that the music
70 	// format supports (NSFE for example).
71 	void clear_playlist();
72 
73 // Informational
74 
75 	// Type of emulator. For example if this returns gme_nsfe_type, this object
76 	// is an NSFE emulator, and you can cast to an Nsfe_Emu* if necessary.
77 	gme_type_t type() const;
78 
79 	// Most recent warning string, or NULL if none. Clears current warning after
80 	// returning.
81 	const char* warning();
82 
83 	// Number of tracks or 0 if no file has been loaded
84 	int track_count() const;
85 
86 	// Get information for a track (length, name, author, etc.)
87 	// See gme.h for definition of struct track_info_t.
88 	blargg_err_t track_info( track_info_t* out, int track ) const;
89 
90 // User data/cleanup
91 
92 	// Set/get pointer to data you want to associate with this emulator.
93 	// You can use this for whatever you want.
94 	void set_user_data( void* p )       { user_data_ = p; }
95 	void* user_data() const             { return user_data_; }
96 
97 	// Register cleanup function to be called when deleting emulator, or NULL to
98 	// clear it. Passes user_data to cleanup function.
99 	void set_user_cleanup( gme_user_cleanup_t func ) { user_cleanup_ = func; }
100 
101 public:
102 	// deprecated
103 	int error_count() const; // use warning()
104 public:
105 	Gme_File();
106 	virtual ~Gme_File();
107 	BLARGG_DISABLE_NOTHROW
108 	typedef uint8_t byte;
109 protected:
110 	// Services
111 	void set_track_count( int n )       { track_count_ = raw_track_count_ = n; }
112 	void set_warning( const char* s )   { warning_ = s; }
113 	void set_type( gme_type_t t )       { type_ = t; }
114 	blargg_err_t load_remaining_( void const* header, long header_size, Data_Reader& remaining );
115 
116 	// Overridable
117 	virtual void unload();  // called before loading file and if loading fails
118 	virtual blargg_err_t load_( Data_Reader& ); // default loads then calls load_mem_()
119 	virtual blargg_err_t load_mem_( byte const* data, long size ); // use data in memory
120 	virtual blargg_err_t track_info_( track_info_t* out, int track ) const = 0;
121 	virtual void pre_load();
122 	virtual void post_load_();
123 	virtual void clear_playlist_() { }
124 
125 public:
126 	blargg_err_t remap_track_( int* track_io ) const; // need by Music_Emu
127 private:
128 	// noncopyable
129 	Gme_File( const Gme_File& );
130 	Gme_File& operator = ( const Gme_File& );
131 
132 	gme_type_t type_;
133 	int track_count_;
134 	int raw_track_count_;
135 	const char* warning_;
136 	void* user_data_;
137 	gme_user_cleanup_t user_cleanup_;
138 	M3u_Playlist playlist;
139 	char playlist_warning [64];
140 	blargg_vector<byte> file_data; // only if loaded into memory using default load
141 
142 	blargg_err_t load_m3u_( blargg_err_t );
143 	blargg_err_t post_load( blargg_err_t err );
144 public:
145 	// track_info field copying
146 	enum { max_field_ = 255 };
147 	static void copy_field_( char* out, const char* in );
148 	static void copy_field_( char* out, const char* in, int len );
149 };
150 
151 Music_Emu* gme_new_( Music_Emu*, long sample_rate );
152 
153 #define GME_COPY_FIELD( in, out, name ) \
154 	{ Gme_File::copy_field_( out->name, in.name, sizeof in.name ); }
155 
156 #ifndef GME_FILE_READER
157 	#define GME_FILE_READER Std_File_Reader
158 #elif defined (GME_FILE_READER_INCLUDE)
159 	#include GME_FILE_READER_INCLUDE
160 #endif
161 
162 inline gme_type_t Gme_File::type() const            { return type_; }
163 inline int Gme_File::error_count() const            { return warning_ != 0; }
164 inline int Gme_File::track_count() const            { return track_count_; }
165 
166 inline const char* Gme_File::warning()
167 {
168 	const char* s = warning_;
169 	warning_ = 0;
170 	return s;
171 }
172 
173 #endif
174