Refer to loaded ROM imagesets as handles
[lsnes.git] / include / core / romimage.hpp
blobe7a6f6e74e902b0f7178c766cbaccd3c2c4e238c
1 #ifndef _romimage__hpp__included__
2 #define _romimage__hpp__included__
4 #include "core/rom-small.hpp"
5 #include "interface/romtype.hpp"
6 #include "library/fileimage.hpp"
7 #include "library/threads.hpp"
9 //ROM request.
10 struct rom_request
12 //List of core types.
13 std::vector<core_type*> cores;
14 //Selected core (default core on call).
15 bool core_guessed;
16 size_t selected;
17 //Filename selected (on entry, filename hint).
18 bool has_slot[ROM_SLOT_COUNT];
19 bool guessed[ROM_SLOT_COUNT];
20 std::string filename[ROM_SLOT_COUNT];
21 std::string hash[ROM_SLOT_COUNT];
22 std::string hashxml[ROM_SLOT_COUNT];
23 //Canceled flag.
24 bool canceled;
27 /**
28 * A collection of files making up a ROM image.
30 class rom_image
32 public:
33 /**
34 * Create blank ROM
36 rom_image() throw();
37 /**
38 * Take in ROM filename (or a bundle) and load it to memory.
40 * parameter file: The file to load
41 * parameter tmpprefer: The core name to prefer.
42 * throws std::bad_alloc: Not enough memory.
43 * throws std::runtime_error: Loading ROM file failed.
45 rom_image(const std::string& file, const std::string& tmpprefer = "") throw(std::bad_alloc,
46 std::runtime_error);
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) throw(std::bad_alloc, std::runtime_error);
66 /**
67 * Get ROM type.
69 core_type& get_type() { return *rtype; }
70 /**
71 * Get ROM region.
73 core_region& get_region() { return *orig_region; }
74 /**
75 * Do region setup. Changes orig_region to specified if NULL.
77 void setup_region(core_region& reg);
78 /**
79 * Get image.
81 fileimage::image& get_image(size_t index, bool xml)
83 if(index < ROM_SLOT_COUNT) {
84 if(xml)
85 return romxml[index];
86 else
87 return romimg[index];
88 } else
89 return null_img;
91 /**
92 * Get filename of ROM pack, if any.
94 const std::string& get_pack_filename() { return load_filename; }
95 /**
96 * Get MSU-1 base fileaname.
98 const std::string& get_msu1_base() { return msu1_base; }
99 /**
100 * Is same ROM type?
102 bool is_of_type(core_type& type) { return (rtype == &type); }
104 * Is file a gamepak?
106 * parameter filename: The file to probe.
107 * retruns: True if gamepak, false if not.
108 * throws std::runtime_error: No such file.
110 static bool is_gamepak(const std::string& filename) throw(std::bad_alloc, std::runtime_error);
111 //ROM functions.
112 std::list<core_region*> get_regions() { return rtype->get_regions(); }
113 const std::string& get_hname() { return rtype->get_hname(); }
114 private:
115 rom_image(const rom_image&);
116 rom_image& operator=(const rom_image&);
117 //Static NULL image.
118 static fileimage::image null_img;
119 //Loaded ROM images.
120 fileimage::image romimg[ROM_SLOT_COUNT];
121 //Loaded ROM XML (markup) images.
122 fileimage::image romxml[ROM_SLOT_COUNT];
123 //MSU-1 base filename.
124 std::string msu1_base;
125 //Load filename.
126 std::string load_filename;
127 //ROM type.
128 core_type* rtype;
129 //ROM region.
130 core_region* region;
131 //Region ROM was loaded as.
132 core_region* orig_region;
133 //Reference count.
134 threads::lock usage_lock;
135 size_t usage_count;
136 void get() { threads::alock l(usage_lock); usage_count++; }
137 bool put() { threads::alock l(usage_lock); return !--usage_count; }
138 friend class rom_image_handle;
139 //Handle bundle load case.
140 void load_bundle(const std::string& file, std::istream& spec, const std::string& tmpprefer)
141 throw(std::bad_alloc, std::runtime_error);
145 * A handle for ROM imageset.
147 class rom_image_handle
149 public:
151 * Create a handle to NULL imageset.
153 rom_image_handle()
155 img = &null_img;
158 * Create a new handle with refcount 1. The specified ROM imageset has to be allocated using new.
160 rom_image_handle(rom_image* _img)
162 img = _img;
163 img->usage_count = 1;
166 * Copy-construct a handle.
168 rom_image_handle(const rom_image_handle& h)
170 h.get();
171 img = h.img;
174 * Assign a handle.
176 rom_image_handle& operator=(const rom_image_handle& h)
178 if(img == h.img) return *this;
179 h.get();
180 put();
181 img = h.img;
182 return *this;
185 * Destroy a handle.
187 ~rom_image_handle()
189 put();
192 * Access the handle.
194 rom_image& operator*()
196 return *img;
199 * Access the handle.
201 rom_image* operator->()
203 return img;
205 private:
206 static rom_image null_img;
207 mutable rom_image* img;
208 void get() const { if(img != &null_img) img->get(); }
209 void put() const { if(img != &null_img && img->put()) delete img; }
213 void record_filehash(const std::string& file, uint64_t prefix, const std::string& hash);
214 void set_hasher_callback(std::function<void(uint64_t, uint64_t)> cb);
215 rom_image_handle construct_rom(const std::string& movie_filename, const std::vector<std::string>& cmdline);
217 //Map of preferred cores for each extension and type.
218 extern std::map<std::string, core_type*> preferred_core;
219 //Main hasher
220 extern fileimage::hash lsnes_image_hasher;
222 #endif