2011-10-02 10:05:45 +00:00
|
|
|
#ifdef NALL_STRING_INTERNAL_HPP
|
2010-08-09 13:28:56 +00:00
|
|
|
|
|
|
|
namespace nall {
|
|
|
|
|
2011-03-17 10:39:55 +00:00
|
|
|
static void istring(string &output) {
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T, typename... Args>
|
|
|
|
static void istring(string &output, const T &value, Args&&... args) {
|
Update to v084r01 release.
I rewrote the S-SMP processor core (implementation of the 256 opcodes),
utilizing my new 6502-like syntax. It matches what bass v05r01 uses.
Took 10 hours.
Due to being able to group the "mov reg,mem" opcodes together with
"adc/sbc/ora/and/eor/cmp" sets, the total code size was reduced from
55.7KB to 42.5KB for identical accuracy and speed.
I also dropped the trick I was using to pass register variables as
template arguments, and instead just use a switch table to pass them as
function arguments. Makes the table a lot easier to read.
Passes all of my S-SMP tests, and all of blargg's
arithmetic/cycle-timing S-SMP tests. Runs Zelda 3 great as well. Didn't
test further.
This does have the potential to cause some regressions if I've messed
anything up, and none of the above tests caught it, so as always,
testing would be appreciated.
Anyway, yeah. By writing the actual processor with this new mnemonic
set, it confirms the parallels I've made.
My guess is that Sony really did clone the 6502, but was worried about
legal implications or something and changed the mnemonics last-minute.
(Note to self: need to re-enable snes.random before v085 official.)
EDIT: oh yeah, I also commented out the ALSA snd_pcm_drain() inside
term(). Without it, there is a tiny pop when the driver is
re-initialized. But with it, the entire emulator would lock up for five
whole seconds waiting on that call to complete. I'll take the pop any
day over that.
2011-11-17 12:05:35 +00:00
|
|
|
output.append_(make_string(value));
|
2011-03-17 10:39:55 +00:00
|
|
|
istring(output, std::forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
|
2010-08-09 13:28:56 +00:00
|
|
|
void string::reserve(unsigned size_) {
|
|
|
|
if(size_ > size) {
|
|
|
|
size = size_;
|
|
|
|
data = (char*)realloc(data, size + 1);
|
|
|
|
data[size] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-12 10:59:53 +00:00
|
|
|
bool string::empty() const {
|
|
|
|
return !*data;
|
|
|
|
}
|
|
|
|
|
2011-03-17 10:39:55 +00:00
|
|
|
template<typename... Args> string& string::assign(Args&&... args) {
|
|
|
|
*data = 0;
|
|
|
|
istring(*this, std::forward<Args>(args)...);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename... Args> string& string::append(Args&&... args) {
|
|
|
|
istring(*this, std::forward<Args>(args)...);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
string& string::assign_(const char *s) {
|
2010-08-09 13:28:56 +00:00
|
|
|
unsigned length = strlen(s);
|
|
|
|
reserve(length);
|
|
|
|
strcpy(data, s);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2011-03-17 10:39:55 +00:00
|
|
|
string& string::append_(const char *s) {
|
2010-08-09 13:28:56 +00:00
|
|
|
unsigned length = strlen(data) + strlen(s);
|
|
|
|
reserve(length);
|
|
|
|
strcat(data, s);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
string::operator const char*() const {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
char* string::operator()() {
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
char& string::operator[](int index) {
|
|
|
|
reserve(index);
|
|
|
|
return data[index];
|
|
|
|
}
|
|
|
|
|
|
|
|
bool string::operator==(const char *str) const { return strcmp(data, str) == 0; }
|
|
|
|
bool string::operator!=(const char *str) const { return strcmp(data, str) != 0; }
|
|
|
|
bool string::operator< (const char *str) const { return strcmp(data, str) < 0; }
|
|
|
|
bool string::operator<=(const char *str) const { return strcmp(data, str) <= 0; }
|
|
|
|
bool string::operator> (const char *str) const { return strcmp(data, str) > 0; }
|
|
|
|
bool string::operator>=(const char *str) const { return strcmp(data, str) >= 0; }
|
|
|
|
|
|
|
|
string& string::operator=(const string &value) {
|
2011-09-09 04:16:25 +00:00
|
|
|
if(&value == this) return *this;
|
2010-08-09 13:28:56 +00:00
|
|
|
assign(value);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
string& string::operator=(string &&source) {
|
2011-09-09 04:16:25 +00:00
|
|
|
if(&source == this) return *this;
|
2010-08-09 13:28:56 +00:00
|
|
|
if(data) free(data);
|
|
|
|
size = source.size;
|
|
|
|
data = source.data;
|
2011-09-29 12:08:22 +00:00
|
|
|
source.data = nullptr;
|
2010-08-09 13:28:56 +00:00
|
|
|
source.size = 0;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2010-09-22 12:49:49 +00:00
|
|
|
template<typename... Args> string::string(Args&&... args) {
|
2010-08-09 13:28:56 +00:00
|
|
|
size = 64;
|
|
|
|
data = (char*)malloc(size + 1);
|
|
|
|
*data = 0;
|
2010-09-22 12:49:49 +00:00
|
|
|
istring(*this, std::forward<Args>(args)...);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
string::string(const string &value) {
|
2011-09-09 04:16:25 +00:00
|
|
|
if(&value == this) return;
|
2010-08-09 13:28:56 +00:00
|
|
|
size = strlen(value);
|
|
|
|
data = strdup(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
string::string(string &&source) {
|
2011-09-09 04:16:25 +00:00
|
|
|
if(&source == this) return;
|
2010-08-09 13:28:56 +00:00
|
|
|
size = source.size;
|
|
|
|
data = source.data;
|
2011-09-29 12:08:22 +00:00
|
|
|
source.data = nullptr;
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
string::~string() {
|
|
|
|
if(data) free(data);
|
|
|
|
}
|
|
|
|
|
2011-01-29 09:48:44 +00:00
|
|
|
bool string::readfile(const string &filename) {
|
2010-08-09 13:28:56 +00:00
|
|
|
assign("");
|
|
|
|
|
|
|
|
#if !defined(_WIN32)
|
|
|
|
FILE *fp = fopen(filename, "rb");
|
|
|
|
#else
|
|
|
|
FILE *fp = _wfopen(utf16_t(filename), L"rb");
|
|
|
|
#endif
|
|
|
|
if(!fp) return false;
|
|
|
|
|
|
|
|
fseek(fp, 0, SEEK_END);
|
|
|
|
unsigned size = ftell(fp);
|
|
|
|
rewind(fp);
|
|
|
|
char *fdata = new char[size + 1];
|
|
|
|
unsigned unused = fread(fdata, 1, size, fp);
|
|
|
|
fclose(fp);
|
|
|
|
fdata[size] = 0;
|
|
|
|
assign(fdata);
|
|
|
|
delete[] fdata;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-10-14 10:07:38 +00:00
|
|
|
optional<unsigned> lstring::find(const char *key) const {
|
2010-08-09 13:28:56 +00:00
|
|
|
for(unsigned i = 0; i < size(); i++) {
|
|
|
|
if(operator[](i) == key) return { true, i };
|
|
|
|
}
|
|
|
|
return { false, 0 };
|
|
|
|
}
|
|
|
|
|
Update to v087r30 release.
byuu says:
Changelog:
- DMA channel masks added (some are 27-bit source/target and some are
14-bit length -- hooray, varuint_t class.)
- No more state.pending flags. Instead, we set dma.pending flag when we
want a transfer (fixes GBA Video - Pokemon audio) [Cydrak]
- fixed OBJ Vmosaic [Cydrak, krom]
- OBJ cannot read <=0x13fff in BG modes 3-5 (fixes the garbled tile at
the top-left of some games)
- DMA timing should be much closer to hardware now, but probably not
perfect
- PPU frame blending uses blargg's bit-perfect, rounded method (slower,
but what can you do?)
- GBA carts really unload now
- added nall/gba/cartridge.hpp: used when there is no manifest. Scans
ROMs for library tags, and selects the first valid one found
- added EEPROM auto-detection when EEPROM size=0. Forces disk/save state
size to 8192 (otherwise states could crash between pre and post
detect.)
- detects first read after a set read address command when the size
is zero, and sets all subsequent bit-lengths to that value, prints
detected size to terminal
- added nall/nes/cartridge.hpp: moves iNES detection out of emulation
core.
Important to note: long-term goal is to remove all
nall/(system)/cartridge.hpp detections from the core and replace with
databases. All in good time.
Anyway, the GBA workarounds should work for ~98.5% of the library, if my
pre-scanning was correct (~40 games with odd tags. I reject ones without
numeric versions now, too.)
I think we're basically at a point where we can release a new version
now. Compatibility should be relatively high (at least for a first
release), and fixes are only going to affect one or two games at a time.
I'd like to start doing some major cleaning house internally (rename
NES->Famicom, SNES->SuperFamicom and such.) Would be much wiser to do
that on a .01 WIP to minimize regressions.
The main problems with a release now:
- speed is pretty bad, haven't really optimized much yet (not sure how
much we can improve it yet, this usually isn't easy)
- sound isn't -great-, but the GBA audio sucks anyway :P
- couple of known bugs (Sonic X video, etc.)
2012-04-22 10:49:19 +00:00
|
|
|
string lstring::concatenate(const char *separator) const {
|
|
|
|
string output;
|
|
|
|
for(unsigned i = 0; i < size(); i++) {
|
|
|
|
output.append(operator[](i), i < size() - 1 ? separator : "");
|
|
|
|
}
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
2012-06-18 10:13:51 +00:00
|
|
|
template<typename... Args> void lstring::append(const string &data, Args&&... args) {
|
|
|
|
vector::append(data);
|
|
|
|
append(std::forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
|
Update to higan v091r14 and ananke v00r03 releases.
byuu says:
higan changelog:
- generates title displayed in emulator window by asking the core
- core builds title solely from "information/title" ... if it's not
there, you don't get a title at all
- sub-system load menu is gone ... since there are multiple revisions of
the SGB, this never really worked well anyway
- to load an SGB, BS-X or ST cartridge, load the base cartridge first
- "File->Load Game" moved to "Load->Import Game" ... may cause a bit of
confusion to new users, but I don't like having a single-item menu,
we'll just have to explain it to new users
- browser window redone to look like ananke
- home button here goes to ~/Emulation rather than just ~ like ananke,
since this is the home of game folders
- game folder icon is now the executable icon for the Tango theme
(orange diamond), meant to represent a complete game rather than
a game file or archive
ananke changelog:
- outputs GBC games to "Game Boy Color/" instead of "Game Boy/"
- adds the file basename to "information/title"
Known issues:
- using ananke to load a GB game trips the Super Famicom SGB mode and
fails (need to make the full-path auto-detection ignore non-bootable
systems)
- need to dump and test some BS-X media before releasing
- ananke lacks BS-X Satellaview cartridge support
- v092 isn't going to let you retarget the ananke/higan game folder path
of ~/Emulation, you will have to wait for a future version if that
bothers you so greatly
[Later, after the v092 release, byuu posted this additional changelog:
- kill laevateinn
- add title()
- add bootable, remove load
- combine file, library
- combine [][][] paths
- fix SFC subtype handling XML->BML
- update file browser to use buttons
- update file browser keyboard handling
- update system XML->BML
- fix sufami turbo hashing
- remove Cartridge::manifest
]
2012-12-25 05:31:55 +00:00
|
|
|
void lstring::isort() {
|
|
|
|
nall::sort(pool, objectsize, [](const string &x, const string &y) {
|
|
|
|
return istrcmp(x, y) < 0;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-09-19 12:34:18 +00:00
|
|
|
bool lstring::operator==(const lstring &source) const {
|
|
|
|
if(this == &source) return true;
|
|
|
|
if(size() != source.size()) return false;
|
|
|
|
for(unsigned n = 0; n < size(); n++) {
|
|
|
|
if(operator[](n) != source[n]) return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool lstring::operator!=(const lstring &source) const {
|
|
|
|
return !operator==(source);
|
|
|
|
}
|
|
|
|
|
2012-06-18 10:13:51 +00:00
|
|
|
lstring& lstring::operator=(const lstring &source) {
|
|
|
|
vector::operator=(source);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
lstring& lstring::operator=(lstring &source) {
|
|
|
|
vector::operator=(source);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
lstring& lstring::operator=(lstring &&source) {
|
|
|
|
vector::operator=(std::move(source));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<typename... Args> lstring::lstring(Args&&... args) {
|
|
|
|
append(std::forward<Args>(args)...);
|
|
|
|
}
|
|
|
|
|
|
|
|
lstring::lstring(const lstring &source) {
|
|
|
|
vector::operator=(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
lstring::lstring(lstring &source) {
|
|
|
|
vector::operator=(source);
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
2012-06-18 10:13:51 +00:00
|
|
|
lstring::lstring(lstring &&source) {
|
|
|
|
vector::operator=(std::move(source));
|
2010-08-09 13:28:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|