Actually call on_reset callback
[lsnes.git] / include / core / romimage.hpp
blob015b5605bf7fb5f2e75b5333508df8a2c751d037
1 #ifndef _romimage__hpp__included__
2 #define _romimage__hpp__included__
4 #include <functional>
5 #include "core/rom-small.hpp"
6 #include "interface/romtype.hpp"
7 #include "library/fileimage.hpp"
8 #include "library/threads.hpp"
10 //ROM request.
11 struct rom_request
13 //List of core types.
14 std::vector<core_type*> cores;
15 //Selected core (default core on call).
16 bool core_guessed;
17 size_t selected;
18 //Filename selected (on entry, filename hint).
19 bool has_slot[ROM_SLOT_COUNT];
20 bool guessed[ROM_SLOT_COUNT];
21 std::string filename[ROM_SLOT_COUNT];
22 std::string hash[ROM_SLOT_COUNT];
23 std::string hashxml[ROM_SLOT_COUNT];
24 //Canceled flag.
25 bool canceled;
28 /**
29 * A collection of files making up a ROM image.
31 class rom_image
33 public:
34 /**
35 * Create blank ROM
37 rom_image() throw();
38 /**
39 * Take in ROM filename (or a bundle) and load it to memory.
41 * parameter file: The file to load
42 * parameter tmpprefer: The core name to prefer.
43 * throws std::bad_alloc: Not enough memory.
44 * throws std::runtime_error: Loading ROM file failed.
46 rom_image(const std::string& file, const std::string& tmpprefer = "");
47 /**
48 * Take a ROM and load it.
50 rom_image(const std::string& file, const std::string& core, const std::string& type,
51 const std::string& region);
52 /**
53 * Load a multi-file ROM.
55 rom_image(const std::string file[ROM_SLOT_COUNT], const std::string& core, const std::string& type,
56 const std::string& region);
57 /**
58 * Take in ROM filename and load it to memory with specified type.
60 * parameter file: The file to load
61 * parameter ctype: The core type to use.
62 * throws std::bad_alloc: Not enough memory.
63 * throws std::runtime_error: Loading ROM file failed.
65 rom_image(const std::string& file, core_type& ctype);
66 /**
67 * Destroy ROM image.
69 ~rom_image();
70 /**
71 * Get ROM type.
73 core_type& get_type() { return *rtype; }
74 /**
75 * Get ROM region.
77 core_region& get_region() { return *orig_region; }
78 /**
79 * Do region setup. Changes orig_region to specified if NULL.
81 void setup_region(core_region& reg);
82 /**
83 * Get image.
85 fileimage::image& get_image(size_t index, bool xml)
87 if(index < ROM_SLOT_COUNT) {
88 if(xml)
89 return romxml[index];
90 else
91 return romimg[index];
92 } else
93 return null_img;
95 /**
96 * Get filename of ROM pack, if any.
98 const std::string& get_pack_filename() { return load_filename; }
99 /**
100 * Get MSU-1 base fileaname.
102 const std::string& get_msu1_base() { return msu1_base; }
104 * Is same ROM type?
106 bool is_of_type(core_type& type) { return (rtype == &type); }
108 * Is file a gamepak?
110 * parameter filename: The file to probe.
111 * retruns: True if gamepak, false if not.
112 * throws std::runtime_error: No such file.
114 static bool is_gamepak(const std::string& filename);
115 //ROM functions.
116 std::list<core_region*> get_regions() { return rtype->get_regions(); }
117 const std::string& get_hname() { return rtype->get_hname(); }
118 private:
119 rom_image(const rom_image&);
120 rom_image& operator=(const rom_image&);
121 //Account images.
122 void account_images();
123 //Static NULL image.
124 static fileimage::image null_img;
125 //Loaded ROM images.
126 fileimage::image romimg[ROM_SLOT_COUNT];
127 //Loaded ROM XML (markup) images.
128 fileimage::image romxml[ROM_SLOT_COUNT];
129 //MSU-1 base filename.
130 std::string msu1_base;
131 //Load filename.
132 std::string load_filename;
133 //ROM type.
134 core_type* rtype;
135 //ROM region.
136 core_region* region;
137 //Region ROM was loaded as.
138 core_region* orig_region;
139 //Reference count.
140 threads::lock usage_lock;
141 size_t usage_count;
142 void get() { threads::alock l(usage_lock); usage_count++; }
143 bool put() { threads::alock l(usage_lock); return !--usage_count; }
144 friend class rom_image_handle;
145 //Handle bundle load case.
146 void load_bundle(const std::string& file, std::istream& spec, const std::string& tmpprefer);
147 //Tracker.
148 memtracker::autorelease tracker;
152 * A handle for ROM imageset.
154 class rom_image_handle
156 public:
158 * Create a handle to NULL imageset.
160 rom_image_handle()
162 img = &null_img;
165 * Create a new handle with refcount 1. The specified ROM imageset has to be allocated using new.
167 rom_image_handle(rom_image* _img)
169 img = _img;
170 img->usage_count = 1;
173 * Copy-construct a handle.
175 rom_image_handle(const rom_image_handle& h)
177 h.get();
178 img = h.img;
181 * Assign a handle.
183 rom_image_handle& operator=(const rom_image_handle& h)
185 if(img == h.img) return *this;
186 h.get();
187 put();
188 img = h.img;
189 return *this;
192 * Destroy a handle.
194 ~rom_image_handle()
196 put();
199 * Access the handle.
201 rom_image& operator*()
203 return *img;
206 * Access the handle.
208 rom_image* operator->()
210 return img;
212 private:
213 static rom_image null_img;
214 mutable rom_image* img;
215 void get() const { if(img != &null_img) img->get(); }
216 void put() const { if(img != &null_img && img->put()) delete img; }
220 void record_filehash(const std::string& file, uint64_t prefix, const std::string& hash);
221 void set_hasher_callback(std::function<void(uint64_t, uint64_t)> cb);
222 rom_image_handle construct_rom(const std::string& movie_filename, const std::vector<std::string>& cmdline);
224 //Map of preferred cores for each extension and type.
225 extern std::map<std::string, core_type*> preferred_core;
226 //Main hasher
227 extern fileimage::hash lsnes_image_hasher;
229 #endif