1
by OV2
Initial 1.52 import |
1 |
/***********************************************************************************
|
2 |
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
3 |
||
4 |
(c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
|
|
5 |
Jerremy Koot (jkoot@snes9x.com)
|
|
6 |
||
7 |
(c) Copyright 2002 - 2004 Matthew Kendora
|
|
8 |
||
9 |
(c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
|
|
10 |
||
11 |
(c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
|
|
12 |
||
13 |
(c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
|
|
14 |
||
15 |
(c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
|
|
16 |
Kris Bleakley (codeviolation@hotmail.com)
|
|
17 |
||
18 |
(c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
|
|
19 |
Nach (n-a-c-h@users.sourceforge.net),
|
|
87
by OV2
Update copyright in all files |
20 |
|
21 |
(c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com)
|
|
1
by OV2
Initial 1.52 import |
22 |
|
23 |
(c) Copyright 2006 - 2007 nitsuja
|
|
24 |
||
290
by Brandon Wright
Update some copyrights, bump version number. |
25 |
(c) Copyright 2009 - 2016 BearOso,
|
1
by OV2
Initial 1.52 import |
26 |
OV2
|
27 |
||
28 |
||
29 |
BS-X C emulator code
|
|
30 |
(c) Copyright 2005 - 2006 Dreamer Nom,
|
|
31 |
zones
|
|
32 |
||
33 |
C4 x86 assembler and some C emulation code
|
|
34 |
(c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
|
|
35 |
Nach,
|
|
36 |
zsKnight (zsknight@zsnes.com)
|
|
37 |
||
38 |
C4 C++ code
|
|
39 |
(c) Copyright 2003 - 2006 Brad Jorsch,
|
|
40 |
Nach
|
|
41 |
||
42 |
DSP-1 emulator code
|
|
43 |
(c) Copyright 1998 - 2006 _Demo_,
|
|
44 |
Andreas Naive (andreasnaive@gmail.com),
|
|
45 |
Gary Henderson,
|
|
46 |
Ivar (ivar@snes9x.com),
|
|
47 |
John Weidman,
|
|
48 |
Kris Bleakley,
|
|
49 |
Matthew Kendora,
|
|
50 |
Nach,
|
|
51 |
neviksti (neviksti@hotmail.com)
|
|
52 |
||
53 |
DSP-2 emulator code
|
|
54 |
(c) Copyright 2003 John Weidman,
|
|
55 |
Kris Bleakley,
|
|
56 |
Lord Nightmare (lord_nightmare@users.sourceforge.net),
|
|
57 |
Matthew Kendora,
|
|
58 |
neviksti
|
|
59 |
||
60 |
DSP-3 emulator code
|
|
61 |
(c) Copyright 2003 - 2006 John Weidman,
|
|
62 |
Kris Bleakley,
|
|
63 |
Lancer,
|
|
64 |
z80 gaiden
|
|
65 |
||
66 |
DSP-4 emulator code
|
|
67 |
(c) Copyright 2004 - 2006 Dreamer Nom,
|
|
68 |
John Weidman,
|
|
69 |
Kris Bleakley,
|
|
70 |
Nach,
|
|
71 |
z80 gaiden
|
|
72 |
||
73 |
OBC1 emulator code
|
|
74 |
(c) Copyright 2001 - 2004 zsKnight,
|
|
75 |
pagefault (pagefault@zsnes.com),
|
|
76 |
Kris Bleakley
|
|
77 |
Ported from x86 assembler to C by sanmaiwashi
|
|
78 |
||
79 |
SPC7110 and RTC C++ emulator code used in 1.39-1.51
|
|
80 |
(c) Copyright 2002 Matthew Kendora with research by
|
|
81 |
zsKnight,
|
|
82 |
John Weidman,
|
|
83 |
Dark Force
|
|
84 |
||
85 |
SPC7110 and RTC C++ emulator code used in 1.52+
|
|
86 |
(c) Copyright 2009 byuu,
|
|
87 |
neviksti
|
|
88 |
||
89 |
S-DD1 C emulator code
|
|
90 |
(c) Copyright 2003 Brad Jorsch with research by
|
|
91 |
Andreas Naive,
|
|
92 |
John Weidman
|
|
93 |
||
94 |
S-RTC C emulator code
|
|
95 |
(c) Copyright 2001 - 2006 byuu,
|
|
96 |
John Weidman
|
|
97 |
||
98 |
ST010 C++ emulator code
|
|
99 |
(c) Copyright 2003 Feather,
|
|
100 |
John Weidman,
|
|
101 |
Kris Bleakley,
|
|
102 |
Matthew Kendora
|
|
103 |
||
104 |
Super FX x86 assembler emulator code
|
|
105 |
(c) Copyright 1998 - 2003 _Demo_,
|
|
106 |
pagefault,
|
|
107 |
zsKnight
|
|
108 |
||
109 |
Super FX C emulator code
|
|
110 |
(c) Copyright 1997 - 1999 Ivar,
|
|
111 |
Gary Henderson,
|
|
112 |
John Weidman
|
|
113 |
||
114 |
Sound emulator code used in 1.5-1.51
|
|
115 |
(c) Copyright 1998 - 2003 Brad Martin
|
|
116 |
(c) Copyright 1998 - 2006 Charles Bilyue'
|
|
117 |
||
118 |
Sound emulator code used in 1.52+
|
|
119 |
(c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
|
|
120 |
||
295
by Brandon Wright
Add byuu copyright for his S-SMP |
121 |
S-SMP emulator code used in 1.54+
|
122 |
(c) Copyright 2016 byuu
|
|
123 |
||
1
by OV2
Initial 1.52 import |
124 |
SH assembler code partly based on x86 assembler code
|
125 |
(c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
|
|
126 |
||
127 |
2xSaI filter
|
|
128 |
(c) Copyright 1999 - 2001 Derek Liauw Kie Fa
|
|
129 |
||
130 |
HQ2x, HQ3x, HQ4x filters
|
|
131 |
(c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
|
|
132 |
||
133 |
NTSC filter
|
|
134 |
(c) Copyright 2006 - 2007 Shay Green
|
|
135 |
||
136 |
GTK+ GUI code
|
|
290
by Brandon Wright
Update some copyrights, bump version number. |
137 |
(c) Copyright 2004 - 2016 BearOso
|
1
by OV2
Initial 1.52 import |
138 |
|
139 |
Win32 GUI code
|
|
140 |
(c) Copyright 2003 - 2006 blip,
|
|
141 |
funkyass,
|
|
142 |
Matthew Kendora,
|
|
143 |
Nach,
|
|
144 |
nitsuja
|
|
298
by Brandon Wright
Bump OV2 Windows port copyright. |
145 |
(c) Copyright 2009 - 2016 OV2
|
1
by OV2
Initial 1.52 import |
146 |
|
147 |
Mac OS GUI code
|
|
148 |
(c) Copyright 1998 - 2001 John Stiles
|
|
87
by OV2
Update copyright in all files |
149 |
(c) Copyright 2001 - 2011 zones
|
1
by OV2
Initial 1.52 import |
150 |
|
151 |
||
152 |
Specific ports contains the works of other authors. See headers in
|
|
153 |
individual files.
|
|
154 |
||
155 |
||
156 |
Snes9x homepage: http://www.snes9x.com/
|
|
157 |
||
158 |
Permission to use, copy, modify and/or distribute Snes9x in both binary
|
|
159 |
and source form, for non-commercial purposes, is hereby granted without
|
|
160 |
fee, providing that this license information and copyright notice appear
|
|
161 |
with all copies and any derived work.
|
|
162 |
||
163 |
This software is provided 'as-is', without any express or implied
|
|
164 |
warranty. In no event shall the authors be held liable for any damages
|
|
165 |
arising from the use of this software or it's derivatives.
|
|
166 |
||
167 |
Snes9x is freeware for PERSONAL USE only. Commercial users should
|
|
168 |
seek permission of the copyright holders first. Commercial use includes,
|
|
169 |
but is not limited to, charging money for Snes9x or software derived from
|
|
170 |
Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
|
|
171 |
using Snes9x as a promotion for your commercial product.
|
|
172 |
||
173 |
The copyright holders request that bug fixes and improvements to the code
|
|
174 |
should be forwarded to them so everyone can benefit from the modifications
|
|
175 |
in future versions.
|
|
176 |
||
177 |
Super NES and Super Nintendo Entertainment System are trademarks of
|
|
178 |
Nintendo Co., Limited and its subsidiary companies.
|
|
179 |
***********************************************************************************/
|
|
180 |
||
181 |
||
182 |
#ifndef _CONFIG_H_
|
|
183 |
#define _CONFIG_H_
|
|
184 |
||
185 |
#include <set> |
|
1.1.5
by OV2
faster config file saving |
186 |
#include <map> |
1
by OV2
Initial 1.52 import |
187 |
#include <vector> |
188 |
#include <string> |
|
189 |
||
190 |
#ifdef UNZIP_SUPPORT
|
|
191 |
#include "unzip/unzip.h" |
|
192 |
#endif
|
|
193 |
#include "snes9x.h" |
|
194 |
||
1.1.5
by OV2
faster config file saving |
195 |
#ifndef MAX
|
196 |
# define MAX(a,b) ((a) > (b)? (a) : (b))
|
|
197 |
# define MIN(a,b) ((a) < (b)? (a) : (b))
|
|
198 |
#endif
|
|
199 |
||
1
by OV2
Initial 1.52 import |
200 |
class ConfigFile { |
201 |
public: |
|
202 |
ConfigFile(void); |
|
203 |
||
204 |
void Clear(void); |
|
205 |
||
206 |
// return false on failure
|
|
207 |
bool LoadFile(const char *filename); |
|
162.1.1
by OV2
Allow membased rom/state load/save, add libsnes interface (Themaister) |
208 |
void LoadFile(Stream *r, const char *name=NULL); |
1
by OV2
Initial 1.52 import |
209 |
|
210 |
// return false if key does not exist or is empty
|
|
211 |
bool Exists(const char *key); |
|
212 |
||
213 |
// return the value / default
|
|
214 |
std::string GetString(const char *key, std::string def); |
|
215 |
char *GetString(const char *key, char *out, uint32 outlen); // return NULL if it doesn't exist, out not affected |
|
216 |
const char *GetString(const char *key, const char *def=NULL); // NOTE: returned pointer becomes invalid when key is deleted/modified, or the ConfigFile is Clear()ed or deleted. |
|
217 |
char *GetStringDup(const char *key, const char *def=NULL); // Much like "strdup(GetString(key, def))" |
|
218 |
int32 GetInt(const char *key, int32 def=-1, bool *bad=NULL); |
|
219 |
uint32 GetUInt(const char *key, uint32 def=0, int base=0, bool *bad=NULL); // base = 0, 8, 10, or 16 |
|
220 |
bool GetBool(const char *key, bool def=false, bool *bad=NULL); |
|
221 |
const char* GetComment(const char *key); // NOTE: returned pointer becomes invalid when key is deleted/modified, or the ConfigFile is Clear()ed or deleted. |
|
222 |
||
223 |
// return true if the key existed prior to setting
|
|
224 |
bool SetString(const char *key, std::string val, const char *comment=""); |
|
225 |
bool SetInt(const char *key, int32 val, const char *comment=""); |
|
226 |
bool SetUInt(const char *key, uint32 val, int base=10, const char *comment=""); // base = 8, 10, or 16 |
|
227 |
bool SetBool(const char *key, bool val, const char *true_val="TRUE", const char *false_val="FALSE", const char *comment=""); |
|
228 |
bool DeleteKey(const char *key); |
|
229 |
||
230 |
// Operation on entire sections
|
|
231 |
bool DeleteSection(const char *section); |
|
232 |
typedef std::vector<std::pair<std::string,std::string> > secvec_t; |
|
233 |
secvec_t GetSection(const char *section); |
|
1.1.5
by OV2
faster config file saving |
234 |
int GetSectionSize(const std::string section); |
1
by OV2
Initial 1.52 import |
235 |
|
236 |
// Clears all key-value pairs that didn't receive a Set command, or a Get command with autoAdd on
|
|
237 |
void ClearUnused(void); |
|
238 |
||
239 |
// Clears all stored line numbers
|
|
240 |
void ClearLines(void); |
|
241 |
||
242 |
bool SaveTo(const char *filename); |
|
243 |
||
244 |
static void SetDefaultAutoAdd(bool autoAdd); |
|
245 |
static void SetNiceAlignment(bool align); |
|
246 |
static void SetShowComments(bool show); |
|
247 |
static void SetAlphaSort(bool sort); |
|
248 |
static void SetTimeSort(bool sort); |
|
249 |
||
250 |
private: |
|
251 |
std::string Get(const char *key); |
|
252 |
bool Has(const char *key); |
|
253 |
||
254 |
class ConfigEntry { |
|
255 |
protected: |
|
256 |
int line; |
|
257 |
std::string section; |
|
258 |
std::string key; |
|
259 |
std::string val; |
|
260 |
std::string comment; |
|
261 |
mutable bool used; |
|
262 |
||
263 |
struct section_then_key_less { |
|
264 |
bool operator()(const ConfigEntry &a, const ConfigEntry &b); |
|
265 |
};
|
|
266 |
||
267 |
struct key_less { |
|
268 |
bool operator()(const ConfigEntry &a, const ConfigEntry &b) const{ |
|
269 |
if(a.section!=b.section) return a.section<b.section; |
|
270 |
return a.key<b.key; |
|
271 |
}
|
|
272 |
};
|
|
273 |
||
274 |
struct line_less { |
|
275 |
bool operator()(const ConfigEntry &a, const ConfigEntry &b){ |
|
276 |
if(a.line==b.line) return (b.val.empty() && !a.val.empty()) || a.key<b.key; |
|
277 |
if(b.line<0) return true; |
|
278 |
if(a.line<0) return false; |
|
279 |
return a.line<b.line; |
|
280 |
}
|
|
281 |
};
|
|
282 |
||
283 |
static void trim(std::string &s){ |
|
284 |
int i; |
|
285 |
i=s.find_first_not_of(" \f\n\r\t\v"); |
|
286 |
if(i==-1){ |
|
287 |
s.clear(); |
|
288 |
return; |
|
289 |
}
|
|
290 |
if(i>0) s.erase(0, i); // erase leading whitespace |
|
291 |
i=s.find_last_not_of(" \f\n\r\t\v"); |
|
292 |
if(i!=-1) s.erase(i+1); // erase trailing whitespace |
|
293 |
return; |
|
294 |
}
|
|
295 |
||
296 |
// trims comments and leading/trailing whitespace from s, and returns any trimmed comments
|
|
297 |
// make sure not to call this more than once on the same string
|
|
298 |
static std::string trimCommented(std::string &s){ |
|
299 |
std::string cmt; |
|
300 |
int i; |
|
301 |
i=s.find_first_not_of(" \f\n\r\t\v"); |
|
302 |
if(i==-1){ |
|
303 |
s.clear(); |
|
304 |
return cmt; |
|
305 |
}
|
|
306 |
if(i>0) s.erase(0, i); // erase leading whitespace |
|
307 |
int off=0; |
|
308 |
for(;;){ |
|
309 |
i=s.find('#',off); // find trailing comment |
|
310 |
if(i>=0) |
|
311 |
{
|
|
312 |
if((int)s.length()>i+1 && s.at(i+1) == '#') { |
|
313 |
s.erase(i,1); // ignore ## and change to # |
|
314 |
off = i+1; |
|
315 |
continue; |
|
316 |
} else { |
|
317 |
int j=s.find_first_not_of(" \f\n\r\t\v",i+1); |
|
318 |
if(j!=-1) cmt = s.substr(j); // store |
|
319 |
s.erase(i); // erase trailing comment |
|
320 |
}
|
|
321 |
}
|
|
322 |
break; |
|
323 |
}
|
|
324 |
i=s.find_last_not_of(" \f\n\r\t\v"); |
|
325 |
if(i!=-1) s.erase(i+1); // erase trailing whitespace |
|
326 |
return cmt; |
|
327 |
}
|
|
328 |
||
329 |
public: |
|
330 |
ConfigEntry(int l, const std::string &s, const std::string &k, const std::string &v) : |
|
331 |
line(l), section(s), key(k), val(v) { |
|
332 |
trim(section); |
|
333 |
trim(key); |
|
334 |
used=false; |
|
335 |
}
|
|
336 |
||
337 |
void parse_key(const std::string &k){ |
|
338 |
int i=k.find("::"); |
|
339 |
if(i==-1){ |
|
340 |
section="Uncategorized"; key=k; |
|
341 |
} else { |
|
342 |
section=k.substr(0,i); key=k.substr(i+2); |
|
343 |
}
|
|
344 |
trim(section); |
|
345 |
trim(key); |
|
346 |
used=false; |
|
347 |
}
|
|
348 |
||
349 |
ConfigEntry(const std::string k){ |
|
350 |
parse_key(k); |
|
351 |
}
|
|
352 |
||
353 |
ConfigEntry(const std::string k, const std::string &v) : line(-1), val(v) { |
|
354 |
parse_key(k); |
|
355 |
}
|
|
356 |
||
357 |
friend class ConfigFile; |
|
358 |
friend struct key_less; |
|
359 |
friend struct line_less; |
|
360 |
};
|
|
1.1.5
by OV2
faster config file saving |
361 |
class SectionSizes { |
362 |
protected: |
|
363 |
std::map<std::string,uint32> sections; |
|
364 |
||
365 |
public: |
|
366 |
uint32 GetSectionSize(const std::string section) { |
|
367 |
uint32 count=0; |
|
368 |
uint32 seclen; |
|
369 |
std::map<std::string,uint32>::iterator it; |
|
370 |
for(it=sections.begin(); it!=sections.end(); it++) { |
|
371 |
seclen = MIN(section.size(),it->first.size()); |
|
372 |
if(it->first==section || !section.compare(0,seclen,it->first,0,seclen)) count+=it->second; |
|
373 |
}
|
|
374 |
return count; |
|
375 |
}
|
|
376 |
||
377 |
void IncreaseSectionSize(const std::string section) { |
|
378 |
std::map<std::string,uint32>::iterator it=sections.find(section); |
|
379 |
if(it!=sections.end()) |
|
380 |
it->second++; |
|
381 |
else
|
|
382 |
sections.insert(std::pair<std::string,uint32>(section,1)); |
|
383 |
}
|
|
384 |
||
385 |
void DecreaseSectionSize(const std::string section) { |
|
386 |
std::map<std::string,uint32>::iterator it=sections.find(section); |
|
387 |
if(it!=sections.end()) |
|
388 |
it->second--; |
|
389 |
}
|
|
390 |
||
391 |
void ClearSections() { |
|
392 |
sections.clear(); |
|
393 |
}
|
|
394 |
||
395 |
void DeleteSection(const std::string section) { |
|
396 |
sections.erase(section); |
|
397 |
}
|
|
398 |
||
399 |
};
|
|
1
by OV2
Initial 1.52 import |
400 |
std::set<ConfigEntry, ConfigEntry::key_less> data; |
1.1.5
by OV2
faster config file saving |
401 |
SectionSizes sectionSizes; |
1
by OV2
Initial 1.52 import |
402 |
int linectr; |
403 |
static bool defaultAutoAdd; |
|
404 |
static bool niceAlignment; |
|
405 |
static bool showComments; |
|
406 |
static bool alphaSort; |
|
407 |
static bool timeSort; |
|
408 |
};
|
|
409 |
||
410 |
/* Config file format:
|
|
411 |
*
|
|
412 |
* Comments are any lines whose first non-whitespace character is ';' or '#'.
|
|
413 |
* Note that comments can also follow a value, on the same line.
|
|
414 |
* To intentionally have a '#' character in the value, use ##
|
|
415 |
*
|
|
416 |
* All parameters fall into sections. To name a section, the first
|
|
417 |
* non-whitespace character on the line will be '[', and the last will be ']'.
|
|
418 |
*
|
|
419 |
* Parameters are simple key=value pairs. Whitespace around the '=', and at the
|
|
420 |
* beginning or end of the line is ignored. Key names may not contain '=' nor
|
|
421 |
* begin with '[', however values can. If the last character of the value is
|
|
422 |
* '\', the next line (sans leading/trailing whitespace) is considered part of
|
|
423 |
* the value as well. Programmatically, the key "K" in section "S" is referred
|
|
424 |
* to as "S::K", much like C++ namespaces. For example:
|
|
425 |
* [Section1]
|
|
426 |
* # this is a comment
|
|
427 |
* foo = bar \
|
|
428 |
* baz\
|
|
429 |
* quux \
|
|
430 |
* ## this is not a comment! # this IS a comment
|
|
431 |
* means the value of "Section1::foo" is "bar bazquux # this is not a comment!"
|
|
432 |
*
|
|
433 |
* Parameters may be of several types:
|
|
434 |
* String - Bare characters. If the first and last characters are both '"',
|
|
435 |
* they are removed (so just double them if you really want quotes
|
|
436 |
* there)
|
|
437 |
* Int - A decimal number from -2147483648 to 2147483647
|
|
438 |
* UInt - A number in decimal, hex, or octal from 0 to 4294967295 (or
|
|
439 |
* 0xffffffff, or 037777777777)
|
|
440 |
* Bool - true/false, 0/1, on/off, yes/no
|
|
441 |
*
|
|
442 |
* Of course, the actual accepted values for a parameter may be further
|
|
443 |
* restricted ;)
|
|
444 |
*/
|
|
445 |
||
446 |
||
447 |
/* You must write this for your port */
|
|
448 |
void S9xParsePortConfig(ConfigFile &, int pass); |
|
449 |
||
450 |
/* This may or may not be useful to you */
|
|
451 |
const char *S9xParseDisplayConfig(ConfigFile &, int pass); |
|
452 |
||
453 |
#endif
|