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