mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-09-14 14:22:23 +02:00
Compare commits
40 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a266a2b5e2 | ||
|
53f03be5a2 | ||
|
77375c3c68 | ||
|
dce3e61f06 | ||
|
20b44ddfd1 | ||
|
79f20030a0 | ||
|
79b939e1c7 | ||
|
3ae74ff5a5 | ||
|
7351b910c5 | ||
|
6bbb609f2f | ||
|
0d19902435 | ||
|
44bab83d68 | ||
|
42a4c1d60e | ||
|
645689e683 | ||
|
8b0153daf0 | ||
|
9ca1e259cb | ||
|
7227107d5e | ||
|
65ff00e28a | ||
|
717aa69d42 | ||
|
35fdb71f3d | ||
|
c33f70a8c6 | ||
|
0a3fdc404d | ||
|
efa7879c6d | ||
|
b11f22f517 | ||
|
9614275b34 | ||
|
9995876bc5 | ||
|
43a3991ddf | ||
|
27c24bc8a6 | ||
|
fac95dfec5 | ||
|
362542924e | ||
|
4179282244 | ||
|
02820ef2e9 | ||
|
0ecce7b93d | ||
|
f94fcd6f30 | ||
|
57f903630a | ||
|
9329de0a8d | ||
|
989648c21c | ||
|
0f0dcf9538 | ||
|
78e1a5b067 | ||
|
79404ec523 |
BIN
QtCore4.dll
BIN
QtCore4.dll
Binary file not shown.
BIN
QtGui4.dll
BIN
QtGui4.dll
Binary file not shown.
Binary file not shown.
231
bsnes/Makefile
231
bsnes/Makefile
@@ -1,231 +0,0 @@
|
||||
include lib/nall/Makefile
|
||||
|
||||
ui := ui_qt
|
||||
qtlibs := $(strip QtCore QtGui $(if $(findstring osx,$(platform)),QtOpenGL))
|
||||
include lib/nall/qt/Makefile
|
||||
|
||||
################
|
||||
### compiler ###
|
||||
################
|
||||
|
||||
c := $(compiler) --std=gnu99
|
||||
cpp := $(subst cc,++,$(compiler)) -std=gnu++0x
|
||||
flags := -O3 -fomit-frame-pointer -Ilib
|
||||
link :=
|
||||
|
||||
# profile-guided instrumentation:
|
||||
# flags += -fprofile-generate
|
||||
# link += -lgcov
|
||||
|
||||
# profile-guided optimization:
|
||||
# flags += -fprofile-use
|
||||
|
||||
################
|
||||
### platform ###
|
||||
################
|
||||
|
||||
ifeq ($(platform),x)
|
||||
link += -s -ldl -lX11 -lXext
|
||||
|
||||
ruby := video.glx video.xv video.qtraster video.sdl
|
||||
ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||
ruby += input.sdl input.x
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-lopenal)
|
||||
else ifeq ($(platform),osx)
|
||||
ruby := video.qtopengl video.qtraster
|
||||
ruby += audio.openal
|
||||
ruby += input.carbon
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-framework OpenAL)
|
||||
else ifeq ($(platform),win)
|
||||
link += -mwindows -mthreads
|
||||
# link += -mconsole -mthreads
|
||||
link += -s -luuid -lkernel32 -luser32 -lgdi32 -lshell32
|
||||
# statically link Qt for Windows build
|
||||
link += -enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
|
||||
|
||||
ruby := video.direct3d video.wgl video.directdraw video.gdi video.qtraster
|
||||
ruby += audio.directsound
|
||||
ruby += input.rawinput input.directinput
|
||||
|
||||
link += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
|
||||
else
|
||||
unknown_platform: help;
|
||||
endif
|
||||
|
||||
############
|
||||
### ruby ###
|
||||
############
|
||||
|
||||
rubyflags := $(if $(finstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
rubyflags += $(if $(findstring .qt,$(ruby)),$(qtinc))
|
||||
|
||||
link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
|
||||
link += $(if $(findstring video.direct3d,$(ruby)),-ld3d9)
|
||||
link += $(if $(findstring video.directdraw,$(ruby)),-lddraw)
|
||||
link += $(if $(findstring video.glx,$(ruby)),-lGL)
|
||||
link += $(if $(findstring video.wgl,$(ruby)),-lopengl32)
|
||||
link += $(if $(findstring video.xv,$(ruby)),-lXv)
|
||||
link += $(if $(findstring audio.alsa,$(ruby)),-lasound)
|
||||
link += $(if $(findstring audio.ao,$(ruby)),-lao)
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),-ldsound)
|
||||
link += $(if $(findstring audio.pulseaudio,$(ruby)),-lpulse)
|
||||
link += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple)
|
||||
link += $(if $(findstring input.directinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
link += $(if $(findstring input.rawinput,$(ruby)),-ldinput8 -ldxguid)
|
||||
|
||||
###############
|
||||
### objects ###
|
||||
###############
|
||||
|
||||
objects := libco ruby
|
||||
objects += system cartridge cheat
|
||||
objects += memory smemory cpu cpucore scpu smp smpcore ssmp dsp sdsp ppu bppu
|
||||
objects += supergameboy superfx sa1
|
||||
objects += bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st0010 st0011 st0018
|
||||
objects += msu1
|
||||
|
||||
######################
|
||||
### implicit rules ###
|
||||
######################
|
||||
|
||||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(c) $(flags) $1 -c $< -o $@, \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(cpp) $(flags) $1 -c $< -o $@ \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
%.o: $<; $(call compile)
|
||||
|
||||
all: build;
|
||||
|
||||
include $(ui)/Makefile
|
||||
objects := $(patsubst %,obj/%.o,$(objects))
|
||||
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||
|
||||
#################
|
||||
### libraries ###
|
||||
#################
|
||||
|
||||
obj/ruby.o: lib/ruby/ruby.cpp $(call rwildcard,lib/ruby/*)
|
||||
$(call compile,$(rubydef) $(rubyflags))
|
||||
obj/libco.o: lib/libco/libco.c lib/libco/*
|
||||
|
||||
#################
|
||||
### utilities ###
|
||||
#################
|
||||
|
||||
obj/cartridge.o: cartridge/cartridge.cpp cartridge/*
|
||||
obj/cheat.o : cheat/cheat.cpp cheat/*
|
||||
|
||||
##############
|
||||
### memory ###
|
||||
##############
|
||||
|
||||
obj/memory.o : memory/memory.cpp memory/*
|
||||
obj/smemory.o: memory/smemory/smemory.cpp $(call rwildcard,memory/smemory/)
|
||||
|
||||
###########
|
||||
### cpu ###
|
||||
###########
|
||||
|
||||
obj/cpu.o : cpu/cpu.cpp cpu/*
|
||||
obj/cpucore.o: cpu/core/core.cpp $(call rwildcard,cpu/core/)
|
||||
obj/scpu.o : cpu/scpu/scpu.cpp $(call rwildcard,cpu/scpu/)
|
||||
|
||||
###########
|
||||
### smp ###
|
||||
###########
|
||||
|
||||
obj/smp.o : smp/smp.cpp smp/*
|
||||
obj/smpcore.o: smp/core/core.cpp $(call rwildcard,smp/core/)
|
||||
obj/ssmp.o : smp/ssmp/ssmp.cpp $(call rwildcard,smp/ssmp/)
|
||||
|
||||
###########
|
||||
### dsp ###
|
||||
###########
|
||||
|
||||
obj/dsp.o : dsp/dsp.cpp dsp/*
|
||||
obj/adsp.o: dsp/adsp/adsp.cpp dsp/adsp/*
|
||||
obj/sdsp.o: dsp/sdsp/sdsp.cpp dsp/sdsp/*
|
||||
|
||||
###########
|
||||
### ppu ###
|
||||
###########
|
||||
|
||||
obj/ppu.o : ppu/ppu.cpp ppu/*
|
||||
obj/bppu.o: ppu/bppu/bppu.cpp $(call rwildcard,ppu/bppu/)
|
||||
|
||||
##############
|
||||
### system ###
|
||||
##############
|
||||
|
||||
obj/system.o: system/system.cpp $(call rwildcard,system/)
|
||||
|
||||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
|
||||
obj/supergameboy.o: chip/supergameboy/supergameboy.cpp $(call rwildcard,chip/supergameboy/)
|
||||
obj/superfx.o : chip/superfx/superfx.cpp $(call rwildcard,chip/superfx/)
|
||||
obj/sa1.o : chip/sa1/sa1.cpp $(call rwildcard,chip/sa1/)
|
||||
obj/bsx.o : chip/bsx/bsx.cpp chip/bsx/*
|
||||
obj/srtc.o : chip/srtc/srtc.cpp chip/srtc/*
|
||||
obj/sdd1.o : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
obj/spc7110.o : chip/spc7110/spc7110.cpp chip/spc7110/*
|
||||
obj/cx4.o : chip/cx4/cx4.cpp chip/cx4/*
|
||||
obj/dsp1.o : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
obj/dsp2.o : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
obj/dsp3.o : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||
obj/dsp4.o : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||
obj/obc1.o : chip/obc1/obc1.cpp chip/obc1/*
|
||||
obj/st0010.o : chip/st0010/st0010.cpp chip/st0010/*
|
||||
obj/st0011.o : chip/st0011/st0011.cpp chip/st0011/*
|
||||
obj/st0018.o : chip/st0018/st0018.cpp chip/st0018/*
|
||||
obj/msu1.o : chip/msu1/msu1.cpp chip/msu1/*
|
||||
|
||||
###############
|
||||
### targets ###
|
||||
###############
|
||||
|
||||
build: ui_build $(objects)
|
||||
ifeq ($(platform),osx)
|
||||
test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS
|
||||
$(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link))
|
||||
else
|
||||
$(strip $(cpp) -o ../bsnes $(objects) $(link))
|
||||
endif
|
||||
|
||||
install:
|
||||
install -D -m 755 ../bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
||||
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
|
||||
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
|
||||
|
||||
clean: ui_clean
|
||||
-@$(call delete,obj/*.o)
|
||||
-@$(call delete,*.res)
|
||||
-@$(call delete,*.pgd)
|
||||
-@$(call delete,*.pgc)
|
||||
-@$(call delete,*.ilk)
|
||||
-@$(call delete,*.pdb)
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
help:
|
||||
@echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]"
|
||||
@echo ""
|
||||
@echo "Supported platforms:"
|
||||
@echo " x - Linux / BSD (x86, x86-64)"
|
||||
@echo " win - Windows (x86, x86-64)"
|
||||
@echo ""
|
||||
@echo "Supported compilers:"
|
||||
@echo " gcc - GCC compiler"
|
||||
@echo " mingw32-gcc - MinGW compiler"
|
||||
@echo " i586-mingw32-gcc - MinGW cross compiler"
|
||||
@echo ""
|
||||
@echo "Example: $(MAKE) platform=x compiler=gcc"
|
||||
@echo ""
|
@@ -1,47 +0,0 @@
|
||||
static const char bsnesVersion[] = "061";
|
||||
static const char bsnesTitle[] = "bsnes";
|
||||
static const unsigned bsnesSerializerVersion = 5;
|
||||
|
||||
//S-DSP can be encapsulated into a state machine using #define magic
|
||||
//this avoids ~2.048m co_switch() calls per second (~5% speedup)
|
||||
#define DSP_STATE_MACHINE
|
||||
|
||||
//game genie + pro action replay code support (~2% speed hit)
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
//enable debugging extensions (~15% speed hit)
|
||||
//#define DEBUGGER
|
||||
|
||||
#include <libco/libco.h>
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/any.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/dl.hpp>
|
||||
#include <nall/endian.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/moduloarray.hpp>
|
||||
#include <nall/platform.hpp>
|
||||
#include <nall/priorityqueue.hpp>
|
||||
#include <nall/property.hpp>
|
||||
#include <nall/serializer.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
using namespace nall;
|
||||
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
#include "interface.hpp"
|
@@ -1,655 +0,0 @@
|
||||
#ifdef CARTRIDGE_CPP
|
||||
|
||||
void Cartridge::parse_xml(const lstring &list) {
|
||||
parse_xml_cartridge(list[0]);
|
||||
|
||||
if(mode == Mode::BsxSlotted) {
|
||||
parse_xml_bsx(list[1]);
|
||||
} else if(mode == Mode::Bsx) {
|
||||
parse_xml_bsx(list[1]);
|
||||
} else if(mode == Mode::SufamiTurbo) {
|
||||
parse_xml_sufami_turbo(list[1], 0);
|
||||
parse_xml_sufami_turbo(list[2], 1);
|
||||
} else if(mode == Mode::SuperGameBoy) {
|
||||
parse_xml_gameboy(list[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_cartridge(const char *data) {
|
||||
xml_element *document = xml_parse(data);
|
||||
if(document == 0) return;
|
||||
|
||||
foreach(head, document->element) {
|
||||
if(head->name == "cartridge") {
|
||||
foreach(attr, head->attribute) {
|
||||
if(attr->name == "region") {
|
||||
if(attr->content == "NTSC") region = Region::NTSC;
|
||||
if(attr->content == "PAL") region = Region::PAL;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(node, head->element) {
|
||||
if(node->name == "rom") xml_parse_rom(node);
|
||||
if(node->name == "ram") xml_parse_ram(node);
|
||||
if(node->name == "superfx") xml_parse_superfx(node);
|
||||
if(node->name == "sa1") xml_parse_sa1(node);
|
||||
if(node->name == "bsx") xml_parse_bsx(node);
|
||||
if(node->name == "sufamiturbo") xml_parse_sufamiturbo(node);
|
||||
if(node->name == "supergameboy") xml_parse_supergameboy(node);
|
||||
if(node->name == "srtc") xml_parse_srtc(node);
|
||||
if(node->name == "sdd1") xml_parse_sdd1(node);
|
||||
if(node->name == "spc7110") xml_parse_spc7110(node);
|
||||
if(node->name == "cx4") xml_parse_cx4(node);
|
||||
if(node->name == "necdsp") xml_parse_necdsp(node);
|
||||
if(node->name == "obc1") xml_parse_obc1(node);
|
||||
if(node->name == "setadsp") xml_parse_setadsp(node);
|
||||
if(node->name == "setarisc") xml_parse_setarisc(node);
|
||||
if(node->name == "msu1") xml_parse_msu1(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_bsx(const char *data) {
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_sufami_turbo(const char *data, bool slot) {
|
||||
}
|
||||
|
||||
void Cartridge::parse_xml_gameboy(const char *data) {
|
||||
xml_element *document = xml_parse(data);
|
||||
if(document == 0) return;
|
||||
|
||||
foreach(head, document->element) {
|
||||
if(head->name == "cartridge") {
|
||||
foreach(attr, head->attribute) {
|
||||
if(attr->name == "rtc") {
|
||||
supergameboy_rtc_size = (attr->content == "true") ? 4 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(leaf, head->element) {
|
||||
if(leaf->name == "ram") {
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "size") {
|
||||
supergameboy_ram_size = strhex(attr->content);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete document;
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_rom(xml_element *root) {
|
||||
foreach(leaf, root->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cartrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_ram(xml_element *root) {
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, root->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cartram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_superfx(xml_element *root) {
|
||||
has_superfx = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "rom") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::fxrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "ram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::fxram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(superfx);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sa1(xml_element *root) {
|
||||
has_sa1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "rom") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::vsprom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "iram") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cpuiram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "bwram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::cc1bwram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(sa1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_bsx(xml_element *root) {
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "slot") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(memory::bsxflash);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(bsxcart);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sufamiturbo(xml_element *root) {
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "slot") {
|
||||
bool slotid = 0;
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "id") {
|
||||
if(attr->content == "A") slotid = 0;
|
||||
if(attr->content == "B") slotid = 1;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(slot, node->element) {
|
||||
if(slot->name == "rom") {
|
||||
foreach(leaf, slot->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(slotid == 0 ? memory::stArom : memory::stBrom);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
if(m.memory->size() > 0) mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(slot->name == "ram") {
|
||||
foreach(leaf, slot->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(slotid == 0 ? memory::stAram : memory::stBram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
if(m.memory->size() > 0) mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_supergameboy(xml_element *root) {
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "revision") {
|
||||
if(attr->content == "1") supergameboy_version = SuperGameBoyVersion::Version1;
|
||||
if(attr->content == "2") supergameboy_version = SuperGameBoyVersion::Version2;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m((Memory&)supergameboy);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_srtc(xml_element *root) {
|
||||
has_srtc = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(srtc);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_sdd1(xml_element *root) {
|
||||
has_sdd1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m((Memory&)sdd1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m((MMIO&)sdd1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_spc7110(xml_element *root) {
|
||||
has_spc7110 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "dcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110dcu);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mcu") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110mcu);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "offset") spc7110_data_rom_offset = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "ram") {
|
||||
foreach(attr, node->attribute) {
|
||||
if(attr->name == "size") ram_size = strhex(attr->content);
|
||||
}
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110ram);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
if(attr->name == "mode") xml_parse_mode(m, attr->content);
|
||||
if(attr->name == "offset") m.offset = strhex(attr->content);
|
||||
if(attr->name == "size") m.size = strhex(attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "rtc") {
|
||||
has_spc7110rtc = true;
|
||||
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(spc7110);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_cx4(xml_element *root) {
|
||||
has_cx4 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(cx4);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_necdsp(xml_element *root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "DSP-1" || attr->content == "DSP-1A" || attr->content == "DSP-1B") {
|
||||
program = 1;
|
||||
has_dsp1 = true;
|
||||
} else if(attr->content == "DSP-2") {
|
||||
program = 2;
|
||||
has_dsp2 = true;
|
||||
} else if(attr->content == "DSP-3") {
|
||||
program = 3;
|
||||
has_dsp3 = true;
|
||||
} else if(attr->content == "DSP-4") {
|
||||
program = 4;
|
||||
has_dsp4 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Memory *dr[5] = { 0, &dsp1dr, &dsp2, &dsp3, &dsp4 };
|
||||
Memory *sr[5] = { 0, &dsp1sr, &dsp2, &dsp3, &dsp4 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "dr" && dr[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*dr[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
} else if(node->name == "sr" && sr[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*sr[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_obc1(xml_element *root) {
|
||||
has_obc1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(obc1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_setadsp(xml_element *root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "ST-0010") {
|
||||
program = 1;
|
||||
has_st0010 = true;
|
||||
} else if(attr->content == "ST-0011") {
|
||||
program = 2;
|
||||
has_st0011 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Memory *map[3] = { 0, &st0010, 0 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio" && map[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*map[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_setarisc(xml_element *root) {
|
||||
unsigned program = 0;
|
||||
|
||||
foreach(attr, root->attribute) {
|
||||
if(attr->name == "program") {
|
||||
if(attr->content == "ST-0018") {
|
||||
program = 1;
|
||||
has_st0018 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MMIO *map[2] = { 0, &st0018 };
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio" && map[program]) {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(*map[program]);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_msu1(xml_element *root) {
|
||||
has_msu1 = true;
|
||||
|
||||
foreach(node, root->element) {
|
||||
if(node->name == "mmio") {
|
||||
foreach(leaf, node->element) {
|
||||
if(leaf->name == "map") {
|
||||
Mapping m(msu1);
|
||||
foreach(attr, leaf->attribute) {
|
||||
if(attr->name == "address") xml_parse_address(m, attr->content);
|
||||
}
|
||||
mapping.add(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_address(Mapping &m, const string &data) {
|
||||
lstring part;
|
||||
part.split(":", data);
|
||||
if(part.size() != 2) return;
|
||||
|
||||
lstring subpart;
|
||||
subpart.split("-", part[0]);
|
||||
if(subpart.size() == 1) {
|
||||
m.banklo = strhex(subpart[0]);
|
||||
m.bankhi = m.banklo;
|
||||
} else if(subpart.size() == 2) {
|
||||
m.banklo = strhex(subpart[0]);
|
||||
m.bankhi = strhex(subpart[1]);
|
||||
}
|
||||
|
||||
subpart.split("-", part[1]);
|
||||
if(subpart.size() == 1) {
|
||||
m.addrlo = strhex(subpart[0]);
|
||||
m.addrhi = m.addrlo;
|
||||
} else if(subpart.size() == 2) {
|
||||
m.addrlo = strhex(subpart[0]);
|
||||
m.addrhi = strhex(subpart[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::xml_parse_mode(Mapping &m, const string& data) {
|
||||
if(data == "direct") m.mode = Bus::MapMode::Direct;
|
||||
else if(data == "linear") m.mode = Bus::MapMode::Linear;
|
||||
else if(data == "shadow") m.mode = Bus::MapMode::Shadow;
|
||||
}
|
||||
|
||||
Cartridge::Mapping::Mapping() {
|
||||
memory = 0;
|
||||
mmio = 0;
|
||||
mode = Bus::MapMode::Direct;
|
||||
banklo = bankhi = addrlo = addrhi = offset = size = 0;
|
||||
}
|
||||
|
||||
Cartridge::Mapping::Mapping(Memory &memory_) {
|
||||
memory = &memory_;
|
||||
mmio = 0;
|
||||
mode = Bus::MapMode::Direct;
|
||||
banklo = bankhi = addrlo = addrhi = offset = size = 0;
|
||||
}
|
||||
|
||||
Cartridge::Mapping::Mapping(MMIO &mmio_) {
|
||||
memory = 0;
|
||||
mmio = &mmio_;
|
||||
mode = Bus::MapMode::Direct;
|
||||
banklo = bankhi = addrlo = addrhi = offset = size = 0;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,17 +0,0 @@
|
||||
#include "supergameboy/supergameboy.hpp"
|
||||
#include "superfx/superfx.hpp"
|
||||
#include "sa1/sa1.hpp"
|
||||
#include "bsx/bsx.hpp"
|
||||
#include "srtc/srtc.hpp"
|
||||
#include "sdd1/sdd1.hpp"
|
||||
#include "spc7110/spc7110.hpp"
|
||||
#include "cx4/cx4.hpp"
|
||||
#include "dsp1/dsp1.hpp"
|
||||
#include "dsp2/dsp2.hpp"
|
||||
#include "dsp3/dsp3.hpp"
|
||||
#include "dsp4/dsp4.hpp"
|
||||
#include "obc1/obc1.hpp"
|
||||
#include "st0010/st0010.hpp"
|
||||
#include "st0011/st0011.hpp"
|
||||
#include "st0018/st0018.hpp"
|
||||
#include "msu1/msu1.hpp"
|
@@ -1,29 +0,0 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define CPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "cpu-debugger.cpp"
|
||||
#endif
|
||||
|
||||
void CPU::power() {
|
||||
cpu_version = config.cpu.version;
|
||||
}
|
||||
|
||||
void CPU::reset() {
|
||||
PPUcounter::reset();
|
||||
}
|
||||
|
||||
void CPU::serialize(serializer &s) {
|
||||
PPUcounter::serialize(s);
|
||||
s.integer(cpu_version);
|
||||
}
|
||||
|
||||
CPU::CPU() {
|
||||
}
|
||||
|
||||
CPU::~CPU() {
|
||||
}
|
||||
|
||||
};
|
@@ -1,71 +0,0 @@
|
||||
struct {
|
||||
//$420b
|
||||
bool dma_enabled;
|
||||
|
||||
//$420c
|
||||
bool hdma_enabled;
|
||||
|
||||
//$43x0
|
||||
uint8 dmap;
|
||||
bool direction;
|
||||
bool hdma_indirect;
|
||||
bool reversexfer;
|
||||
bool fixedxfer;
|
||||
uint8 xfermode;
|
||||
|
||||
//$43x1
|
||||
uint8 destaddr;
|
||||
|
||||
//$43x2-$43x3
|
||||
uint16 srcaddr;
|
||||
|
||||
//$43x4
|
||||
uint8 srcbank;
|
||||
|
||||
//$43x5-$43x6
|
||||
union {
|
||||
uint16 xfersize;
|
||||
uint16 hdma_iaddr;
|
||||
};
|
||||
|
||||
//$43x7
|
||||
uint8 hdma_ibank;
|
||||
|
||||
//$43x8-$43x9
|
||||
uint16 hdma_addr;
|
||||
|
||||
//$43xa
|
||||
uint8 hdma_line_counter;
|
||||
|
||||
//$43xb/$43xf
|
||||
uint8 unknown;
|
||||
|
||||
//internal variables
|
||||
bool hdma_completed;
|
||||
bool hdma_do_transfer;
|
||||
} channel[8];
|
||||
|
||||
void dma_add_clocks(unsigned clocks);
|
||||
bool dma_addr_valid(uint32 abus);
|
||||
uint8 dma_read(uint32 abus);
|
||||
void dma_transfer(bool direction, uint8 bbus, uint32 abus);
|
||||
|
||||
uint8 dma_bbus(uint8 i, uint8 index);
|
||||
uint32 dma_addr(uint8 i);
|
||||
uint32 hdma_addr(uint8 i);
|
||||
uint32 hdma_iaddr(uint8 i);
|
||||
|
||||
uint8 dma_enabled_channels();
|
||||
void dma_run();
|
||||
|
||||
bool hdma_active(uint8 i);
|
||||
bool hdma_active_after(uint8 i);
|
||||
uint8 hdma_enabled_channels();
|
||||
uint8 hdma_active_channels();
|
||||
void hdma_update(uint8 i);
|
||||
void hdma_run();
|
||||
void hdma_init_reset();
|
||||
void hdma_init();
|
||||
|
||||
void dma_power();
|
||||
void dma_reset();
|
@@ -1,71 +0,0 @@
|
||||
void mmio_power();
|
||||
void mmio_reset();
|
||||
uint8 mmio_read(unsigned addr);
|
||||
void mmio_write(unsigned addr, uint8 data);
|
||||
|
||||
uint8 pio();
|
||||
bool joylatch();
|
||||
|
||||
uint8 mmio_r2180();
|
||||
uint8 mmio_r4016();
|
||||
uint8 mmio_r4017();
|
||||
uint8 mmio_r4210();
|
||||
uint8 mmio_r4211();
|
||||
uint8 mmio_r4212();
|
||||
uint8 mmio_r4213();
|
||||
uint8 mmio_r4214();
|
||||
uint8 mmio_r4215();
|
||||
uint8 mmio_r4216();
|
||||
uint8 mmio_r4217();
|
||||
uint8 mmio_r4218();
|
||||
uint8 mmio_r4219();
|
||||
uint8 mmio_r421a();
|
||||
uint8 mmio_r421b();
|
||||
uint8 mmio_r421c();
|
||||
uint8 mmio_r421d();
|
||||
uint8 mmio_r421e();
|
||||
uint8 mmio_r421f();
|
||||
uint8 mmio_r43x0(uint8 i);
|
||||
uint8 mmio_r43x1(uint8 i);
|
||||
uint8 mmio_r43x2(uint8 i);
|
||||
uint8 mmio_r43x3(uint8 i);
|
||||
uint8 mmio_r43x4(uint8 i);
|
||||
uint8 mmio_r43x5(uint8 i);
|
||||
uint8 mmio_r43x6(uint8 i);
|
||||
uint8 mmio_r43x7(uint8 i);
|
||||
uint8 mmio_r43x8(uint8 i);
|
||||
uint8 mmio_r43x9(uint8 i);
|
||||
uint8 mmio_r43xa(uint8 i);
|
||||
uint8 mmio_r43xb(uint8 i);
|
||||
|
||||
void mmio_w2180(uint8 data);
|
||||
void mmio_w2181(uint8 data);
|
||||
void mmio_w2182(uint8 data);
|
||||
void mmio_w2183(uint8 data);
|
||||
void mmio_w4016(uint8 data);
|
||||
void mmio_w4200(uint8 data);
|
||||
void mmio_w4201(uint8 data);
|
||||
void mmio_w4202(uint8 data);
|
||||
void mmio_w4203(uint8 data);
|
||||
void mmio_w4204(uint8 data);
|
||||
void mmio_w4205(uint8 data);
|
||||
void mmio_w4206(uint8 data);
|
||||
void mmio_w4207(uint8 data);
|
||||
void mmio_w4208(uint8 data);
|
||||
void mmio_w4209(uint8 data);
|
||||
void mmio_w420a(uint8 data);
|
||||
void mmio_w420b(uint8 data);
|
||||
void mmio_w420c(uint8 data);
|
||||
void mmio_w420d(uint8 data);
|
||||
void mmio_w43x0(uint8 i, uint8 data);
|
||||
void mmio_w43x1(uint8 i, uint8 data);
|
||||
void mmio_w43x2(uint8 i, uint8 data);
|
||||
void mmio_w43x3(uint8 i, uint8 data);
|
||||
void mmio_w43x4(uint8 i, uint8 data);
|
||||
void mmio_w43x5(uint8 i, uint8 data);
|
||||
void mmio_w43x6(uint8 i, uint8 data);
|
||||
void mmio_w43x7(uint8 i, uint8 data);
|
||||
void mmio_w43x8(uint8 i, uint8 data);
|
||||
void mmio_w43x9(uint8 i, uint8 data);
|
||||
void mmio_w43xa(uint8 i, uint8 data);
|
||||
void mmio_w43xb(uint8 i, uint8 data);
|
@@ -1,35 +0,0 @@
|
||||
#ifdef SCPU_CPP
|
||||
|
||||
void sCPU::queue_event(unsigned id) {
|
||||
switch(id) {
|
||||
//interrupts triggered during (H)DMA do not trigger immediately after
|
||||
case EventIrqLockRelease: {
|
||||
status.irq_lock = false;
|
||||
} break;
|
||||
|
||||
//ALU multiplication / division results are not immediately calculated;
|
||||
//the exact formula for the calculations are unknown, but this lock at least
|
||||
//allows emulation to avoid returning to fully computed results too soon.
|
||||
case EventAluLockRelease: {
|
||||
status.alu_lock = false;
|
||||
} break;
|
||||
|
||||
//S-CPU WRAM consists of two 64kbyte DRAM chips, which must be refreshed
|
||||
//once per scanline to avoid memory decay.
|
||||
case EventDramRefresh: {
|
||||
add_clocks(40);
|
||||
} break;
|
||||
|
||||
//HDMA init routine; occurs once per frame
|
||||
case EventHdmaInit: {
|
||||
cycle_edge_state |= EventFlagHdmaInit;
|
||||
} break;
|
||||
|
||||
//HDMA run routine; occurs once per scanline
|
||||
case EventHdmaRun: {
|
||||
cycle_edge_state |= EventFlagHdmaRun;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,40 +0,0 @@
|
||||
enum {
|
||||
EventNone,
|
||||
EventIrqLockRelease,
|
||||
EventAluLockRelease,
|
||||
EventDramRefresh,
|
||||
EventHdmaInit,
|
||||
EventHdmaRun,
|
||||
|
||||
//cycle edge
|
||||
EventFlagHdmaInit = 1 << 0,
|
||||
EventFlagHdmaRun = 1 << 1,
|
||||
};
|
||||
unsigned cycle_edge_state;
|
||||
|
||||
//timing.cpp
|
||||
unsigned dma_counter();
|
||||
|
||||
void add_clocks(unsigned clocks);
|
||||
void scanline();
|
||||
|
||||
alwaysinline void cycle_edge();
|
||||
alwaysinline void last_cycle();
|
||||
|
||||
void timing_power();
|
||||
void timing_reset();
|
||||
|
||||
//irq.cpp
|
||||
alwaysinline void poll_interrupts();
|
||||
void nmitimen_update(uint8 data);
|
||||
bool rdnmi();
|
||||
bool timeup();
|
||||
|
||||
alwaysinline bool nmi_test();
|
||||
alwaysinline bool irq_test();
|
||||
|
||||
//joypad.cpp
|
||||
void run_auto_joypad_poll();
|
||||
|
||||
//event.cpp
|
||||
void queue_event(unsigned); //priorityqueue callback function
|
@@ -1,174 +0,0 @@
|
||||
class aDSP : public DSP {
|
||||
private:
|
||||
uint8 dspram[128];
|
||||
uint8 *spcram;
|
||||
|
||||
uint32 dsp_counter;
|
||||
|
||||
enum { BRR_END = 1, BRR_LOOP = 2 };
|
||||
|
||||
uint8 readb (uint16 addr);
|
||||
uint16 readw (uint16 addr);
|
||||
void writeb(uint16 addr, uint8 data);
|
||||
void writew(uint16 addr, uint16 data);
|
||||
|
||||
public:
|
||||
static const uint16 rate_table[32];
|
||||
static const int16 gaussian_table[512];
|
||||
|
||||
enum EnvelopeStates {
|
||||
ATTACK,
|
||||
DECAY,
|
||||
SUSTAIN,
|
||||
RELEASE,
|
||||
SILENCE
|
||||
};
|
||||
|
||||
enum EnvelopeModes {
|
||||
DIRECT,
|
||||
LINEAR_DEC,
|
||||
EXP_DEC,
|
||||
LINEAR_INC,
|
||||
BENT_INC,
|
||||
|
||||
FAST_ATTACK,
|
||||
RELEASE_DEC
|
||||
};
|
||||
|
||||
private:
|
||||
struct Status {
|
||||
//$0c,$1c
|
||||
int8 MVOLL, MVOLR;
|
||||
//$2c,$3c
|
||||
int8 EVOLL, EVOLR;
|
||||
//$4c,$5c
|
||||
uint8 KON, KOFF;
|
||||
//$6c
|
||||
uint8 FLG;
|
||||
//$7c
|
||||
uint8 ENDX;
|
||||
//$0d
|
||||
int8 EFB;
|
||||
//$2d,$3d,$4d
|
||||
uint8 PMON, NON, EON;
|
||||
//$5d
|
||||
uint8 DIR;
|
||||
//$6d,$7d
|
||||
uint8 ESA, EDL;
|
||||
|
||||
//$xf
|
||||
int8 FIR[8];
|
||||
|
||||
//internal variables
|
||||
uint8 kon, esa;
|
||||
|
||||
int16 noise_ctr, noise_rate;
|
||||
uint16 noise_sample;
|
||||
|
||||
uint16 echo_index, echo_length;
|
||||
int16 fir_buffer[2][8];
|
||||
uint8 fir_buffer_index;
|
||||
|
||||
//functions
|
||||
bool soft_reset() { return !!(FLG & 0x80); }
|
||||
bool mute() { return !!(FLG & 0x40); }
|
||||
bool echo_write() { return !(FLG & 0x20); }
|
||||
} status;
|
||||
|
||||
struct Voice {
|
||||
//$x0-$x1
|
||||
int8 VOLL, VOLR;
|
||||
//$x2-$x3
|
||||
int16 PITCH;
|
||||
//$x4
|
||||
uint8 SRCN;
|
||||
//$x5-$x7
|
||||
uint8 ADSR1, ADSR2, GAIN;
|
||||
//$x8-$x9
|
||||
uint8 ENVX, OUTX;
|
||||
|
||||
//internal variables
|
||||
int16 pitch_ctr;
|
||||
|
||||
int8 brr_index;
|
||||
uint16 brr_ptr;
|
||||
uint8 brr_header;
|
||||
bool brr_looped;
|
||||
|
||||
int16 brr_data[4];
|
||||
uint8 brr_data_index;
|
||||
|
||||
int16 envx;
|
||||
uint16 env_ctr, env_rate, env_sustain;
|
||||
enum EnvelopeStates env_state;
|
||||
enum EnvelopeModes env_mode;
|
||||
|
||||
int16 outx;
|
||||
|
||||
//functions
|
||||
int16 pitch_rate() { return PITCH & 0x3fff; }
|
||||
|
||||
uint8 brr_header_shift() { return brr_header >> 4; }
|
||||
uint8 brr_header_filter() { return (brr_header >> 2) & 3; }
|
||||
uint8 brr_header_flags() { return brr_header & 3; }
|
||||
|
||||
bool ADSR_enabled() { return !!(ADSR1 & 0x80); }
|
||||
uint8 ADSR_decay() { return (ADSR1 >> 4) & 7; }
|
||||
uint8 ADSR_attack() { return ADSR1 & 15; }
|
||||
uint8 ADSR_sus_level() { return ADSR2 >> 5; }
|
||||
uint8 ADSR_sus_rate() { return ADSR2 & 31; }
|
||||
|
||||
void AdjustEnvelope() {
|
||||
if(env_state == SILENCE) {
|
||||
env_mode = DIRECT;
|
||||
env_rate = 0;
|
||||
envx = 0;
|
||||
} else if(env_state == RELEASE) {
|
||||
env_mode = RELEASE_DEC;
|
||||
env_rate = 0x7800;
|
||||
} else if(ADSR_enabled()) {
|
||||
switch(env_state) {
|
||||
case ATTACK:
|
||||
env_rate = rate_table[(ADSR_attack() << 1) + 1];
|
||||
env_mode = (env_rate == 0x7800) ? FAST_ATTACK : LINEAR_INC;
|
||||
break;
|
||||
case DECAY:
|
||||
env_rate = rate_table[(ADSR_decay() << 1) + 0x10];
|
||||
env_mode = EXP_DEC;
|
||||
break;
|
||||
case SUSTAIN:
|
||||
env_rate = rate_table[ADSR_sus_rate()];
|
||||
env_mode = (env_rate == 0) ? DIRECT : EXP_DEC;
|
||||
break;
|
||||
}
|
||||
} else if(GAIN & 0x80) {
|
||||
switch(GAIN & 0x60) {
|
||||
case 0x00: env_mode = LINEAR_DEC; break;
|
||||
case 0x20: env_mode = EXP_DEC; break;
|
||||
case 0x40: env_mode = LINEAR_INC; break;
|
||||
case 0x60: env_mode = BENT_INC; break;
|
||||
}
|
||||
env_rate = rate_table[GAIN & 0x1f];
|
||||
} else {
|
||||
env_mode = DIRECT;
|
||||
env_rate = 0;
|
||||
envx = (GAIN & 0x7f) << 4;
|
||||
}
|
||||
}
|
||||
} voice[8];
|
||||
|
||||
public:
|
||||
void enter();
|
||||
void run();
|
||||
|
||||
uint8 read (uint8 addr);
|
||||
void write(uint8 addr, uint8 data);
|
||||
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
aDSP();
|
||||
~aDSP();
|
||||
};
|
||||
|
||||
extern aDSP dsp;
|
@@ -1,10 +0,0 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define DSP_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "dsp-debugger.cpp"
|
||||
#endif
|
||||
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
#if defined(DEBUGGER)
|
||||
#include "dsp-debugger.hpp"
|
||||
#endif
|
||||
|
||||
class DSP {
|
||||
public:
|
||||
virtual void enter() = 0;
|
||||
|
||||
virtual uint8 read(uint8 addr) = 0;
|
||||
virtual void write(uint8 addr, uint8 data) = 0;
|
||||
|
||||
virtual void power() = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
virtual void serialize(serializer&) {}
|
||||
};
|
@@ -1,44 +0,0 @@
|
||||
#ifdef DEBUGGER
|
||||
#define debugvirtual virtual
|
||||
#else
|
||||
#define debugvirtual
|
||||
#endif
|
||||
|
||||
namespace SNES {
|
||||
struct ChipDebugger {
|
||||
virtual bool property(unsigned id, string &name, string &value) = 0;
|
||||
};
|
||||
|
||||
#include "memory/memory.hpp"
|
||||
#include "memory/smemory/smemory.hpp"
|
||||
|
||||
#include "ppu/ppu.hpp"
|
||||
#include "ppu/bppu/bppu.hpp"
|
||||
|
||||
#include "cpu/cpu.hpp"
|
||||
#include "cpu/core/core.hpp"
|
||||
#include "cpu/scpu/scpu.hpp"
|
||||
|
||||
#include "smp/smp.hpp"
|
||||
#include "smp/core/core.hpp"
|
||||
#include "smp/ssmp/ssmp.hpp"
|
||||
|
||||
#include "dsp/dsp.hpp"
|
||||
#include "dsp/sdsp/sdsp.hpp"
|
||||
|
||||
#include "system/system.hpp"
|
||||
#include "chip/chip.hpp"
|
||||
#include "cartridge/cartridge.hpp"
|
||||
#include "cheat/cheat.hpp"
|
||||
|
||||
#include "memory/memory-inline.hpp"
|
||||
#include "ppu/ppu-inline.hpp"
|
||||
#include "cheat/cheat-inline.hpp"
|
||||
}
|
||||
|
||||
namespace nall {
|
||||
template<> struct has_size<SNES::MappedRAM> { enum { value = true }; };
|
||||
template<> struct has_size<SNES::StaticRAM> { enum { value = true }; };
|
||||
}
|
||||
|
||||
#undef debugvirtual
|
@@ -1,15 +0,0 @@
|
||||
#ifndef NALL_CONCEPT_HPP
|
||||
#define NALL_CONCEPT_HPP
|
||||
|
||||
namespace nall {
|
||||
//unsigned count() const;
|
||||
template<typename T> struct has_count { enum { value = false }; };
|
||||
|
||||
//unsigned length() const;
|
||||
template<typename T> struct has_length { enum { value = false }; };
|
||||
|
||||
//unsigned size() const;
|
||||
template<typename T> struct has_size { enum { value = false }; };
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,31 +0,0 @@
|
||||
#ifndef NALL_FOREACH_HPP
|
||||
#define NALL_FOREACH_HPP
|
||||
|
||||
#undef foreach
|
||||
#define foreach(iter, object) \
|
||||
for(unsigned foreach_counter = 0, foreach_limit = foreach_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(auto &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
|
||||
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
|
||||
return object.count();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_length<T>>::type = 0) {
|
||||
return object.length();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_size<T>>::type = 0) {
|
||||
return object.size();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename remove_extent<T>::type);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,190 +0,0 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//prologue
|
||||
|
||||
#define TN typename
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
}
|
||||
|
||||
//parameters = 0
|
||||
|
||||
#define cat(n) n
|
||||
#define TL typename R
|
||||
#define PL
|
||||
#define CL
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 1
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1
|
||||
#define PL P1 p1
|
||||
#define CL p1
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 2
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2
|
||||
#define PL P1 p1, P2 p2
|
||||
#define CL p1, p2
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 3
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3
|
||||
#define PL P1 p1, P2 p2, P3 p3
|
||||
#define CL p1, p2, p3
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 4
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4
|
||||
#define CL p1, p2, p3, p4
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 5
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5
|
||||
#define CL p1, p2, p3, p4, p5
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 6
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6
|
||||
#define CL p1, p2, p3, p4, p5, p6
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 7
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 8
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7, TN P8
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7, p8
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//epilogue
|
||||
|
||||
#undef TN
|
||||
#define NALL_FUNCTION_T
|
||||
|
||||
#elif !defined(NALL_FUNCTION_T)
|
||||
|
||||
//function implementation template class
|
||||
|
||||
namespace nall {
|
||||
template<TL>
|
||||
class function<R (PL)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(PL) {} };
|
||||
struct base2 { virtual void func2(PL) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
|
||||
struct data_t {
|
||||
R (*fn_call)(const data_t& cat(PL));
|
||||
union {
|
||||
R (*fn_global)(PL);
|
||||
struct {
|
||||
R (derived::*fn_member)(PL);
|
||||
void *object;
|
||||
};
|
||||
};
|
||||
} data;
|
||||
|
||||
static R fn_call_global(const data_t &d cat(PL)) {
|
||||
return d.fn_global(CL);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R fn_call_member(const data_t &d cat(PL)) {
|
||||
return (((C*)d.object)->*((R (C::*&)(PL))d.fn_member))(CL);
|
||||
}
|
||||
|
||||
public:
|
||||
R operator()(PL) const { return data.fn_call(data cat(CL)); }
|
||||
operator bool() const { return data.fn_call; }
|
||||
|
||||
function() { data.fn_call = 0; }
|
||||
|
||||
function(void *fn) {
|
||||
data.fn_call = fn ? &fn_call_global : 0;
|
||||
data.fn_global = (R (*)(PL))fn;
|
||||
}
|
||||
|
||||
function(R (*fn)(PL)) {
|
||||
data.fn_call = &fn_call_global;
|
||||
data.fn_global = fn;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL), C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL) const, C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = (R (C::*&)(PL))fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
function& operator=(void *fn) { return operator=(function(fn)); }
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); }
|
||||
};
|
||||
|
||||
template<TL>
|
||||
function<R (PL)> bind(R (*fn)(PL)) {
|
||||
return function<R (PL)>(fn);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL), C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL) const, C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
}
|
||||
}
|
||||
|
||||
#undef cat
|
||||
#undef TL
|
||||
#undef PL
|
||||
#undef CL
|
||||
|
||||
#endif
|
@@ -1,126 +0,0 @@
|
||||
#ifndef NALL_STRING_BASE_HPP
|
||||
#define NALL_STRING_BASE_HPP
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/utf8.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
inline size_t strlcpy(char *dest, const char *src, size_t length);
|
||||
inline size_t strlcat(char *dest, const char *src, size_t length);
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
namespace nall {
|
||||
class string;
|
||||
template<typename T> inline string to_string(T);
|
||||
|
||||
class string {
|
||||
public:
|
||||
inline void reserve(size_t);
|
||||
inline unsigned length() const;
|
||||
|
||||
inline string& assign(const char*);
|
||||
inline string& append(const char*);
|
||||
template<typename T> inline string& operator= (T value);
|
||||
template<typename T> inline string& operator<<(T value);
|
||||
|
||||
inline operator const char*() const;
|
||||
inline char* operator()();
|
||||
inline char& operator[](int);
|
||||
|
||||
inline bool operator==(const char*) const;
|
||||
inline bool operator!=(const char*) const;
|
||||
inline bool operator< (const char*) const;
|
||||
inline bool operator<=(const char*) const;
|
||||
inline bool operator> (const char*) const;
|
||||
inline bool operator>=(const char*) const;
|
||||
|
||||
inline string();
|
||||
inline string(const char*);
|
||||
inline string(const string&);
|
||||
inline string(string&&);
|
||||
inline string& operator=(const string&);
|
||||
inline string& operator=(string&&);
|
||||
inline ~string();
|
||||
|
||||
inline bool readfile(const char*);
|
||||
inline string& replace (const char*, const char*);
|
||||
inline string& qreplace(const char*, const char*);
|
||||
|
||||
protected:
|
||||
char *data;
|
||||
size_t size;
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
public:
|
||||
inline operator QString() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
class lstring : public linear_vector<string> {
|
||||
public:
|
||||
template<typename T> inline lstring& operator<<(T value);
|
||||
|
||||
inline int find(const char*);
|
||||
inline void split (const char*, const char*, unsigned = 0);
|
||||
inline void qsplit(const char*, const char*, unsigned = 0);
|
||||
|
||||
lstring();
|
||||
lstring(std::initializer_list<string>);
|
||||
};
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args);
|
||||
template<typename... Args> inline void print(const char *s, Args... args);
|
||||
};
|
||||
|
||||
inline size_t strlcpy(nall::string &dest, const char *src, size_t length);
|
||||
inline size_t strlcat(nall::string &dest, const char *src, size_t length);
|
||||
|
||||
inline nall::string& strlower(nall::string &str);
|
||||
inline nall::string& strupper(nall::string &str);
|
||||
inline nall::string& strtr(nall::string &dest, const char *before, const char *after);
|
||||
inline nall::string& ltrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim (nall::string &str, const char *key = " ");
|
||||
inline nall::string& ltrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim_once (nall::string &str, const char *key = " ");
|
||||
|
||||
inline nall::string substr(const char *src, size_t start = 0, size_t length = 0);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strbin(uintmax_t value);
|
||||
inline size_t strdouble(char *str, double value);
|
||||
inline nall::string strdouble(double value);
|
||||
|
||||
#endif
|
@@ -1,29 +0,0 @@
|
||||
#ifndef NALL_STRING_CAST_HPP
|
||||
#define NALL_STRING_CAST_HPP
|
||||
|
||||
namespace nall {
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,60 +0,0 @@
|
||||
#ifndef NALL_FILENAME_HPP
|
||||
#define NALL_FILENAME_HPP
|
||||
|
||||
namespace nall {
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,37 +0,0 @@
|
||||
#ifndef NALL_STRING_VARIADIC_HPP
|
||||
#define NALL_STRING_VARIADIC_HPP
|
||||
|
||||
namespace nall {
|
||||
static void sprint(string &output, unsigned &offset, const char *&s) {
|
||||
while(*s) output[offset++] = *s++;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void sprint(string &output, unsigned &offset, const char *&s, T value, Args... args) {
|
||||
while(*s) {
|
||||
if(*s == '$') {
|
||||
string data = to_string<T>(value);
|
||||
unsigned i = 0;
|
||||
while(data[i]) output[offset++] = data[i++];
|
||||
sprint(output, offset, ++s, args...);
|
||||
return;
|
||||
} else {
|
||||
output[offset++] = *s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
sprint(output, offset, s, args...);
|
||||
output[offset] = 0;
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(const char *s, Args... args) {
|
||||
printf("%s", (const char*)sprint(s, args...));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,97 +0,0 @@
|
||||
#ifndef NALL_TRAITS_HPP
|
||||
#define NALL_TRAITS_HPP
|
||||
|
||||
namespace nall {
|
||||
//==
|
||||
//is
|
||||
//==
|
||||
|
||||
template<typename T> struct is_integral { enum { value = false }; };
|
||||
template<> struct is_integral<bool> { enum { value = true }; };
|
||||
template<> struct is_integral<char> { enum { value = true }; };
|
||||
template<> struct is_integral<signed char> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned char> { enum { value = true }; };
|
||||
template<> struct is_integral<wchar_t> { enum { value = true }; };
|
||||
template<> struct is_integral<short> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned short> { enum { value = true }; };
|
||||
template<> struct is_integral<long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long> { enum { value = true }; };
|
||||
template<> struct is_integral<long long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long long> { enum { value = true }; };
|
||||
template<> struct is_integral<int> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned int> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_floating_point { enum { value = false }; };
|
||||
template<> struct is_floating_point<float> { enum { value = true }; };
|
||||
template<> struct is_floating_point<double> { enum { value = true }; };
|
||||
template<> struct is_floating_point<long double> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_bool { enum { value = false }; };
|
||||
template<> struct is_bool<bool> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_void { enum { value = false }; };
|
||||
template<> struct is_void<void> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_arithmetic {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_fundamental {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value || is_void<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_compound {
|
||||
enum { value = !is_fundamental<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_array { enum { value = false }; };
|
||||
template<typename T> struct is_array<T[]> { enum { value = true }; };
|
||||
template<typename T, int N> struct is_array<T[N]> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_const { enum { value = false }; };
|
||||
template<typename T> struct is_const<const T> { enum { value = true }; };
|
||||
template<typename T> struct is_const<const T&> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_pointer { enum { value = false }; };
|
||||
template<typename T> struct is_pointer<T*> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_reference { enum { value = false }; };
|
||||
template<typename T> struct is_reference<T&> { enum { value = true }; };
|
||||
|
||||
template<typename T, typename U> struct is_same { enum { value = false }; };
|
||||
template<typename T> struct is_same<T, T> { enum { value = true }; };
|
||||
|
||||
//===
|
||||
//add
|
||||
//===
|
||||
|
||||
template<typename T> struct add_const { typedef const T type; };
|
||||
template<typename T> struct add_const<const T> { typedef const T type; };
|
||||
template<typename T> struct add_const<const T&> { typedef const T& type; };
|
||||
|
||||
template<typename T> struct add_pointer { typedef T* type; };
|
||||
template<typename T> struct add_pointer<T*> { typedef T** type; };
|
||||
|
||||
template<typename T> struct add_reference { typedef T& type; };
|
||||
template<typename T> struct add_reference<T&> { typedef T& type; };
|
||||
|
||||
//======
|
||||
//remove
|
||||
//======
|
||||
|
||||
template<typename T> struct remove_const { typedef T type; };
|
||||
template<typename T> struct remove_const<const T> { typedef T type; };
|
||||
template<typename T> struct remove_const<const T&> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_extent { typedef T type; };
|
||||
template<typename T> struct remove_extent<T[]> { typedef T type; };
|
||||
template<typename T, int N> struct remove_extent<T[N]> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,7 +0,0 @@
|
||||
rmdir /Q /S nall
|
||||
rmdir /Q /S ruby
|
||||
|
||||
mkdir nall
|
||||
mkdir ruby
|
||||
xcopy /E ..\..\..\nall nall
|
||||
xcopy /E ..\..\..\ruby ruby
|
@@ -1,10 +0,0 @@
|
||||
rm -r libco
|
||||
rm -r nall
|
||||
rm -r ruby
|
||||
|
||||
cp -r ../../../libco ./libco
|
||||
cp -r ../../../nall ./nall
|
||||
cp -r ../../../ruby ./ruby
|
||||
|
||||
rm -r libco/doc
|
||||
rm -r libco/test
|
@@ -1,56 +0,0 @@
|
||||
#include <../base.hpp>
|
||||
|
||||
#define PPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "ppu-debugger.cpp"
|
||||
#endif
|
||||
|
||||
#include "serialization.cpp"
|
||||
|
||||
void PPU::enable_renderer(bool r) { status.render_output = r; }
|
||||
bool PPU::renderer_enabled() { return status.render_output; }
|
||||
|
||||
void PPU::frame() {
|
||||
status.frame_executed = true;
|
||||
|
||||
static int32 fr = 0, fe = 0;
|
||||
static time_t prev, curr;
|
||||
fe++;
|
||||
if(status.render_output)fr++;
|
||||
|
||||
time(&curr);
|
||||
if(curr != prev) {
|
||||
status.frames_updated = true;
|
||||
status.frames_rendered = fr;
|
||||
status.frames_executed = fe;
|
||||
fr = fe = 0;
|
||||
}
|
||||
prev = curr;
|
||||
}
|
||||
|
||||
void PPU::power() {
|
||||
ppu1_version = config.ppu1.version;
|
||||
ppu2_version = config.ppu2.version;
|
||||
}
|
||||
|
||||
void PPU::reset() {
|
||||
PPUcounter::reset();
|
||||
memset(output, 0, 512 * 480 * sizeof(uint16));
|
||||
}
|
||||
|
||||
PPU::PPU() {
|
||||
output = new uint16[512 * 480];
|
||||
|
||||
status.render_output = true;
|
||||
status.frames_updated = false;
|
||||
status.frames_rendered = 0;
|
||||
status.frames_executed = 0;
|
||||
}
|
||||
|
||||
PPU::~PPU() {
|
||||
delete[] output;
|
||||
}
|
||||
|
||||
}
|
@@ -1,22 +0,0 @@
|
||||
#ifdef SSMP_CPP
|
||||
|
||||
void sSMP::add_clocks(unsigned clocks) {
|
||||
scheduler.addclocks_smp(clocks);
|
||||
#if !defined(DSP_STATE_MACHINE)
|
||||
scheduler.sync_smpdsp();
|
||||
#else
|
||||
while(scheduler.clock.smpdsp < 0) dsp.enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
void sSMP::tick_timers() {
|
||||
t0.tick();
|
||||
t1.tick();
|
||||
t2.tick();
|
||||
|
||||
//forcefully sync S-SMP to S-CPU in case chips are not communicating
|
||||
//sync if S-SMP is more than 24 samples ahead of S-CPU
|
||||
if(scheduler.clock.cpusmp > +(768 * 24 * (int64)24000000)) scheduler.sync_smpcpu();
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,34 +0,0 @@
|
||||
template<unsigned cycle_frequency>
|
||||
class sSMPTimer {
|
||||
public:
|
||||
uint8 target;
|
||||
uint8 stage1_ticks, stage2_ticks, stage3_ticks;
|
||||
bool enabled;
|
||||
|
||||
void tick() {
|
||||
//stage 1 increment
|
||||
stage1_ticks++;
|
||||
if(stage1_ticks < cycle_frequency) return;
|
||||
|
||||
stage1_ticks -= cycle_frequency;
|
||||
if(enabled == false) return;
|
||||
|
||||
//stage 2 increment
|
||||
stage2_ticks++;
|
||||
|
||||
if(stage2_ticks != target) return;
|
||||
|
||||
//stage 3 increment
|
||||
stage2_ticks = 0;
|
||||
stage3_ticks++;
|
||||
stage3_ticks &= 15;
|
||||
}
|
||||
};
|
||||
|
||||
sSMPTimer<128> t0;
|
||||
sSMPTimer<128> t1;
|
||||
sSMPTimer< 16> t2;
|
||||
|
||||
alwaysinline void add_clocks(unsigned clocks);
|
||||
alwaysinline void tick_timers();
|
||||
uint32 clocks_executed();
|
@@ -1,67 +0,0 @@
|
||||
#ifdef SYSTEM_CPP
|
||||
|
||||
Scheduler scheduler;
|
||||
|
||||
void threadentry_cpu() { cpu.enter(); }
|
||||
void threadentry_cop() { system.coprocessor_enter(); }
|
||||
void threadentry_smp() { smp.enter(); }
|
||||
void threadentry_ppu() { ppu.enter(); }
|
||||
void threadentry_dsp() { dsp.enter(); }
|
||||
|
||||
void Scheduler::enter() {
|
||||
co_switch(thread_active);
|
||||
}
|
||||
|
||||
void Scheduler::exit(ExitReason reason) {
|
||||
exit_reason_ = reason;
|
||||
co_switch(thread_snes);
|
||||
}
|
||||
|
||||
Scheduler::ExitReason Scheduler::exit_reason() const {
|
||||
return exit_reason_;
|
||||
}
|
||||
|
||||
void Scheduler::init() {
|
||||
clock.cpu_freq = system.region() == System::Region::NTSC
|
||||
? config.cpu.ntsc_clock_rate
|
||||
: config.cpu.pal_clock_rate;
|
||||
clock.smp_freq = system.region() == System::Region::NTSC
|
||||
? config.smp.ntsc_clock_rate
|
||||
: config.smp.pal_clock_rate;
|
||||
clock.cop_freq = clock.cpu_freq;
|
||||
|
||||
clock.cpucop = 0;
|
||||
clock.cpuppu = 0;
|
||||
clock.cpusmp = 0;
|
||||
clock.smpdsp = 0;
|
||||
|
||||
if(thread_cpu) co_delete(thread_cpu);
|
||||
if(thread_cop) co_delete(thread_cop);
|
||||
if(thread_smp) co_delete(thread_smp);
|
||||
if(thread_ppu) co_delete(thread_ppu);
|
||||
if(thread_dsp) co_delete(thread_dsp);
|
||||
|
||||
thread_snes = co_active();
|
||||
thread_cpu = co_create(65536 * sizeof(void*), threadentry_cpu);
|
||||
thread_cop = co_create(65536 * sizeof(void*), threadentry_cop);
|
||||
thread_smp = co_create(65536 * sizeof(void*), threadentry_smp);
|
||||
thread_ppu = co_create(65536 * sizeof(void*), threadentry_ppu);
|
||||
thread_dsp = co_create(65536 * sizeof(void*), threadentry_dsp);
|
||||
|
||||
//start execution with S-CPU after reset
|
||||
thread_active = thread_cpu;
|
||||
}
|
||||
|
||||
Scheduler::Scheduler() {
|
||||
thread_snes = 0;
|
||||
thread_cpu = 0;
|
||||
thread_cop = 0;
|
||||
thread_smp = 0;
|
||||
thread_ppu = 0;
|
||||
thread_dsp = 0;
|
||||
thread_active = 0;
|
||||
|
||||
exit_reason_ = ExitReason::UnknownEvent;
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,141 +0,0 @@
|
||||
//scheduler thread relationships:
|
||||
//S-PPU <-> S-CPU <-> cartridge co-processor
|
||||
// <|>
|
||||
// S-SMP <-> S-DSP
|
||||
|
||||
class Scheduler {
|
||||
public:
|
||||
enum class SynchronizeMode : unsigned { None, CPU, All } sync;
|
||||
enum class ExitReason : unsigned { UnknownEvent, FrameEvent, SynchronizeEvent, DebuggerEvent };
|
||||
|
||||
cothread_t thread_snes;
|
||||
cothread_t thread_cpu; //S-CPU (5a22)
|
||||
cothread_t thread_cop; //cartridge co-processor (SuperFX, SA-1, ...)
|
||||
cothread_t thread_smp; //S-SMP (SPC700)
|
||||
cothread_t thread_ppu; //S-PPU
|
||||
cothread_t thread_dsp; //S-DSP
|
||||
cothread_t thread_active; //reference to active thread
|
||||
|
||||
struct {
|
||||
uint32 cpu_freq;
|
||||
uint32 cop_freq;
|
||||
uint32 smp_freq;
|
||||
|
||||
int64 cpucop;
|
||||
int64 cpuppu;
|
||||
int64 cpusmp;
|
||||
int64 smpdsp;
|
||||
} clock;
|
||||
|
||||
//==========
|
||||
//CPU <> COP
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_cpucop() {
|
||||
if(clock.cpucop < 0) {
|
||||
thread_active = thread_cop;
|
||||
co_switch(thread_cop);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_copcpu() {
|
||||
if(clock.cpucop >= 0 && sync != SynchronizeMode::All) {
|
||||
thread_active = thread_cpu;
|
||||
co_switch(thread_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
//==========
|
||||
//CPU <> PPU
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_cpuppu() {
|
||||
if(clock.cpuppu < 0) {
|
||||
thread_active = thread_ppu;
|
||||
co_switch(thread_ppu);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_ppucpu() {
|
||||
if(clock.cpuppu >= 0 && sync != SynchronizeMode::All) {
|
||||
thread_active = thread_cpu;
|
||||
co_switch(thread_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
//==========
|
||||
//CPU <> SMP
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_cpusmp() {
|
||||
if(clock.cpusmp < 0) {
|
||||
thread_active = thread_smp;
|
||||
co_switch(thread_smp);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_smpcpu() {
|
||||
if(clock.cpusmp >= 0 && sync != SynchronizeMode::All) {
|
||||
thread_active = thread_cpu;
|
||||
co_switch(thread_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
//==========
|
||||
//SMP <> DSP
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_smpdsp() {
|
||||
if(clock.smpdsp < 0 && sync != SynchronizeMode::All) {
|
||||
thread_active = thread_dsp;
|
||||
co_switch(thread_dsp);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_dspsmp() {
|
||||
if(clock.smpdsp >= 0 && sync != SynchronizeMode::All) {
|
||||
thread_active = thread_smp;
|
||||
co_switch(thread_smp);
|
||||
}
|
||||
}
|
||||
|
||||
//==========
|
||||
//add clocks
|
||||
//==========
|
||||
|
||||
alwaysinline void addclocks_cpu(unsigned clocks) {
|
||||
clock.cpucop -= clocks * (uint64)clock.cop_freq;
|
||||
clock.cpuppu -= clocks;
|
||||
clock.cpusmp -= clocks * (uint64)clock.smp_freq;
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_cop(unsigned clocks) {
|
||||
clock.cpucop += clocks * (uint64)clock.cpu_freq;
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_ppu(unsigned clocks) {
|
||||
clock.cpuppu += clocks;
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_smp(unsigned clocks) {
|
||||
clock.cpusmp += clocks * (uint64)clock.cpu_freq;
|
||||
clock.smpdsp -= clocks;
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_dsp(unsigned clocks) {
|
||||
clock.smpdsp += clocks;
|
||||
}
|
||||
|
||||
void enter();
|
||||
void exit(ExitReason);
|
||||
ExitReason exit_reason() const;
|
||||
|
||||
void init();
|
||||
|
||||
Scheduler();
|
||||
|
||||
private:
|
||||
ExitReason exit_reason_;
|
||||
};
|
||||
|
||||
extern Scheduler scheduler;
|
@@ -1,48 +0,0 @@
|
||||
objects := ui-main ui-base ui-cartridge ui-debugger ui-input ui-movie ui-settings ui-state ui-tools $(objects)
|
||||
objects += $(if $(call streq,$(platform),win),resource)
|
||||
link += $(qtlib)
|
||||
|
||||
headers := $(call rwildcard,$(ui)/,%.hpp)
|
||||
moc_headers := $(call rwildcard,lib/nall/qt/,%.moc.hpp) $(call rwildcard,$(ui)/,%.moc.hpp)
|
||||
moc_objects := $(foreach f,$(moc_headers),obj/$(notdir $(patsubst %.moc.hpp,%.moc,$f)))
|
||||
qt_compile = $(call compile,-Iobj $(qtinc))
|
||||
|
||||
#############
|
||||
### rules ###
|
||||
#############
|
||||
|
||||
# automatically run moc on all .moc.hpp (MOC header) files
|
||||
%.moc: $<; $(moc) -i $< -o $@
|
||||
|
||||
# automatically generate %.moc build rules
|
||||
__list = $(moc_headers)
|
||||
$(foreach f,$(moc_objects), \
|
||||
$(eval __file = $(word 1,$(__list))) \
|
||||
$(eval __list = $(wordlist 2,$(words $(__list)),$(__list))) \
|
||||
$(eval $f: $(__file)) \
|
||||
)
|
||||
|
||||
obj/ui-main.o: $(ui)/main.cpp $(headers) $(wildcard $(ui)/*.cpp) $(wildcard $(ui)/link/*.cpp) $(wildcard $(ui)/platform/*.cpp) $(wildcard $(ui)/utility/*.cpp); $(qt_compile)
|
||||
obj/ui-base.o: $(ui)/base/base.cpp $(headers) $(wildcard $(ui)/base/*.cpp); $(qt_compile)
|
||||
obj/ui-cartridge.o: $(ui)/cartridge/cartridge.cpp $(headers) $(wildcard $(ui)/cartridge/*.cpp); $(qt_compile)
|
||||
obj/ui-debugger.o: $(ui)/debugger/debugger.cpp $(headers) $(call rwildcard,$(ui)/debugger/,%.cpp); $(qt_compile)
|
||||
obj/ui-input.o: $(ui)/input/input.cpp $(headers) $(wildcard $(ui)/input/*.cpp); $(qt_compile)
|
||||
obj/ui-movie.o: $(ui)/movie/movie.cpp $(headers) $(wildcard $(ui)/movie/*.cpp); $(qt_compile)
|
||||
obj/ui-settings.o: $(ui)/settings/settings.cpp $(headers) $(wildcard $(ui)/settings/*.cpp); $(qt_compile)
|
||||
obj/ui-state.o: $(ui)/state/state.cpp $(headers) $(wildcard $(ui)/state/*.cpp); $(qt_compile)
|
||||
obj/ui-tools.o: $(ui)/tools/tools.cpp $(headers) $(wildcard $(ui)/tools/*.cpp); $(qt_compile)
|
||||
|
||||
obj/resource.rcc: $(ui)/resource/resource.qrc data/*
|
||||
$(rcc) $(ui)/resource/resource.qrc -o obj/resource.rcc
|
||||
|
||||
obj/resource.o: $(ui)/resource/resource.rc
|
||||
windres $(ui)/resource/resource.rc obj/resource.o
|
||||
|
||||
###############
|
||||
### targets ###
|
||||
###############
|
||||
|
||||
ui_build: obj/resource.rcc $(moc_objects);
|
||||
ui_clean:
|
||||
-@$(call delete,obj/*.rcc)
|
||||
-@$(call delete,obj/*.moc)
|
BIN
libgomp-1.dll
BIN
libgomp-1.dll
Binary file not shown.
BIN
mingwm10.dll
BIN
mingwm10.dll
Binary file not shown.
@@ -1,17 +0,0 @@
|
||||
//CRT curvature shader
|
||||
//license: GPL
|
||||
//author: DOLLS
|
||||
|
||||
uniform sampler2D rubyTexture;
|
||||
|
||||
#define distortion 0.2
|
||||
|
||||
vec2 barrelDistortion(vec2 coord) {
|
||||
vec2 cc = coord - 0.5;
|
||||
float dist = dot(cc, cc);
|
||||
return coord + cc * (dist + distortion * dist * dist) * distortion;
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = texture2D(rubyTexture, barrelDistortion(gl_TexCoord[0].xy));
|
||||
}
|
@@ -1,14 +0,0 @@
|
||||
//HDRTV GLSL shader
|
||||
//license: GPL
|
||||
//original version by SimoneT
|
||||
//ruby port by byuu
|
||||
|
||||
uniform sampler2D rubyTexture;
|
||||
|
||||
void main(void) {
|
||||
vec4 rgb = texture2D(rubyTexture, gl_TexCoord[0].xy);
|
||||
vec4 intens = smoothstep(0.2,0.8,rgb) + normalize(vec4(rgb.xyz, 1.0));
|
||||
|
||||
if(fract(gl_FragCoord.y * 0.5) > 0.5) intens = rgb * 0.8;
|
||||
gl_FragColor = intens;
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
//HDRTV GLSL shader
|
||||
//license: GPL
|
||||
//original version by SimoneT
|
||||
//ruby port by byuu
|
||||
|
||||
void main(void) {
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
texture rubyTexture;
|
||||
|
||||
float4 vec;
|
||||
|
||||
sampler s0 = sampler_state { texture = <rubyTexture>; };
|
||||
float3 LightColor = { 1.0, 0.7, 0.5 };
|
||||
float3 DarkColor = { 0.2, 0.05, 0.0 };
|
||||
|
||||
float4 DiffColorPass(in float2 Tex : TEXCOORD0) : COLOR0
|
||||
{
|
||||
vec.x = 0.5;
|
||||
vec.y = 1.0;
|
||||
float3 scnColor = LightColor * tex2D(s0, Tex).xyz;
|
||||
float3 grayXfer = float3(0.3, 0.59, 0.11);
|
||||
float gray = dot(grayXfer, scnColor);
|
||||
float3 muted = lerp(scnColor, gray.xxx, vec.x);
|
||||
float3 sepia = lerp(DarkColor, LightColor, gray);
|
||||
float3 result = lerp(muted, sepia, vec.y);
|
||||
return float4(result, 1);
|
||||
}
|
||||
|
||||
Technique T0
|
||||
{
|
||||
pass p0 { PixelShader = compile ps_2_0 DiffColorPass(); }
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
//HQ2x GLSL shader
|
||||
//license: GPL
|
||||
//original version by guest(r)
|
||||
//ruby port by byuu
|
||||
|
||||
uniform sampler2D rubyTexture;
|
||||
|
||||
const float mx = 0.325; // start smoothing wt.
|
||||
const float k = -0.250; // wt. decrease factor
|
||||
const float max_w = 0.25; // max filter weigth
|
||||
const float min_w =-0.05; // min filter weigth
|
||||
const float lum_add = 0.25; // effects smoothing
|
||||
|
||||
void main() {
|
||||
vec3 c00 = texture2D(rubyTexture, gl_TexCoord[1].xy).xyz;
|
||||
vec3 c10 = texture2D(rubyTexture, gl_TexCoord[1].zw).xyz;
|
||||
vec3 c20 = texture2D(rubyTexture, gl_TexCoord[2].xy).xyz;
|
||||
vec3 c01 = texture2D(rubyTexture, gl_TexCoord[4].zw).xyz;
|
||||
vec3 c11 = texture2D(rubyTexture, gl_TexCoord[0].xy).xyz;
|
||||
vec3 c21 = texture2D(rubyTexture, gl_TexCoord[2].zw).xyz;
|
||||
vec3 c02 = texture2D(rubyTexture, gl_TexCoord[4].xy).xyz;
|
||||
vec3 c12 = texture2D(rubyTexture, gl_TexCoord[3].zw).xyz;
|
||||
vec3 c22 = texture2D(rubyTexture, gl_TexCoord[3].xy).xyz;
|
||||
vec3 dt = vec3(1.0, 1.0, 1.0);
|
||||
|
||||
float md1 = dot(abs(c00 - c22), dt);
|
||||
float md2 = dot(abs(c02 - c20), dt);
|
||||
|
||||
float w1 = dot(abs(c22 - c11), dt) * md2;
|
||||
float w2 = dot(abs(c02 - c11), dt) * md1;
|
||||
float w3 = dot(abs(c00 - c11), dt) * md2;
|
||||
float w4 = dot(abs(c20 - c11), dt) * md1;
|
||||
|
||||
float t1 = w1 + w3;
|
||||
float t2 = w2 + w4;
|
||||
float ww = max(t1, t2) + 0.0001;
|
||||
|
||||
c11 = (w1 * c00 + w2 * c20 + w3 * c22 + w4 * c02 + ww * c11) / (t1 + t2 + ww);
|
||||
|
||||
float lc1 = k / (0.12 * dot(c10 + c12 + c11, dt) + lum_add);
|
||||
float lc2 = k / (0.12 * dot(c01 + c21 + c11, dt) + lum_add);
|
||||
|
||||
w1 = clamp(lc1 * dot(abs(c11 - c10), dt) + mx, min_w, max_w);
|
||||
w2 = clamp(lc2 * dot(abs(c11 - c21), dt) + mx, min_w, max_w);
|
||||
w3 = clamp(lc1 * dot(abs(c11 - c12), dt) + mx, min_w, max_w);
|
||||
w4 = clamp(lc2 * dot(abs(c11 - c01), dt) + mx, min_w, max_w);
|
||||
|
||||
gl_FragColor.xyz = w1 * c10 + w2 * c21 + w3 * c12 + w4 * c01 + (1.0 - w1 - w2 - w3 - w4) * c11;
|
||||
}
|
@@ -1,26 +0,0 @@
|
||||
//HQ2x GLSL shader
|
||||
//license: GPL
|
||||
//original version by guest(r)
|
||||
//ruby port by byuu
|
||||
|
||||
uniform vec2 rubyTextureSize;
|
||||
|
||||
void main() {
|
||||
float x = 0.5 * (1.0 / rubyTextureSize.x);
|
||||
float y = 0.5 * (1.0 / rubyTextureSize.y);
|
||||
vec2 dg1 = vec2( x, y);
|
||||
vec2 dg2 = vec2(-x, y);
|
||||
vec2 dx = vec2(x, 0.0);
|
||||
vec2 dy = vec2(0.0, y);
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
gl_TexCoord[1].xy = gl_TexCoord[0].xy - dg1;
|
||||
gl_TexCoord[1].zw = gl_TexCoord[0].xy - dy;
|
||||
gl_TexCoord[2].xy = gl_TexCoord[0].xy - dg2;
|
||||
gl_TexCoord[2].zw = gl_TexCoord[0].xy + dx;
|
||||
gl_TexCoord[3].xy = gl_TexCoord[0].xy + dg1;
|
||||
gl_TexCoord[3].zw = gl_TexCoord[0].xy + dy;
|
||||
gl_TexCoord[4].xy = gl_TexCoord[0].xy + dg2;
|
||||
gl_TexCoord[4].zw = gl_TexCoord[0].xy - dx;
|
||||
}
|
@@ -1,36 +0,0 @@
|
||||
//Pixellate shader
|
||||
//license: GPL
|
||||
//author: Fes
|
||||
|
||||
uniform sampler2D rubyTexture;
|
||||
uniform vec2 rubyTextureSize;
|
||||
|
||||
void main() {
|
||||
vec2 texelSize = 1.0 / rubyTextureSize;
|
||||
|
||||
vec2 range;
|
||||
range.x = dFdx(gl_TexCoord[0].x) / 2.0 * 0.99;
|
||||
range.y = dFdy(gl_TexCoord[0].y) / 2.0 * 0.99;
|
||||
|
||||
float left = gl_TexCoord[0].x - range.x;
|
||||
float top = gl_TexCoord[0].y + range.y;
|
||||
float right = gl_TexCoord[0].x + range.x;
|
||||
float bottom = gl_TexCoord[0].y - range.y;
|
||||
|
||||
vec4 topLeftColor = texture2D(rubyTexture, (floor(vec2(left, top) / texelSize) + 0.5) * texelSize);
|
||||
vec4 bottomRightColor = texture2D(rubyTexture, (floor(vec2(right, bottom) / texelSize) + 0.5) * texelSize);
|
||||
vec4 bottomLeftColor = texture2D(rubyTexture, (floor(vec2(left, bottom) / texelSize) + 0.5) * texelSize);
|
||||
vec4 topRightColor = texture2D(rubyTexture, (floor(vec2(right, top) / texelSize) + 0.5) * texelSize);
|
||||
|
||||
vec2 border = clamp(round(gl_TexCoord[0] / texelSize) * texelSize, vec2(left, bottom), vec2(right, top));
|
||||
|
||||
float totalArea = 4.0 * range.x * range.y;
|
||||
|
||||
vec4 averageColor;
|
||||
averageColor = ((border.x - left) * (top - border.y) / totalArea) * topLeftColor;
|
||||
averageColor += ((right - border.x) * (border.y - bottom) / totalArea) * bottomRightColor;
|
||||
averageColor += ((border.x - left) * (border.y - bottom) / totalArea) * bottomLeftColor;
|
||||
averageColor += ((right - border.x) * (top - border.y) / totalArea) * topRightColor;
|
||||
|
||||
gl_FragColor = averageColor;
|
||||
}
|
@@ -1,8 +0,0 @@
|
||||
//Pixellate shader
|
||||
//license: GPL
|
||||
//author: Fes
|
||||
|
||||
void main() {
|
||||
gl_Position = ftransform();
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0;
|
||||
}
|
@@ -1,28 +0,0 @@
|
||||
//Scale2x GLSL shader
|
||||
//license: GPL
|
||||
//original version by Pete Bernert
|
||||
//ruby port by byuu
|
||||
|
||||
uniform sampler2D rubyTexture;
|
||||
uniform vec2 rubyTextureSize;
|
||||
|
||||
void main() {
|
||||
vec4 colD, colF, colB, colH, col, tmp;
|
||||
vec2 sel;
|
||||
|
||||
col = texture2DProj(rubyTexture, gl_TexCoord[0]); //central (can be E0-E3)
|
||||
colD = texture2DProj(rubyTexture, gl_TexCoord[1]); //D (left)
|
||||
colF = texture2DProj(rubyTexture, gl_TexCoord[2]); //F (right)
|
||||
colB = texture2DProj(rubyTexture, gl_TexCoord[3]); //B (top)
|
||||
colH = texture2DProj(rubyTexture, gl_TexCoord[4]); //H (bottom)
|
||||
|
||||
sel = fract(gl_TexCoord[0].xy * rubyTextureSize.xy); //where are we (E0-E3)?
|
||||
//E0 is default
|
||||
if(sel.y >= 0.5) { tmp = colB; colB = colH; colH = tmp; } //E1 (or E3): swap B and H
|
||||
if(sel.x >= 0.5) { tmp = colF; colF = colD; colD = tmp; } //E2 (or E3): swap D and F
|
||||
|
||||
if(colB == colD && colB != colF && colD != colH) { //do the Scale2x rule
|
||||
col = colD;
|
||||
}
|
||||
|
||||
gl_FragColor = col;
|
@@ -1,28 +0,0 @@
|
||||
//Scale2x GLSL shader
|
||||
//license: GPL
|
||||
//original version by Pete Bernert
|
||||
//ruby port by byuu
|
||||
|
||||
uniform vec2 rubyTextureSize;
|
||||
|
||||
void main() {
|
||||
vec4 offsetx;
|
||||
vec4 offsety;
|
||||
|
||||
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
|
||||
|
||||
offsetx.x = 1.0 / rubyTextureSize.x;
|
||||
offsetx.y = 0.0;
|
||||
offsetx.w = 0.0;
|
||||
offsetx.z = 0.0;
|
||||
offsety.y = 1.0 / rubyTextureSize.y;
|
||||
offsety.x = 0.0;
|
||||
offsety.w = 0.0;
|
||||
offsety.z = 0.0;
|
||||
|
||||
gl_TexCoord[0] = gl_MultiTexCoord0; //center
|
||||
gl_TexCoord[1] = gl_TexCoord[0] - offsetx; //left
|
||||
gl_TexCoord[2] = gl_TexCoord[0] + offsetx; //right
|
||||
gl_TexCoord[3] = gl_TexCoord[0] - offsety; //top
|
||||
gl_TexCoord[4] = gl_TexCoord[0] + offsety; //bottom
|
||||
}
|
BIN
pthreadGC2.dll
BIN
pthreadGC2.dll
Binary file not shown.
BIN
snesfilter.dll
BIN
snesfilter.dll
Binary file not shown.
@@ -20,11 +20,11 @@ void _2xSaIFilter::size(unsigned &outwidth, unsigned &outheight, unsigned width,
|
||||
}
|
||||
|
||||
void _2xSaIFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
if(width > 256 || height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, line, width, height);
|
||||
filter_direct.render(output, outpitch, input, pitch, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -62,11 +62,11 @@ void Super2xSaIFilter::size(unsigned &outwidth, unsigned &outheight, unsigned wi
|
||||
}
|
||||
|
||||
void Super2xSaIFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
if(width > 256 || height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, line, width, height);
|
||||
filter_direct.render(output, outpitch, input, pitch, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,11 +104,11 @@ void SuperEagleFilter::size(unsigned &outwidth, unsigned &outheight, unsigned wi
|
||||
}
|
||||
|
||||
void SuperEagleFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
if(width > 256 || height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, line, width, height);
|
||||
filter_direct.render(output, outpitch, input, pitch, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
class _2xSaIFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
|
||||
_2xSaIFilter();
|
||||
~_2xSaIFilter();
|
||||
@@ -13,7 +13,7 @@ private:
|
||||
class Super2xSaIFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
|
||||
Super2xSaIFilter();
|
||||
~Super2xSaIFilter();
|
||||
@@ -25,7 +25,7 @@ private:
|
||||
class SuperEagleFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
|
||||
SuperEagleFilter();
|
||||
~SuperEagleFilter();
|
||||
|
@@ -7,24 +7,15 @@ void DirectFilter::size(unsigned &outwidth, unsigned &outheight, unsigned width,
|
||||
|
||||
void DirectFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
unsigned width, unsigned height
|
||||
) {
|
||||
pitch >>= 1;
|
||||
outpitch >>= 2;
|
||||
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
if(width == 512 && line[y] == 256) {
|
||||
for(unsigned x = 0; x < 256; x++) {
|
||||
uint16_t p = *input++;
|
||||
*output++ = colortable[p];
|
||||
*output++ = colortable[p];
|
||||
}
|
||||
input += 256;
|
||||
} else {
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
uint16_t p = *input++;
|
||||
*output++ = colortable[p];
|
||||
}
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
uint16_t p = *input++;
|
||||
*output++ = colortable[p];
|
||||
}
|
||||
input += pitch - width;
|
||||
output += outpitch - width;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
class DirectFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
} filter_direct;
|
||||
|
@@ -8,17 +8,17 @@
|
||||
#include "hq2x.hpp"
|
||||
|
||||
void HQ2xFilter::size(unsigned &outwidth, unsigned &outheight, unsigned width, unsigned height) {
|
||||
if(height > 240) return filter_direct.size(outwidth, outheight, width, height);
|
||||
outwidth = (width <= 256) ? width * 2 : width;
|
||||
outheight = (height <= 240) ? height * 2 : height;
|
||||
if(width > 256 || height > 240) return filter_direct.size(outwidth, outheight, width, height);
|
||||
outwidth = width * 2;
|
||||
outheight = height * 2;
|
||||
}
|
||||
|
||||
void HQ2xFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
if(height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, line, width, height);
|
||||
if(width > 256 || height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,59 +28,51 @@ void HQ2xFilter::render(
|
||||
#pragma omp parallel for
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
const uint16_t *in = input + y * pitch;
|
||||
uint32_t *out0 = output + y * pitch;
|
||||
uint32_t *out1 = output + y * pitch + outpitch;
|
||||
uint32_t *out0 = output + y * outpitch * 2;
|
||||
uint32_t *out1 = output + y * outpitch * 2 + outpitch;
|
||||
|
||||
unsigned linewidth = line[y];
|
||||
int prevline = (y == 0 ? 0 : pitch);
|
||||
int nextline = (y == height - 1 ? 0 : pitch);
|
||||
|
||||
if(linewidth == 256) {
|
||||
int prevline = (y == 0) || (linewidth != line[y - 1]) ? 0 : pitch;
|
||||
int nextline = (y == height - 1) || (linewidth != line[y + 1]) ? 0 : pitch;
|
||||
in++;
|
||||
*out0++ = 0; *out0++ = 0;
|
||||
*out1++ = 0; *out1++ = 0;
|
||||
|
||||
for(unsigned x = 1; x < 256 - 1; x++) {
|
||||
uint16_t A = *(in - prevline - 1);
|
||||
uint16_t B = *(in - prevline + 0);
|
||||
uint16_t C = *(in - prevline + 1);
|
||||
uint16_t D = *(in - 1);
|
||||
uint16_t E = *(in + 0);
|
||||
uint16_t F = *(in + 1);
|
||||
uint16_t G = *(in + nextline - 1);
|
||||
uint16_t H = *(in + nextline + 0);
|
||||
uint16_t I = *(in + nextline + 1);
|
||||
uint32_t e = yuvTable[E] + diff_offset;
|
||||
|
||||
uint8_t pattern;
|
||||
pattern = diff(e, A) << 0;
|
||||
pattern |= diff(e, B) << 1;
|
||||
pattern |= diff(e, C) << 2;
|
||||
pattern |= diff(e, D) << 3;
|
||||
pattern |= diff(e, F) << 4;
|
||||
pattern |= diff(e, G) << 5;
|
||||
pattern |= diff(e, H) << 6;
|
||||
pattern |= diff(e, I) << 7;
|
||||
|
||||
*(out0 + 0) = colortable[blend(hqTable[pattern], E, A, B, D, F, H)]; pattern = rotate[pattern];
|
||||
*(out0 + 1) = colortable[blend(hqTable[pattern], E, C, F, B, H, D)]; pattern = rotate[pattern];
|
||||
*(out1 + 1) = colortable[blend(hqTable[pattern], E, I, H, F, D, B)]; pattern = rotate[pattern];
|
||||
*(out1 + 0) = colortable[blend(hqTable[pattern], E, G, D, H, B, F)];
|
||||
|
||||
in++;
|
||||
*out0++ = 0; *out0++ = 0;
|
||||
*out1++ = 0; *out1++ = 0;
|
||||
|
||||
for(unsigned x = 1; x < 256 - 1; x++) {
|
||||
uint16_t A = *(in - prevline - 1);
|
||||
uint16_t B = *(in - prevline + 0);
|
||||
uint16_t C = *(in - prevline + 1);
|
||||
uint16_t D = *(in - 1);
|
||||
uint16_t E = *(in + 0);
|
||||
uint16_t F = *(in + 1);
|
||||
uint16_t G = *(in + nextline - 1);
|
||||
uint16_t H = *(in + nextline + 0);
|
||||
uint16_t I = *(in + nextline + 1);
|
||||
uint32_t e = yuvTable[E] + diff_offset;
|
||||
|
||||
uint8_t pattern;
|
||||
pattern = diff(e, A) << 0;
|
||||
pattern |= diff(e, B) << 1;
|
||||
pattern |= diff(e, C) << 2;
|
||||
pattern |= diff(e, D) << 3;
|
||||
pattern |= diff(e, F) << 4;
|
||||
pattern |= diff(e, G) << 5;
|
||||
pattern |= diff(e, H) << 6;
|
||||
pattern |= diff(e, I) << 7;
|
||||
|
||||
*(out0 + 0) = colortable[blend(hqTable[pattern], E, A, B, D, F, H)]; pattern = rotate[pattern];
|
||||
*(out0 + 1) = colortable[blend(hqTable[pattern], E, C, F, B, H, D)]; pattern = rotate[pattern];
|
||||
*(out1 + 1) = colortable[blend(hqTable[pattern], E, I, H, F, D, B)]; pattern = rotate[pattern];
|
||||
*(out1 + 0) = colortable[blend(hqTable[pattern], E, G, D, H, B, F)];
|
||||
|
||||
in++;
|
||||
out0 += 2;
|
||||
out1 += 2;
|
||||
}
|
||||
|
||||
in++;
|
||||
*out0++ = 0; *out0++ = 0;
|
||||
*out1++ = 0; *out1++ = 0;
|
||||
} else {
|
||||
for(unsigned x = 0; x < 512; x++) {
|
||||
*out0++ = *out1++ = colortable[*in++];
|
||||
}
|
||||
out0 += 2;
|
||||
out1 += 2;
|
||||
}
|
||||
|
||||
in++;
|
||||
*out0++ = 0; *out0++ = 0;
|
||||
*out1++ = 0; *out1++ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
class HQ2xFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
|
||||
HQ2xFilter();
|
||||
~HQ2xFilter();
|
||||
|
@@ -1,17 +1,17 @@
|
||||
#include "lq2x.hpp"
|
||||
|
||||
void LQ2xFilter::size(unsigned &outwidth, unsigned &outheight, unsigned width, unsigned height) {
|
||||
if(height > 240) return filter_direct.size(outwidth, outheight, width, height);
|
||||
outwidth = (width <= 256) ? width * 2 : width;
|
||||
outheight = (height <= 240) ? height * 2 : height;
|
||||
if(width > 256 || height > 240) return filter_direct.size(outwidth, outheight, width, height);
|
||||
outwidth = width * 2;
|
||||
outheight = height * 2;
|
||||
}
|
||||
|
||||
void LQ2xFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
if(height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, line, width, height);
|
||||
if(width > 256 || height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,39 +22,31 @@ void LQ2xFilter::render(
|
||||
uint32_t *out1 = output + outpitch;
|
||||
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
unsigned linewidth = line[y];
|
||||
int prevline = (y == 0 ? 0 : pitch);
|
||||
int nextline = (y == height - 1 ? 0 : pitch);
|
||||
|
||||
if(linewidth == 256) {
|
||||
int prevline = (y == 0) || (linewidth != line[y - 1]) ? 0 : pitch;
|
||||
int nextline = (y == height - 1) || (linewidth != line[y + 1]) ? 0 : pitch;
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
uint16_t A = *(input - prevline);
|
||||
uint16_t B = (x > 0) ? *(input - 1) : *input;
|
||||
uint16_t C = *input;
|
||||
uint16_t D = (x < 255) ? *(input + 1) : *input;
|
||||
uint16_t E = *(input++ + nextline);
|
||||
uint32_t c = colortable[C];
|
||||
|
||||
for(unsigned x = 0; x < 256; x++) {
|
||||
uint16_t A = *(input - prevline);
|
||||
uint16_t B = (x > 0) ? *(input - 1) : *input;
|
||||
uint16_t C = *input;
|
||||
uint16_t D = (x < 255) ? *(input + 1) : *input;
|
||||
uint16_t E = *(input++ + nextline);
|
||||
uint32_t c = colortable[C];
|
||||
|
||||
if(A != E && B != D) {
|
||||
*out0++ = (A == B ? colortable[C + A - ((C ^ A) & 0x0421) >> 1] : c);
|
||||
*out0++ = (A == D ? colortable[C + A - ((C ^ A) & 0x0421) >> 1] : c);
|
||||
*out1++ = (E == B ? colortable[C + E - ((C ^ E) & 0x0421) >> 1] : c);
|
||||
*out1++ = (E == D ? colortable[C + E - ((C ^ E) & 0x0421) >> 1] : c);
|
||||
} else {
|
||||
*out0++ = c;
|
||||
*out0++ = c;
|
||||
*out1++ = c;
|
||||
*out1++ = c;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(unsigned x = 0; x < 512; x++) {
|
||||
*out0++ = *out1++ = colortable[*input++];
|
||||
if(A != E && B != D) {
|
||||
*out0++ = (A == B ? colortable[C + A - ((C ^ A) & 0x0421) >> 1] : c);
|
||||
*out0++ = (A == D ? colortable[C + A - ((C ^ A) & 0x0421) >> 1] : c);
|
||||
*out1++ = (E == B ? colortable[C + E - ((C ^ E) & 0x0421) >> 1] : c);
|
||||
*out1++ = (E == D ? colortable[C + E - ((C ^ E) & 0x0421) >> 1] : c);
|
||||
} else {
|
||||
*out0++ = c;
|
||||
*out0++ = c;
|
||||
*out1++ = c;
|
||||
*out1++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
input += pitch - linewidth;
|
||||
input += pitch - width;
|
||||
out0 += outpitch + outpitch - 512;
|
||||
out1 += outpitch + outpitch - 512;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
class LQ2xFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
} filter_lq2x;
|
||||
|
@@ -30,7 +30,7 @@ endif
|
||||
|
||||
ifeq ($(compiler),)
|
||||
ifeq ($(platform),osx)
|
||||
compiler := gcc-4.2
|
||||
compiler := gcc-mp-4.4
|
||||
else
|
||||
compiler := gcc
|
||||
endif
|
||||
|
@@ -12,12 +12,6 @@ namespace nall {
|
||||
template<typename T, typename U> T max(const T &t, const U &u) {
|
||||
return t > u ? t : u;
|
||||
}
|
||||
|
||||
//pseudo-random number generator
|
||||
inline unsigned prng() {
|
||||
static unsigned n = 0;
|
||||
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2,8 +2,8 @@
|
||||
#define NALL_ANY_HPP
|
||||
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
class any {
|
||||
@@ -13,8 +13,8 @@ namespace nall {
|
||||
|
||||
template<typename T> any& operator=(const T& value_) {
|
||||
typedef typename static_if<
|
||||
is_array<T>::value,
|
||||
typename remove_extent<typename add_const<T>::type>::type*,
|
||||
std::is_array<T>::value,
|
||||
typename std::remove_extent<typename std::add_const<T>::type>::type*,
|
||||
T
|
||||
>::type auto_t;
|
||||
|
||||
@@ -49,13 +49,13 @@ namespace nall {
|
||||
};
|
||||
|
||||
template<typename T> T any_cast(any &value) {
|
||||
typedef typename remove_reference<T>::type nonref;
|
||||
typedef typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
||||
template<typename T> T any_cast(const any &value) {
|
||||
typedef const typename remove_reference<T>::type nonref;
|
||||
typedef const typename std::remove_reference<T>::type nonref;
|
||||
if(value.type() != typeid(nonref)) throw;
|
||||
return static_cast<any::holder<nonref>*>(value.container)->value;
|
||||
}
|
||||
|
@@ -3,10 +3,13 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
//dynamic vector array
|
||||
@@ -47,13 +50,32 @@ namespace nall {
|
||||
return pool;
|
||||
}
|
||||
|
||||
void add(const T data) {
|
||||
void append(const T data) {
|
||||
operator[](buffersize) = data;
|
||||
}
|
||||
|
||||
signed find(const T data) {
|
||||
for(unsigned i = 0; i < size(); i++) if(pool[i] == data) return i;
|
||||
return -1; //not found
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
unsigned listsize = container_size(list);
|
||||
resize(buffersize + listsize);
|
||||
memmove(pool + index + listsize, pool + index, (buffersize - index) * sizeof(T));
|
||||
foreach(item, list) pool[index++] = item;
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, array<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < buffersize; i++) {
|
||||
pool[i] = pool[count + i];
|
||||
}
|
||||
if(count + index >= buffersize) resize(index); //every element >= index was removed
|
||||
else resize(buffersize - count);
|
||||
}
|
||||
|
||||
optional<unsigned> find(const T data) {
|
||||
for(unsigned i = 0; i < size(); i++) if(pool[i] == data) return { true, i };
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
void clear() {
|
||||
@@ -64,7 +86,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
array(std::initializer_list<T> list) : pool(0), poolsize(0), buffersize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) add(*p);
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~array() {
|
||||
@@ -81,7 +103,7 @@ namespace nall {
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(const array &source) : pool(0) {
|
||||
array(const array &source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -92,11 +114,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
array(array &&source) {
|
||||
operator=(move(source));
|
||||
array(array &&source) : pool(0), poolsize(0), buffersize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//index
|
||||
|
@@ -1,6 +1,9 @@
|
||||
#ifndef NALL_CONCEPT_HPP
|
||||
#define NALL_CONCEPT_HPP
|
||||
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
//unsigned count() const;
|
||||
template<typename T> struct has_count { enum { value = false }; };
|
||||
@@ -10,6 +13,22 @@ namespace nall {
|
||||
|
||||
//unsigned size() const;
|
||||
template<typename T> struct has_size { enum { value = false }; };
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
|
||||
return object.count();
|
||||
}
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_length<T>>::type = 0) {
|
||||
return object.length();
|
||||
}
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<has_size<T>>::type = 0) {
|
||||
return object.size();
|
||||
}
|
||||
|
||||
template<typename T> unsigned container_size(const T& object, typename mp_enable_if<std::is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename std::remove_extent<T>::type);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -78,9 +78,8 @@ namespace nall {
|
||||
line.split("\n", data);
|
||||
|
||||
for(unsigned i = 0; i < line.size(); i++) {
|
||||
int position = qstrpos(line[i], "#");
|
||||
if(position >= 0) line[i][position] = 0;
|
||||
if(qstrpos(line[i], " = ") < 0) continue;
|
||||
if(auto position = qstrpos(line[i], "#")) line[i][position()] = 0;
|
||||
if(!qstrpos(line[i], " = ")) continue;
|
||||
|
||||
lstring part;
|
||||
part.qsplit(" = ", line[i]);
|
||||
|
@@ -15,9 +15,8 @@ namespace nall {
|
||||
|
||||
//no match, use input; remove input identifier, if one exists
|
||||
if(strbegin(input, "{{")) {
|
||||
int pos = strpos(input, "}}");
|
||||
if(pos >= 0) {
|
||||
string temp = substr(input, pos + 2);
|
||||
if(auto pos = strpos(input, "}}")) {
|
||||
string temp = substr(input, pos() + 2);
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
|
@@ -1,31 +1,12 @@
|
||||
#ifndef NALL_FOREACH_HPP
|
||||
#define NALL_FOREACH_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <nall/concept.hpp>
|
||||
|
||||
#undef foreach
|
||||
#define foreach(iter, object) \
|
||||
for(unsigned foreach_counter = 0, foreach_limit = foreach_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(unsigned foreach_counter = 0, foreach_limit = container_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(auto &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
|
||||
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/static.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_count<T>>::type = 0) {
|
||||
return object.count();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_length<T>>::type = 0) {
|
||||
return object.length();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<has_size<T>>::type = 0) {
|
||||
return object.size();
|
||||
}
|
||||
|
||||
template<typename T> unsigned foreach_size(const T& object, typename mp_enable_if<is_array<T>>::type = 0) {
|
||||
return sizeof(T) / sizeof(typename remove_extent<T>::type);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,190 +1,90 @@
|
||||
#ifndef NALL_FUNCTION_HPP
|
||||
#define NALL_FUNCTION_HPP
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
//prologue
|
||||
|
||||
#define TN typename
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> class function;
|
||||
}
|
||||
|
||||
//parameters = 0
|
||||
|
||||
#define cat(n) n
|
||||
#define TL typename R
|
||||
#define PL
|
||||
#define CL
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 1
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1
|
||||
#define PL P1 p1
|
||||
#define CL p1
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 2
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2
|
||||
#define PL P1 p1, P2 p2
|
||||
#define CL p1, p2
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 3
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3
|
||||
#define PL P1 p1, P2 p2, P3 p3
|
||||
#define CL p1, p2, p3
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 4
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4
|
||||
#define CL p1, p2, p3, p4
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 5
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5
|
||||
#define CL p1, p2, p3, p4, p5
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 6
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6
|
||||
#define CL p1, p2, p3, p4, p5, p6
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 7
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//parameters = 8
|
||||
|
||||
#define cat(n) , n
|
||||
#define TL TN R, TN P1, TN P2, TN P3, TN P4, TN P5, TN P6, TN P7, TN P8
|
||||
#define PL P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8
|
||||
#define CL p1, p2, p3, p4, p5, p6, p7, p8
|
||||
|
||||
#include "function.hpp"
|
||||
|
||||
//epilogue
|
||||
|
||||
#undef TN
|
||||
#define NALL_FUNCTION_T
|
||||
|
||||
#elif !defined(NALL_FUNCTION_T)
|
||||
|
||||
//function implementation template class
|
||||
|
||||
namespace nall {
|
||||
template<TL>
|
||||
class function<R (PL)> {
|
||||
template<typename R, typename... P>
|
||||
class function<R (P...)> {
|
||||
private:
|
||||
struct base1 { virtual void func1(PL) {} };
|
||||
struct base2 { virtual void func2(PL) {} };
|
||||
struct base1 { virtual void func1(P...) {} };
|
||||
struct base2 { virtual void func2(P...) {} };
|
||||
struct derived : base1, virtual base2 {};
|
||||
|
||||
struct data_t {
|
||||
R (*fn_call)(const data_t& cat(PL));
|
||||
R (*callback)(const data_t&, P...);
|
||||
union {
|
||||
R (*fn_global)(PL);
|
||||
R (*callback_global)(P...);
|
||||
struct {
|
||||
R (derived::*fn_member)(PL);
|
||||
R (derived::*callback_member)(P...);
|
||||
void *object;
|
||||
};
|
||||
};
|
||||
} data;
|
||||
|
||||
static R fn_call_global(const data_t &d cat(PL)) {
|
||||
return d.fn_global(CL);
|
||||
static R callback_global(const data_t &data, P... p) {
|
||||
return data.callback_global(p...);
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
static R fn_call_member(const data_t &d cat(PL)) {
|
||||
return (((C*)d.object)->*((R (C::*&)(PL))d.fn_member))(CL);
|
||||
static R callback_member(const data_t &data, P... p) {
|
||||
return (((C*)data.object)->*((R (C::*&)(P...))data.callback_member))(p...);
|
||||
}
|
||||
|
||||
public:
|
||||
R operator()(PL) const { return data.fn_call(data cat(CL)); }
|
||||
operator bool() const { return data.fn_call; }
|
||||
R operator()(P... p) const { return data.callback(data, p...); }
|
||||
operator bool() const { return data.callback; }
|
||||
void reset() { data.callback = 0; }
|
||||
|
||||
function() { data.fn_call = 0; }
|
||||
|
||||
function(void *fn) {
|
||||
data.fn_call = fn ? &fn_call_global : 0;
|
||||
data.fn_global = (R (*)(PL))fn;
|
||||
}
|
||||
|
||||
function(R (*fn)(PL)) {
|
||||
data.fn_call = &fn_call_global;
|
||||
data.fn_global = fn;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL), C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
template<typename C>
|
||||
function(R (C::*fn)(PL) const, C *obj) {
|
||||
data.fn_call = &fn_call_member<C>;
|
||||
(R (C::*&)(PL))data.fn_member = (R (C::*&)(PL))fn;
|
||||
assert(sizeof data.fn_member >= sizeof fn);
|
||||
data.object = obj;
|
||||
}
|
||||
|
||||
function& operator=(void *fn) { return operator=(function(fn)); }
|
||||
function& operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; }
|
||||
function(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); }
|
||||
function(const function &source) { operator=(source); }
|
||||
|
||||
//no pointer
|
||||
function() {
|
||||
data.callback = 0;
|
||||
}
|
||||
|
||||
//symbolic link pointer (nall/dl.hpp::sym, etc)
|
||||
function(void *callback) {
|
||||
data.callback = callback ? &callback_global : 0;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
|
||||
//global function pointer
|
||||
function(R (*callback)(P...)) {
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = callback;
|
||||
}
|
||||
|
||||
//member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...), C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//const member function pointer
|
||||
template<typename C>
|
||||
function(R (C::*callback)(P...) const, C *object) {
|
||||
static_assert(sizeof data.callback_member >= sizeof callback, "callback_member is too small");
|
||||
data.callback = &callback_member<C>;
|
||||
(R (C::*&)(P...))data.callback_member = (R (C::*&)(P...))callback;
|
||||
data.object = object;
|
||||
}
|
||||
|
||||
//lambda function pointer
|
||||
template<typename T>
|
||||
function(T callback) {
|
||||
static_assert(std::is_same<R, typename std::result_of<T(P...)>::type>::value, "lambda mismatch");
|
||||
data.callback = &callback_global;
|
||||
data.callback_global = (R (*)(P...))callback;
|
||||
}
|
||||
};
|
||||
|
||||
template<TL>
|
||||
function<R (PL)> bind(R (*fn)(PL)) {
|
||||
return function<R (PL)>(fn);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL), C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
}
|
||||
|
||||
template<typename C, TL>
|
||||
function<R (PL)> bind(R (C::*fn)(PL) const, C *obj) {
|
||||
return function<R (PL)>(fn, obj);
|
||||
}
|
||||
}
|
||||
|
||||
#undef cat
|
||||
#undef TL
|
||||
#undef PL
|
||||
#undef CL
|
||||
|
||||
#endif
|
||||
|
@@ -93,9 +93,9 @@ struct Keyboard {
|
||||
if(!strbegin(name, "KB")) return 0;
|
||||
ltrim(s, "KB");
|
||||
unsigned id = strunsigned(s);
|
||||
int pos = strpos(s, "::");
|
||||
if(pos < 0) return 0;
|
||||
s = substr(s, pos + 2);
|
||||
auto pos = strpos(s, "::");
|
||||
if(!pos) return 0;
|
||||
s = substr(s, pos() + 2);
|
||||
for(unsigned i = 0; i < Limit; i++) {
|
||||
if(s == KeyboardScancodeName[i]) return Base + Size * id + i;
|
||||
}
|
||||
@@ -190,9 +190,9 @@ struct Mouse {
|
||||
if(!strbegin(name, "MS")) return 0;
|
||||
ltrim(s, "MS");
|
||||
unsigned id = strunsigned(s);
|
||||
int pos = strpos(s, "::");
|
||||
if(pos < 0) return 0;
|
||||
s = substr(s, pos + 2);
|
||||
auto pos = strpos(s, "::");
|
||||
if(!pos) return 0;
|
||||
s = substr(s, pos() + 2);
|
||||
for(unsigned i = 0; i < Limit; i++) {
|
||||
if(s == MouseScancodeName[i]) return Base + Size * id + i;
|
||||
}
|
||||
@@ -314,9 +314,9 @@ struct Joypad {
|
||||
if(!strbegin(name, "JP")) return 0;
|
||||
ltrim(s, "JP");
|
||||
unsigned id = strunsigned(s);
|
||||
int pos = strpos(s, "::");
|
||||
if(pos < 0) return 0;
|
||||
s = substr(s, pos + 2);
|
||||
auto pos = strpos(s, "::");
|
||||
if(!pos) return 0;
|
||||
s = substr(s, pos() + 2);
|
||||
for(unsigned i = 0; i < Limit; i++) {
|
||||
if(s == JoypadScancodeName[i]) return Base + Size * id + i;
|
||||
}
|
||||
|
@@ -211,7 +211,7 @@ inline void FileDialog::filterBoxChanged() {
|
||||
if(filters.length() == 0) {
|
||||
fileSystemModel->setNameFilters(QStringList() << "*");
|
||||
} else {
|
||||
filters = substr(filters, strpos(filters, "("));
|
||||
filters = substr(filters, strpos(filters, "(")());
|
||||
ltrim(filters, "(");
|
||||
rtrim(filters, ")");
|
||||
lstring part;
|
||||
|
20
snesfilter/nall/random.hpp
Normal file
20
snesfilter/nall/random.hpp
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef NALL_RANDOM_HPP
|
||||
#define NALL_RANDOM_HPP
|
||||
|
||||
namespace nall {
|
||||
//pseudo-random number generator
|
||||
inline unsigned prng() {
|
||||
static unsigned n = 0;
|
||||
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
|
||||
struct random_cyclic {
|
||||
unsigned seed;
|
||||
inline unsigned operator()() {
|
||||
return seed = (seed >> 1) ^ (((seed & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
random_cyclic() : seed(0) {}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,8 +1,9 @@
|
||||
#ifndef NALL_SERIALIZER_HPP
|
||||
#define NALL_SERIALIZER_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -16,6 +17,7 @@ namespace nall {
|
||||
//caveats:
|
||||
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
|
||||
//- floating-point usage is not portable across platforms
|
||||
|
||||
class serializer {
|
||||
public:
|
||||
enum mode_t { Load, Save, Size };
|
||||
@@ -51,7 +53,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void integer(T &value) {
|
||||
enum { size = is_bool<T>::value ? 1 : sizeof(T) };
|
||||
enum { size = std::is_same<bool, T>::value ? 1 : sizeof(T) };
|
||||
if(imode == Save) {
|
||||
for(unsigned n = 0; n < size; n++) idata[isize++] = value >> (n << 3);
|
||||
} else if(imode == Load) {
|
||||
@@ -63,7 +65,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
template<typename T> void array(T &array) {
|
||||
enum { size = sizeof(T) / sizeof(typename remove_extent<T>::type) };
|
||||
enum { size = sizeof(T) / sizeof(typename std::remove_extent<T>::type) };
|
||||
for(unsigned n = 0; n < size; n++) integer(array[n]);
|
||||
}
|
||||
|
||||
@@ -102,7 +104,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
serializer(serializer &&s) {
|
||||
operator=(move(s));
|
||||
operator=(std::move(s));
|
||||
}
|
||||
|
||||
//construction
|
||||
|
@@ -1,28 +1,135 @@
|
||||
#include "xml.hpp"
|
||||
XML xml;
|
||||
#ifndef NALL_SNES_INFO_HPP
|
||||
#define NALL_SNES_INFO_HPP
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
namespace nall {
|
||||
|
||||
void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
class snes_information {
|
||||
public:
|
||||
string xml_memory_map;
|
||||
|
||||
inline snes_information(const uint8_t *data, unsigned size);
|
||||
|
||||
private:
|
||||
inline void read_header(const uint8_t *data, unsigned size);
|
||||
inline unsigned find_header(const uint8_t *data, unsigned size);
|
||||
inline unsigned score_header(const uint8_t *data, unsigned size, unsigned addr);
|
||||
inline unsigned gameboy_ram_size(const uint8_t *data, unsigned size);
|
||||
inline bool gameboy_has_rtc(const uint8_t *data, unsigned size);
|
||||
|
||||
enum HeaderField {
|
||||
CartName = 0x00,
|
||||
Mapper = 0x15,
|
||||
RomType = 0x16,
|
||||
RomSize = 0x17,
|
||||
RamSize = 0x18,
|
||||
CartRegion = 0x19,
|
||||
Company = 0x1a,
|
||||
Version = 0x1b,
|
||||
Complement = 0x1c, //inverse checksum
|
||||
Checksum = 0x1e,
|
||||
ResetVector = 0x3c,
|
||||
};
|
||||
|
||||
enum Mode {
|
||||
ModeNormal,
|
||||
ModeBsxSlotted,
|
||||
ModeBsx,
|
||||
ModeSufamiTurbo,
|
||||
ModeSuperGameBoy,
|
||||
};
|
||||
|
||||
enum Type {
|
||||
TypeNormal,
|
||||
TypeBsxSlotted,
|
||||
TypeBsxBios,
|
||||
TypeBsx,
|
||||
TypeSufamiTurboBios,
|
||||
TypeSufamiTurbo,
|
||||
TypeSuperGameBoy1Bios,
|
||||
TypeSuperGameBoy2Bios,
|
||||
TypeGameBoy,
|
||||
TypeUnknown,
|
||||
};
|
||||
|
||||
enum Region {
|
||||
NTSC,
|
||||
PAL,
|
||||
};
|
||||
|
||||
enum MemoryMapper {
|
||||
LoROM,
|
||||
HiROM,
|
||||
ExLoROM,
|
||||
ExHiROM,
|
||||
SuperFXROM,
|
||||
SA1ROM,
|
||||
SPC7110ROM,
|
||||
BSCLoROM,
|
||||
BSCHiROM,
|
||||
BSXROM,
|
||||
STROM,
|
||||
};
|
||||
|
||||
enum DSP1MemoryMapper {
|
||||
DSP1Unmapped,
|
||||
DSP1LoROM1MB,
|
||||
DSP1LoROM2MB,
|
||||
DSP1HiROM,
|
||||
};
|
||||
|
||||
bool loaded; //is a base cartridge inserted?
|
||||
unsigned crc32; //crc32 of all cartridges (base+slot(s))
|
||||
unsigned rom_size;
|
||||
unsigned ram_size;
|
||||
|
||||
Mode mode;
|
||||
Type type;
|
||||
Region region;
|
||||
MemoryMapper mapper;
|
||||
DSP1MemoryMapper dsp1_mapper;
|
||||
|
||||
bool has_bsx_slot;
|
||||
bool has_superfx;
|
||||
bool has_sa1;
|
||||
bool has_srtc;
|
||||
bool has_sdd1;
|
||||
bool has_spc7110;
|
||||
bool has_spc7110rtc;
|
||||
bool has_cx4;
|
||||
bool has_dsp1;
|
||||
bool has_dsp2;
|
||||
bool has_dsp3;
|
||||
bool has_dsp4;
|
||||
bool has_obc1;
|
||||
bool has_st010;
|
||||
bool has_st011;
|
||||
bool has_st018;
|
||||
};
|
||||
|
||||
snes_information::snes_information(const uint8_t *data, unsigned size) {
|
||||
read_header(data, size);
|
||||
|
||||
xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
|
||||
string xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
|
||||
|
||||
if(type == TypeBsx) {
|
||||
xml << "<cartridge/>";
|
||||
xml_memory_map = xml;
|
||||
return;
|
||||
} else if(type == TypeSufamiTurbo) {
|
||||
}
|
||||
|
||||
if(type == TypeSufamiTurbo) {
|
||||
xml << "<cartridge/>";
|
||||
xml_memory_map = xml;
|
||||
return;
|
||||
} else if(type == TypeGameBoy) {
|
||||
}
|
||||
|
||||
if(type == TypeGameBoy) {
|
||||
xml << "<cartridge rtc='" << gameboy_has_rtc(data, size) << "'>\n";
|
||||
if(gameboy_ram_size(data, size) > 0) {
|
||||
xml << " <ram size='" << strhex(gameboy_ram_size(data, size)) << "'/>\n";
|
||||
}
|
||||
xml << "</cartridge>\n";
|
||||
xml_memory_map = xml;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -56,30 +163,6 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
xml << " <map address='80-bf:6000-7fff'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </supergameboy>\n";
|
||||
} else if(has_sdd1) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='linear' address='00-3f:8000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='40-7f:0000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='80-bf:8000-ffff'/>\n";
|
||||
xml << " </rom>\n";
|
||||
|
||||
if(ram_size > 0) {
|
||||
xml << " <ram size='" << strhex(ram_size) << "'>\n";
|
||||
xml << " <map mode='linear' address='20-3f:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='a0-bf:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='70-7f:0000-7fff'/>\n";
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
|
||||
xml << " <sdd1>\n";
|
||||
xml << " <mcu>\n";
|
||||
xml << " <map address='c0-ff:0000-ffff'/>\n";
|
||||
xml << " </mcu>\n";
|
||||
xml << " <mmio>\n";
|
||||
xml << " <map address='00-3f:4800-4807'/>\n";
|
||||
xml << " <map address='80-bf:4800-4807'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </sdd1>\n";
|
||||
} else if(has_spc7110) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='shadow' address='00-0f:8000-ffff'/>\n";
|
||||
@@ -147,6 +230,20 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
}
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
} else if(mapper == ExLoROM) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='linear' address='00-3f:8000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='40-7f:0000-ffff'/>\n";
|
||||
xml << " <map mode='linear' address='80-bf:8000-ffff'/>\n";
|
||||
xml << " </rom>\n";
|
||||
|
||||
if(ram_size > 0) {
|
||||
xml << " <ram size='" << strhex(ram_size) << "'>\n";
|
||||
xml << " <map mode='linear' address='20-3f:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='a0-bf:6000-7fff'/>\n";
|
||||
xml << " <map mode='linear' address='70-7f:0000-7fff'/>\n";
|
||||
xml << " </ram>\n";
|
||||
}
|
||||
} else if(mapper == ExHiROM) {
|
||||
xml << " <rom>\n";
|
||||
xml << " <map mode='shadow' address='00-3f:8000-ffff' offset='400000'/>\n";
|
||||
@@ -290,6 +387,18 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
xml << " </srtc>\n";
|
||||
}
|
||||
|
||||
if(has_sdd1) {
|
||||
xml << " <sdd1>\n";
|
||||
xml << " <mcu>\n";
|
||||
xml << " <map address='c0-ff:0000-ffff'/>\n";
|
||||
xml << " </mcu>\n";
|
||||
xml << " <mmio>\n";
|
||||
xml << " <map address='00-3f:4800-4807'/>\n";
|
||||
xml << " <map address='80-bf:4800-4807'/>\n";
|
||||
xml << " </mmio>\n";
|
||||
xml << " </sdd1>\n";
|
||||
}
|
||||
|
||||
if(has_cx4) {
|
||||
xml << " <cx4>\n";
|
||||
xml << " <mmio>\n";
|
||||
@@ -335,12 +444,12 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
if(has_dsp2) {
|
||||
xml << " <necdsp program='DSP-2'>\n";
|
||||
xml << " <dr>\n";
|
||||
xml << " <map address='20-3f:6000-6fff'/>\n";
|
||||
xml << " <map address='a0-bf:6000-6fff'/>\n";
|
||||
xml << " </dr>\n";
|
||||
xml << " <sr>\n";
|
||||
xml << " <map address='20-3f:8000-bfff'/>\n";
|
||||
xml << " <map address='a0-bf:8000-bfff'/>\n";
|
||||
xml << " </dr>\n";
|
||||
xml << " <sr>\n";
|
||||
xml << " <map address='20-3f:c000-ffff'/>\n";
|
||||
xml << " <map address='a0-bf:c000-ffff'/>\n";
|
||||
xml << " </sr>\n";
|
||||
xml << " </necdsp>\n";
|
||||
}
|
||||
@@ -409,9 +518,10 @@ void XML::generate(string &xml, const uint8_t *data, unsigned size) {
|
||||
}
|
||||
|
||||
xml << "</cartridge>\n";
|
||||
xml_memory_map = xml;
|
||||
}
|
||||
|
||||
void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
void snes_information::read_header(const uint8_t *data, unsigned size) {
|
||||
type = TypeUnknown;
|
||||
mapper = LoROM;
|
||||
dsp1_mapper = DSP1Unmapped;
|
||||
@@ -449,11 +559,11 @@ void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
}
|
||||
|
||||
const unsigned index = find_header(data, size);
|
||||
const uint8 mapperid = data[index + Mapper];
|
||||
const uint8 rom_type = data[index + RomType];
|
||||
const uint8 rom_size = data[index + RomSize];
|
||||
const uint8 company = data[index + Company];
|
||||
const uint8 regionid = data[index + CartRegion] & 0x7f;
|
||||
const uint8_t mapperid = data[index + Mapper];
|
||||
const uint8_t rom_type = data[index + RomType];
|
||||
const uint8_t rom_size = data[index + RomSize];
|
||||
const uint8_t company = data[index + Company];
|
||||
const uint8_t regionid = data[index + CartRegion] & 0x7f;
|
||||
|
||||
ram_size = 1024 << (data[index + RamSize] & 7);
|
||||
if(ram_size == 1024) ram_size = 0; //no RAM present
|
||||
@@ -515,7 +625,7 @@ void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
||||
if(data[index - 14] == 'Z') {
|
||||
if(data[index - 11] == 'J') {
|
||||
uint8 n13 = data[index - 13];
|
||||
uint8_t n13 = data[index - 13];
|
||||
if((n13 >= 'A' && n13 <= 'Z') || (n13 >= '0' && n13 <= '9')) {
|
||||
if(company == 0x33 || (data[index - 10] == 0x00 && data[index - 4] == 0x00)) {
|
||||
has_bsx_slot = true;
|
||||
@@ -634,7 +744,7 @@ void XML::read_header(const uint8_t *data, unsigned size) {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned XML::find_header(const uint8_t *data, unsigned size) const {
|
||||
unsigned snes_information::find_header(const uint8_t *data, unsigned size) {
|
||||
unsigned score_lo = score_header(data, size, 0x007fc0);
|
||||
unsigned score_hi = score_header(data, size, 0x00ffc0);
|
||||
unsigned score_ex = score_header(data, size, 0x40ffc0);
|
||||
@@ -649,16 +759,16 @@ unsigned XML::find_header(const uint8_t *data, unsigned size) const {
|
||||
}
|
||||
}
|
||||
|
||||
unsigned XML::score_header(const uint8_t *data, unsigned size, unsigned addr) const {
|
||||
unsigned snes_information::score_header(const uint8_t *data, unsigned size, unsigned addr) {
|
||||
if(size < addr + 64) return 0; //image too small to contain header at this location?
|
||||
int score = 0;
|
||||
|
||||
uint16 resetvector = data[addr + ResetVector] | (data[addr + ResetVector + 1] << 8);
|
||||
uint16 checksum = data[addr + Checksum ] | (data[addr + Checksum + 1] << 8);
|
||||
uint16 complement = data[addr + Complement ] | (data[addr + Complement + 1] << 8);
|
||||
uint16_t resetvector = data[addr + ResetVector] | (data[addr + ResetVector + 1] << 8);
|
||||
uint16_t checksum = data[addr + Checksum ] | (data[addr + Checksum + 1] << 8);
|
||||
uint16_t complement = data[addr + Complement ] | (data[addr + Complement + 1] << 8);
|
||||
|
||||
uint8 resetop = data[(addr & ~0x7fff) | (resetvector & 0x7fff)]; //first opcode executed upon reset
|
||||
uint8 mapper = data[addr + Mapper] & ~0x10; //mask off irrelevent FastROM-capable bit
|
||||
uint8_t resetop = data[(addr & ~0x7fff) | (resetvector & 0x7fff)]; //first opcode executed upon reset
|
||||
uint8_t mapper = data[addr + Mapper] & ~0x10; //mask off irrelevent FastROM-capable bit
|
||||
|
||||
//$00:[000-7fff] contains uninitialized RAM and MMIO.
|
||||
//reset vector must point to ROM at $00:[8000-ffff] to be considered valid.
|
||||
@@ -730,7 +840,7 @@ unsigned XML::score_header(const uint8_t *data, unsigned size, unsigned addr) co
|
||||
return score;
|
||||
}
|
||||
|
||||
unsigned XML::gameboy_ram_size(const uint8_t *data, unsigned size) const {
|
||||
unsigned snes_information::gameboy_ram_size(const uint8_t *data, unsigned size) {
|
||||
if(size < 512) return 0;
|
||||
switch(data[0x0149]) {
|
||||
case 0x00: return 0 * 1024;
|
||||
@@ -743,8 +853,12 @@ unsigned XML::gameboy_ram_size(const uint8_t *data, unsigned size) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool XML::gameboy_has_rtc(const uint8_t *data, unsigned size) const {
|
||||
bool snes_information::gameboy_has_rtc(const uint8_t *data, unsigned size) {
|
||||
if(size < 512) return false;
|
||||
if(data[0x0147] == 0x0f ||data[0x0147] == 0x10) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -2,6 +2,8 @@
|
||||
#define NALL_STRING_HPP
|
||||
|
||||
#include <initializer_list>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
#include <nall/string/base.hpp>
|
||||
#include <nall/string/core.hpp>
|
||||
#include <nall/string/cast.hpp>
|
||||
@@ -11,6 +13,7 @@
|
||||
#include <nall/string/match.hpp>
|
||||
#include <nall/string/math.hpp>
|
||||
#include <nall/string/strl.hpp>
|
||||
#include <nall/string/strpos.hpp>
|
||||
#include <nall/string/trim.hpp>
|
||||
#include <nall/string/replace.hpp>
|
||||
#include <nall/string/split.hpp>
|
||||
|
@@ -10,42 +10,13 @@
|
||||
#include <nall/utf8.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline int strpos (const char *str, const char *key);
|
||||
inline int qstrpos(const char *str, const char *key);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
inline size_t strlcpy(char *dest, const char *src, size_t length);
|
||||
inline size_t strlcat(char *dest, const char *src, size_t length);
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
namespace nall {
|
||||
class string;
|
||||
template<typename T> inline string to_string(T);
|
||||
|
||||
class string {
|
||||
public:
|
||||
inline void reserve(size_t);
|
||||
inline void reserve(unsigned);
|
||||
inline unsigned length() const;
|
||||
|
||||
inline string& assign(const char*);
|
||||
@@ -64,12 +35,13 @@ namespace nall {
|
||||
inline bool operator> (const char*) const;
|
||||
inline bool operator>=(const char*) const;
|
||||
|
||||
inline string& operator=(const string&);
|
||||
inline string& operator=(string&&);
|
||||
|
||||
inline string();
|
||||
inline string(const char*);
|
||||
inline string(const string&);
|
||||
inline string(string&&);
|
||||
inline string& operator=(const string&);
|
||||
inline string& operator=(string&&);
|
||||
inline ~string();
|
||||
|
||||
inline bool readfile(const char*);
|
||||
@@ -78,9 +50,9 @@ namespace nall {
|
||||
|
||||
protected:
|
||||
char *data;
|
||||
size_t size;
|
||||
unsigned size;
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
#if defined(QSTRING_H)
|
||||
public:
|
||||
inline operator QString() const;
|
||||
#endif
|
||||
@@ -98,29 +70,67 @@ namespace nall {
|
||||
lstring(std::initializer_list<string>);
|
||||
};
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args);
|
||||
template<typename... Args> inline void print(const char *s, Args... args);
|
||||
//compare.hpp
|
||||
inline char chrlower(char c);
|
||||
inline char chrupper(char c);
|
||||
inline int stricmp(const char *dest, const char *src);
|
||||
inline bool strbegin (const char *str, const char *key);
|
||||
inline bool stribegin(const char *str, const char *key);
|
||||
inline bool strend (const char *str, const char *key);
|
||||
inline bool striend(const char *str, const char *key);
|
||||
|
||||
//convert.hpp
|
||||
inline char* strlower(char *str);
|
||||
inline char* strupper(char *str);
|
||||
inline char* strtr(char *dest, const char *before, const char *after);
|
||||
inline uintmax_t strhex (const char *str);
|
||||
inline intmax_t strsigned (const char *str);
|
||||
inline uintmax_t strunsigned(const char *str);
|
||||
inline uintmax_t strbin (const char *str);
|
||||
inline double strdouble (const char *str);
|
||||
|
||||
//match.hpp
|
||||
inline bool match(const char *pattern, const char *str);
|
||||
|
||||
//math.hpp
|
||||
inline bool strint (const char *str, int &result);
|
||||
inline bool strmath(const char *str, int &result);
|
||||
|
||||
//strl.hpp
|
||||
inline unsigned strlcpy(char *dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(char *dest, const char *src, unsigned length);
|
||||
|
||||
//trim.hpp
|
||||
inline char* ltrim(char *str, const char *key = " ");
|
||||
inline char* rtrim(char *str, const char *key = " ");
|
||||
inline char* trim (char *str, const char *key = " ");
|
||||
inline char* ltrim_once(char *str, const char *key = " ");
|
||||
inline char* rtrim_once(char *str, const char *key = " ");
|
||||
inline char* trim_once (char *str, const char *key = " ");
|
||||
|
||||
//utility.hpp
|
||||
inline unsigned strlcpy(string &dest, const char *src, unsigned length);
|
||||
inline unsigned strlcat(string &dest, const char *src, unsigned length);
|
||||
inline string substr(const char *src, unsigned start = 0, unsigned length = 0);
|
||||
inline string& strlower(string &str);
|
||||
inline string& strupper(string &str);
|
||||
inline string& strtr(string &dest, const char *before, const char *after);
|
||||
inline string& ltrim(string &str, const char *key = " ");
|
||||
inline string& rtrim(string &str, const char *key = " ");
|
||||
inline string& trim (string &str, const char *key = " ");
|
||||
inline string& ltrim_once(string &str, const char *key = " ");
|
||||
inline string& rtrim_once(string &str, const char *key = " ");
|
||||
inline string& trim_once (string &str, const char *key = " ");
|
||||
template<unsigned length = 0, char padding = '0'> inline string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline string strbin(uintmax_t value);
|
||||
inline unsigned strdouble(char *str, double value);
|
||||
inline string strdouble(double value);
|
||||
|
||||
//variadic.hpp
|
||||
template<typename... Args> inline string sprint(Args... args);
|
||||
template<typename... Args> inline void print(Args... args);
|
||||
};
|
||||
|
||||
inline size_t strlcpy(nall::string &dest, const char *src, size_t length);
|
||||
inline size_t strlcat(nall::string &dest, const char *src, size_t length);
|
||||
|
||||
inline nall::string& strlower(nall::string &str);
|
||||
inline nall::string& strupper(nall::string &str);
|
||||
inline nall::string& strtr(nall::string &dest, const char *before, const char *after);
|
||||
inline nall::string& ltrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim (nall::string &str, const char *key = " ");
|
||||
inline nall::string& ltrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& rtrim_once(nall::string &str, const char *key = " ");
|
||||
inline nall::string& trim_once (nall::string &str, const char *key = " ");
|
||||
|
||||
inline nall::string substr(const char *src, size_t start = 0, size_t length = 0);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strhex(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strsigned(intmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strunsigned(uintmax_t value);
|
||||
template<unsigned length = 0, char padding = '0'> inline nall::string strbin(uintmax_t value);
|
||||
inline size_t strdouble(char *str, double value);
|
||||
inline nall::string strdouble(double value);
|
||||
|
||||
#endif
|
||||
|
@@ -2,28 +2,31 @@
|
||||
#define NALL_STRING_CAST_HPP
|
||||
|
||||
namespace nall {
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
//this is needed, as C++0x does not support explicit template specialization inside classes
|
||||
template<> inline string to_string<bool> (bool v) { return v ? "true" : "false"; }
|
||||
template<> inline string to_string<signed int> (signed int v) { return strsigned(v); }
|
||||
template<> inline string to_string<unsigned int> (unsigned int v) { return strunsigned(v); }
|
||||
template<> inline string to_string<double> (double v) { return strdouble(v); }
|
||||
template<> inline string to_string<char*> (char *v) { return v; }
|
||||
template<> inline string to_string<const char*> (const char *v) { return v; }
|
||||
template<> inline string to_string<string> (string v) { return v; }
|
||||
template<> inline string to_string<const string&>(const string &v) { return v; }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
template<typename T> string& string::operator= (T value) { return assign(to_string<T>(value)); }
|
||||
template<typename T> string& string::operator<<(T value) { return append(to_string<T>(value)); }
|
||||
|
||||
template<typename T> lstring& lstring::operator<<(T value) {
|
||||
operator[](size()).assign(to_string<T>(value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if defined(QSTRING_H)
|
||||
template<> inline string to_string<QString>(QString v) { return v.toUtf8().constData(); }
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
|
||||
#if defined(QT_CORE_LIB)
|
||||
template<> inline string to_string<const QString&>(const QString &v) { return v.toUtf8().constData(); }
|
||||
string::operator QString() const { return QString::fromUtf8(*this); }
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_COMPARE_HPP
|
||||
#define NALL_STRING_COMPARE_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char chrlower(char c) {
|
||||
return (c >= 'A' && c <= 'Z') ? c + ('a' - 'A') : c;
|
||||
}
|
||||
@@ -19,38 +21,6 @@ int stricmp(const char *dest, const char *src) {
|
||||
return (int)chrlower(*dest) - (int)chrlower(*src);
|
||||
}
|
||||
|
||||
int strpos(const char *str, const char *key) {
|
||||
int ssl = strlen(str), ksl = strlen(key);
|
||||
|
||||
if(ksl > ssl) return -1;
|
||||
for(int i = 0; i <= ssl - ksl; i++) {
|
||||
if(!memcmp(str + i, key, ksl)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int qstrpos(const char *str, const char *key) {
|
||||
int ssl = strlen(str), ksl = strlen(key);
|
||||
|
||||
if(ksl > ssl) return -1;
|
||||
for(int i = 0; i <= ssl - ksl;) {
|
||||
uint8_t x = str[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
uint8_t z = i++;
|
||||
while(str[i] != x && i < ssl) i++;
|
||||
if(i >= ssl) i = z;
|
||||
}
|
||||
if(!memcmp(str + i, key, ksl)) {
|
||||
return i;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool strbegin(const char *str, const char *key) {
|
||||
int i, ssl = strlen(str), ksl = strlen(key);
|
||||
|
||||
@@ -97,4 +67,6 @@ bool striend(const char *str, const char *key) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_CONVERT_HPP
|
||||
#define NALL_STRING_CONVERT_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* strlower(char *str) {
|
||||
if(!str) return 0;
|
||||
int i = 0;
|
||||
@@ -125,7 +127,7 @@ double strdouble(const char *str) {
|
||||
while(*str) {
|
||||
uint8_t x = *str++;
|
||||
if(x >= '0' && x <= '9') x -= '0';
|
||||
else if(x == '.') break; //break loop and read fractional part
|
||||
else if(x == '.' || x == ',') break; //break loop and read fractional part
|
||||
else return (double)result_integral; //invalid value, assume no fractional part
|
||||
result_integral = result_integral * 10 + x;
|
||||
}
|
||||
@@ -146,4 +148,6 @@ double strdouble(const char *str) {
|
||||
return !negate ? result : -result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -3,7 +3,7 @@
|
||||
|
||||
namespace nall {
|
||||
|
||||
void string::reserve(size_t size_) {
|
||||
void string::reserve(unsigned size_) {
|
||||
if(size_ > size) {
|
||||
size = size_;
|
||||
data = (char*)realloc(data, size + 1);
|
||||
@@ -49,6 +49,20 @@ 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) {
|
||||
assign(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string& string::operator=(string &&source) {
|
||||
if(data) free(data);
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
source.size = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string::string() {
|
||||
size = 64;
|
||||
data = (char*)malloc(size + 1);
|
||||
@@ -71,19 +85,6 @@ string::string(string &&source) {
|
||||
source.data = 0;
|
||||
}
|
||||
|
||||
string& string::operator=(const string &value) {
|
||||
assign(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string& string::operator=(string &&source) {
|
||||
if(data) free(data);
|
||||
size = source.size;
|
||||
data = source.data;
|
||||
source.data = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
string::~string() {
|
||||
free(data);
|
||||
}
|
||||
@@ -94,12 +95,12 @@ bool string::readfile(const char *filename) {
|
||||
#if !defined(_WIN32)
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
#else
|
||||
FILE *fp = _wfopen(nall::utf16_t(filename), L"rb");
|
||||
FILE *fp = _wfopen(utf16_t(filename), L"rb");
|
||||
#endif
|
||||
if(!fp) return false;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size_t size = ftell(fp);
|
||||
unsigned size = ftell(fp);
|
||||
rewind(fp);
|
||||
char *fdata = new char[size + 1];
|
||||
unsigned unused = fread(fdata, 1, size, fp);
|
||||
|
@@ -2,59 +2,60 @@
|
||||
#define NALL_FILENAME_HPP
|
||||
|
||||
namespace nall {
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/", "bar.c" -> "./"
|
||||
inline string dir(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
result[i + 1] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
if(i == 0) result = "./";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "bar.c"
|
||||
inline string notdir(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '/' || name[i] == '\\') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
// "foo/bar.c" -> "foo/bar"
|
||||
inline string basename(char const *name) {
|
||||
string result = name;
|
||||
for(signed i = strlen(result); i >= 0; i--) {
|
||||
if(result[i] == '/' || result[i] == '\\') {
|
||||
//file has no extension
|
||||
break;
|
||||
}
|
||||
if(result[i] == '.') {
|
||||
result[i] = 0;
|
||||
break;
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// "foo/bar.c" -> "c"
|
||||
inline string extension(char const *name) {
|
||||
for(signed i = strlen(name); i >= 0; i--) {
|
||||
if(name[i] == '.') {
|
||||
name += i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string result = name;
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATCH_HPP
|
||||
#define NALL_STRING_MATCH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
bool match(const char *p, const char *s) {
|
||||
const char *p_ = 0, *s_ = 0;
|
||||
|
||||
@@ -69,4 +71,6 @@ bool match(const char *p, const char *s) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_MATH_HPP
|
||||
#define NALL_STRING_MATH_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
static int eval_integer(const char *&s) {
|
||||
if(!*s) throw "unrecognized_integer";
|
||||
int value = 0, x = *s, y = *(s + 1);
|
||||
@@ -157,4 +159,6 @@ bool strmath(const char *s, int &result) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,13 +1,15 @@
|
||||
#ifndef NALL_STRING_STRL_HPP
|
||||
#define NALL_STRING_STRL_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
//strlcpy, strlcat based on OpenBSD implementation by Todd C. Miller
|
||||
|
||||
//return = strlen(src)
|
||||
size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcpy(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
if(n) {
|
||||
while(--n && (*d++ = *s++)); //copy as many bytes as possible, or until null terminator reached
|
||||
@@ -22,13 +24,13 @@ size_t strlcpy(char *dest, const char *src, size_t length) {
|
||||
}
|
||||
|
||||
//return = strlen(src) + min(length, strlen(dest))
|
||||
size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
unsigned strlcat(char *dest, const char *src, unsigned length) {
|
||||
char *d = dest;
|
||||
const char *s = src;
|
||||
size_t n = length;
|
||||
unsigned n = length;
|
||||
|
||||
while(n-- && *d) d++; //find end of dest
|
||||
size_t dlength = d - dest;
|
||||
unsigned dlength = d - dest;
|
||||
n = length - dlength; //subtract length of dest from maximum string length
|
||||
|
||||
if(!n) return dlength + strlen(s);
|
||||
@@ -45,4 +47,6 @@ size_t strlcat(char *dest, const char *src, size_t length) {
|
||||
return dlength + (s - src); //return length of resulting string, sans null terminator
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
41
snesfilter/nall/string/strpos.hpp
Normal file
41
snesfilter/nall/string/strpos.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef NALL_STRING_STRPOS_HPP
|
||||
#define NALL_STRING_STRPOS_HPP
|
||||
|
||||
//usage example:
|
||||
//if(auto pos = strpos(str, key)) print(pos(), "\n");
|
||||
//prints position of key within str, only if it is found
|
||||
|
||||
namespace nall {
|
||||
|
||||
optional<unsigned> inline strpos(const char *str, const char *key) {
|
||||
unsigned ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl) return { false, 0 };
|
||||
|
||||
for(unsigned i = 0; i <= ssl - ksl; i++) {
|
||||
if(!memcmp(str + i, key, ksl)) return { true, i };
|
||||
}
|
||||
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
optional<unsigned> inline qstrpos(const char *str, const char *key) {
|
||||
unsigned ssl = strlen(str), ksl = strlen(key);
|
||||
if(ksl > ssl) return { false, 0 };
|
||||
|
||||
for(unsigned i = 0; i <= ssl - ksl;) {
|
||||
uint8_t x = str[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
uint8_t z = i++;
|
||||
while(str[i] != x && i < ssl) i++;
|
||||
if(i >= ssl) i = z;
|
||||
}
|
||||
if(!memcmp(str + i, key, ksl)) return { true, i };
|
||||
i++;
|
||||
}
|
||||
|
||||
return { false, 0 };
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,6 +1,8 @@
|
||||
#ifndef NALL_STRING_TRIM_HPP
|
||||
#define NALL_STRING_TRIM_HPP
|
||||
|
||||
namespace nall {
|
||||
|
||||
char* ltrim(char *str, const char *key) {
|
||||
if(!key || !*key) return str;
|
||||
while(strbegin(str, key)) {
|
||||
@@ -47,4 +49,6 @@ char* trim_once(char *str, const char *key) {
|
||||
return ltrim_once(rtrim_once(str, key), key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,18 +1,20 @@
|
||||
#ifndef NALL_STRING_UTILITY_HPP
|
||||
#define NALL_STRING_UTILITY_HPP
|
||||
|
||||
size_t strlcpy(nall::string &dest, const char *src, size_t length) {
|
||||
namespace nall {
|
||||
|
||||
unsigned strlcpy(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcpy(dest(), src, length);
|
||||
}
|
||||
|
||||
size_t strlcat(nall::string &dest, const char *src, size_t length) {
|
||||
unsigned strlcat(string &dest, const char *src, unsigned length) {
|
||||
dest.reserve(length);
|
||||
return strlcat(dest(), src, length);
|
||||
}
|
||||
|
||||
nall::string substr(const char *src, size_t start, size_t length) {
|
||||
nall::string dest;
|
||||
string substr(const char *src, unsigned start, unsigned length) {
|
||||
string dest;
|
||||
if(length == 0) {
|
||||
//copy entire string
|
||||
dest = src + start;
|
||||
@@ -23,22 +25,22 @@ nall::string substr(const char *src, size_t start, size_t length) {
|
||||
return dest;
|
||||
}
|
||||
|
||||
/* very simplistic wrappers to return nall::string& instead of char* type */
|
||||
/* very simplistic wrappers to return string& instead of char* type */
|
||||
|
||||
nall::string& strlower(nall::string &str) { strlower(str()); return str; }
|
||||
nall::string& strupper(nall::string &str) { strupper(str()); return str; }
|
||||
nall::string& strtr(nall::string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
nall::string& ltrim(nall::string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
nall::string& rtrim(nall::string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
nall::string& trim (nall::string &str, const char *key) { trim (str(), key); return str; }
|
||||
nall::string& ltrim_once(nall::string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
nall::string& rtrim_once(nall::string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
nall::string& trim_once (nall::string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
string& strlower(string &str) { strlower(str()); return str; }
|
||||
string& strupper(string &str) { strupper(str()); return str; }
|
||||
string& strtr(string &dest, const char *before, const char *after) { strtr(dest(), before, after); return dest; }
|
||||
string& ltrim(string &str, const char *key) { ltrim(str(), key); return str; }
|
||||
string& rtrim(string &str, const char *key) { rtrim(str(), key); return str; }
|
||||
string& trim (string &str, const char *key) { trim (str(), key); return str; }
|
||||
string& ltrim_once(string &str, const char *key) { ltrim_once(str(), key); return str; }
|
||||
string& rtrim_once(string &str, const char *key) { rtrim_once(str(), key); return str; }
|
||||
string& trim_once (string &str, const char *key) { trim_once (str(), key); return str; }
|
||||
|
||||
/* arithmetic <> string */
|
||||
|
||||
template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strhex(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
//render string backwards, as we do not know its length yet
|
||||
@@ -61,8 +63,8 @@ template<unsigned length, char padding> nall::string strhex(uintmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strsigned(intmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
bool negative = value < 0;
|
||||
@@ -87,8 +89,8 @@ template<unsigned length, char padding> nall::string strsigned(intmax_t value) {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strunsigned(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strunsigned(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -109,8 +111,8 @@ template<unsigned length, char padding> nall::string strunsigned(uintmax_t value
|
||||
return output;
|
||||
}
|
||||
|
||||
template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
nall::string output;
|
||||
template<unsigned length, char padding> string strbin(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
|
||||
do {
|
||||
@@ -134,7 +136,7 @@ template<unsigned length, char padding> nall::string strbin(uintmax_t value) {
|
||||
//using sprintf is certainly not the most ideal method to convert
|
||||
//a double to a string ... but attempting to parse a double by
|
||||
//hand, digit-by-digit, results in subtle rounding errors.
|
||||
size_t strdouble(char *str, double value) {
|
||||
unsigned strdouble(char *str, double value) {
|
||||
char buffer[256];
|
||||
sprintf(buffer, "%f", value);
|
||||
|
||||
@@ -155,11 +157,13 @@ size_t strdouble(char *str, double value) {
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
nall::string strdouble(double value) {
|
||||
nall::string temp;
|
||||
string strdouble(double value) {
|
||||
string temp;
|
||||
temp.reserve(strdouble(0, value));
|
||||
strdouble(temp(), value);
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2,36 +2,26 @@
|
||||
#define NALL_STRING_VARIADIC_HPP
|
||||
|
||||
namespace nall {
|
||||
static void sprint(string &output, unsigned &offset, const char *&s) {
|
||||
while(*s) output[offset++] = *s++;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
static void sprint(string &output, unsigned &offset, const char *&s, T value, Args... args) {
|
||||
while(*s) {
|
||||
if(*s == '$') {
|
||||
string data = to_string<T>(value);
|
||||
unsigned i = 0;
|
||||
while(data[i]) output[offset++] = data[i++];
|
||||
sprint(output, offset, ++s, args...);
|
||||
return;
|
||||
} else {
|
||||
output[offset++] = *s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void isprint(string &output) {
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(const char *s, Args... args) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
sprint(output, offset, s, args...);
|
||||
output[offset] = 0;
|
||||
return output;
|
||||
}
|
||||
template<typename T, typename... Args>
|
||||
static void isprint(string &output, T value, Args... args) {
|
||||
output << to_string<T>(value);
|
||||
isprint(output, args...);
|
||||
}
|
||||
|
||||
template<typename... Args> inline string sprint(Args... args) {
|
||||
string output;
|
||||
isprint(output, args...);
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(Args... args) {
|
||||
printf("%s", (const char*)sprint(args...));
|
||||
}
|
||||
|
||||
template<typename... Args> inline void print(const char *s, Args... args) {
|
||||
printf("%s", (const char*)sprint(s, args...));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -2,9 +2,7 @@
|
||||
#define NALL_STRING_XML_HPP
|
||||
|
||||
//XML subset parser
|
||||
//version 0.04
|
||||
|
||||
#include <nall/array.hpp>
|
||||
//version 0.05
|
||||
|
||||
namespace nall {
|
||||
|
||||
@@ -16,15 +14,14 @@ struct xml_attribute {
|
||||
|
||||
struct xml_element : xml_attribute {
|
||||
string parse() const;
|
||||
array<xml_attribute*> attribute;
|
||||
array<xml_element*> element;
|
||||
~xml_element();
|
||||
linear_vector<xml_attribute> attribute;
|
||||
linear_vector<xml_element> element;
|
||||
|
||||
protected:
|
||||
void parse_doctype(const char *&data);
|
||||
bool parse_head(string data);
|
||||
bool parse_body(const char *&data);
|
||||
friend xml_element *xml_parse(const char *data);
|
||||
friend xml_element xml_parse(const char *data);
|
||||
};
|
||||
|
||||
inline string xml_attribute::parse() const {
|
||||
@@ -68,21 +65,25 @@ inline string xml_element::parse() const {
|
||||
}
|
||||
|
||||
if(strbegin(source, "<!--")) {
|
||||
signed pos = strpos(source, "-->");
|
||||
if(pos == -1) return "";
|
||||
source += pos + 3;
|
||||
continue;
|
||||
if(auto pos = strpos(source, "-->")) {
|
||||
source += pos() + 3;
|
||||
continue;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
if(strbegin(source, "<![CDATA[")) {
|
||||
signed pos = strpos(source, "]]>");
|
||||
if(pos == -1) return "";
|
||||
string cdata = substr(source, 9, pos - 9);
|
||||
data << cdata;
|
||||
offset += strlen(cdata);
|
||||
if(auto pos = strpos(source, "]]>")) {
|
||||
string cdata = substr(source, 9, pos() - 9);
|
||||
data << cdata;
|
||||
offset += strlen(cdata);
|
||||
|
||||
source += offset + 3;
|
||||
continue;
|
||||
source += offset + 3;
|
||||
continue;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
//reject illegal characters
|
||||
@@ -118,7 +119,7 @@ inline bool xml_element::parse_head(string data) {
|
||||
data.qreplace("\t", " ");
|
||||
data.qreplace("\r", " ");
|
||||
data.qreplace("\n", " ");
|
||||
while(qstrpos(data, " ") >= 0) data.qreplace(" ", " ");
|
||||
while(qstrpos(data, " ")) data.qreplace(" ", " ");
|
||||
data.qreplace(" =", "=");
|
||||
data.qreplace("= ", "=");
|
||||
rtrim(data);
|
||||
@@ -134,13 +135,13 @@ inline bool xml_element::parse_head(string data) {
|
||||
side.qsplit("=", part[i]);
|
||||
if(side.size() != 2) throw "...";
|
||||
|
||||
xml_attribute *attr = new xml_attribute;
|
||||
attr->name = side[0];
|
||||
attr->content = side[1];
|
||||
if(strbegin(attr->content, "\"") && strend(attr->content, "\"")) trim_once(attr->content, "\"");
|
||||
else if(strbegin(attr->content, "'") && strend(attr->content, "'")) trim_once(attr->content, "'");
|
||||
xml_attribute attr;
|
||||
attr.name = side[0];
|
||||
attr.content = side[1];
|
||||
if(strbegin(attr.content, "\"") && strend(attr.content, "\"")) trim_once(attr.content, "\"");
|
||||
else if(strbegin(attr.content, "'") && strend(attr.content, "'")) trim_once(attr.content, "'");
|
||||
else throw "...";
|
||||
attribute.add(attr);
|
||||
attribute.append(attr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,24 +157,28 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
}
|
||||
|
||||
if(strbegin(data, "!--")) {
|
||||
signed offset = strpos(data, "-->");
|
||||
if(offset == -1) throw "...";
|
||||
data += offset + 3;
|
||||
continue;
|
||||
if(auto offset = strpos(data, "-->")) {
|
||||
data += offset() + 3;
|
||||
continue;
|
||||
} else {
|
||||
throw "...";
|
||||
}
|
||||
}
|
||||
|
||||
if(strbegin(data, "![CDATA[")) {
|
||||
signed offset = strpos(data, "]]>");
|
||||
if(offset == -1) throw "...";
|
||||
data += offset + 3;
|
||||
continue;
|
||||
if(auto offset = strpos(data, "]]>")) {
|
||||
data += offset() + 3;
|
||||
continue;
|
||||
} else {
|
||||
throw "...";
|
||||
}
|
||||
}
|
||||
|
||||
signed offset = strpos(data, ">");
|
||||
if(offset == -1) throw "...";
|
||||
auto offset = strpos(data, ">");
|
||||
if(!offset) throw "...";
|
||||
|
||||
string tag = substr(data, 0, offset);
|
||||
data += offset + 1;
|
||||
string tag = substr(data, 0, offset());
|
||||
data += offset() + 1;
|
||||
const char *content_begin = data;
|
||||
|
||||
bool self_terminating = false;
|
||||
@@ -191,48 +196,41 @@ inline bool xml_element::parse_body(const char *&data) {
|
||||
|
||||
while(*data) {
|
||||
unsigned index = element.size();
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
if(*data == '/') {
|
||||
signed length = data - content_begin - 1;
|
||||
if(length > 0) content = substr(content_begin, 0, length);
|
||||
|
||||
data++;
|
||||
offset = strpos(data, ">");
|
||||
if(offset == -1) throw "...";
|
||||
auto offset = strpos(data, ">");
|
||||
if(!offset) throw "...";
|
||||
|
||||
tag = substr(data, 0, offset);
|
||||
data += offset + 1;
|
||||
tag = substr(data, 0, offset());
|
||||
data += offset() + 1;
|
||||
|
||||
tag.replace("\t", " ");
|
||||
tag.replace("\r", " ");
|
||||
tag.replace("\n", " ");
|
||||
while(strpos(tag, " ") >= 0) tag.replace(" ", " ");
|
||||
while(strpos(tag, " ")) tag.replace(" ", " ");
|
||||
rtrim(tag);
|
||||
|
||||
if(name != tag) throw "...";
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
element.add(elem);
|
||||
element.append(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline xml_element::~xml_element() {
|
||||
for(unsigned i = 0; i < attribute.size(); i++) delete attribute[i];
|
||||
for(unsigned i = 0; i < element.size(); i++) delete element[i];
|
||||
}
|
||||
|
||||
//ensure there is only one root element
|
||||
inline bool xml_validate(xml_element *document) {
|
||||
inline bool xml_validate(xml_element &document) {
|
||||
unsigned root_counter = 0;
|
||||
|
||||
for(unsigned i = 0; i < document->element.size(); i++) {
|
||||
string &name = document->element[i]->name;
|
||||
for(unsigned i = 0; i < document.element.size(); i++) {
|
||||
string &name = document.element[i].name;
|
||||
if(strbegin(name, "?")) continue;
|
||||
if(strbegin(name, "!")) continue;
|
||||
if(++root_counter > 1) return false;
|
||||
@@ -241,25 +239,24 @@ inline bool xml_validate(xml_element *document) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline xml_element* xml_parse(const char *data) {
|
||||
xml_element *self = new xml_element;
|
||||
inline xml_element xml_parse(const char *data) {
|
||||
xml_element self;
|
||||
|
||||
try {
|
||||
while(*data) {
|
||||
xml_element *elem = new xml_element;
|
||||
if(elem->parse_body(data) == false) {
|
||||
delete elem;
|
||||
xml_element node;
|
||||
if(node.parse_body(data) == false) {
|
||||
break;
|
||||
} else {
|
||||
self->element.add(elem);
|
||||
self.element.append(node);
|
||||
}
|
||||
}
|
||||
|
||||
if(xml_validate(self) == false) throw "...";
|
||||
return self;
|
||||
} catch(const char*) {
|
||||
delete self;
|
||||
return 0;
|
||||
xml_element empty;
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,97 +0,0 @@
|
||||
#ifndef NALL_TRAITS_HPP
|
||||
#define NALL_TRAITS_HPP
|
||||
|
||||
namespace nall {
|
||||
//==
|
||||
//is
|
||||
//==
|
||||
|
||||
template<typename T> struct is_integral { enum { value = false }; };
|
||||
template<> struct is_integral<bool> { enum { value = true }; };
|
||||
template<> struct is_integral<char> { enum { value = true }; };
|
||||
template<> struct is_integral<signed char> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned char> { enum { value = true }; };
|
||||
template<> struct is_integral<wchar_t> { enum { value = true }; };
|
||||
template<> struct is_integral<short> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned short> { enum { value = true }; };
|
||||
template<> struct is_integral<long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long> { enum { value = true }; };
|
||||
template<> struct is_integral<long long> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned long long> { enum { value = true }; };
|
||||
template<> struct is_integral<int> { enum { value = true }; };
|
||||
template<> struct is_integral<unsigned int> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_floating_point { enum { value = false }; };
|
||||
template<> struct is_floating_point<float> { enum { value = true }; };
|
||||
template<> struct is_floating_point<double> { enum { value = true }; };
|
||||
template<> struct is_floating_point<long double> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_bool { enum { value = false }; };
|
||||
template<> struct is_bool<bool> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_void { enum { value = false }; };
|
||||
template<> struct is_void<void> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_arithmetic {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_fundamental {
|
||||
enum { value = is_integral<T>::value || is_floating_point<T>::value || is_void<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_compound {
|
||||
enum { value = !is_fundamental<T>::value };
|
||||
};
|
||||
|
||||
template<typename T> struct is_array { enum { value = false }; };
|
||||
template<typename T> struct is_array<T[]> { enum { value = true }; };
|
||||
template<typename T, int N> struct is_array<T[N]> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_const { enum { value = false }; };
|
||||
template<typename T> struct is_const<const T> { enum { value = true }; };
|
||||
template<typename T> struct is_const<const T&> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_pointer { enum { value = false }; };
|
||||
template<typename T> struct is_pointer<T*> { enum { value = true }; };
|
||||
|
||||
template<typename T> struct is_reference { enum { value = false }; };
|
||||
template<typename T> struct is_reference<T&> { enum { value = true }; };
|
||||
|
||||
template<typename T, typename U> struct is_same { enum { value = false }; };
|
||||
template<typename T> struct is_same<T, T> { enum { value = true }; };
|
||||
|
||||
//===
|
||||
//add
|
||||
//===
|
||||
|
||||
template<typename T> struct add_const { typedef const T type; };
|
||||
template<typename T> struct add_const<const T> { typedef const T type; };
|
||||
template<typename T> struct add_const<const T&> { typedef const T& type; };
|
||||
|
||||
template<typename T> struct add_pointer { typedef T* type; };
|
||||
template<typename T> struct add_pointer<T*> { typedef T** type; };
|
||||
|
||||
template<typename T> struct add_reference { typedef T& type; };
|
||||
template<typename T> struct add_reference<T&> { typedef T& type; };
|
||||
|
||||
//======
|
||||
//remove
|
||||
//======
|
||||
|
||||
template<typename T> struct remove_const { typedef T type; };
|
||||
template<typename T> struct remove_const<const T> { typedef T type; };
|
||||
template<typename T> struct remove_const<const T&> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_extent { typedef T type; };
|
||||
template<typename T> struct remove_extent<T[]> { typedef T type; };
|
||||
template<typename T, int N> struct remove_extent<T[N]> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_pointer { typedef T type; };
|
||||
template<typename T> struct remove_pointer<T*> { typedef T type; };
|
||||
|
||||
template<typename T> struct remove_reference { typedef T type; };
|
||||
template<typename T> struct remove_reference<T&> { typedef T type; };
|
||||
}
|
||||
|
||||
#endif
|
@@ -1,29 +1,18 @@
|
||||
#ifndef NALL_UTILITY_HPP
|
||||
#define NALL_UTILITY_HPP
|
||||
|
||||
#include <nall/traits.hpp>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> struct identity {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<typename T> typename remove_reference<T>::type&& move(T &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<typename T> T&& forward(typename identity<T>::type &&value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
template<bool C, typename T = bool> struct enable_if { typedef T type; };
|
||||
template<typename T> struct enable_if<false, T> {};
|
||||
template<typename C, typename T = bool> struct mp_enable_if : enable_if<C::value, T> {};
|
||||
|
||||
template<typename T> inline void swap(T &x, T &y) {
|
||||
T temp(move(x));
|
||||
x = move(y);
|
||||
y = move(temp);
|
||||
T temp(std::move(x));
|
||||
x = std::move(y);
|
||||
y = std::move(temp);
|
||||
}
|
||||
|
||||
template<typename T> struct base_from_member {
|
||||
@@ -31,9 +20,18 @@ namespace nall {
|
||||
base_from_member(T value_) : value(value_) {}
|
||||
};
|
||||
|
||||
template<typename T> inline T* allocate(size_t size, const T &value) {
|
||||
template<typename T> class optional {
|
||||
bool valid;
|
||||
T value;
|
||||
public:
|
||||
inline operator bool() const { return valid; }
|
||||
inline const T& operator()() const { if(!valid) throw; return value; }
|
||||
inline optional(bool valid, const T &value) : valid(valid), value(value) {}
|
||||
};
|
||||
|
||||
template<typename T> inline T* allocate(unsigned size, const T &value) {
|
||||
T *array = new T[size];
|
||||
for(size_t i = 0; i < size; i++) array[i] = value;
|
||||
for(unsigned i = 0; i < size; i++) array[i] = value;
|
||||
return array;
|
||||
}
|
||||
}
|
||||
|
@@ -3,10 +3,12 @@
|
||||
|
||||
#include <initializer_list>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
#include <nall/traits.hpp>
|
||||
#include <nall/foreach.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
|
||||
namespace nall {
|
||||
@@ -67,11 +69,31 @@ namespace nall {
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void add(const T data) {
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
new(pool + objectsize++) T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
linear_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(pool[i]);
|
||||
foreach(item, list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, linear_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
pool[i] = pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
return pool[index];
|
||||
@@ -86,11 +108,12 @@ namespace nall {
|
||||
inline linear_vector<T>& operator=(const linear_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(const linear_vector<T> &source) {
|
||||
linear_vector(const linear_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -101,11 +124,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
linear_vector(linear_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
linear_vector(linear_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
@@ -113,7 +137,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
linear_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) add(*p);
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~linear_vector() {
|
||||
@@ -173,11 +197,31 @@ namespace nall {
|
||||
objectsize = newsize;
|
||||
}
|
||||
|
||||
void add(const T data) {
|
||||
void append(const T data) {
|
||||
if(objectsize + 1 > poolsize) reserve(objectsize + 1);
|
||||
pool[objectsize++] = new T(data);
|
||||
}
|
||||
|
||||
template<typename U> void insert(unsigned index, const U list) {
|
||||
pointer_vector<T> merged;
|
||||
for(unsigned i = 0; i < index; i++) merged.append(*pool[i]);
|
||||
foreach(item, list) merged.append(item);
|
||||
for(unsigned i = index; i < objectsize; i++) merged.append(*pool[i]);
|
||||
operator=(merged);
|
||||
}
|
||||
|
||||
void insert(unsigned index, const T item) {
|
||||
insert(index, pointer_vector<T>{ item });
|
||||
}
|
||||
|
||||
void remove(unsigned index, unsigned count = 1) {
|
||||
for(unsigned i = index; count + i < objectsize; i++) {
|
||||
*pool[i] = *pool[count + i];
|
||||
}
|
||||
if(count + index >= objectsize) resize(index); //every element >= index was removed
|
||||
else resize(objectsize - count);
|
||||
}
|
||||
|
||||
inline T& operator[](unsigned index) {
|
||||
if(index >= objectsize) resize(index + 1);
|
||||
if(!pool[index]) pool[index] = new T;
|
||||
@@ -193,11 +237,12 @@ namespace nall {
|
||||
inline pointer_vector<T>& operator=(const pointer_vector<T> &source) {
|
||||
reset();
|
||||
reserve(source.capacity());
|
||||
for(unsigned i = 0; i < source.size(); i++) add(source[i]);
|
||||
resize(source.size());
|
||||
for(unsigned i = 0; i < source.size(); i++) operator[](i) = source.operator[](i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(const pointer_vector<T> &source) {
|
||||
pointer_vector(const pointer_vector<T> &source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
@@ -208,11 +253,12 @@ namespace nall {
|
||||
poolsize = source.poolsize;
|
||||
objectsize = source.objectsize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
pointer_vector(pointer_vector<T> &&source) {
|
||||
operator=(move(source));
|
||||
pointer_vector(pointer_vector<T> &&source) : pool(0), poolsize(0), objectsize(0) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
//construction
|
||||
@@ -220,7 +266,7 @@ namespace nall {
|
||||
}
|
||||
|
||||
pointer_vector(std::initializer_list<T> list) : pool(0), poolsize(0), objectsize(0) {
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) add(*p);
|
||||
for(const T *p = list.begin(); p != list.end(); ++p) append(*p);
|
||||
}
|
||||
|
||||
~pointer_vector() {
|
||||
|
@@ -24,37 +24,21 @@ void NTSCFilter::size(unsigned &outwidth, unsigned &outheight, unsigned width, u
|
||||
}
|
||||
|
||||
void NTSCFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
if(!ntsc) return;
|
||||
|
||||
width = SNES_NTSC_OUT_WIDTH(256);
|
||||
burst ^= burst_toggle;
|
||||
|
||||
pitch >>= 1;
|
||||
outpitch >>= 2;
|
||||
|
||||
unsigned line_burst = burst;
|
||||
for(unsigned y = 0; y < height;) {
|
||||
const uint16_t *in = input + y * pitch;
|
||||
uint32_t *out = output + y * outpitch;
|
||||
|
||||
//render as many lines in one snes_ntsc_blit as possible:
|
||||
//do this by determining for how many lines the width stays the same
|
||||
unsigned rheight = 1;
|
||||
unsigned rwidth = line[y];
|
||||
while(y + rheight < height && rwidth == line[y + rheight]) rheight++;
|
||||
|
||||
if(rwidth == 256) {
|
||||
snes_ntsc_blit (ntsc, in, pitch, line_burst, rwidth, rheight, out, outpitch << 2);
|
||||
} else {
|
||||
snes_ntsc_blit_hires(ntsc, in, pitch, line_burst, rwidth, rheight, out, outpitch << 2);
|
||||
}
|
||||
|
||||
line_burst = (line_burst + rheight) % 3;
|
||||
y += rheight;
|
||||
if(width <= 256) {
|
||||
snes_ntsc_blit (ntsc, input, pitch, burst, width, height, output, outpitch << 2);
|
||||
} else {
|
||||
snes_ntsc_blit_hires(ntsc, input, pitch, burst, width, height, output, outpitch << 2);
|
||||
}
|
||||
|
||||
burst ^= burst_toggle;
|
||||
}
|
||||
|
||||
QWidget* NTSCFilter::settings() {
|
||||
|
@@ -4,7 +4,7 @@ class NTSCFilter : public QObject {
|
||||
public:
|
||||
void bind(configuration&);
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
QWidget* settings();
|
||||
|
||||
NTSCFilter();
|
||||
|
@@ -6,8 +6,8 @@ void Pixellate2xFilter::size(unsigned &outwidth, unsigned &outheight, unsigned w
|
||||
}
|
||||
|
||||
void Pixellate2xFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
pitch >>= 1;
|
||||
outpitch >>= 2;
|
||||
@@ -16,19 +16,18 @@ void Pixellate2xFilter::render(
|
||||
uint32_t *out1 = output + outpitch;
|
||||
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
unsigned linewidth = line[y];
|
||||
for(unsigned x = 0; x < linewidth; x++) {
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
uint32_t p = colortable[*input++];
|
||||
|
||||
*out0++ = p;
|
||||
if(height <= 240) *out1++ = p;
|
||||
if(linewidth > 256) continue;
|
||||
if(width > 256) continue;
|
||||
|
||||
*out0++ = p;
|
||||
if(height <= 240) *out1++ = p;
|
||||
}
|
||||
|
||||
input += pitch - linewidth;
|
||||
input += pitch - width;
|
||||
if(height <= 240) {
|
||||
out0 += outpitch + outpitch - 512;
|
||||
out1 += outpitch + outpitch - 512;
|
||||
|
@@ -1,5 +1,5 @@
|
||||
class Pixellate2xFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
} filter_pixellate2x;
|
||||
|
@@ -1,17 +1,17 @@
|
||||
#include "scale2x.hpp"
|
||||
|
||||
void Scale2xFilter::size(unsigned &outwidth, unsigned &outheight, unsigned width, unsigned height) {
|
||||
if(height > 240) return filter_direct.size(outwidth, outheight, width, height);
|
||||
outwidth = (width <= 256) ? width * 2 : width;
|
||||
outheight = (height <= 240) ? height * 2 : height;
|
||||
if(width > 256 || height > 240) return filter_direct.size(outwidth, outheight, width, height);
|
||||
outwidth = width * 2;
|
||||
outheight = height * 2;
|
||||
}
|
||||
|
||||
void Scale2xFilter::render(
|
||||
uint32_t *output, unsigned outpitch, const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
if(height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, line, width, height);
|
||||
if(width > 256 || height > 240) {
|
||||
filter_direct.render(output, outpitch, input, pitch, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,39 +22,31 @@ void Scale2xFilter::render(
|
||||
uint32_t *out1 = output + outpitch;
|
||||
|
||||
for(unsigned y = 0; y < height; y++) {
|
||||
unsigned linewidth = line[y];
|
||||
int prevline = (y == 0 ? 0 : pitch);
|
||||
int nextline = (y == height - 1 ? 0 : pitch);
|
||||
|
||||
if(linewidth == 256) {
|
||||
int prevline = (y == 0) || (linewidth != line[y - 1]) ? 0 : pitch;
|
||||
int nextline = (y == height - 1) || (linewidth != line[y + 1]) ? 0 : pitch;
|
||||
for(unsigned x = 0; x < width; x++) {
|
||||
uint16_t A = *(input - prevline);
|
||||
uint16_t B = (x > 0) ? *(input - 1) : *input;
|
||||
uint16_t C = *input;
|
||||
uint16_t D = (x < 255) ? *(input + 1) : *input;
|
||||
uint16_t E = *(input++ + nextline);
|
||||
uint32_t c = colortable[C];
|
||||
|
||||
for(unsigned x = 0; x < 256; x++) {
|
||||
uint16_t A = *(input - prevline);
|
||||
uint16_t B = (x > 0) ? *(input - 1) : *input;
|
||||
uint16_t C = *input;
|
||||
uint16_t D = (x < 255) ? *(input + 1) : *input;
|
||||
uint16_t E = *(input++ + nextline);
|
||||
uint32_t c = colortable[C];
|
||||
|
||||
if(A != E && B != D) {
|
||||
*out0++ = (A == B ? colortable[A] : c);
|
||||
*out0++ = (A == D ? colortable[A] : c);
|
||||
*out1++ = (E == B ? colortable[E] : c);
|
||||
*out1++ = (E == D ? colortable[E] : c);
|
||||
} else {
|
||||
*out0++ = c;
|
||||
*out0++ = c;
|
||||
*out1++ = c;
|
||||
*out1++ = c;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(unsigned x = 0; x < 512; x++) {
|
||||
*out0++ = *out1++ = colortable[*input++];
|
||||
if(A != E && B != D) {
|
||||
*out0++ = (A == B ? colortable[A] : c);
|
||||
*out0++ = (A == D ? colortable[A] : c);
|
||||
*out1++ = (E == B ? colortable[E] : c);
|
||||
*out1++ = (E == D ? colortable[E] : c);
|
||||
} else {
|
||||
*out0++ = c;
|
||||
*out0++ = c;
|
||||
*out1++ = c;
|
||||
*out1++ = c;
|
||||
}
|
||||
}
|
||||
|
||||
input += pitch - linewidth;
|
||||
input += pitch - width;
|
||||
out0 += outpitch + outpitch - 512;
|
||||
out1 += outpitch + outpitch - 512;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
class Scale2xFilter {
|
||||
public:
|
||||
void size(unsigned&, unsigned&, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, const unsigned*, unsigned, unsigned);
|
||||
void render(uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
} filter_scale2x;
|
||||
|
@@ -60,19 +60,18 @@ dllexport void snesfilter_size(unsigned filter, unsigned &outwidth, unsigned &ou
|
||||
|
||||
dllexport void snesfilter_render(
|
||||
unsigned filter, uint32_t *output, unsigned outpitch,
|
||||
const uint16_t *input, unsigned pitch,
|
||||
const unsigned *line, unsigned width, unsigned height
|
||||
const uint16_t *input, unsigned pitch, unsigned width, unsigned height
|
||||
) {
|
||||
switch(filter) {
|
||||
default: return filter_direct.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 1: return filter_pixellate2x.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 2: return filter_scale2x.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 3: return filter_2xsai.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 4: return filter_super2xsai.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 5: return filter_supereagle.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 6: return filter_lq2x.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 7: return filter_hq2x.render(output, outpitch, input, pitch, line, width, height);
|
||||
case 8: return filter_ntsc.render(output, outpitch, input, pitch, line, width, height);
|
||||
default: return filter_direct.render(output, outpitch, input, pitch, width, height);
|
||||
case 1: return filter_pixellate2x.render(output, outpitch, input, pitch, width, height);
|
||||
case 2: return filter_scale2x.render(output, outpitch, input, pitch, width, height);
|
||||
case 3: return filter_2xsai.render(output, outpitch, input, pitch, width, height);
|
||||
case 4: return filter_super2xsai.render(output, outpitch, input, pitch, width, height);
|
||||
case 5: return filter_supereagle.render(output, outpitch, input, pitch, width, height);
|
||||
case 6: return filter_lq2x.render(output, outpitch, input, pitch, width, height);
|
||||
case 7: return filter_hq2x.render(output, outpitch, input, pitch, width, height);
|
||||
case 8: return filter_ntsc.render(output, outpitch, input, pitch, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -7,10 +7,6 @@ extern "C" {
|
||||
void snesfilter_configuration(nall::configuration&);
|
||||
void snesfilter_colortable(const uint32_t*);
|
||||
void snesfilter_size(unsigned, unsigned&, unsigned&, unsigned, unsigned);
|
||||
void snesfilter_render(
|
||||
unsigned, uint32_t*, unsigned,
|
||||
const uint16_t*, unsigned,
|
||||
const unsigned*, unsigned, unsigned
|
||||
);
|
||||
void snesfilter_render(unsigned, uint32_t*, unsigned, const uint16_t*, unsigned, unsigned, unsigned);
|
||||
QWidget* snesfilter_settings(unsigned);
|
||||
}
|
||||
|
BIN
snesreader.dll
BIN
snesreader.dll
Binary file not shown.
@@ -59,7 +59,6 @@ $(foreach f,$(moc_objects), \
|
||||
$(eval $f: $(__file)) \
|
||||
)
|
||||
|
||||
|
||||
##################
|
||||
### snesreader ###
|
||||
##################
|
||||
|
@@ -19,16 +19,17 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#ifndef __PORTABLE_H
|
||||
#define __PORTABLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UINT8;
|
||||
typedef short INT16;
|
||||
typedef unsigned short UINT16;
|
||||
typedef long INT32;
|
||||
typedef unsigned long UINT32;
|
||||
typedef long long INT64;
|
||||
typedef unsigned long long UINT64;
|
||||
typedef int8_t INT8;
|
||||
typedef uint8_t UINT8;
|
||||
typedef int16_t INT16;
|
||||
typedef uint16_t UINT16;
|
||||
typedef int32_t INT32;
|
||||
typedef uint32_t UINT32;
|
||||
typedef int64_t INT64;
|
||||
typedef uint64_t UINT64;
|
||||
|
||||
typedef UINT8 BYTE;
|
||||
typedef UINT16 WORD;
|
||||
|
@@ -64,8 +64,9 @@ public:
|
||||
MoveBlockBackward();
|
||||
BYTE *p = m_Buffer + m_Pos;
|
||||
aDistance++;
|
||||
BYTE *p2 = p - aDistance;
|
||||
for(UINT32 i = 0; i < aLen; i++)
|
||||
p[i] = p[i - aDistance];
|
||||
p[i] = p2[i];
|
||||
m_Pos += aLen;
|
||||
}
|
||||
|
||||
|
@@ -30,7 +30,7 @@ endif
|
||||
|
||||
ifeq ($(compiler),)
|
||||
ifeq ($(platform),osx)
|
||||
compiler := gcc-4.2
|
||||
compiler := gcc-mp-4.4
|
||||
else
|
||||
compiler := gcc
|
||||
endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user