Fix crash if text containing \n is printed at nonzero x
[lsnes.git] / include / core / romimage.hpp
blobdcc87990d3a280dcb21980312889df24d4910512
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 * 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) throw(std::bad_alloc, std::runtime_error);
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 throw(std::bad_alloc, std::runtime_error);
148 //Tracker.
149 memtracker::autorelease tracker;
153 * A handle for ROM imageset.
155 class rom_image_handle
157 public:
159 * Create a handle to NULL imageset.
161 rom_image_handle()
163 img = &null_img;
166 * Create a new handle with refcount 1. The specified ROM imageset has to be allocated using new.
168 rom_image_handle(rom_image* _img)
170 img = _img;
171 img->usage_count = 1;
174 * Copy-construct a handle.
176 rom_image_handle(const rom_image_handle& h)
178 h.get();
179 img = h.img;
182 * Assign a handle.
184 rom_image_handle& operator=(const rom_image_handle& h)
186 if(img == h.img) return *this;
187 h.get();
188 put();
189 img = h.img;
190 return *this;
193 * Destroy a handle.
195 ~rom_image_handle()
197 put();
200 * Access the handle.
202 rom_image& operator*()
204 return *img;
207 * Access the handle.
209 rom_image* operator->()
211 return img;
213 private:
214 static rom_image null_img;
215 mutable rom_image* img;
216 void get() const { if(img != &null_img) img->get(); }
217 void put() const { if(img != &null_img && img->put()) delete img; }
221 void record_filehash(const std::string& file, uint64_t prefix, const std::string& hash);
222 void set_hasher_callback(std::function<void(uint64_t, uint64_t)> cb);
223 rom_image_handle construct_rom(const std::string& movie_filename, const std::vector<std::string>& cmdline);
225 //Map of preferred cores for each extension and type.
226 extern std::map<std::string, core_type*> preferred_core;
227 //Main hasher
228 extern fileimage::hash lsnes_image_hasher;
230 #endif