1 // Common interface for track information
2 
3 // Game_Music_Emu $vers
4 #ifndef GME_FILE_H
5 #define GME_FILE_H
6 
7 #include "gme.h"
8 #include "Gme_Loader.h"
9 #include "M3u_Playlist.h"
10 
11 struct track_info_t
12 {
13 	int track_count;
14 
15 	/* times in milliseconds; -1 if unknown */
16 	int length;         /* total length, if file specifies it */
17 	int intro_length;   /* length of song up to looping section */
18 	int loop_length;    /* length of looping section */
19 	int fade_length;
20 	int repeat_count;
21 
22 	/* Length if available, otherwise intro_length+loop_length*2 if available,
23 	otherwise a default of 150000 (2.5 minutes). */
24 	int play_length;
25 
26 	/* empty string if not available */
27 	char system    [256];
28 	char game      [256];
29 	char song      [256];
30 	char author    [256];
31 	char composer  [256];
32 	char engineer  [256];
33 	char sequencer [256];
34 	char tagger    [256];
35 	char copyright [256];
36 	char date      [256];
37 	char comment   [256];
38 	char dumper    [256];
39 	char disc      [256];
40 	char track     [256];
41 	char ost       [256];
42 };
43 enum { gme_max_field = 255 };
44 
45 class Gme_File : public Gme_Loader {
46 public:
47 	// Type of emulator. For example if this returns gme_nsfe_type, this object
48 	// is an NSFE emulator, and you can downcast to an Nsfe_Emu* if necessary.
49 	gme_type_t type() const;
50 
51 	// Loads an m3u playlist. Must be done AFTER loading main music file.
52 	blargg_err_t load_m3u( const char path [] );
53 	blargg_err_t load_m3u( Data_Reader& in );
54 
55 	// Clears any loaded m3u playlist and any internal playlist that the music
56 	// format supports (NSFE for example).
57 	void clear_playlist();
58 
59 	// Number of tracks or 0 if no file has been loaded
60 	int track_count() const;
61 
62 	// Gets information for a track (length, name, author, etc.)
63 	// See gme.h for definition of struct track_info_t.
64 	blargg_err_t track_info( track_info_t* out, int track ) const;
65 
66 // User data/cleanup
67 
68 	// Sets/gets pointer to data you want to associate with this emulator.
69 	// You can use this for whatever you want.
set_user_data(void * p)70 	void set_user_data( void* p )       { user_data_ = p; }
user_data()71 	void* user_data() const             { return user_data_; }
72 
73 	// Registers cleanup function to be called when deleting emulator, or NULL to
74 	// clear it. Passes user_data to cleanup function.
set_user_cleanup(gme_user_cleanup_t func)75 	void set_user_cleanup( gme_user_cleanup_t func ) { user_cleanup_ = func; }
76 
77 public:
78 	Gme_File();
79 	~Gme_File();
80 
81 protected:
82 	// Services
set_type(gme_type_t t)83 	void set_type( gme_type_t t )               { type_ = t; }
set_track_count(int n)84 	void set_track_count( int n )               { track_count_ = raw_track_count_ = n; }
85 
86 	// Must be overridden
track_info_(track_info_t * out,int track)87 	virtual blargg_err_t track_info_( track_info_t* out, int track ) const BLARGG_PURE( ; )
88 
89 	// Optionally overridden
90 	virtual void clear_playlist_() { }
91 
92 protected: // Gme_Loader overrides
93 	virtual void unload();
94 	virtual blargg_err_t post_load();
95 
96 protected:
97 	blargg_err_t remap_track_( int* track_io ) const; // need by Music_Emu
98 private:
99 	gme_type_t type_;
100 	void* user_data_;
101 	gme_user_cleanup_t user_cleanup_;
102 	int track_count_;
103 	int raw_track_count_;
104 	M3u_Playlist playlist;
105 	char playlist_warning [64];
106 
107 	blargg_err_t load_m3u_( blargg_err_t );
108 
109 public:
110 	// track_info field copying
111 	enum { max_field_ = 255 };
112 	static void copy_field_( char out [], const char* in );
113 	static void copy_field_( char out [], const char* in, int len );
114 };
115 
116 struct gme_type_t_
117 {
118 	const char* system;      /* name of system this music file type is generally for */
119 	int track_count;         /* non-zero for formats with a fixed number of tracks */
120 	Music_Emu* (*new_emu)(); /* Create new emulator for this type (C++ only) */
121 	Music_Emu* (*new_info)();/* Create new info reader for this type (C++ only) */
122 
123 	/* internal */
124 	const char* extension_;
125 	int flags_;
126 };
127 
128 /* Emulator type constants for each supported file type */
129 extern const gme_type_t_
130 	gme_ay_type [1],
131 	gme_gbs_type [1],
132 	gme_gym_type [1],
133 	gme_hes_type [1],
134 	gme_kss_type [1],
135 	gme_nsf_type [1],
136 	gme_nsfe_type [1],
137 	gme_sap_type [1],
138     gme_sfm_type [1],
139 	gme_sgc_type [1],
140 	gme_spc_type [1],
141 	gme_vgm_type [1],
142 	gme_vgz_type [1];
143 
144 #define GME_COPY_FIELD( in, out, name ) \
145 	{ Gme_File::copy_field_( out->name, in.name, sizeof in.name ); }
146 
type()147 inline gme_type_t Gme_File::type() const            { return type_; }
148 
track_count()149 inline int Gme_File::track_count() const            { return track_count_; }
150 
track_info_(track_info_t *,int)151 inline blargg_err_t Gme_File::track_info_( track_info_t*, int ) const { return blargg_ok; }
152 
153 #endif
154