diff --git a/src/Makefile b/src/Makefile index 43cbce47..55be4d92 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,69 +1,40 @@ -include lib/nall/Makefile.string -prefix = /usr/local +include lib/nall/Makefile ui = ui_qt ################ ### compiler ### ################ -ifneq ($(findstring gcc,$(compiler)),) # GCC family - flags = -O3 -fomit-frame-pointer -Ilib - # note: libco *requires* -fomit-frame-pointer on i386 arch - libcoflags := $(flags) -static - c = $(compiler) - cpp = $(subst cc,++,$(compiler)) - obj = o - rule = -c $< -o $@ - link = -s - mkbin = -o$1 - mkdef = -D$1 - mkincpath = -I$1 - mklib = -l$1 - mklibpath = -L$1 +c := $(compiler) +cpp := $(subst cc,++,$(compiler)) +flags := -O3 -fomit-frame-pointer -Ilib +link := -s - # profile-guided optimization: - # flags += -fprofile-generate - # link += -lgcov - # flags += -fprofile-use -else ifeq ($(compiler),cl) # Visual C++ - flags = /nologo /wd4355 /wd4805 /wd4996 /Ox /GL /EHsc /Ilib - libcoflags = $(flags) - c = cl - cpp = cl - obj = obj - rule = /c $< /Fo$@ - link = /link - mkbin = /Fe$1 - mkdef = /D$1 - mkincpath = /I$1 - mklib = $1.lib - mklibpath = /L$1 -else - unknown_compiler: help; -endif +# profile-guided instrumentation: +# flags += -fprofile-generate +# link += -lgcov -########## -### os ### -########## +# profile-guided optimization: +flags += -fprofile-use -ifeq ($(platform),x) # X11 - ruby = video.glx video.xv video.sdl audio.alsa audio.openal audio.oss audio.pulseaudio audio.ao input.sdl input.x - delete = rm -f $1 -else ifeq ($(platform),win) # Windows - mingw_link_flags = -mwindows - # mingw_links_flags = -mconsole +################ +### platform ### +################ - # enable static linking to Qt for Windows build - mingw_link_flags += -enable-stdcall-fixup -Wl,-s -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc +ifeq ($(platform),x) + ruby := video.glx video.xv video.sdl + ruby += audio.alsa audio.openal audio.oss audio.pulseaudio audio.ao + ruby += input.sdl input.x +else ifeq ($(platform),win) + ruby := video.direct3d video.wgl video.directdraw video.gdi + ruby += audio.directsound + ruby += input.rawinput input.directinput - ruby = video.direct3d video.wgl video.directdraw video.gdi audio.directsound input.rawinput input.directinput - delete = $(if $(findstring i586-mingw-gcc,$(compiler)),rm -f $1,del $(subst /,\,$1)) - link += $(if $(findstring mingw,$(compiler)),$(mingw_link_flags)) - link += $(call mklib,uuid) - link += $(call mklib,kernel32) - link += $(call mklib,user32) - link += $(call mklib,gdi32) - link += $(call mklib,shell32) + link += -mwindows +# link += -mconsole + link += -luuid -lkernel32 -luser32 -lgdi32 -lshell32 + # statically link Qt for Windows build + link += -enable-stdcall-fixup -Wl,-s -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc else unknown_platform: help; endif @@ -72,46 +43,39 @@ endif ### ruby ### ############ -rubyflags = $(if $(findstring .sdl,$(ruby)),`sdl-config --cflags`) -link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`) +rubyflags = $(call ifhas,.sdl,$(ruby),`sdl-config --cflags`) -link += $(if $(findstring video.direct3d,$(ruby)),$(call mklib,d3d9)) -link += $(if $(findstring video.directdraw,$(ruby)),$(call mklib,ddraw)) -link += $(if $(findstring video.glx,$(ruby)),$(call mklib,GL)) -link += $(if $(findstring video.wgl,$(ruby)),$(call mklib,opengl32)) -link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv)) -link += $(if $(findstring audio.alsa,$(ruby)),$(call mklib,asound)) -link += $(if $(findstring audio.ao,$(ruby)),$(call mklib,ao)) -link += $(if $(findstring audio.directsound,$(ruby)),$(call mklib,dsound)) -link += $(if $(findstring audio.openal,$(ruby)),$(if $(call streq,$(platform),x),$(call mklib,openal),$(call mklib,openal32))) -link += $(if $(findstring audio.pulseaudio,$(ruby)),$(call mklib,pulse-simple)) -link += $(if $(findstring input.directinput,$(ruby)),$(call mklib,dinput8) $(call mklib,dxguid)) -link += $(if $(findstring input.rawinput,$(ruby)),$(call mklib,xinput) $(call mklib,dinput8) $(call mklib,dxguid)) +link += $(call ifhas,.sdl,$(ruby),`sdl-config --libs`) +link += $(call ifhas,video.direct3d,$(ruby),-ld3d9) +link += $(call ifhas,video.directdraw,$(ruby),-lddraw) +link += $(call ifhas,video.glx,$(ruby),-lGL) +link += $(call ifhas,video.wgl,$(ruby),-lopengl32) +link += $(call ifhas,video.xv,$(ruby),-lXv) +link += $(call ifhas,audio.alsa,$(ruby),-lasound) +link += $(call ifhas,audio.ao,$(ruby),-lao) +link += $(call ifhas,audio.directsound,$(ruby),-ldsound) +link += $(call ifhas,audio.openal,$(ruby),$(if $(call streq,$(platform),x),-lopenal,-lopenal32)) +link += $(call ifhas,audio.pulseaudio,$(ruby),-lpulse-simple) +link += $(call ifhas,input.directinput,$(ruby),-ldinput8 -ldxguid) +link += $(call ifhas,input.rawinput,$(ruby),-lxinput -ldinput8 -ldxguid) #################### ### core objects ### #################### -objects = libco ruby libfilter string \ - reader cartridge cheat \ - memory smemory cpu cpucore scpu smp smpcore ssmp sdsp ppu bppu system \ +objects = libco ruby libreader libfilter string \ + system cartridge cheat \ + memory smemory cpu cpucore scpu smp smpcore ssmp sdsp ppu bppu \ sgb sa1 bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010 ifeq ($(enable_gzip),true) objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil - flags += $(call mkdef,GZIP_SUPPORT) + flags += -DGZIP_SUPPORT endif ifeq ($(enable_jma),true) objects += jma jcrc32 lzmadec 7zlzma iiostrm inbyte lzma winout - flags += $(call mkdef,JMA_SUPPORT) -endif - -sgbflags = -ifeq ($(sgb),gambatte) - sgbflags += $(call mkdef,SGB_GAMBATTE) - link += $(call mklibpath,lib/libgambatte) - link += $(call mklib,gambatte) + flags += -DJMA_SUPPORT endif ###################### @@ -121,139 +85,138 @@ endif compile = \ $(strip \ $(if $(filter %.c,$<), \ - $(c) $(flags) $1 $(rule), \ + $(c) $(flags) $1 -c $< -o $@, \ $(if $(filter %.cpp,$<), \ - $(cpp) $(flags) $1 $(rule) \ + $(cpp) $(flags) $1 -c $< -o $@ \ ) \ ) \ ) -%.$(obj): $<; $(call compile) +%.o: $<; $(call compile) all: build; include $(ui)/Makefile -objects := $(patsubst %,obj/%.$(obj),$(objects)) -rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),$(call mkdef,$c)) +objects := $(patsubst %,obj/%.o,$(objects)) +rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c) ################# ### libraries ### ################# -obj/ruby.$(obj): lib/ruby/ruby.cpp lib/ruby/* lib/ruby/video/* lib/ruby/audio/* lib/ruby/input/* +obj/ruby.o: lib/ruby/ruby.cpp $(call rwildcard,lib/ruby/*) $(call compile,$(rubydef) $(rubyflags)) -obj/libco.$(obj): lib/libco/libco.c lib/libco/* - $(c) $(libcoflags) $(rule) -obj/libfilter.$(obj): lib/libfilter/libfilter.cpp lib/libfilter/* -obj/string.$(obj): lib/nall/string.cpp lib/nall/* -obj/reader.$(obj): lib/reader/reader.cpp lib/reader/* +obj/libco.o: lib/libco/libco.c lib/libco/* + $(c) -O3 -fomit-frame-pointer -static -Ilib -c $< -o $@ +obj/libreader.o: lib/libreader/libreader.cpp lib/libreader/* +obj/libfilter.o: lib/libfilter/libfilter.cpp lib/libfilter/* +obj/string.o: lib/nall/string.cpp lib/nall/* ################# ### utilities ### ################# -obj/cartridge.$(obj): cartridge/cartridge.cpp cartridge/* -obj/cheat.$(obj) : cheat/cheat.cpp cheat/* +obj/cartridge.o: cartridge/cartridge.cpp cartridge/* +obj/cheat.o : cheat/cheat.cpp cheat/* ############## ### memory ### ############## -obj/memory.$(obj) : memory/memory.cpp memory/* -obj/smemory.$(obj): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/* +obj/memory.o : memory/memory.cpp memory/* +obj/smemory.o: memory/smemory/smemory.cpp $(call rwildcard,memory/smemory/) ########### ### cpu ### ########### -obj/cpu.$(obj) : cpu/cpu.cpp cpu/* -obj/cpucore.$(obj): cpu/core/core.cpp cpu/core/* cpu/core/disasm/* -obj/scpu.$(obj) : cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/* +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.$(obj) : smp/smp.cpp smp/* -obj/smpcore.$(obj): smp/core/core.cpp smp/core/* smp/core/disasm/* -obj/ssmp.$(obj) : smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/memory/* smp/ssmp/timing/* +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/adsp.$(obj): dsp/adsp/adsp.cpp dsp/adsp/* -obj/sdsp.$(obj): dsp/sdsp/sdsp.cpp dsp/sdsp/* +obj/adsp.o: dsp/adsp/adsp.cpp dsp/adsp/* +obj/sdsp.o: dsp/sdsp/sdsp.cpp dsp/sdsp/* ########### ### ppu ### ########### -obj/ppu.$(obj) : ppu/ppu.cpp ppu/* -obj/bppu.$(obj): ppu/bppu/bppu.cpp ppu/bppu/* +obj/ppu.o : ppu/ppu.cpp ppu/* +obj/bppu.o: ppu/bppu/bppu.cpp ppu/bppu/* ############## ### system ### ############## -obj/system.$(obj): system/system.cpp system/* system/scheduler/* system/video/* system/audio/* system/input/* +obj/system.o: system/system.cpp $(call rwildcard,system/) ##################### ### special chips ### ##################### -obj/sgb.$(obj): chip/sgb/sgb.cpp chip/sgb/* chip/sgb/interface/* - $(call compile,$(sgbflags)) -obj/sa1.$(obj) : chip/sa1/sa1.cpp chip/sa1/* chip/sa1/bus/* chip/sa1/dma/* chip/sa1/memory/* chip/sa1/mmio/* -obj/bsx.$(obj) : chip/bsx/bsx.cpp chip/bsx/* -obj/srtc.$(obj) : chip/srtc/srtc.cpp chip/srtc/* -obj/sdd1.$(obj) : chip/sdd1/sdd1.cpp chip/sdd1/* -obj/spc7110.$(obj): chip/spc7110/spc7110.cpp chip/spc7110/* -obj/cx4.$(obj) : chip/cx4/cx4.cpp chip/cx4/* -obj/dsp1.$(obj) : chip/dsp1/dsp1.cpp chip/dsp1/* -obj/dsp2.$(obj) : chip/dsp2/dsp2.cpp chip/dsp2/* -obj/dsp3.$(obj) : chip/dsp3/dsp3.cpp chip/dsp3/* -obj/dsp4.$(obj) : chip/dsp4/dsp4.cpp chip/dsp4/* -obj/obc1.$(obj) : chip/obc1/obc1.cpp chip/obc1/* -obj/st010.$(obj) : chip/st010/st010.cpp chip/st010/* +obj/sgb.o : chip/sgb/sgb.cpp $(call rwildcard,chip/sgb/) +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/st010.o : chip/st010/st010.cpp chip/st010/* ############ ### zlib ### ############ -obj/adler32.$(obj) : lib/zlib/adler32.c lib/zlib/* -obj/compress.$(obj): lib/zlib/compress.c lib/zlib/* -obj/crc32.$(obj) : lib/zlib/crc32.c lib/zlib/* -obj/deflate.$(obj) : lib/zlib/deflate.c lib/zlib/* -obj/gzio.$(obj) : lib/zlib/gzio.c lib/zlib/* -obj/inffast.$(obj) : lib/zlib/inffast.c lib/zlib/* -obj/inflate.$(obj) : lib/zlib/inflate.c lib/zlib/* -obj/inftrees.$(obj): lib/zlib/inftrees.c lib/zlib/* -obj/ioapi.$(obj) : lib/zlib/ioapi.c lib/zlib/* -obj/trees.$(obj) : lib/zlib/trees.c lib/zlib/* -obj/unzip.$(obj) : lib/zlib/unzip.c lib/zlib/* -obj/zip.$(obj) : lib/zlib/zip.c lib/zlib/* -obj/zutil.$(obj) : lib/zlib/zutil.c lib/zlib/* +obj/adler32.o : lib/zlib/adler32.c lib/zlib/* +obj/compress.o: lib/zlib/compress.c lib/zlib/* +obj/crc32.o : lib/zlib/crc32.c lib/zlib/* +obj/deflate.o : lib/zlib/deflate.c lib/zlib/* +obj/gzio.o : lib/zlib/gzio.c lib/zlib/* +obj/inffast.o : lib/zlib/inffast.c lib/zlib/* +obj/inflate.o : lib/zlib/inflate.c lib/zlib/* +obj/inftrees.o: lib/zlib/inftrees.c lib/zlib/* +obj/ioapi.o : lib/zlib/ioapi.c lib/zlib/* +obj/trees.o : lib/zlib/trees.c lib/zlib/* +obj/unzip.o : lib/zlib/unzip.c lib/zlib/* +obj/zip.o : lib/zlib/zip.c lib/zlib/* +obj/zutil.o : lib/zlib/zutil.c lib/zlib/* ############## ### libjma ### ############## -obj/jma.$(obj) : lib/libjma/jma.cpp lib/libjma/* -obj/jcrc32.$(obj) : lib/libjma/jcrc32.cpp lib/libjma/* -obj/lzmadec.$(obj): lib/libjma/lzmadec.cpp lib/libjma/* -obj/7zlzma.$(obj) : lib/libjma/7zlzma.cpp lib/libjma/* -obj/iiostrm.$(obj): lib/libjma/iiostrm.cpp lib/libjma/* -obj/inbyte.$(obj) : lib/libjma/inbyte.cpp lib/libjma/* -obj/lzma.$(obj) : lib/libjma/lzma.cpp lib/libjma/* -obj/winout.$(obj) : lib/libjma/winout.cpp lib/libjma/* +obj/jma.o : lib/libjma/jma.cpp lib/libjma/* +obj/jcrc32.o : lib/libjma/jcrc32.cpp lib/libjma/* +obj/lzmadec.o: lib/libjma/lzmadec.cpp lib/libjma/* +obj/7zlzma.o : lib/libjma/7zlzma.cpp lib/libjma/* +obj/iiostrm.o: lib/libjma/iiostrm.cpp lib/libjma/* +obj/inbyte.o : lib/libjma/inbyte.cpp lib/libjma/* +obj/lzma.o : lib/libjma/lzma.cpp lib/libjma/* +obj/winout.o : lib/libjma/winout.cpp lib/libjma/* ############### ### targets ### ############### build: ui_build $(objects) - $(strip $(cpp) $(call mkbin,../bsnes) $(objects) $(link)) + $(strip $(cpp) -o../bsnes $(objects) $(link)) install: install -D -m 755 ../bsnes $(DESTDIR)$(prefix)/bin/bsnes @@ -261,7 +224,7 @@ install: install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop clean: ui_clean - -@$(call delete,obj/*.$(obj)) + -@$(call delete,obj/*.o) -@$(call delete,*.res) -@$(call delete,*.pgd) -@$(call delete,*.pgc) @@ -280,7 +243,6 @@ help: @echo " gcc - GCC compiler" @echo " mingw32-gcc - MinGW compiler" @echo " i586-mingw32-gcc - MinGW cross compiler" - @echo " cl - Visual C++" @echo "" @echo "Available options:" @echo " enable_gzip=[true|false] - Enable ZIP / GZ support (default=false)" @@ -288,3 +250,4 @@ help: @echo "" @echo "Example: $(MAKE) platform=x compiler=gcc enable_gzip=true" @echo "" + diff --git a/src/base.hpp b/src/base.hpp index 9d4a8ba8..01990d18 100644 --- a/src/base.hpp +++ b/src/base.hpp @@ -1,4 +1,4 @@ -#define BSNES_VERSION "0.045.09" +#define BSNES_VERSION "0.046" #define BSNES_TITLE "bsnes v" BSNES_VERSION #define BUSCORE sBus @@ -20,8 +20,9 @@ #include #include #include +#include #include -#include +#include #include #include #include @@ -40,3 +41,4 @@ typedef uint16_t uint16; typedef uint32_t uint32; #include "interface.hpp" + diff --git a/src/cartridge/cartridge.cpp b/src/cartridge/cartridge.cpp index 1e9f865e..e4b5f577 100644 --- a/src/cartridge/cartridge.cpp +++ b/src/cartridge/cartridge.cpp @@ -1,82 +1,98 @@ #include <../base.hpp> - -#define CART_CPP + +#define CARTRIDGE_CPP namespace SNES { -#include "cartridge_header.cpp" -#include "cartridge_loader.cpp" +#include "header.cpp" namespace memory { MappedRAM cartrom, cartram, cartrtc; - MappedRAM bscram; + MappedRAM bsxflash, bsxram, bsxpram; MappedRAM stArom, stAram; - MappedRAM stBrom, stBram; - MappedRAM dmgrom, dmgram, dmgrtc; + MappedRAM stBrom, stBram; + MappedRAM gbrom, gbram; }; Cartridge cartridge; - -void Cartridge::load_begin(Mode cartridge_mode) { - memory::cartrom.map(0, 0); - memory::cartram.map(0, 0); - memory::cartrtc.map(0, 0); - memory::bscram.map (0, 0); - memory::stArom.map (0, 0); - memory::stAram.map (0, 0); - memory::stBrom.map (0, 0); - memory::stBram.map (0, 0); - memory::dmgrom.map (0, 0); - memory::dmgram.map (0, 0); - memory::dmgrtc.map (0, 0); - - set(loaded, false); - set(bsx_flash_loaded, false); - set(patched, false); - set(mode, cartridge_mode); -} - -void Cartridge::load_end() { + +void Cartridge::load(Mode cartridge_mode) { + cartinfo_t cartinfo; + read_header(cartinfo, memory::cartrom.data(), memory::cartrom.size()); + set_cartinfo(cartinfo); + + set(mode, cartridge_mode); + + if(cartinfo.ram_size > 0) { + memory::cartram.map(new(zeromemory) uint8_t[cartinfo.ram_size], cartinfo.ram_size); + } + + if(cartinfo.srtc || cartinfo.spc7110rtc) { + memory::cartrtc.map(new(zeromemory) uint8_t[20], 20); + } + + if(mode() == ModeBsx) { + memory::bsxram.map (new(zeromemory) uint8_t[ 32 * 1024], 32 * 1024); + memory::bsxpram.map(new(zeromemory) uint8_t[512 * 1024], 512 * 1024); + } + + if(mode() == ModeSufamiTurbo) { + if(memory::stArom.data()) memory::stAram.map(new(zeromemory) uint8_t[128 * 1024], 128 * 1024); + if(memory::stBrom.data()) memory::stBram.map(new(zeromemory) uint8_t[128 * 1024], 128 * 1024); + } + + if(mode() == ModeSuperGameBoy) { + if(memory::gbrom.data()) memory::gbram.map(new(zeromemory) uint8_t[64 * 1024], 64 * 1024); + } + memory::cartrom.write_protect(true); - memory::cartram.write_protect(false); + memory::cartram.write_protect(false); memory::cartrtc.write_protect(false); - memory::bscram.write_protect (true); - memory::stArom.write_protect (true); - memory::stAram.write_protect (false); - memory::stBrom.write_protect (true); - memory::stBram.write_protect (false); - memory::dmgrom.write_protect (true); - memory::dmgram.write_protect (false); - memory::dmgrtc.write_protect (false); - - bus.load_cart(); - set(loaded, true); + memory::bsxflash.write_protect(true); + memory::bsxram.write_protect(false); + memory::bsxpram.write_protect(false); + memory::stArom.write_protect(true); + memory::stAram.write_protect(false); + memory::stBrom.write_protect(true); + memory::stBram.write_protect(false); + memory::gbrom.write_protect(true); + memory::gbram.write_protect(false); + + bus.load_cart(); + set(loaded, true); } -void Cartridge::unload() { +void Cartridge::unload() { + memory::cartrom.reset(); + memory::cartram.reset(); + memory::cartrtc.reset(); + memory::bsxflash.reset(); + memory::bsxram.reset(); + memory::bsxpram.reset(); + memory::stArom.reset(); + memory::stAram.reset(); + memory::stBrom.reset(); + memory::stBram.reset(); + memory::gbrom.reset(); + memory::gbram.reset(); + if(loaded() == false) return; bus.unload_cart(); - - memory::cartrom.reset(); - memory::cartram.reset(); - memory::cartrtc.reset(); - memory::bscram.reset(); - memory::stArom.reset(); - memory::stAram.reset(); - memory::stBrom.reset(); - memory::stBram.reset(); - memory::dmgrom.reset(); - memory::dmgram.reset(); - memory::dmgrtc.reset(); - set(loaded, false); +} + +Cartridge::Type Cartridge::detect_image_type(uint8_t *data, unsigned size) const { + cartinfo_t info; + read_header(info, data, size); + return info.type; } Cartridge::Cartridge() { - set(loaded, false); + set(loaded, false); + unload(); } Cartridge::~Cartridge() { - if(loaded() == true) unload(); + unload(); } void Cartridge::set_cartinfo(const Cartridge::cartinfo_t &source) { @@ -137,4 +153,5 @@ Cartridge::cartinfo_t::cartinfo_t() { reset(); } -}; +}; + diff --git a/src/cartridge/cartridge.hpp b/src/cartridge/cartridge.hpp index c4b02c1a..80ea40cd 100644 --- a/src/cartridge/cartridge.hpp +++ b/src/cartridge/cartridge.hpp @@ -4,8 +4,8 @@ public: ModeNormal, ModeBsxSlotted, ModeBsx, - ModeSufamiTurbo, - ModeSuperGameboy, + ModeSufamiTurbo, + ModeSuperGameBoy, }; enum Type { @@ -14,9 +14,9 @@ public: TypeBsxBios, TypeBsx, TypeSufamiTurboBios, - TypeSufamiTurbo, - TypeSuperGameboyBios, - TypeGameboy, + TypeSufamiTurbo, + TypeSuperGameBoyBios, + TypeGameBoy, TypeUnknown, }; @@ -48,9 +48,7 @@ public: //properties can be read via operator(), eg "if(cartridge.loaded() == true)"; //warning: if loaded() == false, no other property is considered valid! - property_t loaded; //is a base cartridge inserted? - property_t bsx_flash_loaded; //is a BS-X flash cart connected? - property_t patched; //has a UPS patch been applied? + property_t loaded; //is a base cartridge inserted? property_t mode; property_t region; @@ -68,22 +66,17 @@ public: property_t has_obc1; property_t has_st010, has_st011, has_st018; - //main interface - Type detect_image_type (uint8_t*, unsigned) const; - bool load_normal (uint8_t*, unsigned); - bool load_bsx_slotted (uint8_t*, unsigned, uint8_t*, unsigned); - bool load_bsx (uint8_t*, unsigned, uint8_t*, unsigned); - bool load_sufami_turbo (uint8_t*, unsigned, uint8_t*, unsigned, uint8_t*, unsigned); - bool load_super_gameboy(uint8_t*, unsigned, uint8_t*, unsigned); + //main interface + void load(Mode); +//void read(); +//void load(); void unload(); + Type detect_image_type(uint8_t *data, unsigned size) const; Cartridge(); ~Cartridge(); private: - void load_begin(Mode); - void load_end(); - struct cartinfo_t { Type type; Region region; @@ -128,10 +121,10 @@ private: namespace memory { extern MappedRAM cartrom, cartram, cartrtc; - extern MappedRAM bscram; + extern MappedRAM bsxflash, bsxram, bsxpram; extern MappedRAM stArom, stAram; - extern MappedRAM stBrom, stBram; - extern MappedRAM dmgrom, dmgram, dmgrtc; + extern MappedRAM stBrom, stBram; + extern MappedRAM gbrom, gbram; }; extern Cartridge cartridge; diff --git a/src/cartridge/cartridge_loader.cpp b/src/cartridge/cartridge_loader.cpp deleted file mode 100644 index 3a6df01d..00000000 --- a/src/cartridge/cartridge_loader.cpp +++ /dev/null @@ -1,148 +0,0 @@ -#ifdef CART_CPP - -Cartridge::Type Cartridge::detect_image_type(uint8_t *data, unsigned size) const { - cartinfo_t info; - read_header(info, data, size); - return info.type; -} - -//================ -//Normal cartridge -//================ - -bool Cartridge::load_normal(uint8_t *basedata, unsigned basesize) { - load_begin(ModeNormal); - - memory::cartrom.map(new uint8_t[basesize], basesize); - memcpy(memory::cartrom.handle(), basedata, basesize); - - cartinfo_t cartinfo; - read_header(cartinfo, basedata, basesize); - set_cartinfo(cartinfo); - - if(cartinfo.ram_size) { - memory::cartram.map(new(zeromemory) uint8_t[cartinfo.ram_size], cartinfo.ram_size); - } - - if(cartinfo.srtc || cartinfo.spc7110rtc) { - memory::cartrtc.map(new(zeromemory) uint8_t[20], 20); - } - - load_end(); - return true; -} - -//====================== -//BS-X slotted cartridge -//====================== - -bool Cartridge::load_bsx_slotted(uint8_t *basedata, unsigned basesize, uint8_t *slotdata, unsigned slotsize) { - load_begin(ModeBsxSlotted); - - memory::cartrom.map(new uint8_t[basesize], basesize); - memcpy(memory::cartrom.handle(), basedata, basesize); - - cartinfo_t cartinfo; - read_header(cartinfo, basedata, basesize); - set_cartinfo(cartinfo); - - if(slotdata) { - memory::bscram.map(new uint8_t[slotsize], slotsize); - memcpy(memory::bscram.handle(), slotdata, slotsize); - set(bsx_flash_loaded, true); - } - - if(cartinfo.ram_size) { - memory::cartram.map(new(zeromemory) uint8_t[cartinfo.ram_size], cartinfo.ram_size); - } - - load_end(); - return true; -} - -//==================== -//BS-X flash cartridge -//==================== - -bool Cartridge::load_bsx(uint8_t *basedata, unsigned basesize, uint8_t *slotdata, unsigned slotsize) { - load_begin(ModeBsx); - - memory::cartrom.map(new uint8_t[basesize], basesize); - memcpy(memory::cartrom.handle(), basedata, basesize); - - cartinfo_t cartinfo; - read_header(cartinfo, basedata, basesize); - set_cartinfo(cartinfo); - - if(slotdata) { - memory::bscram.map(new uint8_t[slotsize], slotsize); - memcpy(memory::bscram.handle(), slotdata, slotsize); - set(bsx_flash_loaded, true); - } - - memset(bsxcart.sram.handle (), 0x00, bsxcart.sram.size ()); - memset(bsxcart.psram.handle(), 0x00, bsxcart.psram.size()); - - load_end(); - return true; -} - -//============================ -//Sufami Turbo flash cartridge -//============================ - -bool Cartridge::load_sufami_turbo(uint8_t *basedata, unsigned basesize, uint8_t *slotAdata, unsigned slotAsize, uint8_t *slotBdata, unsigned slotBsize) { - load_begin(ModeSufamiTurbo); - - memory::cartrom.map(new uint8_t[basesize], basesize); - memcpy(memory::cartrom.handle(), basedata, basesize); - - cartinfo_t cartinfo; - read_header(cartinfo, basedata, basesize); - set_cartinfo(cartinfo); - - if(slotAdata) { - memory::stArom.map(new uint8_t[slotAsize], slotAsize); - memory::stAram.map(new uint8_t[0x020000], 0x020000); - memcpy(memory::stArom.handle(), slotAdata, slotAsize); - } - - if(slotBdata) { - memory::stBrom.map(new uint8_t[slotBsize], slotBsize); - memory::stBram.map(new uint8_t[0x020000], 0x020000); - memcpy(memory::stBrom.handle(), slotBdata, slotBsize); - } - - load_end(); - return true; -} - -//======================= -//Super Gameboy cartridge -//======================= - -bool Cartridge::load_super_gameboy(uint8_t *basedata, unsigned basesize, uint8_t *slotdata, unsigned slotsize) { - load_begin(ModeSuperGameboy); - - memory::cartrom.map(new uint8_t[basesize], basesize); - memcpy(memory::cartrom.handle(), basedata, basesize); - - cartinfo_t cartinfo; - read_header(cartinfo, basedata, basesize); - set_cartinfo(cartinfo); - - if(slotdata) { - uint8_t *data = new uint8_t[slotsize]; - memcpy(data, slotdata, slotsize); - memory::dmgrom.map(data, slotsize); - - //TODO: determine proper RAM size via GB ROM header - memory::dmgram.map(new uint8_t[524288], 524288); - memory::dmgrtc.map(new uint8_t[4], 4); - } - - load_end(); - return true; -} - -#endif diff --git a/src/cartridge/cartridge_header.cpp b/src/cartridge/header.cpp similarity index 92% rename from src/cartridge/cartridge_header.cpp rename to src/cartridge/header.cpp index 0f5fb9a8..e48cea14 100644 --- a/src/cartridge/cartridge_header.cpp +++ b/src/cartridge/header.cpp @@ -1,18 +1,17 @@ -#ifdef CART_CPP +#ifdef CARTRIDGE_CPP void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size) const { info.reset(); - //==================== - //detect Gameboy carts - //==================== + //===================== + //detect Game Boy carts + //===================== - if(size >= 0x0150) { - if(data[0x0104] == 0xce && data[0x0105] == 0xed && data[0x0106] == 0x66 && data[0x0107] == 0x66) { - if(data[0x0108] == 0xcc && data[0x0109] == 0x0d && data[0x010a] == 0x00 && data[0x010b] == 0x0b) { - info.type = TypeGameboy; - return; - } + if(size >= 0x0140) { + if(data[0x0104] == 0xce && data[0x0105] == 0xed && data[0x0106] == 0x66 && data[0x0107] == 0x66 + && data[0x0108] == 0xcc && data[0x0109] == 0x0d && data[0x010a] == 0x00 && data[0x010b] == 0x0b) { + info.type = TypeGameBoy; + return; } } @@ -23,6 +22,12 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size const uint8 company = data[index + Company]; const uint8 region = data[index + CartRegion] & 0x7f; + if(data[index + RamSize] & 7) { + info.ram_size = 1024 << (data[index + RamSize] & 7); + } else { + info.ram_size = 0; + } + //0, 1, 13 = NTSC; 2 - 12 = PAL info.region = (region <= 1 || region >= 13) ? NTSC : PAL; @@ -37,6 +42,7 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size if(data[index + 0x1a] == 0x33 || data[index + 0x1a] == 0xff) { info.type = TypeBsx; info.mapper = BSXROM; + info.region = NTSC; //BS-X only released in Japan return; } } @@ -54,16 +60,16 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size info.type = TypeSufamiTurbo; } info.mapper = STROM; - return; + info.region = NTSC; //Sufami Turbo only released in Japan + return; //RAM size handled internally by load_cart_st(); } - //========================= - //detect Super Gameboy cart - //========================= + //========================== + //detect Super Game Boy BIOS + //========================== if(!memcmp(data + index, "Super GAMEBOY", 13)) { - info.type = TypeSuperGameboyBios; - info.mapper = LoROM; + info.type = TypeSuperGameBoyBios; return; } @@ -187,12 +193,6 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size if(mapper == 0x30 && rom_type == 0xf5) { info.st018 = true; } - - if(data[index + RamSize] & 7) { - info.ram_size = 1024 << (data[index + RamSize] & 7); - } else { - info.ram_size = 0; - } } unsigned Cartridge::find_header(const uint8_t *data, unsigned size) const { diff --git a/src/cc.bat b/src/cc.bat index c052b562..d8ae3c6d 100644 --- a/src/cc.bat +++ b/src/cc.bat @@ -1,3 +1,3 @@ -@mingw32-make platform=win compiler=mingw32-gcc sgb=gambatte -::@mingw32-make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true +@mingw32-make +::@mingw32-make enable_gzip=true enable_jma=true @pause diff --git a/src/cc.sh b/src/cc.sh deleted file mode 100644 index 2f828102..00000000 --- a/src/cc.sh +++ /dev/null @@ -1,2 +0,0 @@ -make platform=x compiler=gcc sgb=gambatte -#make platform=x compiler=gcc enable_gzip=true enable_jma=true diff --git a/src/cheat/cheat.cpp b/src/cheat/cheat.cpp index ab0fcbf3..7bc11311 100644 --- a/src/cheat/cheat.cpp +++ b/src/cheat/cheat.cpp @@ -1,6 +1,6 @@ -#include <../base.hpp> - -#define CHEAT_CPP +#include <../base.hpp> + +#define CHEAT_CPP namespace SNES { Cheat cheat; @@ -181,9 +181,7 @@ void Cheat::disable(unsigned i) { //... //=============================== -bool Cheat::load(const char *fn) { - string data; - if(!data.readfile(fn)) return false; +void Cheat::load(string data) { data.replace("\r\n", "\n"); data.qreplace(" ", ""); @@ -196,21 +194,16 @@ bool Cheat::load(const char *fn) { trim(part[0], "\""); add(part[1] == "enabled", /* code = */ part[2], /* desc = */ part[0]); } - - return true; } -bool Cheat::save(const char *fn) const { - file fp; - if(!fp.open(fn, file::mode_write)) return false; - for(unsigned i = 0; i < code.size(); i++) { - fp.print(string() - << "\"" << code[i].desc << "\", " - << (code[i].enabled ? "enabled, " : "disabled, ") - << code[i].code << "\r\n"); - } - fp.close(); - return true; +string Cheat::save() const { + string data; + for(unsigned i = 0; i < code.size(); i++) { + data << "\"" << code[i].desc << "\", " + << (code[i].enabled ? "enabled, " : "disabled, ") + << code[i].code << "\r\n"; + } + return data; } void Cheat::clear() { @@ -393,5 +386,6 @@ string& Cheat::decode_description(string &desc) const { desc.replace("\\n", "\n"); return desc; } - -}; + +}; + diff --git a/src/cheat/cheat.hpp b/src/cheat/cheat.hpp index 58fa8b6c..56fef316 100644 --- a/src/cheat/cheat.hpp +++ b/src/cheat/cheat.hpp @@ -38,8 +38,8 @@ public: void enable(unsigned i); void disable(unsigned i); - bool load(const char *fn); - bool save(const char *fn) const; + void load(string data); + string save() const; void clear(); Cheat(); diff --git a/src/chip/bsx/bsx.cpp b/src/chip/bsx/bsx.cpp index 9f92f01f..f871597e 100644 --- a/src/chip/bsx/bsx.cpp +++ b/src/chip/bsx/bsx.cpp @@ -1,10 +1,10 @@ #include <../base.hpp> - -#define BSX_CPP + +#define BSX_CPP namespace SNES { #include "bsx_base.cpp" #include "bsx_cart.cpp" #include "bsx_flash.cpp" - -}; +}; + diff --git a/src/chip/bsx/bsx.hpp b/src/chip/bsx/bsx.hpp index 484cf421..efcaaf7f 100644 --- a/src/chip/bsx/bsx.hpp +++ b/src/chip/bsx/bsx.hpp @@ -32,16 +32,10 @@ public: uint8 mmio_read(unsigned addr); void mmio_write(unsigned addr, uint8 data); - MappedRAM sram; - MappedRAM psram; - BSXCart(); ~BSXCart(); private: - uint8 *sram_data; //256kbit SRAM - uint8 *psram_data; // 4mbit PSRAM - struct { uint8 r[16]; } regs; diff --git a/src/chip/bsx/bsx_base.cpp b/src/chip/bsx/bsx_base.cpp index 496150a7..2272c174 100644 --- a/src/chip/bsx/bsx_base.cpp +++ b/src/chip/bsx/bsx_base.cpp @@ -1,5 +1,7 @@ #ifdef BSX_CPP +BSXBase bsxbase; + void BSXBase::init() { } @@ -135,3 +137,4 @@ void BSXBase::mmio_write(unsigned addr, uint8 data) { } #endif + diff --git a/src/chip/bsx/bsx_cart.cpp b/src/chip/bsx/bsx_cart.cpp index 68a07583..92d6ead6 100644 --- a/src/chip/bsx/bsx_cart.cpp +++ b/src/chip/bsx/bsx_cart.cpp @@ -1,5 +1,7 @@ #ifdef BSX_CPP +BSXCart bsxcart; + void BSXCart::init() { } @@ -20,7 +22,7 @@ void BSXCart::reset() { } void BSXCart::update_memory_map() { - Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)psram; + Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)memory::bsxpram; if((regs.r[0x02] & 0x80) == 0x00) { //LoROM mapping @@ -35,16 +37,16 @@ void BSXCart::update_memory_map() { } if(regs.r[0x03] & 0x80) { - bus.map(Bus::MapLinear, 0x60, 0x6f, 0x0000, 0xffff, psram); - //bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram); + bus.map(Bus::MapLinear, 0x60, 0x6f, 0x0000, 0xffff, memory::bsxpram); + //bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram); } if((regs.r[0x05] & 0x80) == 0x00) { - bus.map(Bus::MapLinear, 0x40, 0x4f, 0x0000, 0xffff, psram); + bus.map(Bus::MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::bsxpram); } if((regs.r[0x06] & 0x80) == 0x00) { - bus.map(Bus::MapLinear, 0x50, 0x5f, 0x0000, 0xffff, psram); + bus.map(Bus::MapLinear, 0x50, 0x5f, 0x0000, 0xffff, memory::bsxpram); } if(regs.r[0x07] & 0x80) { @@ -55,8 +57,8 @@ void BSXCart::update_memory_map() { bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom); } - bus.map(Bus::MapShadow, 0x20, 0x3f, 0x6000, 0x7fff, psram); - bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram); + bus.map(Bus::MapShadow, 0x20, 0x3f, 0x6000, 0x7fff, memory::bsxpram); + bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, memory::bsxpram); } uint8 BSXCart::mmio_read(unsigned addr) { @@ -66,7 +68,7 @@ uint8 BSXCart::mmio_read(unsigned addr) { } if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM - return sram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff)); + return memory::bsxram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff)); } return 0x00; @@ -81,21 +83,15 @@ void BSXCart::mmio_write(unsigned addr, uint8 data) { } if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM - return sram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data); + return memory::bsxram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data); } } BSXCart::BSXCart() { - sram_data = new uint8_t[ 32 * 1024]; - psram_data = new uint8_t[512 * 1024]; - - sram.map (sram_data, 32 * 1024); - psram.map(psram_data, 512 * 1024); } BSXCart::~BSXCart() { - delete[] sram_data; - delete[] psram_data; } #endif + diff --git a/src/chip/bsx/bsx_flash.cpp b/src/chip/bsx/bsx_flash.cpp index deceb95e..dfd7eadf 100644 --- a/src/chip/bsx/bsx_flash.cpp +++ b/src/chip/bsx/bsx_flash.cpp @@ -1,5 +1,7 @@ #ifdef BSX_CPP +BSXFlash bsxflash; + void BSXFlash::init() {} void BSXFlash::enable() {} @@ -15,10 +17,11 @@ void BSXFlash::reset() { regs.flash_enable = false; regs.read_enable = false; regs.write_enable = false; + memory::bsxflash.write_protect(!regs.write_enable); } unsigned BSXFlash::size() const { - return memory::bscram.size(); + return memory::bsxflash.size(); } uint8 BSXFlash::read(unsigned addr) { @@ -45,7 +48,7 @@ uint8 BSXFlash::read(unsigned addr) { } } - return memory::bscram.read(addr); + return memory::bsxflash.read(addr); } void BSXFlash::write(unsigned addr, uint8 data) { @@ -64,11 +67,11 @@ void BSXFlash::write(unsigned addr, uint8 data) { regs.write_new = data; if(regs.write_enable && regs.write_old == regs.write_new) { - return memory::bscram.write(addr, data); + return memory::bsxflash.write(addr, data); } } else { if(regs.write_enable) { - return memory::bscram.write(addr, data); + return memory::bsxflash.write(addr, data); } } @@ -107,7 +110,10 @@ void BSXFlash::write(unsigned addr, uint8 data) { regs.read_enable = false; regs.write_enable = false; } + + memory::bsxflash.write_protect(!regs.write_enable); } } #endif + diff --git a/src/chip/chip.hpp b/src/chip/chip.hpp index 5a648727..eac962d9 100644 --- a/src/chip/chip.hpp +++ b/src/chip/chip.hpp @@ -1,9 +1,4 @@ -struct Chip { - virtual void load() {} - virtual void unload() {} -}; - -#include "sgb/sgb.hpp" +#include "sgb/sgb.hpp" #include "sa1/sa1.hpp" #include "bsx/bsx.hpp" #include "srtc/srtc.hpp" diff --git a/src/chip/cx4/cx4.cpp b/src/chip/cx4/cx4.cpp index df1d8b57..bfca06db 100644 --- a/src/chip/cx4/cx4.cpp +++ b/src/chip/cx4/cx4.cpp @@ -6,9 +6,11 @@ */ #include <../base.hpp> - -#define CX4_CPP -namespace SNES { + +#define CX4_CPP +namespace SNES { + +Cx4 cx4; #include "cx4data.cpp" #include "cx4fn.cpp" @@ -196,5 +198,5 @@ void Cx4::reset() { memset(ram, 0, 0x0c00); memset(reg, 0, 0x0100); } - -}; +}; + diff --git a/src/chip/dsp1/dsp1.cpp b/src/chip/dsp1/dsp1.cpp index 9bfc1661..56fdb903 100644 --- a/src/chip/dsp1/dsp1.cpp +++ b/src/chip/dsp1/dsp1.cpp @@ -1,7 +1,9 @@ #include <../base.hpp> - -#define DSP1_CPP -namespace SNES { + +#define DSP1_CPP +namespace SNES { + +DSP1 dsp1; #include "dsp1emu.cpp" @@ -57,5 +59,5 @@ void DSP1::write(unsigned addr, uint8 data) { dsp1.setDr(data); } } - -}; +}; + diff --git a/src/chip/dsp2/dsp2.cpp b/src/chip/dsp2/dsp2.cpp index ee0bc1a3..5d49663a 100644 --- a/src/chip/dsp2/dsp2.cpp +++ b/src/chip/dsp2/dsp2.cpp @@ -1,7 +1,9 @@ #include <../base.hpp> - -#define DSP2_CPP -namespace SNES { + +#define DSP2_CPP +namespace SNES { + +DSP2 dsp2; #include "dsp2_op.cpp" @@ -135,5 +137,5 @@ void DSP2::write(unsigned addr, uint8 data) { DSP2::DSP2() {} DSP2::~DSP2() {} - -}; +}; + diff --git a/src/chip/dsp3/dsp3.cpp b/src/chip/dsp3/dsp3.cpp index a3e8bdd8..896227a7 100644 --- a/src/chip/dsp3/dsp3.cpp +++ b/src/chip/dsp3/dsp3.cpp @@ -1,7 +1,9 @@ #include <../base.hpp> - -#define DSP3_CPP -namespace SNES { + +#define DSP3_CPP +namespace SNES { + +DSP3 dsp3; namespace DSP3i { #define bool8 uint8 @@ -34,5 +36,5 @@ void DSP3::write(unsigned addr, uint8 data) { DSP3i::dsp3_byte = data; DSP3i::DSP3SetByte(); } - -}; +}; + diff --git a/src/chip/dsp4/dsp4.cpp b/src/chip/dsp4/dsp4.cpp index 943457cd..74459a85 100644 --- a/src/chip/dsp4/dsp4.cpp +++ b/src/chip/dsp4/dsp4.cpp @@ -1,7 +1,9 @@ #include <../base.hpp> - -#define DSP4_CPP -namespace SNES { + +#define DSP4_CPP +namespace SNES { + +DSP4 dsp4; namespace DSP4i { inline uint16 READ_WORD(uint8 *addr) { @@ -54,5 +56,5 @@ void DSP4::write(unsigned addr, uint8 data) { DSP4i::DSP4SetByte(); } } - -}; +}; + diff --git a/src/chip/obc1/obc1.cpp b/src/chip/obc1/obc1.cpp index f568ef83..4fd555ba 100644 --- a/src/chip/obc1/obc1.cpp +++ b/src/chip/obc1/obc1.cpp @@ -1,7 +1,9 @@ #include <../base.hpp> -#define OBC1_CPP -namespace SNES { +#define OBC1_CPP +namespace SNES { + +OBC1 obc1; void OBC1::init() {} void OBC1::enable() {} @@ -70,6 +72,7 @@ void OBC1::ram_write(unsigned addr, uint8 data) { } OBC1::OBC1() {} -OBC1::~OBC1() {} +OBC1::~OBC1() {} -}; +}; + diff --git a/src/chip/sa1/bus/bus.cpp b/src/chip/sa1/bus/bus.cpp index ede42379..a38ff35b 100644 --- a/src/chip/sa1/bus/bus.cpp +++ b/src/chip/sa1/bus/bus.cpp @@ -1,5 +1,7 @@ #ifdef SA1_CPP +SA1Bus sa1bus; + namespace memory { VectorSelectionPage vectorsp; StaticRAM iram(2048); diff --git a/src/chip/sa1/mmio/mmio.cpp b/src/chip/sa1/mmio/mmio.cpp index 7607637c..204c11ea 100644 --- a/src/chip/sa1/mmio/mmio.cpp +++ b/src/chip/sa1/mmio/mmio.cpp @@ -2,7 +2,7 @@ //BS-X flash carts, when present, are mapped to 0x400000+ Memory& SA1::mmio_access(unsigned &addr) { - if(cartridge.bsx_flash_loaded() == false) return memory::cartrom; + if(!memory::bsxflash.data()) return memory::cartrom; if(addr < 0x400000) return memory::cartrom; addr &= 0x3fffff; return bsxflash; diff --git a/src/chip/sa1/sa1.cpp b/src/chip/sa1/sa1.cpp index 0dd60830..cd822dda 100644 --- a/src/chip/sa1/sa1.cpp +++ b/src/chip/sa1/sa1.cpp @@ -3,6 +3,8 @@ #define SA1_CPP namespace SNES { +SA1 sa1; + #include "bus/bus.cpp" #include "dma/dma.cpp" #include "memory/memory.cpp" @@ -313,3 +315,4 @@ SA1::SA1() { } }; + diff --git a/src/chip/sdd1/sdd1.cpp b/src/chip/sdd1/sdd1.cpp index a3b264ca..0338b2ab 100644 --- a/src/chip/sdd1/sdd1.cpp +++ b/src/chip/sdd1/sdd1.cpp @@ -1,7 +1,9 @@ #include <../base.hpp> - -#define SDD1_CPP -namespace SNES { + +#define SDD1_CPP +namespace SNES { + +SDD1 sdd1; #include "sdd1emu.cpp" @@ -156,5 +158,5 @@ SDD1::SDD1() { SDD1::~SDD1() { delete[] buffer.data; } - -}; +}; + diff --git a/src/chip/sgb/interface/gambatte.cpp b/src/chip/sgb/interface/gambatte.cpp deleted file mode 100644 index c5a7ba42..00000000 --- a/src/chip/sgb/interface/gambatte.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include - -namespace SNES { - -class GambatteVideo : public Gambatte::VideoBlitter { -public: - unsigned bufferWidth, bufferHeight; - uint32_t *buffer; - - void setBufferDimensions(unsigned width, unsigned height) { - if(buffer) delete[] buffer; - buffer = new uint32_t[width * height]; - bufferWidth = width; - bufferHeight = height; - } - - const Gambatte::PixelBuffer inBuffer() { - Gambatte::PixelBuffer pb; - pb.pixels = (void*)buffer; - pb.format = Gambatte::PixelBuffer::RGB32; - pb.pitch = bufferWidth; - return pb; - } - - void blit() { - } - - void update(unsigned row) { - uint32_t *source = buffer + row * 160 * 8; - uint8_t *buffer = new(zeromemory) uint8_t[5760]; - - for(unsigned y = row * 8; y < row * 8 + 8; y++) { - for(unsigned x = 0; x < 160; x++) { - unsigned pixel = *source++ / 0x555555; - pixel ^= 3; - - unsigned tile = ((y / 8) * 20) + (x / 8); - unsigned addr = (tile * 16) + ((y & 7) * 2); - - buffer[addr + 0] |= ((pixel & 1) >> 0) << (7 - (x & 7)); - buffer[addr + 1] |= ((pixel & 2) >> 1) << (7 - (x & 7)); - } - } - - memcpy(sgb.gameboy->vram, buffer, 5760); - delete[] buffer; - } - - ~GambatteVideo() { - if(buffer) delete[] buffer; - } -}; - -class GambatteInput : public Gambatte::InputStateGetter { -public: - Gambatte::InputState is; - const Gambatte::InputState& operator()() { - unsigned joypad = sgb.gameboy->joypadid(); - unsigned data = sgb.mmio.joypad[joypad]; - - //TODO: fix SGB detection - joypad = 1; - data = sgb.mmio.joypad[0]; - - is.joypadId = 0x0f - joypad; - is.startButton = !(data & 0x80); - is.selectButton = !(data & 0x40); - is.bButton = !(data & 0x20); - is.aButton = !(data & 0x10); - is.dpadDown = !(data & 0x08); - is.dpadUp = !(data & 0x04); - is.dpadLeft = !(data & 0x02); - is.dpadRight = !(data & 0x01); - return is; - } -}; - -class GambatteMemory : public Gambatte::MemoryInterface { -public: - Gambatte::MemoryBuffer loadRomData() { - Gambatte::MemoryBuffer mb; - mb.data = (void*)memory::dmgrom.handle(); - mb.size = memory::dmgrom.size(); - return mb; - } - - Gambatte::MemoryBuffer loadRamData() { - Gambatte::MemoryBuffer mb; - mb.data = (void*)memory::dmgram.handle(); - mb.size = memory::dmgram.size(); - return mb; - } - - Gambatte::MemoryBuffer loadRtcData() { - Gambatte::MemoryBuffer mb; - mb.data = (void*)memory::dmgrtc.handle(); - mb.size = memory::dmgram.size(); - return mb; - } - - Gambatte::MemoryBuffer saveRamData(unsigned size) { - memory::dmgram.reset(); - memory::dmgram.map(new uint8_t[size], size); - - Gambatte::MemoryBuffer mb; - mb.data = (void*)memory::dmgram.handle(); - mb.size = memory::dmgram.size(); - return mb; - } - - Gambatte::MemoryBuffer saveRtcData() { - memory::dmgrtc.reset(); - memory::dmgrtc.map(new uint8_t[4], 4); - - Gambatte::MemoryBuffer mb; - mb.data = (void*)memory::dmgrtc.handle(); - mb.size = memory::dmgrtc.size(); - return mb; - } - - void joypWrite(bool p15, bool p14) { - sgb.gameboy->write(p15, p14); - } -}; - -class GameboyGambatte : public Gameboy { -public: - Gambatte::GB gambatte; - GambatteInput gambatte_input; - GambatteVideo gambatte_video; - GambatteMemory gambatte_memory; - uint32_t audio_buffer[65536]; - - unsigned run() { - unsigned samples = gambatte.runFor(audio_buffer, 16); - for(unsigned i = 0; i < samples; i++) { - system.audio.cop_sample(audio_buffer[i] >> 0, audio_buffer[i] >> 16); - } - return (samples << 3) + (samples << 1); //1 sample = 10 S-CPU clock cycles - } - - unsigned lyCounter() { - return gambatte.lyCounter(); - } - - void updateVideo(unsigned row) { - gambatte.updateVideo(); - gambatte_video.update(row); - } - - void unload() { - gambatte.save(); - } - - void power() { - Gameboy::power(); - gambatte.load(true); - system.audio.set_cop_frequency(60 * 35112); - } - - void reset() { - Gameboy::reset(); - gambatte.reset(); - system.audio.set_cop_frequency(60 * 35112); - } - - GameboyGambatte() { - gambatte.setVideoBlitter(&gambatte_video); - gambatte.setInputStateGetter(&gambatte_input); - gambatte.setMemoryInterface(&gambatte_memory); - } -}; - -}; diff --git a/src/chip/sgb/interface/interface.hpp b/src/chip/sgb/interface/interface.hpp deleted file mode 100644 index 11cb67eb..00000000 --- a/src/chip/sgb/interface/interface.hpp +++ /dev/null @@ -1,98 +0,0 @@ -namespace SNES { - -static const char command_name[32][64] = { - "PAL01", "PAL23", "PAL03", "PAL12", - "ATTR_BLK", "ATTR_LIN", "ATTR_DIV", "ATTR_CHR", - "SOUND", "SOU_TRN", "PAL_SET", "PAL_TRN", - "ATRC_EN", "TEST_EN", "ICON_EN", "DATA_SND", - "DATA_TRN", "MLT_REG", "JUMP", "CHR_TRN", - "PCT_TRN", "ATTR_TRN", "ATTR_SET", "MASK_EN", - "OBJ_TRN", "19_???", "1A_???", "1B_???", - "1C_???", "1D_???", "1E_ROM", "1F_???", -}; - -class Gameboy { -public: - uint8_t vram[(160 / 8) * (144 / 8) * (64 / 4)]; - - bool pulselock; - bool strobelock; - bool packetlock; - - SuperGameboy::Packet packet; - uint8_t packetoffset; - uint8_t bitdata, bitoffset; - - unsigned joypadid() { - return sgb.mmio.joypadid; - } - - void write(bool p15, bool p14) { - if(p15 == 1 && p14 == 1) { - sgb.mmio.joypadid++; - if(sgb.mmio.r6003 & 0x20) sgb.mmio.joypadid &= 3; - else if(sgb.mmio.r6003 & 0x10) sgb.mmio.joypadid &= 1; - else sgb.mmio.joypadid &= 0; - } - - if(p15 == 0 && p14 == 0) { - //pulse - pulselock = false; - packetoffset = 0; - bitoffset = 0; - strobelock = true; - packetlock = false; - return; - } - - if(pulselock) return; - - if(p15 == 1 && p14 == 1) { - strobelock = false; - return; - } - - if(strobelock) return; - - //p15(1), p14(0) = 0 - //p15(0), p14(1) = 1 - bool bit = (p15 == 0); - strobelock = true; - - if(packetlock) { - if(p15 == 1 && p14 == 0) { - //packet stop bit - printf("%s\n", command_name[packet[0] >> 3]); - sgb.packet.add(packet); - packetlock = false; - pulselock = true; - } - return; - } - - bitdata = (bit << 7) | (bitdata >> 1); - if(++bitoffset < 8) return; - - bitoffset = 0; - packet[packetoffset] = bitdata; - if(++packetoffset < 16) return; - packetlock = true; - } - - virtual unsigned run() { return 64; } - virtual unsigned lyCounter() { return 0; } - virtual void updateVideo(unsigned) {} - virtual void unload() {} - - virtual void power() { - pulselock = true; - memset(&vram, 0, sizeof vram); - } - - virtual void reset() { - pulselock = true; - memset(&vram, 0, sizeof vram); - } -}; - -}; diff --git a/src/chip/sgb/interface/reference.cpp b/src/chip/sgb/interface/reference.cpp deleted file mode 100644 index 5f288c99..00000000 --- a/src/chip/sgb/interface/reference.cpp +++ /dev/null @@ -1,24 +0,0 @@ -namespace SNES { - -class Gameboy { -public: - unsigned run() { - for(unsigned i = 0; i < memory::sgbvram.size(); i++) { - memory::sgbvram.write(i, rand()); - } - sgb.refresh(); - return 0; - } - - void unload() { - } - - void power() { - } - - void reset() { - } -}; - -}; - diff --git a/src/chip/sgb/sgb.cpp b/src/chip/sgb/sgb.cpp index 577d47c3..e1af7959 100644 --- a/src/chip/sgb/sgb.cpp +++ b/src/chip/sgb/sgb.cpp @@ -1,147 +1,66 @@ #include <../base.hpp> -#include "interface/interface.hpp" -#if defined(SGB_GAMBATTE) - #include "interface/gambatte.cpp" -#else - #include "interface/reference.cpp" -#endif - #define SGB_CPP namespace SNES { -void SuperGameboy::enter() { +SuperGameBoy sgb; + +void SuperGameBoy::enter() { while(true) { - unsigned clocks; - if((mmio.r6003 & 0x80) == 0) { - clocks = 10; - system.audio.cop_sample(0, 0); + if(sgb_run) { + unsigned samples = sgb_run(samplebuffer, 16); + scheduler.addclocks_cop(samples * 10); + scheduler.sync_copcpu(); } else { - clocks = gameboy->run(); + scheduler.addclocks_cop(64 * 1024 * 1024); + scheduler.sync_copcpu(); } - scheduler.addclocks_cop(clocks); - scheduler.sync_copcpu(); } } -uint8_t SuperGameboy::read(unsigned addr) { +uint8_t SuperGameBoy::read(unsigned addr) { addr &= 0xffff; - - //DMG lyCounter - if(addr == 0x6000) { - return gameboy->lyCounter(); - } - - //command ready port - if(addr == 0x6002) { - bool data = packet.size() > 0; - if(data) { - mmio.r7000 = packet[0]; - unsigned size = packet.size() - 1; - for(unsigned i = 0; i < size; i++) packet[i] = packet[i + 1]; - packet.resize(size); - } - return data; - } - - //command port - if((addr & 0xfff0) == 0x7000) { - return mmio.r7000[addr & 15]; - } - - //screen data port - if(addr == 0x7800) { - uint8_t data = gameboy->vram[mmio.r7800++]; - if(mmio.r7800 >= (160 / 8) * (144 / 8) * (64 / 4)) mmio.r7800 = 0; - return data; - } - + if(sgb_read) return sgb_read(addr); return 0x00; } -void SuperGameboy::write(unsigned addr, uint8_t data) { +void SuperGameBoy::write(unsigned addr, uint8_t data) { addr &= 0xffff; + if(sgb_write) return sgb_write(addr, data); +} - if(addr == 0x6001) { - gameboy->updateVideo(mmio.r7800 / 320); - } - - //control port - //d7 = Gameboy enable - //d5 = four-player enable (1=4-player, 0=see d4) - //d4 = two-player enable (if: d5=0; 1=2-player, 0=1-player) - //d0 = ??? (always 1) - if(addr == 0x6003) { - if(((mmio.r6003 & 0x80) == 0x00) && ((data & 0x80) == 0x80)) { - gameboy->reset(); - command_1e(); - mmio.r7800 = 320 * 16; - } - mmio.r6003 = data; - return; - } - - //joypad ports 1-4 - if((addr & 0x600c) == 0x6004) { - mmio.joypad[addr & 3] = data; - return; +void SuperGameBoy::init() { + if(libsgb.open("SuperGameBoy")) { + sgb_init = libsgb.sym("sgb_init"); + sgb_term = libsgb.sym("sgb_term"); + sgb_power = libsgb.sym("sgb_power"); + sgb_reset = libsgb.sym("sgb_reset"); + sgb_read = libsgb.sym("sgb_read"); + sgb_write = libsgb.sym("sgb_write"); + sgb_run = libsgb.sym("sgb_run"); } } -void SuperGameboy::init() {} -void SuperGameboy::enable() {} - -void SuperGameboy::power() { - multiplier = (system.region() == System::NTSC ? config.cpu.ntsc_clock_rate : config.cpu.pal_clock_rate); - gameboy->power(); - reset(); +void SuperGameBoy::enable() { } -void SuperGameboy::reset() { - gameboy->reset(); - packet.reset(); - counter = 0; - +void SuperGameBoy::power() { bus.map(Bus::MapDirect, 0x00, 0x3f, 0x6000, 0x7fff, *this); bus.map(Bus::MapDirect, 0x80, 0xbf, 0x6000, 0x7fff, *this); - mmio.r6000 = 0; - mmio.r6003 = 0; - - //$6004-$6007 - mmio.joypadid = 0; - for(unsigned i = 0; i < 4; i++) mmio.joypad[i] = 0xff; - - for(unsigned i = 0; i < 16; i++) mmio.r7000[i] = 0; - mmio.r7800 = 0; -} - -void SuperGameboy::unload() { - gameboy->unload(); -} - -// - -void SuperGameboy::command_1e() { - for(unsigned i = 0; i < 6; i++) { - Packet p; - p[0] = (0x1e << 3) + 1; - p[1] = 0; - for(unsigned n = 2; n < 16; n++) { - p[n] = memory::dmgrom.read(0x0104 + (i * 14) + (n - 2)); - } - packet.add(p); + if(sgb_init) { + sgb_init(SGB2, + memory::gbrom.data(), memory::gbrom.size(), + memory::gbram.data(), memory::gbram.size() + ); } + + if(sgb_power) sgb_power(); } -// - -SuperGameboy::SuperGameboy() { - gameboy = new GameboyGambatte; -} - -SuperGameboy::~SuperGameboy() { - delete gameboy; +void SuperGameBoy::reset() { + if(sgb_reset) sgb_reset(); } }; + diff --git a/src/chip/sgb/sgb.hpp b/src/chip/sgb/sgb.hpp index 2784291d..53e5f3f0 100644 --- a/src/chip/sgb/sgb.hpp +++ b/src/chip/sgb/sgb.hpp @@ -1,28 +1,7 @@ -class Gameboy; - -class SuperGameboy : public Memory { +class SuperGameBoy : public Memory { public: - Gameboy *gameboy; void enter(); - struct Packet { - uint8_t data[16]; - uint8_t& operator[](unsigned addr) { return data[addr & 15]; } - }; - vector packet; - - struct MMIO { - unsigned r6000; - uint8_t r6003; - - //$6004-$6007 - uint8_t joypadid; - uint8_t joypad[4]; - - Packet r7000; - unsigned r7800; - } mmio; - uint8_t read(unsigned addr); void write(unsigned addr, uint8_t data); @@ -30,15 +9,20 @@ public: void enable(); void power(); void reset(); - void unload(); - SuperGameboy(); - ~SuperGameboy(); +private: + library libsgb; + uint32_t samplebuffer[4096]; -protected: - uint64_t multiplier; - uint64_t counter; - void command_1e(); + enum { SGB1 = 0, SGB2 = 1 }; + function sgb_init; + function sgb_term; + function sgb_power; + function sgb_reset; + function sgb_read; + function sgb_write; + function sgb_run; }; -extern SuperGameboy sgb; +extern SuperGameBoy sgb; + diff --git a/src/chip/spc7110/spc7110.cpp b/src/chip/spc7110/spc7110.cpp index 9c54a715..4620cf9d 100644 --- a/src/chip/spc7110/spc7110.cpp +++ b/src/chip/spc7110/spc7110.cpp @@ -3,6 +3,8 @@ #define SPC7110_CPP namespace SNES { +SPC7110 spc7110; + #include "decomp.cpp" const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; @@ -672,3 +674,4 @@ SPC7110::SPC7110() { } }; + diff --git a/src/chip/srtc/srtc.cpp b/src/chip/srtc/srtc.cpp index c161ac74..84b1bc5a 100644 --- a/src/chip/srtc/srtc.cpp +++ b/src/chip/srtc/srtc.cpp @@ -3,6 +3,8 @@ #define SRTC_CPP namespace SNES { +SRTC srtc; + const unsigned SRTC::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; void SRTC::init() { @@ -227,3 +229,4 @@ SRTC::SRTC() { } }; + diff --git a/src/chip/st010/st010.cpp b/src/chip/st010/st010.cpp index 84cff71f..b7917b33 100644 --- a/src/chip/st010/st010.cpp +++ b/src/chip/st010/st010.cpp @@ -1,7 +1,9 @@ #include <../base.hpp> - -#define ST010_CPP + +#define ST010_CPP namespace SNES { + +ST010 st010; #include "st010_data.hpp" #include "st010_op.cpp" @@ -86,5 +88,5 @@ void ST010::write(unsigned addr, uint8 data) { ram[0x0021] &= ~0x80; } } - -}; +}; + diff --git a/src/clean.bat b/src/clean.bat index 1d563cce..d8bb7e0b 100644 --- a/src/clean.bat +++ b/src/clean.bat @@ -1 +1 @@ -@mingw32-make platform=win compiler=mingw32-gcc clean +@mingw32-make clean diff --git a/src/clean.sh b/src/clean.sh deleted file mode 100644 index fddeab62..00000000 --- a/src/clean.sh +++ /dev/null @@ -1 +0,0 @@ -make platform=x compiler=gcc clean diff --git a/src/cpu/core/core.cpp b/src/cpu/core/core.cpp index 292b4bb4..6506cf69 100644 --- a/src/cpu/core/core.cpp +++ b/src/cpu/core/core.cpp @@ -48,3 +48,4 @@ CPUcore::CPUcore() { } }; + diff --git a/src/cpu/core/opcode_algorithms.cpp b/src/cpu/core/opcode_algorithms.cpp index 6bb02006..4df8b361 100644 --- a/src/cpu/core/opcode_algorithms.cpp +++ b/src/cpu/core/opcode_algorithms.cpp @@ -1,3 +1,5 @@ +#ifdef CPUCORE_CPP + inline void CPUcore::op_adc_b() { int r; if(regs.p.d) { @@ -363,3 +365,5 @@ inline void CPUcore::op_tsb_w() { regs.p.z = (rd.w & regs.a.w) == 0; rd.w |= regs.a.w; } +#endif + diff --git a/src/cpu/core/opcode_headers.bpp b/src/cpu/core/opcode_headers.bpp index f3e277d8..82d5f878 100644 --- a/src/cpu/core/opcode_headers.bpp +++ b/src/cpu/core/opcode_headers.bpp @@ -383,6 +383,4 @@ void op_per_e(); void op_per_n(); @endmacro -// - @include "opcode_list.bpp" diff --git a/src/cpu/core/opcode_tables.cpp b/src/cpu/core/opcode_tables.cpp index e75787a1..bafccb73 100644 --- a/src/cpu/core/opcode_tables.cpp +++ b/src/cpu/core/opcode_tables.cpp @@ -1,37 +1,37 @@ -void CPUcore::initialize_opcode_table() { - for(unsigned i = 0; i < 256 * 5; i++) op_table[i] = 0; +#ifdef CPUCORE_CPP +void CPUcore::initialize_opcode_table() { //same implementation for all processor states #define opA(id, name) \ - op_table[table_EM + id] = &sCPU::op_ ## name; \ - op_table[table_MX + id] = &sCPU::op_ ## name; \ - op_table[table_Mx + id] = &sCPU::op_ ## name; \ - op_table[table_mX + id] = &sCPU::op_ ## name; \ - op_table[table_mx + id] = &sCPU::op_ ## name; + op_table[table_EM + id] = &CPUcore::op_ ## name; \ + op_table[table_MX + id] = &CPUcore::op_ ## name; \ + op_table[table_Mx + id] = &CPUcore::op_ ## name; \ + op_table[table_mX + id] = &CPUcore::op_ ## name; \ + op_table[table_mx + id] = &CPUcore::op_ ## name; //implementation changes based on E processor state #define opE(id, name) \ - op_table[table_EM + id] = &sCPU::op_ ## name ## _e; \ - op_table[table_MX + id] = &sCPU::op_ ## name ## _n; \ - op_table[table_Mx + id] = &sCPU::op_ ## name ## _n; \ - op_table[table_mX + id] = &sCPU::op_ ## name ## _n; \ - op_table[table_mx + id] = &sCPU::op_ ## name ## _n; \ + op_table[table_EM + id] = &CPUcore::op_ ## name ## _e; \ + op_table[table_MX + id] = &CPUcore::op_ ## name ## _n; \ + op_table[table_Mx + id] = &CPUcore::op_ ## name ## _n; \ + op_table[table_mX + id] = &CPUcore::op_ ## name ## _n; \ + op_table[table_mx + id] = &CPUcore::op_ ## name ## _n; \ //implementation changes based on M processor state #define opM(id, name) \ - op_table[table_EM + id] = &sCPU::op_ ## name ## _b; \ - op_table[table_MX + id] = &sCPU::op_ ## name ## _b; \ - op_table[table_Mx + id] = &sCPU::op_ ## name ## _b; \ - op_table[table_mX + id] = &sCPU::op_ ## name ## _w; \ - op_table[table_mx + id] = &sCPU::op_ ## name ## _w; + op_table[table_EM + id] = &CPUcore::op_ ## name ## _b; \ + op_table[table_MX + id] = &CPUcore::op_ ## name ## _b; \ + op_table[table_Mx + id] = &CPUcore::op_ ## name ## _b; \ + op_table[table_mX + id] = &CPUcore::op_ ## name ## _w; \ + op_table[table_mx + id] = &CPUcore::op_ ## name ## _w; //implementation changes based on X processor state #define opX(id, name) \ - op_table[table_EM + id] = &sCPU::op_ ## name ## _b; \ - op_table[table_MX + id] = &sCPU::op_ ## name ## _b; \ - op_table[table_Mx + id] = &sCPU::op_ ## name ## _w; \ - op_table[table_mX + id] = &sCPU::op_ ## name ## _b; \ - op_table[table_mx + id] = &sCPU::op_ ## name ## _w; + op_table[table_EM + id] = &CPUcore::op_ ## name ## _b; \ + op_table[table_MX + id] = &CPUcore::op_ ## name ## _b; \ + op_table[table_Mx + id] = &CPUcore::op_ ## name ## _w; \ + op_table[table_mX + id] = &CPUcore::op_ ## name ## _b; \ + op_table[table_mx + id] = &CPUcore::op_ ## name ## _w; opE(0x00, brk) opM(0x01, ora_idpx) opE(0x02, cop) opM(0x03, ora_sr) opM(0x04, tsb_dp) opM(0x05, ora_dp) opM(0x06, asl_dp) opM(0x07, ora_ildp) @@ -136,3 +136,6 @@ void CPUcore::update_table() { } } } + +#endif + diff --git a/src/cpu/cpu.cpp b/src/cpu/cpu.cpp index 69aabf0b..0984f884 100644 --- a/src/cpu/cpu.cpp +++ b/src/cpu/cpu.cpp @@ -1,6 +1,6 @@ #include <../base.hpp> - -#define CPU_CPP + +#define CPU_CPP namespace SNES { void CPU::power() { @@ -15,5 +15,5 @@ CPU::CPU() { CPU::~CPU() { } - -}; +}; + diff --git a/src/cpu/scpu/memory/memory.cpp b/src/cpu/scpu/memory/memory.cpp index bd0de6ba..e50e86dc 100644 --- a/src/cpu/scpu/memory/memory.cpp +++ b/src/cpu/scpu/memory/memory.cpp @@ -4,11 +4,6 @@ void sCPU::op_io() { status.clock_count = 6; precycle_edge(); add_clocks(6); - - if(regs.wai) { - scheduler.sync_cpucop(); - scheduler.sync_cpuppu(); - } cycle_edge(); } @@ -16,9 +11,7 @@ uint8 sCPU::op_read(uint32 addr) { status.clock_count = speed(addr); precycle_edge(); add_clocks(status.clock_count - 4); - scheduler.sync_cpucop(); - scheduler.sync_cpuppu(); regs.mdr = bus.read(addr); add_clocks(4); cycle_edge(); @@ -29,9 +22,7 @@ void sCPU::op_write(uint32 addr, uint8 data) { status.clock_count = speed(addr); precycle_edge(); add_clocks(status.clock_count); - scheduler.sync_cpucop(); - scheduler.sync_cpuppu(); bus.write(addr, regs.mdr = data); cycle_edge(); } @@ -47,3 +38,4 @@ unsigned sCPU::speed(unsigned addr) const { } #endif + diff --git a/src/cpu/scpu/mmio/mmio.cpp b/src/cpu/scpu/mmio/mmio.cpp index 7eb72cac..5ec95afd 100644 --- a/src/cpu/scpu/mmio/mmio.cpp +++ b/src/cpu/scpu/mmio/mmio.cpp @@ -42,7 +42,7 @@ void sCPU::mmio_w4016(uint8 data) { status.joypad_strobe_latch = !!(data & 1); if(status.joypad_strobe_latch == 1) { - system.input.poll(); + input.poll(); } } @@ -54,7 +54,7 @@ void sCPU::mmio_w4016(uint8 data) { //realtime or buffered status of joypadN.b uint8 sCPU::mmio_r4016() { uint8 r = regs.mdr & 0xfc; - r |= system.input.port_read(0) & 3; + r |= input.port_read(0) & 3; return r; } @@ -64,7 +64,7 @@ uint8 sCPU::mmio_r4016() { //1-0 = Joypad serial data uint8 sCPU::mmio_r4017() { uint8 r = (regs.mdr & 0xe0) | 0x1c; - r |= system.input.port_read(1) & 3; + r |= input.port_read(1) & 3; return r; } diff --git a/src/cpu/scpu/scpu.cpp b/src/cpu/scpu/scpu.cpp index e181c390..dc7b822f 100644 --- a/src/cpu/scpu/scpu.cpp +++ b/src/cpu/scpu/scpu.cpp @@ -1,7 +1,7 @@ -#include <../base.hpp> -#include +#include <../base.hpp> +#include -#define SCPU_CPP +#define SCPU_CPP namespace SNES { priority_queue event(512, bind(&sCPU::queue_event, &cpu)); @@ -30,7 +30,7 @@ void sCPU::enter() { } tracer.trace_cpuop(); //traces CPU opcode (only if tracer is enabled) - (this->*opcode_table[op_readpc()])(); + (this->*opcode_table[op_readpc()])(); } } @@ -96,5 +96,5 @@ sCPU::sCPU() { sCPU::~sCPU() { } - -}; +}; + diff --git a/src/cpu/scpu/timing/joypad.cpp b/src/cpu/scpu/timing/joypad.cpp index ea018229..2afb017a 100644 --- a/src/cpu/scpu/timing/joypad.cpp +++ b/src/cpu/scpu/timing/joypad.cpp @@ -3,8 +3,8 @@ void sCPU::run_auto_joypad_poll() { uint16 joy1 = 0, joy2 = 0, joy3 = 0, joy4 = 0; for(unsigned i = 0; i < 16; i++) { - uint8 port0 = system.input.port_read(0); - uint8 port1 = system.input.port_read(1); + uint8 port0 = input.port_read(0); + uint8 port1 = input.port_read(1); joy1 |= (port0 & 1) ? (0x8000 >> i) : 0; joy2 |= (port1 & 1) ? (0x8000 >> i) : 0; diff --git a/src/cpu/scpu/timing/timing.cpp b/src/cpu/scpu/timing/timing.cpp index eb40929e..63bf3ae6 100644 --- a/src/cpu/scpu/timing/timing.cpp +++ b/src/cpu/scpu/timing/timing.cpp @@ -13,21 +13,24 @@ void sCPU::add_clocks(unsigned clocks) { unsigned ticks = clocks >> 1; while(ticks--) { ppu.tick(); - if((ppu.hcounter() & 2) == 0) { - system.input.tick(); - } else { + if(ppu.hcounter() & 2) { + input.tick(); poll_interrupts(); } } scheduler.addclocks_cpu(clocks); } +//called by ppu.tick() when Hcounter=0 void sCPU::scanline() { status.dma_counter = (status.dma_counter + status.line_clocks) & 7; status.line_clocks = ppu.lineclocks(); - //forcefully sync S-CPU and S-SMP, in case chips are not communicating - if((ppu.vcounter() & 7) == 0) scheduler.sync_cpusmp(); + //forcefully sync S-CPU to other processors, in case chips are not communicating + scheduler.sync_cpuppu(); + scheduler.sync_cpucop(); + scheduler.sync_cpusmp(); + system.scanline(); if(ppu.vcounter() == 0) { //hdma init triggers once every frame @@ -44,7 +47,7 @@ void sCPU::scanline() { } if(status.auto_joypad_poll == true && ppu.vcounter() == (ppu.overscan() == false ? 227 : 242)) { - system.input.poll(); + input.poll(); run_auto_joypad_poll(); } } diff --git a/src/data/license.html b/src/data/license.html index 60e97f32..6f5591ec 100644 --- a/src/data/license.html +++ b/src/data/license.html @@ -66,8 +66,6 @@ software which is ordinarily not compatible with this license, such as the GPL. - - diff --git a/src/dsp/adsp/adsp.cpp b/src/dsp/adsp/adsp.cpp index 38849dab..e73350e7 100644 --- a/src/dsp/adsp/adsp.cpp +++ b/src/dsp/adsp/adsp.cpp @@ -1,7 +1,7 @@ #include <../base.hpp> - -#define ADSP_CPP -namespace SNES { + +#define ADSP_CPP +namespaec SNES { #include "adsp_tables.cpp" @@ -582,12 +582,13 @@ int32 fir_samplel, fir_sampler; msampler = sclamp<16>(msampler); } - system.audio.dsp_sample(msamplel, msampler); + audio.sample(msamplel, msampler); scheduler.addclocks_dsp(32 * 3 * 8); scheduler.sync_dspsmp(); } aDSP::aDSP() {} aDSP::~aDSP() {} - -}; + +}; + diff --git a/src/dsp/sdsp/echo.cpp b/src/dsp/sdsp/echo.cpp index afc386b2..fa38f87d 100644 --- a/src/dsp/sdsp/echo.cpp +++ b/src/dsp/sdsp/echo.cpp @@ -106,7 +106,7 @@ void sDSP::echo_27() { } //output sample to DAC - system.audio.dsp_sample(outl, outr); + audio.sample(outl, outr); } void sDSP::echo_28() { diff --git a/src/dsp/sdsp/sdsp.cpp b/src/dsp/sdsp/sdsp.cpp index 3d241ef1..5277dc7b 100644 --- a/src/dsp/sdsp/sdsp.cpp +++ b/src/dsp/sdsp/sdsp.cpp @@ -1,12 +1,11 @@ /* S-DSP emulator - license: LGPLv2 - Note: this is basically a C++ cothreaded implementation of Shay Green's (blargg's) S-DSP emulator. The actual algorithms, timing information, tables, variable names, etc were all from him. */ #include <../base.hpp> + #define SDSP_CPP namespace SNES { @@ -327,3 +326,4 @@ sDSP::~sDSP() { } }; + diff --git a/src/interface.hpp b/src/interface.hpp index 738d45f3..19d66410 100644 --- a/src/interface.hpp +++ b/src/interface.hpp @@ -26,6 +26,6 @@ namespace SNES { #include "system/system.hpp" #include "chip/chip.hpp" - #include "cartridge/cartridge.hpp" -} +}; + diff --git a/src/lib/libgambatte/COPYING b/src/lib/libgambatte/COPYING deleted file mode 100644 index d511905c..00000000 --- a/src/lib/libgambatte/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/src/lib/libgambatte/Makefile b/src/lib/libgambatte/Makefile deleted file mode 100644 index 3382030a..00000000 --- a/src/lib/libgambatte/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -cc = g++ - -cflags = -O2 -fomit-frame-pointer -Wall -Wextra -cflags += -fno-exceptions -fno-rtti -cflags += -DHAVE_STDINT_H -DCHAR_WIDTH_8 -cflags += -Isrc -Iinclude -Icommon - -headers = src/*.h src/file/*.h src/sound/*.h src/video/*.h src/video/filters/*.h -headers += include/*.h -headers += common/*.h common/resample/*.h - -source = \ - src/bitmap_font.cpp \ - src/colorconversion.cpp \ - src/cpu.cpp \ - src/gambatte.cpp \ - src/initstate.cpp \ - src/interrupter.cpp \ - src/memory.cpp \ - src/rtc.cpp \ - src/sound.cpp \ - src/state_osd_elements.cpp \ - src/statesaver.cpp \ - src/video.cpp \ - src/sound/channel1.cpp \ - src/sound/channel2.cpp \ - src/sound/channel3.cpp \ - src/sound/channel4.cpp \ - src/sound/duty_unit.cpp \ - src/sound/envelope_unit.cpp \ - src/sound/length_counter.cpp \ - src/video/basic_add_event.cpp \ - src/video/break_event.cpp \ - src/video/irq_event.cpp \ - src/video/ly_counter.cpp \ - src/video/lyc_irq.cpp \ - src/video/m3_extra_cycles.cpp \ - src/video/mode3_event.cpp \ - src/video/mode0_irq.cpp \ - src/video/mode1_irq.cpp \ - src/video/mode2_irq.cpp \ - src/video/sc_reader.cpp \ - src/video/scx_reader.cpp \ - src/video/sprite_mapper.cpp \ - src/video/we_master_checker.cpp \ - src/video/we.cpp \ - src/video/wx_reader.cpp \ - src/video/wy.cpp \ - src/video/filters/catrom2x.cpp \ - src/video/filters/catrom3x.cpp \ - src/video/filters/kreed2xsai.cpp \ - src/video/filters/maxsthq2x.cpp \ - src/video/filters/maxsthq3x.cpp \ - src/file/file.cpp \ - -all: build; - -clean: - -@rm obj/*.o - -@rm libgambatte.a - -$(foreach item,$(source),$(eval obj/$(notdir $(basename $(item))).o: $(item) $(headers))) -objects := $(foreach item,$(source),obj/$(notdir $(basename $(item))).o) - -%.o: $< - $(cc) -o $@ -c $< $(cflags) - -build: $(objects) - ar rcs libgambatte.a $(objects) diff --git a/src/lib/libgambatte/README b/src/lib/libgambatte/README deleted file mode 100644 index 0e243055..00000000 --- a/src/lib/libgambatte/README +++ /dev/null @@ -1,130 +0,0 @@ --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- -Copyright (C) 2007 by Sindre AamÃ¥s -aamas@stud.ntnu.no - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License version 2 for more details. - -You should have received a copy of the GNU General Public License -version 2 along with this program; if not, write to the -Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA --------------------------------------------------------------------------------- --------------------------------------------------------------------------------- - -About --------------------------------------------------------------------------------- -Gambatte is an accuracy-focused, open-source, cross-platform -Game Boy Color emulator written in C++. It is based on hundreds of -corner case hardware tests, as well as previous documentation and reverse -engineering efforts. - -The core emulation code is contained in a separate library back-end -(libgambatte) written in platform-independent C++. There is currently a GUI -front-end (gambatte_qt) using Trolltech's Qt4 toolkit, and a simple command-line -SDL front-end (gambatte_sdl). - -The GUI front-end contains platform-specific extensions for video, sound and -timers. It should work on MS Windows, Linux/BSD/UNIX-like OSes, and Mac OS X. - -The SDL front-end should be usable on all platforms with a working SDL port. It -should also be quite trivial to create new (simple) front-ends (note that the -library API should in no way be considered stable). - -Usage --------------------------------------------------------------------------------- -You will have to supply Gambatte with a ROM image file of the GB/GBC -program/game you'd like to run/play, either as a command-line argument to -gambatte_sdl, or through the File->Open... menu in gambatte_qt. - -gambatte_sdl keyboard commands: -TAB - fast-forward -Ctrl-f - toggle full screen -Ctrl-r - reset -F5 - save state -F6 - previous state slot -F7 - next state slot -F8 - load state -0 to 9 - select state slot 0 to 9 - -Default key mapping: -Up: Up -Down: Down -Left: Left -Right: Right -A: D -B: C -Start: Return -Select: Shift - -Compiling --------------------------------------------------------------------------------- -Building Gambatte from source code can be done by executing the -build_.sh scripts for the qt/sdl front-ends respectively, or by issueing -the correct build command (either 'scons' or 'qmake && make') in the top-level -subdirectories (libgambatte will have to be built first). The clean.sh script -can be executed to remove all generated files after a compile (including -binaries). - -Requirements for building libgambatte: -- A decent C++ compiler (like g++ in the GNU Compiler Collection). -- SCons. -- optionally zlib - -Requirements for building gambatte_sdl: -- A decent C++ compiler (like g++ in the GNU Compiler Collection). -- SDL headers and library. -- SCons. -(- libgambatte.) - -Requirements for building gambatte_qt: -- A decent C++ compiler (like g++ in the GNU Compiler Collection). -- Qt4 (Core, GUI, OpenGL) headers and library. -- Qmake and make (GNU Make should work). -- Platform-specific requirements: - * MS Windows: - - Win32 API headers and libraries. - - DirectSound and DirectDraw7 headers and libraries. - - Direct3D9 headers - * Linux/BSD/UNIX-like OSes: - - POSIX/UNIX headers (unistd.h, fcntl.h, sys/ioctl.h, sys/time.h, sys/shm.h). - - Open Sound System header (sys/soundcard.h). - - X11 Xlib, XVideo, XRandR and XShm headers and libraries. - - Alsa headers and library (Linux only). - * Max OS X: - - Recent Mac OS X SDK (Panther Xcode/SDK should work) -(- libgambatte.) - -Installing after a compile simply amounts to copying the generated binary -(either gambatte_qt/bin/gambatte_qt<.exe> or gambatte_sdl/gambatte_sdl<.exe>) -to wherever you'd like to keep it. - -Thanks --------------------------------------------------------------------------------- -Derek Liauw Kie Fa (Kreed) -Gilles Vollant -Jeff Frohwein -Jonathan Gevaryahu (Lord Nightmare) -kOOPa -Marat Fayzullin -Martin Korth (nocash) -Maxim Stepin (MaxSt) -Nach -Pan of Anthrox -Pascal Felber -Paul Robson -SDL -Shay Green (blargg) -The OpenGL Extension Wrangler Library - --------------------------------------------------------------------------------- -Game Boy and Game Boy Color are registered trademarks of -Nintendo of America Inc. -Gambatte is not affiliated with or endorsed by any of the companies mentioned. diff --git a/src/lib/libgambatte/common/adaptivesleep.cpp b/src/lib/libgambatte/common/adaptivesleep.cpp deleted file mode 100644 index 48c40979..00000000 --- a/src/lib/libgambatte/common/adaptivesleep.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "adaptivesleep.h" - -usec_t AdaptiveSleep::sleepUntil(usec_t base, usec_t inc) { - usec_t now = getusecs(); - usec_t diff = now - base; - - if (diff >= inc) - return diff - inc; - - diff = inc - diff; - - if (diff > oversleep + oversleepVar) { - diff -= oversleep + oversleepVar; - usecsleep(diff); - const usec_t ideal = now + diff; - now = getusecs(); - - { - usec_t curOversleep = now - ideal; - - if (negate(curOversleep) < curOversleep) - curOversleep = 0; - - oversleepVar = (oversleepVar * 15 + (curOversleep < oversleep ? oversleep - curOversleep : curOversleep - oversleep)) >> 4; - oversleep = (oversleep * 15 + curOversleep) >> 4; - } - - noSleep = 60; - } else if (--noSleep == 0) { - noSleep = 60; - oversleep = oversleepVar = 0; - } - - while (now - base < inc) - now = getusecs(); - - return 0; -} diff --git a/src/lib/libgambatte/common/adaptivesleep.h b/src/lib/libgambatte/common/adaptivesleep.h deleted file mode 100644 index de2010a0..00000000 --- a/src/lib/libgambatte/common/adaptivesleep.h +++ /dev/null @@ -1,34 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef ADAPTIVE_SLEEP_H -#define ADAPTIVE_SLEEP_H - -#include "usec.h" - -class AdaptiveSleep { - usec_t oversleep; - usec_t oversleepVar; - unsigned noSleep; - -public: - AdaptiveSleep() : oversleep(0), oversleepVar(0), noSleep(60) {} - usec_t sleepUntil(usec_t base, usec_t inc); -}; - -#endif diff --git a/src/lib/libgambatte/common/array.h b/src/lib/libgambatte/common/array.h deleted file mode 100644 index f01806ea..00000000 --- a/src/lib/libgambatte/common/array.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef ARRAY_H -#define ARRAY_H - -#include - -template -class Array { - T *a; - std::size_t sz; - - Array(const Array &ar); - -public: - Array(const std::size_t size = 0) : a(size ? new T[size] : 0), sz(size) {} - ~Array() { delete []a; } - void reset(const std::size_t size) { delete []a; a = size ? new T[size] : 0; sz = size; } - std::size_t size() const { return sz; } - operator T*() { return a; } - operator const T*() const { return a; } -}; - -#endif diff --git a/src/lib/libgambatte/common/rateest.cpp b/src/lib/libgambatte/common/rateest.cpp deleted file mode 100644 index c1feba6c..00000000 --- a/src/lib/libgambatte/common/rateest.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "rateest.h" -#include - -void RateEst::SumQueue::reset() { - q.clear(); - samples_ = usecs_ = 0; -} - -void RateEst::SumQueue::push(const long samples, const usec_t usecs) { - q.push_back(pair_t(samples, usecs)); - samples_ += samples; - usecs_ += usecs; -} - -void RateEst::SumQueue::pop() { - const pair_t &f = q.front(); - samples_ -= f.first; - usecs_ -= f.second; - q.pop_front(); -} - -static usec_t sampleUsecs(long samples, long rate) { - return static_cast((samples * 1000000.0f) / (rate ? rate : 1) + 0.5f); -} - -static long limit(long est, const long reference) { - if (est > reference + (reference >> 6)) - est = reference + (reference >> 6); - else if (est < reference - (reference >> 6)) - est = reference - (reference >> 6); - - return est; -} - -void RateEst::init(long srate, long reference, const long maxSamplePeriod) { - maxPeriod = sampleUsecs(maxSamplePeriod, reference); - - srate <<= UPSHIFT; - reference <<= UPSHIFT; - - this->srate.est = limit(srate, reference); - this->srate.var = srate >> 12; - last = 0; - this->reference = reference; - samples = ((this->srate.est >> UPSHIFT) * 12) << 5; - usecs = 12000000 << 5; - sumq.reset(); -} - -void RateEst::feed(long samplesIn, const usec_t now) { - usec_t usecsIn = now - last; - - if (last && usecsIn < maxPeriod) { - sumq.push(samplesIn, usecsIn); - - while ((usecsIn = sumq.usecs()) > 100000) { - samplesIn = sumq.samples(); - sumq.pop(); - - if (std::abs(static_cast(samplesIn * (1000000.0f * UP) / usecsIn) - reference) < reference >> 1) { - samples += (samplesIn - sumq.samples()) << 5; - usecs += (usecsIn - sumq.usecs()) << 5; - - long est = static_cast(samples * (1000000.0f * UP) / usecs + 0.5f); - est = limit((srate.est * 31 + est + 16) >> 5, reference); - srate.var = (srate.var * 15 + std::abs(est - srate.est) + 8) >> 4; - srate.est = est; - - if (usecs > 16000000 << 5) { - samples = (samples * 3 + 2) >> 2; - usecs = (usecs * 3 + 2) >> 2; - } - } - } - } - - last = now; -} diff --git a/src/lib/libgambatte/common/rateest.h b/src/lib/libgambatte/common/rateest.h deleted file mode 100644 index 3e109541..00000000 --- a/src/lib/libgambatte/common/rateest.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef RATEEST_H -#define RATEEST_H - -#include "usec.h" -#include -#include - -class RateEst { -public: - struct Result { - long est; - long var; - }; - -private: - class SumQueue { - typedef std::pair pair_t; - typedef std::deque q_t; - - q_t q; - long samples_; - usec_t usecs_; - - public: - SumQueue() : samples_(0), usecs_(0) {} - void reset(); - long samples() const { return samples_; } - usec_t usecs() const { return usecs_; } - void push(long samples, usec_t usecs); - void pop(); - }; - - enum { UPSHIFT = 5 }; - enum { UP = 1 << UPSHIFT }; - - Result srate; - SumQueue sumq; - usec_t last; - usec_t usecs; - usec_t maxPeriod; - long reference; - long samples; - -public: - RateEst(long srate = 0) { init(srate); } - RateEst(long srate, long reference) { init(srate, reference); } - void init(long srate) { init(srate, srate); } - void init(long srate, long reference) { init(srate, reference, reference); } - void init(long srate, long reference, long maxSamplePeriod); - void reset() { last = 0; } - void feed(long samples, usec_t usecs = getusecs()); - const Result result() const { const Result res = { (srate.est + UP / 2) >> UPSHIFT, (srate.var + UP / 2) >> UPSHIFT }; return res; } -}; - -#endif diff --git a/src/lib/libgambatte/common/resample/blackmansinc.h b/src/lib/libgambatte/common/resample/blackmansinc.h deleted file mode 100644 index 86578239..00000000 --- a/src/lib/libgambatte/common/resample/blackmansinc.h +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef BLACKMANSINC_H -#define BLACKMANSINC_H - -#include "convoluter.h" -#include "subresampler.h" -#include "makesinckernel.h" -#include "cic4.h" -#include -#include - -template -class BlackmanSinc : public SubResampler { - PolyPhaseConvoluter convoluters[channels]; - short *kernel; - - static double blackmanWin(const long i, const long M) { - static const double PI = 3.14159265358979323846; - return 0.42 - 0.5 * std::cos(2 * PI * i / M) + 0.08 * std::cos(4 * PI * i / M); - } - - void init(unsigned div, unsigned phaseLen, double fc); - -public: - enum { MUL = phases }; - - typedef Cic4 Cic; - static float cicLimit() { return 4.7f; } - - class RollOff { - static unsigned toTaps(const float rollOffWidth) { - static const float widthTimesTaps = 4.5f; - return std::ceil(widthTimesTaps / rollOffWidth); - } - - static float toFc(const float rollOffStart, const int taps) { - static const float startToFcDeltaTimesTaps = 1.69f; - return startToFcDeltaTimesTaps / taps + rollOffStart; - } - - public: - const unsigned taps; - const float fc; - - RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {} - }; - - BlackmanSinc(unsigned div, unsigned phaseLen, double fc) { init(div, phaseLen, fc); } - BlackmanSinc(unsigned div, RollOff ro) { init(div, ro.taps, ro.fc); } - ~BlackmanSinc() { delete[] kernel; } - std::size_t resample(short *out, const short *in, std::size_t inlen); - void adjustDiv(unsigned div); - unsigned mul() const { return MUL; } - unsigned div() const { return convoluters[0].div(); } -}; - -template -void BlackmanSinc::init(const unsigned div, const unsigned phaseLen, const double fc) { - kernel = new short[phaseLen * phases]; - - makeSincKernel(kernel, phases, phaseLen, fc, blackmanWin); - - for (unsigned i = 0; i < channels; ++i) - convoluters[i].reset(kernel, phaseLen, div); -} - -template -std::size_t BlackmanSinc::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t samplesOut; - - for (unsigned i = 0; i < channels; ++i) - samplesOut = convoluters[i].filter(out + i, in + i, inlen); - - return samplesOut; -} - -template -void BlackmanSinc::adjustDiv(const unsigned div) { - for (unsigned i = 0; i < channels; ++i) - convoluters[i].adjustDiv(div); -} - -#endif diff --git a/src/lib/libgambatte/common/resample/chainresampler.cpp b/src/lib/libgambatte/common/resample/chainresampler.cpp deleted file mode 100644 index 6836a05b..00000000 --- a/src/lib/libgambatte/common/resample/chainresampler.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "chainresampler.h" - -float ChainResampler::get2ChainMidRatio(const float ratio, const float rollOff) { - return std::sqrt(0.5f * rollOff * ratio) + 1; -} - -float ChainResampler::get2ChainCost(const float ratio, const float rollOff, const float midRatio) { - return midRatio * ratio / ((midRatio - 1) * 2) + midRatio / rollOff; -} - -float ChainResampler::get3ChainRatio1(float ratio1, const float rollOff, const float ratio) { - for (unsigned n = 8; n--;) { - ratio1 = std::sqrt(ratio - ratio / get3ChainRatio2(ratio1, rollOff)) + 1; - } - - return ratio1; -} - -float ChainResampler::get3ChainCost(const float ratio, const float rollOff, const float ratio1, const float ratio2) { - return ratio1 * ratio / ((ratio1 - 1) * 2) + ratio2 * ratio1 / ((ratio2 - 1) * 2) + ratio2 / rollOff; -} - -std::size_t ChainResampler::reallocateBuffer() { - std::size_t bufSz[2] = { 0, 0 }; - std::size_t inSz = periodSize; - int i = -1; - - for (list_t::iterator it = list.begin(); it != list.end(); ++it) { - inSz = (inSz * (*it)->mul() - 1) / (*it)->div() + 1; - - ++i; - - if (inSz > bufSz[i&1]) - bufSz[i&1] = inSz; - } - - if (inSz >= bufSz[i&1]) - bufSz[i&1] = 0; - - if (bufferSize < bufSz[0] + bufSz[1]) { - delete[] buffer; - buffer = (bufferSize = bufSz[0] + bufSz[1]) ? new short[bufferSize * channels] : NULL; - } - - buffer2 = bufSz[1] ? buffer + bufSz[0] * channels : NULL; - - return (maxOut_ = inSz); -} - -void ChainResampler::adjustRate(const long inRate, const long outRate) { - unsigned long mul, div; - - exactRatio(mul, div); - - bigSinc->adjustDiv(static_cast(inRate) * mul / (static_cast(div / bigSinc->div()) * outRate) + 0.5); - - reallocateBuffer(); - setRate(inRate, outRate); -} - -void ChainResampler::exactRatio(unsigned long &mul, unsigned long &div) const { - mul = 1; - div = 1; - - for (list_t::const_iterator it = list.begin(); it != list.end(); ++it) { - mul *= (*it)->mul(); - div *= (*it)->div(); - } -} - -std::size_t ChainResampler::resample(short *const out, const short *const in, std::size_t inlen) { - assert(inlen <= periodSize); - - short *const buf = buffer != buffer2 ? buffer : out; - short *const buf2 = buffer2 ? buffer2 : out; - - const short *inbuf = in; - short *outbuf = NULL; - - for (list_t::iterator it = list.begin(); it != list.end(); ++it) { - outbuf = ++list_t::iterator(it) == list.end() ? out : (inbuf == buf ? buf2 : buf); - inlen = (*it)->resample(outbuf, inbuf, inlen); - inbuf = outbuf; - } - - return inlen; -} - -void ChainResampler::uninit() { - delete[] buffer; - buffer2 = buffer = NULL; - bufferSize = 0; - periodSize = 0; - bigSinc = NULL; - - for (list_t::iterator it = list.begin(); it != list.end(); ++it) - delete *it; - - list.clear(); -} diff --git a/src/lib/libgambatte/common/resample/chainresampler.h b/src/lib/libgambatte/common/resample/chainresampler.h deleted file mode 100644 index aeb52d6c..00000000 --- a/src/lib/libgambatte/common/resample/chainresampler.h +++ /dev/null @@ -1,189 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CHAINRESAMPLER_H -#define CHAINRESAMPLER_H - -#include -#include -#include -#include -#include -#include "subresampler.h" -#include "resampler.h" -#include "upsampler.h" - -class ChainResampler : public Resampler { - enum { channels = 2 }; - - typedef std::list list_t; - - list_t list; - SubResampler *bigSinc; - short *buffer; - short *buffer2; - std::size_t bufferSize; - std::size_t periodSize; - std::size_t maxOut_; - - static float get1ChainCost(const float ratio, const float rollOff) { - return ratio / rollOff; - } - - static float get2ChainMidRatio(float ratio, float rollOff); - static float get2ChainCost(float ratio, float rollOff, float midRatio); - - static float get3ChainRatio2(const float ratio1, const float rollOff) { - return get2ChainMidRatio(ratio1, rollOff); - } - - static float get3ChainRatio1(float ratio1, float rollOff, float ratio); - static float get3ChainCost(float ratio, float rollOff, float ratio1, float ratio2); - - template class Sinc> - std::size_t downinit(long inRate, long outRate, std::size_t periodSize); - - std::size_t reallocateBuffer(); - - template class Sinc> - std::size_t upinit(long inRate, long outRate, std::size_t periodSize); - -public: - ChainResampler() : bigSinc(NULL), buffer(NULL), buffer2(NULL), bufferSize(0), periodSize(0) {} - ~ChainResampler() { uninit(); } - - void adjustRate(long inRate, long outRate); - void exactRatio(unsigned long &mul, unsigned long &div) const; - - template class Sinc> - std::size_t init(long inRate, long outRate, std::size_t periodSize); - std::size_t maxOut(std::size_t /*inlen*/) const { return maxOut_; } - std::size_t resample(short *out, const short *in, std::size_t inlen); - void uninit(); -}; - -template class Sinc> -std::size_t ChainResampler::init(const long inRate, const long outRate, const std::size_t periodSize) { - setRate(inRate, outRate); - - if (outRate > inRate) - return upinit(inRate, outRate, periodSize); - else - return downinit(inRate, outRate, periodSize); -} - -template class Sinc> -std::size_t ChainResampler::downinit(const long inRate, const long outRate, const std::size_t periodSize) { - typedef Sinc BigSinc; - typedef Sinc SmallSinc; - - uninit(); - this->periodSize = periodSize; - - - const float rollOff = std::max((outRate - 36000.0f + outRate - 40000.0f) / outRate, 0.2f); - - double ratio = static_cast(inRate) / outRate; - - while (ratio >= BigSinc::cicLimit() * 2) { - const int div = std::min(static_cast(ratio / BigSinc::cicLimit()), BigSinc::Cic::MAX_DIV); - - list.push_back(new typename BigSinc::Cic(div)); - ratio /= div; - } - - { - int div_2c = ratio * SmallSinc::MUL / get2ChainMidRatio(ratio, rollOff) + 0.5f; - double ratio_2c = ratio * SmallSinc::MUL / div_2c; - float cost_2c = get2ChainCost(ratio, rollOff, ratio_2c); - - if (cost_2c < get1ChainCost(ratio, rollOff)) { - const int div1_3c = ratio * SmallSinc::MUL / get3ChainRatio1(ratio_2c, rollOff, ratio) + 0.5f; - const double ratio1_3c = ratio * SmallSinc::MUL / div1_3c; - const int div2_3c = ratio1_3c * SmallSinc::MUL / get3ChainRatio2(ratio1_3c, rollOff) + 0.5f; - const double ratio2_3c = ratio1_3c * SmallSinc::MUL / div2_3c; - - if (get3ChainCost(ratio, rollOff, ratio1_3c, ratio2_3c) < cost_2c) { - list.push_back(new SmallSinc(div1_3c, typename SmallSinc::RollOff(0.5f / ratio, (ratio1_3c - 1) / ratio))); - ratio = ratio1_3c; - div_2c = div2_3c; - ratio_2c = ratio2_3c; - } - - list.push_back(new SmallSinc(div_2c, typename SmallSinc::RollOff(0.5f / ratio, (ratio_2c - 1) / ratio))); - ratio = ratio_2c; - } - } - - list.push_back(bigSinc = new BigSinc(BigSinc::MUL * ratio + 0.5, - typename BigSinc::RollOff(0.5f * (1 + std::max((outRate - 40000.0f) / outRate, 0.0f) - rollOff) / ratio, 0.5f * rollOff / ratio))); - - return reallocateBuffer(); -} - -template class Sinc> -std::size_t ChainResampler::upinit(const long inRate, const long outRate, const std::size_t periodSize) { - typedef Sinc BigSinc; - typedef Sinc SmallSinc; - - uninit(); - this->periodSize = periodSize; - - const float rollOff = std::max((inRate - 36000.0f) / inRate, 0.2f); - - double ratio = static_cast(outRate) / inRate; - - // Spectral images above 20 kHz assumed inaudible - { - const int div = outRate / std::max(inRate, 40000l); - - if (div >= 2) { - list.push_front(new Upsampler(div)); - ratio /= div; - } - } - - { - int div_2c = get2ChainMidRatio(ratio, rollOff) * SmallSinc::MUL / ratio + 0.5f; - double ratio_2c = ratio * div_2c / SmallSinc::MUL; - float cost_2c = get2ChainCost(ratio, rollOff, ratio_2c); - - if (cost_2c < get1ChainCost(ratio, rollOff)) { - const int div1_3c = get3ChainRatio1(ratio_2c, rollOff, ratio) * SmallSinc::MUL / ratio + 0.5f; - const double ratio1_3c = ratio * div1_3c / SmallSinc::MUL; - const int div2_3c = get3ChainRatio2(ratio1_3c, rollOff) * SmallSinc::MUL / ratio1_3c + 0.5f; - const double ratio2_3c = ratio1_3c * div2_3c / SmallSinc::MUL; - - if (get3ChainCost(ratio, rollOff, ratio1_3c, ratio2_3c) < cost_2c) { - list.push_front(new SmallSinc(div1_3c, typename SmallSinc::RollOff(0.5f / ratio1_3c, (ratio1_3c - 1) / ratio1_3c))); - ratio = ratio1_3c; - div_2c = div2_3c; - ratio_2c = ratio2_3c; - } - - list.push_front(new SmallSinc(div_2c, typename SmallSinc::RollOff(0.5f / ratio_2c, (ratio_2c - 1) / ratio_2c))); - ratio = ratio_2c; - } - } - - list.push_front(bigSinc = new BigSinc(BigSinc::MUL / ratio + 0.5, typename BigSinc::RollOff(0.5f * (1 - rollOff), 0.5f * rollOff))); - - return reallocateBuffer(); -} - -#endif diff --git a/src/lib/libgambatte/common/resample/cic2.h b/src/lib/libgambatte/common/resample/cic2.h deleted file mode 100644 index 1f12bfc9..00000000 --- a/src/lib/libgambatte/common/resample/cic2.h +++ /dev/null @@ -1,198 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CIC2_H -#define CIC2_H - -#include "subresampler.h" - -template -class Cic2Core { -// enum { BUFLEN = 64 }; -// unsigned long buf[BUFLEN]; - unsigned long sum1; - unsigned long sum2; - unsigned long prev1; - unsigned long prev2; - unsigned div_; - unsigned nextdivn; -// unsigned bufpos; - -public: - Cic2Core(const unsigned div = 2) { - reset(div); - } - - unsigned div() const { return div_; } - std::size_t filter(short *out, const short *in, std::size_t inlen); - void reset(unsigned div); -}; - -template -void Cic2Core::reset(const unsigned div) { - sum2 = sum1 = 0; - prev2 = prev1 = 0; - this->div_ = div; - nextdivn = div; -// bufpos = div - 1; -} - -template -std::size_t Cic2Core::filter(short *out, const short *const in, std::size_t inlen) { -// const std::size_t produced = (inlen + div_ - (bufpos + 1)) / div_; - const std::size_t produced = (inlen + div_ - nextdivn) / div_; - const long mul = 0x10000 / (div_ * div_); // trouble if div is too large, may be better to only support power of 2 div - const short *s = in; - - /*unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - - while (inlen >> 2) { - unsigned n = (inlen < BUFLEN ? inlen >> 2 : BUFLEN >> 2); - const unsigned end = n * 4; - unsigned i = 0; - - do { - unsigned long s1 = sm1 += static_cast(*s); - s += channels; - sm1 += static_cast(*s); - s += channels; - buf[i++] = sm2 += s1; - buf[i++] = sm2 += sm1; - s1 = sm1 += static_cast(*s); - s += channels; - sm1 += static_cast(*s); - s += channels; - buf[i++] = sm2 += s1; - buf[i++] = sm2 += sm1; - } while (--n); - - while (bufpos < end) { - const unsigned long out2 = buf[bufpos] - prev2; - prev2 = buf[bufpos]; - bufpos += div_; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - bufpos -= end; - inlen -= end; - } - - if (inlen) { - unsigned n = inlen; - unsigned i = 0; - - do { - sm1 += static_cast(*s); - s += channels; - buf[i++] = sm2 += sm1; - } while (--n); - - while (bufpos < inlen) { - const unsigned long out2 = buf[bufpos] - prev2; - prev2 = buf[bufpos]; - bufpos += div_; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - bufpos -= inlen; - } - - sum1 = sm1; - sum2 = sm2;*/ - - unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - - if (inlen >= nextdivn) { - unsigned divn = nextdivn; - std::size_t n = produced; - - do { - do { - sm1 += static_cast(*s); - s += channels; - sm2 += sm1; - } while (--divn); - - const unsigned long out2 = sm2 - prev2; - prev2 = sm2; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - - divn = div_; - } while (--n); - - nextdivn = div_; - } - - { - unsigned divn = (in + inlen * channels - s) / channels; - nextdivn -= divn; - - while (divn--) { - sm1 += static_cast(*s); - s += channels; - sm2 += sm1; - } - } - - sum1 = sm1; - sum2 = sm2; - - return produced; -} - -template -class Cic2 : public SubResampler { - Cic2Core cics[channels]; - -public: - enum { MAX_DIV = 64 }; - Cic2(unsigned div); - std::size_t resample(short *out, const short *in, std::size_t inlen); - unsigned mul() const { return 1; } - unsigned div() const { return cics[0].div(); } -}; - -template -Cic2::Cic2(const unsigned div) { - for (unsigned i = 0; i < channels; ++i) - cics[i].reset(div); -} - -template -std::size_t Cic2::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t samplesOut; - - for (unsigned i = 0; i < channels; ++i) { - samplesOut = cics[i].filter(out + i, in + i, inlen); - } - - return samplesOut; -} - -#endif diff --git a/src/lib/libgambatte/common/resample/cic3.h b/src/lib/libgambatte/common/resample/cic3.h deleted file mode 100644 index 85b9dcee..00000000 --- a/src/lib/libgambatte/common/resample/cic3.h +++ /dev/null @@ -1,382 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CIC3_H -#define CIC3_H - -#include "subresampler.h" - -template -class Cic3Core { -// enum { BUFLEN = 64 }; -// unsigned long buf[BUFLEN]; - unsigned long sum1; - unsigned long sum2; - unsigned long sum3; - unsigned long prev1; - unsigned long prev2; - unsigned long prev3; - unsigned div_; - unsigned nextdivn; -// unsigned bufpos; - -public: - Cic3Core(const unsigned div = 1) { - reset(div); - } - - unsigned div() const { return div_; } - std::size_t filter(short *out, const short *in, std::size_t inlen); - void reset(unsigned div); -}; - -template -void Cic3Core::reset(const unsigned div) { - sum3 = sum2 = sum1 = 0; - prev3 = prev2 = prev1 = 0; - this->div_ = div; - nextdivn = div; -// bufpos = div - 1; -} - -template -std::size_t Cic3Core::filter(short *out, const short *const in, std::size_t inlen) { -// const std::size_t produced = (inlen + div_ - (bufpos + 1)) / div_; - const std::size_t produced = (inlen + div_ - nextdivn) / div_; - const long mul = 0x10000 / (div_ * div_ * div_); // trouble if div is too large, may be better to only support power of 2 div - const short *s = in; - - /*unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - unsigned long sm3 = sum3; - - while (inlen >> 1) { - unsigned n = (inlen < BUFLEN ? inlen >> 1 : BUFLEN >> 1); - const unsigned end = n * 2; - unsigned i = 0; - - do { - unsigned long s1 = sm1 += static_cast(*s); - s += channels; - sm1 += static_cast(*s); - s += channels; - unsigned long s2 = sm2 += s1; - sm2 += sm1; - buf[i++] = sm3 += s2; - buf[i++] = sm3 += sm2; - } while (--n); - - while (bufpos < end) { - const unsigned long out3 = buf[bufpos] - prev3; - prev3 = buf[bufpos]; - bufpos += div_; - - const unsigned long out2 = out3 - prev2; - prev2 = out3; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - bufpos -= end; - inlen -= end; - } - - if (inlen) { - unsigned n = inlen; - unsigned i = 0; - - do { - sm1 += static_cast(*s); - s += channels; - sm2 += sm1; - buf[i++] = sm3 += sm2; - } while (--n); - - while (bufpos < inlen) { - const unsigned long out3 = buf[bufpos] - prev3; - prev3 = buf[bufpos]; - bufpos += div_; - - const unsigned long out2 = out3 - prev2; - prev2 = out3; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - bufpos -= inlen; - } - - sum1 = sm1; - sum2 = sm2; - sum3 = sm3;*/ - - - unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - unsigned long sm3 = sum3; - - if (inlen >= nextdivn) { - unsigned divn = nextdivn; - std::size_t n = produced; - - do { - do { - sm1 += static_cast(*s); - sm2 += sm1; - sm3 += sm2; - s += channels; - } while (--divn); - - const unsigned long out3 = sm3 - prev3; - prev3 = sm3; - - const unsigned long out2 = out3 - prev2; - prev2 = out3; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - - divn = div_; - } while (--n); - - nextdivn = div_; - } - - { - unsigned divn = (in + inlen * channels - s) / channels; - nextdivn -= divn; - - while (divn--) { - sm1 += static_cast(*s); - sm2 += sm1; - sm3 += sm2; - s += channels; - } - } - - sum1 = sm1; - sum2 = sm2; - sum3 = sm3; - - return produced; -} - -/*template -class Cic3EvenOddCore { - unsigned long sum1; - unsigned long sum2; - unsigned long sum3; - unsigned long prev1; - unsigned long prev2; - unsigned long prev3; - unsigned div_; - unsigned nextdivn; - - static int getMul(unsigned div) { - return 0x10000 / (div * div * div); // trouble if div is too large, may be better to only support power of 2 div - } - - void filterEven(short *out, const short *s, std::size_t n); - void filterOdd(short *out, const short *s, std::size_t n); - -public: - Cic3EvenOddCore(const unsigned div = 2) { - reset(div); - } - - unsigned div() const { return div_; } - std::size_t filter(short *out, const short *in, std::size_t inlen); - void reset(unsigned div); -}; - -template -void Cic3EvenOddCore::reset(const unsigned div) { - sum3 = sum2 = sum1 = 0; - prev3 = prev2 = prev1 = 0; - this->div_ = div; - nextdivn = div; -} - -template -void Cic3EvenOddCore::filterEven(short *out, const short *s, std::size_t n) { - const int mul = getMul(div_); - unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - unsigned long sm3 = sum3; - - while (n--) { - { - unsigned sn = div_ >> 1; - - do { - unsigned long s1 = sm1 += static_cast(*s); - s += channels; - sm1 += static_cast(*s); - s += channels; - unsigned long s2 = sm2 += s1; - sm2 += sm1; - sm3 += s2; - sm3 += sm2; - } while (--sn); - } - - const unsigned long out3 = sm3 - prev3; - prev3 = sm3; - const unsigned long out2 = out3 - prev2; - prev2 = out3; - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - sum1 = sm1; - sum2 = sm2; - sum3 = sm3; -} - -template -void Cic3EvenOddCore::filterOdd(short *out, const short *s, std::size_t n) { - const int mul = getMul(div_); - unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - unsigned long sm3 = sum3; - - while (n--) { - { - unsigned sn = div_ >> 1; - - do { - unsigned long s1 = sm1 += static_cast(*s); - s += channels; - sm1 += static_cast(*s); - s += channels; - unsigned long s2 = sm2 += s1; - sm2 += sm1; - sm3 += s2; - sm3 += sm2; - } while (--sn); - } - - sm1 += static_cast(*s); - s += channels; - sm2 += sm1; - sm3 += sm2; - - const unsigned long out3 = sm3 - prev3; - prev3 = sm3; - const unsigned long out2 = out3 - prev2; - prev2 = out3; - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - sum1 = sm1; - sum2 = sm2; - sum3 = sm3; -} - -template -std::size_t Cic3EvenOddCore::filter(short *out, const short *const in, std::size_t inlen) { - short *const outStart = out; - const short *s = in; - - if (inlen >= nextdivn) { - { - { - unsigned divn = nextdivn; - - do { - sum1 += static_cast(*s); - s += channels; - sum2 += sum1; - sum3 += sum2; - } while (--divn); - } - - const unsigned long out3 = sum3 - prev3; - prev3 = sum3; - const unsigned long out2 = out3 - prev2; - prev2 = out3; - *out = static_cast(out2 - prev1) * getMul(div_) / 0x10000; - prev1 = out2; - out += channels; - } - - std::size_t n = (inlen - nextdivn) / div_; - - if (div_ & 1) - filterOdd(out, s, n); - else - filterEven(out, s, n); - - s += n * div_ * channels; - out += n * channels; - nextdivn = div_; - } - - { - unsigned divn = inlen - (s - in) / channels; - nextdivn -= divn; - - while (divn--) { - sum1 += static_cast(*s); - s += channels; - sum2 += sum1; - sum3 += sum2; - } - } - - return (out - outStart) / channels; -}*/ - -template -class Cic3 : public SubResampler { - Cic3Core cics[channels]; - -public: - enum { MAX_DIV = 23 }; - Cic3(unsigned div); - std::size_t resample(short *out, const short *in, std::size_t inlen); - unsigned mul() const { return 1; } - unsigned div() const { return cics[0].div(); } -}; - -template -Cic3::Cic3(const unsigned div) { - for (unsigned i = 0; i < channels; ++i) - cics[i].reset(div); -} - -template -std::size_t Cic3::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t samplesOut; - - for (unsigned i = 0; i < channels; ++i) { - samplesOut = cics[i].filter(out + i, in + i, inlen); - } - - return samplesOut; -} - -#endif diff --git a/src/lib/libgambatte/common/resample/cic4.h b/src/lib/libgambatte/common/resample/cic4.h deleted file mode 100644 index 430cb03d..00000000 --- a/src/lib/libgambatte/common/resample/cic4.h +++ /dev/null @@ -1,237 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CIC4_H -#define CIC4_H - -#include "subresampler.h" - -template -class Cic4Core { - enum { BUFLEN = 64 }; - unsigned long buf[BUFLEN]; - unsigned long sum1; - unsigned long sum2; - unsigned long sum3; - unsigned long sum4; - unsigned long prev1; - unsigned long prev2; - unsigned long prev3; - unsigned long prev4; - unsigned div_; -// unsigned nextdivn; - unsigned bufpos; - -public: - Cic4Core(const unsigned div = 1) { - reset(div); - } - - unsigned div() const { return div_; } - std::size_t filter(short *out, const short *in, std::size_t inlen); - void reset(unsigned div); -}; - -template -void Cic4Core::reset(const unsigned div) { - sum4 = sum3 = sum2 = sum1 = 0; - prev4 = prev3 = prev2 = prev1 = 0; - this->div_ = div; -// nextdivn = div; - bufpos = div - 1; -} - -template -std::size_t Cic4Core::filter(short *out, const short *const in, std::size_t inlen) { - const std::size_t produced = (inlen + div_ - (bufpos + 1)) / div_; -// const std::size_t produced = (inlen + div_ - nextdivn) / div_; - const long mul = 0x10000 / (div_ * div_ * div_ * div_); // trouble if div is too large, may be better to only support power of 2 div - const short *s = in; - - unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - unsigned long sm3 = sum3; - unsigned long sm4 = sum4; - - while (inlen >> 2) { - unsigned n = (inlen < BUFLEN ? inlen >> 2 : BUFLEN >> 2); - const unsigned end = n * 4; - unsigned i = 0; - - do { - unsigned long s1 = sm1 += static_cast(*s); - s += channels; - sm1 += static_cast(*s); - s += channels; - unsigned long s2 = sm2 += s1; - sm2 += sm1; - unsigned long s3 = sm3 += s2; - sm3 += sm2; - buf[i++] = sm4 += s3; - buf[i++] = sm4 += sm3; - s1 = sm1 += static_cast(*s); - s += channels; - sm1 += static_cast(*s); - s += channels; - s2 = sm2 += s1; - sm2 += sm1; - s3 = sm3 += s2; - sm3 += sm2; - buf[i++] = sm4 += s3; - buf[i++] = sm4 += sm3; - } while (--n); - - while (bufpos < end) { - const unsigned long out4 = buf[bufpos] - prev4; - prev4 = buf[bufpos]; - bufpos += div_; - - const unsigned long out3 = out4 - prev3; - prev3 = out4; - const unsigned long out2 = out3 - prev2; - prev2 = out3; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - bufpos -= end; - inlen -= end; - } - - if (inlen) { - unsigned n = inlen; - unsigned i = 0; - - do { - sm1 += static_cast(*s); - s += channels; - sm2 += sm1; - sm3 += sm2; - buf[i++] = sm4 += sm3; - } while (--n); - - while (bufpos < inlen) { - const unsigned long out4 = buf[bufpos] - prev4; - prev4 = buf[bufpos]; - bufpos += div_; - - const unsigned long out3 = out4 - prev3; - prev3 = out4; - const unsigned long out2 = out3 - prev2; - prev2 = out3; - - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - } - - bufpos -= inlen; - } - - sum1 = sm1; - sum2 = sm2; - sum3 = sm3; - sum4 = sm4; - - /*unsigned long sm1 = sum1; - unsigned long sm2 = sum2; - unsigned long sm3 = sum3; - unsigned long sm4 = sum4; - - if (produced) { - unsigned divn = nextdivn; - std::size_t n = produced; - - do { - do { - sm1 += static_cast(*s); - s += channels; - sm2 += sm1; - sm3 += sm2; - sm4 += sm3; - } while (--divn); - - const unsigned long out4 = sm4 - prev4; - prev4 = sm4; - const unsigned long out3 = out4 - prev3; - prev3 = out4; - const unsigned long out2 = out3 - prev2; - prev2 = out3; - *out = static_cast(out2 - prev1) * mul / 0x10000; - prev1 = out2; - out += channels; - - divn = div_; - } while (--n); - - nextdivn = div_; - } - - { - unsigned divn = (in + inlen * channels - s) / channels; - nextdivn -= divn; - - while (divn--) { - sm1 += static_cast(*s); - s += channels; - sm2 += sm1; - sm3 += sm2; - sm4 += sm3; - } - } - - sum1 = sm1; - sum2 = sm2; - sum3 = sm3; - sum4 = sm4;*/ - - return produced; -} - -template -class Cic4 : public SubResampler { - Cic4Core cics[channels]; - -public: - enum { MAX_DIV = 13 }; - Cic4(unsigned div); - std::size_t resample(short *out, const short *in, std::size_t inlen); - unsigned mul() const { return 1; } - unsigned div() const { return cics[0].div(); } -}; - -template -Cic4::Cic4(const unsigned div) { - for (unsigned i = 0; i < channels; ++i) - cics[i].reset(div); -} - -template -std::size_t Cic4::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t samplesOut; - - for (unsigned i = 0; i < channels; ++i) { - samplesOut = cics[i].filter(out + i, in + i, inlen); - } - - return samplesOut; -} - -#endif diff --git a/src/lib/libgambatte/common/resample/convoluter.h b/src/lib/libgambatte/common/resample/convoluter.h deleted file mode 100644 index 41fab0d0..00000000 --- a/src/lib/libgambatte/common/resample/convoluter.h +++ /dev/null @@ -1,156 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CONVOLUTER_H -#define CONVOLUTER_H - -#include -#include - -template -class PolyPhaseConvoluter { - const short *kernel; - short *prevbuf; - - unsigned phaseLen; - unsigned div_; - unsigned x_; - -public: - PolyPhaseConvoluter() : kernel(NULL), prevbuf(NULL), phaseLen(0), div_(0), x_(0) {} - PolyPhaseConvoluter(const short *kernel, unsigned phaseLen, unsigned div) { reset(kernel, phaseLen, div); } - ~PolyPhaseConvoluter() { delete[] prevbuf; } - void reset(const short *kernel, unsigned phaseLen, unsigned div); - std::size_t filter(short *out, const short *in, std::size_t inlen); - void adjustDiv(const unsigned div) { this->div_ = div; } - unsigned div() const { return div_; } -}; - -template -void PolyPhaseConvoluter::reset(const short *const kernel, const unsigned phaseLen, const unsigned div) { - this->kernel = kernel; - this->phaseLen = phaseLen; - this->div_ = div; - x_ = 0; - delete[] prevbuf; - prevbuf = new short[phaseLen]; - std::fill(prevbuf, prevbuf + phaseLen, 0); -} - -template -std::size_t PolyPhaseConvoluter::filter(short *out, const short *const in, std::size_t inlen) { - if (!kernel || !inlen) - return 0; - - /*for (std::size_t x = 0; x < inlen + M; ++x) { - const int end = x < inlen ? M + 1 : inlen + M - x; - int j = x < M ? M - x : 0; - j += (phases - (x - M + j) % phases) % phases; // adjust j so we don't start on a virtual 0 sample - - for (; j < end; j += phases) { - buffer[x] += kernel[j] * start[(x - M + j) / phases]; - } - }*/ - - /*for (std::size_t x = 0; x < inlen + M; ++x) { - const int end = x < inlen ? M + 1 : inlen + M - x; - int j = x < M ? M - x : 0; - j += (phases - (x - M + j) % phases) % phases; // adjust j so we don't start on a virtual 0 sample - const short *k = kernel + (j % phases) * phaseLen + j / phases; - const short *s = start + (x - M + j) / phases; - int n = ((end - j) + phases - 1) / phases; - - do { - buffer[x] += *k++ * *s++; - } while (--n); - }*/ - - const std::size_t M = phaseLen * phases - 1; - inlen *= phases; - std::size_t x = x_; - - for (; x < (M < inlen ? M : inlen); x += div_) { - long acc = 0; - const unsigned phase = (phases - (x + 1) % phases) % phases; // adjust phase so we don't start on a virtual 0 sample - const short *s = prevbuf + (x + 1 + phase) / phases; - const short *k = kernel + phase * phaseLen; - unsigned n = prevbuf + phaseLen - s; - - while (n--) { - acc += *k++ * *s++; - } - - s = in; - n = x / phases + 1; - - do { - acc += *k++ * *s; - s += channels; - } while (--n); - - *out = acc / 0x10000; - out += channels; - } - - for (; x < inlen; x += div_) { - long acc = 0; - const unsigned phase = (phases - (x - M) % phases) % phases; // adjust phase so we don't start on a virtual 0 sample - const short *s = in + ((x - M + phase) / phases) * channels; - const short *k = kernel + phase * phaseLen; -// unsigned n = (M + 1/* - phase + phases - 1*/) / phases; - unsigned n = phaseLen; - - do { - acc += *k++ * *s; - s += channels; - } while (--n); - - *out = acc / 0x10000; - out += channels; - } - - const std::size_t produced = (x - x_) / div_; - x_ = x - inlen; - - inlen /= phases; - - { - short *p = prevbuf; - const short *s = in + (inlen - phaseLen) * channels; - unsigned n = phaseLen; - - if (inlen < phaseLen) { - const unsigned i = phaseLen - inlen; - - std::memmove(p, p + inlen, i * sizeof(short)); - - p += i; - n -= i; - s = in; - } - - do { - *p++ = *s; - s += channels; - } while (--n); - } - - return produced; -} - -#endif diff --git a/src/lib/libgambatte/common/resample/hammingsinc.h b/src/lib/libgambatte/common/resample/hammingsinc.h deleted file mode 100644 index bb50daee..00000000 --- a/src/lib/libgambatte/common/resample/hammingsinc.h +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef HAMMINGSINC_H -#define HAMMINGSINC_H - -#include "convoluter.h" -#include "subresampler.h" -#include "makesinckernel.h" -#include "cic3.h" -#include -#include - -template -class HammingSinc : public SubResampler { - PolyPhaseConvoluter convoluters[channels]; - short *kernel; - - static double hammingWin(const long i, const long M) { - static const double PI = 3.14159265358979323846; - return 0.53836 - 0.46164 * std::cos(2 * PI * i / M); - } - - void init(unsigned div, unsigned phaseLen, double fc); - -public: - enum { MUL = phases }; - - typedef Cic3 Cic; - static float cicLimit() { return 4.2f; } - - class RollOff { - static unsigned toTaps(const float rollOffWidth) { - static const float widthTimesTaps = 3.0f; - return std::ceil(widthTimesTaps / rollOffWidth); - } - - static float toFc(const float rollOffStart, const int taps) { - static const float startToFcDeltaTimesTaps = 1.27f; - return startToFcDeltaTimesTaps / taps + rollOffStart; - } - - public: - const unsigned taps; - const float fc; - - RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {} - }; - - HammingSinc(unsigned div, unsigned phaseLen, double fc) { init(div, phaseLen, fc); } - HammingSinc(unsigned div, RollOff ro) { init(div, ro.taps, ro.fc); } - ~HammingSinc() { delete[] kernel; } - std::size_t resample(short *out, const short *in, std::size_t inlen); - void adjustDiv(unsigned div); - unsigned mul() const { return MUL; } - unsigned div() const { return convoluters[0].div(); } -}; - -template -void HammingSinc::init(const unsigned div, const unsigned phaseLen, const double fc) { - kernel = new short[phaseLen * phases]; - - makeSincKernel(kernel, phases, phaseLen, fc, hammingWin); - - for (unsigned i = 0; i < channels; ++i) - convoluters[i].reset(kernel, phaseLen, div); -} - -template -std::size_t HammingSinc::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t samplesOut; - - for (unsigned i = 0; i < channels; ++i) - samplesOut = convoluters[i].filter(out + i, in + i, inlen); - - return samplesOut; -} - -template -void HammingSinc::adjustDiv(const unsigned div) { - for (unsigned i = 0; i < channels; ++i) - convoluters[i].adjustDiv(div); -} - -#endif diff --git a/src/lib/libgambatte/common/resample/linint.h b/src/lib/libgambatte/common/resample/linint.h deleted file mode 100644 index 0c6d8cb2..00000000 --- a/src/lib/libgambatte/common/resample/linint.h +++ /dev/null @@ -1,129 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef LININT_H -#define LININT_H - -#include -#include "resampler.h" -#include "u48div.h" - -template -class LinintCore { - unsigned long ratio; - std::size_t pos_; - unsigned fracPos_; - int prevSample_; - -public: - LinintCore(long inRate = 1, long outRate = 1) { init(inRate, outRate); } - void adjustRate(long inRate, long outRate) { ratio = (static_cast(inRate) / outRate) * 0x10000 + 0.5; } - void exactRatio(unsigned long &mul, unsigned long &div) const { mul = 0x10000; div = ratio; } - void init(long inRate, long outRate); - std::size_t maxOut(std::size_t inlen) const { return inlen ? u48div(inlen - 1, 0xFFFF, ratio) + 1 : 0; } - std::size_t resample(short *out, const short *in, std::size_t inlen); -}; - -template -void LinintCore::init(const long inRate, const long outRate) { - adjustRate(inRate, outRate); - pos_ = (ratio >> 16) + 1; - fracPos_ = ratio & 0xFFFF; - prevSample_ = 0; -} - -template -std::size_t LinintCore::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t opos = 0; - std::size_t pos = pos_; - unsigned fracPos = fracPos_; - int prevSample = prevSample_; - - if (pos < inlen) { - if (pos != 0) - prevSample = in[(pos-1) * channels]; - - for (;;) { - out[opos] = prevSample + (in[pos * channels] - prevSample) * static_cast(fracPos) / 0x10000; - opos += channels; - - { - const unsigned long next = ratio + fracPos; - - pos += next >> 16; - fracPos = next & 0xFFFF; - } - - if (pos < inlen) { - prevSample = in[(pos-1) * channels]; - } else - break; - } - - if (pos == inlen) - prevSample = in[(pos-1) * channels]; - } - -// const std::size_t produced = ((pos - pos_) * 0x10000 + fracPos - fracPos_) / ratio; - - pos_ = pos - inlen; - fracPos_ = fracPos; - prevSample_ = prevSample; - - return opos / channels; -} - -template -class Linint : public Resampler { - LinintCore cores[channels]; - -public: - Linint(long inRate, long outRate); - void adjustRate(long inRate, long outRate); - void exactRatio(unsigned long &mul, unsigned long &div) const { cores[0].exactRatio(mul, div); } - std::size_t maxOut(std::size_t inlen) const { return cores[0].maxOut(inlen); } - std::size_t resample(short *out, const short *in, std::size_t inlen); -}; - -template -Linint::Linint(const long inRate, const long outRate) { - setRate(inRate, outRate); - - for (unsigned i = 0; i < channels; ++i) - cores[i].init(inRate, outRate); -} - -template -void Linint::adjustRate(const long inRate, const long outRate) { - setRate(inRate, outRate); - - for (unsigned i = 0; i < channels; ++i) - cores[i].adjustRate(inRate, outRate); -} - -template -std::size_t Linint::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t outlen = 0; - - for (unsigned i = 0; i < channels; ++i) - outlen = cores[i].resample(out + i, in + i, inlen); - - return outlen; -} - -#endif diff --git a/src/lib/libgambatte/common/resample/makesinckernel.h b/src/lib/libgambatte/common/resample/makesinckernel.h deleted file mode 100644 index c6515f2d..00000000 --- a/src/lib/libgambatte/common/resample/makesinckernel.h +++ /dev/null @@ -1,152 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef MAKE_SINC_KERNEL_H -#define MAKE_SINC_KERNEL_H - -#include -#include - -template -void makeSincKernel(short *const kernel, const unsigned phases, const unsigned phaseLen, double fc, Window win) { - static const double PI = 3.14159265358979323846; - fc /= phases; - - /*{ - double *const dkernel = new double[phaseLen * phases]; - const long M = static_cast(phaseLen) * phases - 1; - - for (long i = 0; i < M + 1; ++i) { - const double sinc = i * 2 == M ? - PI * fc : - std::sin(PI * fc * (i * 2 - M)) / (i * 2 - M); - - dkernel[(i % phases) * phaseLen + i / phases] = win(i, M) * sinc; - } - - double maxabsgain = 0; - - for (unsigned ph = 0; ph < phases; ++ph) { - double gain = 0; - double absgain = 0; - - for (unsigned i = 0; i < phaseLen; ++i) { - gain += dkernel[ph * phaseLen + i]; - absgain += std::abs(dkernel[ph * phaseLen + i]); - } - - gain = 1.0 / gain; - - // Per phase normalization to avoid DC fluctuations. - for (unsigned i = 0; i < phaseLen; ++i) - dkernel[ph * phaseLen + i] *= gain; - - absgain *= gain; - - if (absgain > maxabsgain) - maxabsgain = absgain; - } - - const double gain = 0x10000 / maxabsgain; - - for (long i = 0; i < M + 1; ++i) - kernel[i] = std::floor(dkernel[i] * gain + 0.5); - - delete[] dkernel; - }*/ - - // The following is equivalent to the more readable version above - - const long M = static_cast(phaseLen) * phases - 1; - - double *const dkernel = new double[M / 2 + 1]; - - { - double *dk = dkernel; - - for (unsigned ph = 0; ph < phases; ++ph) { - for (long i = ph; i < M / 2 + 1; i += phases) { - const double sinc = i * 2 == M ? - PI * fc : - std::sin(PI * fc * (i * 2 - M)) / (i * 2 - M); - - *dk++ = win(i, M) * sinc; - } - } - } - - double maxabsgain = 0.0; - - { - double *dkp1 = dkernel; - double *dkp2 = dkernel + M / 2; - - for (unsigned ph = 0; ph < (phases + 1) / 2; ++ph) { - double gain = 0.0; - double absgain = 0.0; - - { - const double *kp1 = dkp1; - const double *kp2 = dkp2; - long i = ph; - - for (; i < M / 2 + 1; i += phases) { - gain += *kp1; - absgain += std::abs(*kp1++); - } - - for (; i < M + 1; i += phases) { - gain += *kp2; - absgain += std::abs(*kp2--); - } - } - - gain = 1.0 / gain; - - long i = ph; - - for (; i < M / 2 + 1; i += phases) - *dkp1++ *= gain; - - if (dkp1 < dkp2) { - for (; i < M + 1; i += phases) - *dkp2-- *= gain; - } - - absgain *= gain; - - if (absgain > maxabsgain) - maxabsgain = absgain; - } - } - - const double gain = 0x10000 / maxabsgain; - const double *dk = dkernel; - - for (unsigned ph = 0; ph < phases; ++ph) { - short *k = kernel + ph * phaseLen; - short *km = kernel + M - ph * phaseLen; - - for (long i = ph; i < M / 2 + 1; i += phases) - *km-- = *k++ = std::floor(*dk++ * gain + 0.5); - } - - delete[] dkernel; -} - -#endif diff --git a/src/lib/libgambatte/common/resample/rectsinc.h b/src/lib/libgambatte/common/resample/rectsinc.h deleted file mode 100644 index 9f99ed6b..00000000 --- a/src/lib/libgambatte/common/resample/rectsinc.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef RECTSINC_H -#define RECTSINC_H - -#include "convoluter.h" -#include "subresampler.h" -#include "makesinckernel.h" -#include "cic2.h" -#include -#include - -template -class RectSinc : public SubResampler { - PolyPhaseConvoluter convoluters[channels]; - short *kernel; - - static double rectWin(const long /*i*/, const long /*M*/) { - return 1; - } - - void init(unsigned div, unsigned phaseLen, double fc); - -public: - enum { MUL = phases }; - - typedef Cic2 Cic; - static float cicLimit() { return 2.0f; } - - class RollOff { - static unsigned toTaps(const float rollOffWidth) { - static const float widthTimesTaps = 0.9f; - return std::ceil(widthTimesTaps / rollOffWidth); - } - - static float toFc(const float rollOffStart, const int taps) { - static const float startToFcDeltaTimesTaps = 0.43f; - return startToFcDeltaTimesTaps / taps + rollOffStart; - } - - public: - const unsigned taps; - const float fc; - - RollOff(float rollOffStart, float rollOffWidth) : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) {} - }; - - RectSinc(unsigned div, unsigned phaseLen, double fc) { init(div, phaseLen, fc); } - RectSinc(unsigned div, RollOff ro) { init(div, ro.taps, ro.fc); } - ~RectSinc() { delete[] kernel; } - std::size_t resample(short *out, const short *in, std::size_t inlen); - void adjustDiv(unsigned div); - unsigned mul() const { return MUL; } - unsigned div() const { return convoluters[0].div(); } -}; - -template -void RectSinc::init(const unsigned div, const unsigned phaseLen, const double fc) { - kernel = new short[phaseLen * phases]; - - makeSincKernel(kernel, phases, phaseLen, fc, rectWin); - - for (unsigned i = 0; i < channels; ++i) - convoluters[i].reset(kernel, phaseLen, div); -} - -template -std::size_t RectSinc::resample(short *const out, const short *const in, const std::size_t inlen) { - std::size_t samplesOut; - - for (unsigned i = 0; i < channels; ++i) - samplesOut = convoluters[i].filter(out + i, in + i, inlen); - - return samplesOut; -} - -template -void RectSinc::adjustDiv(const unsigned div) { - for (unsigned i = 0; i < channels; ++i) - convoluters[i].adjustDiv(div); -} - -#endif diff --git a/src/lib/libgambatte/common/resample/resampler.h b/src/lib/libgambatte/common/resample/resampler.h deleted file mode 100644 index f3d448d9..00000000 --- a/src/lib/libgambatte/common/resample/resampler.h +++ /dev/null @@ -1,43 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef RESAMPLER_H -#define RESAMPLER_H - -#include - -class Resampler { - long inRate_; - long outRate_; - -protected: - void setRate(const long inRate, const long outRate) { inRate_ = inRate; outRate_ = outRate; } - -public: - Resampler() : inRate_(0), outRate_(0) {} - long inRate() const { return inRate_; } - long outRate() const { return outRate_; } - - virtual void adjustRate(long inRate, long outRate) = 0; - virtual void exactRatio(unsigned long &mul, unsigned long &div) const = 0; - virtual std::size_t maxOut(std::size_t inlen) const = 0; - virtual std::size_t resample(short *out, const short *in, std::size_t inlen) = 0; - virtual ~Resampler() {} -}; - -#endif diff --git a/src/lib/libgambatte/common/resample/resamplerinfo.cpp b/src/lib/libgambatte/common/resample/resamplerinfo.cpp deleted file mode 100644 index 3abcdaf8..00000000 --- a/src/lib/libgambatte/common/resample/resamplerinfo.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "resamplerinfo.h" -#include "chainresampler.h" -#include "hammingsinc.h" -#include "blackmansinc.h" -#include "rectsinc.h" -#include "linint.h" - -struct LinintInfo { - static Resampler* create(long inRate, long outRate, std::size_t) { return new Linint<2>(inRate, outRate); } -}; - -struct RectsincInfo { - static Resampler* create(long inRate, long outRate, std::size_t periodSz) { - ChainResampler *r = new ChainResampler; - r->init(inRate, outRate, periodSz); - return r; - } -}; - -struct HammingsincInfo { - static Resampler* create(long inRate, long outRate, std::size_t periodSz) { - ChainResampler *r = new ChainResampler; - r->init(inRate, outRate, periodSz); - return r; - } -}; - -struct BlackmansincInfo { - static Resampler* create(long inRate, long outRate, std::size_t periodSz) { - ChainResampler *r = new ChainResampler; - r->init(inRate, outRate, periodSz); - return r; - } -}; - -const ResamplerInfo ResamplerInfo::resamplers[] = { - { "2-tap linear interpolation", LinintInfo::create }, - { "Rectangular windowed sinc (~20 dB SNR)", RectsincInfo::create }, - { "Hamming windowed sinc (~50 dB SNR)", HammingsincInfo::create }, - { "Blackman windowed sinc (~70 dB SNR)", BlackmansincInfo::create } -}; - -const unsigned ResamplerInfo::num_ = sizeof(ResamplerInfo::resamplers) / sizeof(ResamplerInfo); diff --git a/src/lib/libgambatte/common/resample/resamplerinfo.h b/src/lib/libgambatte/common/resample/resamplerinfo.h deleted file mode 100644 index 23f4a545..00000000 --- a/src/lib/libgambatte/common/resample/resamplerinfo.h +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef RESAMPLER_INFO_H -#define RESAMPLER_INFO_H - -#include "resampler.h" - -struct ResamplerInfo { - const char *desc; - Resampler* (*create)(long inRate, long outRate, std::size_t periodSz); - - static unsigned num() { return num_; } - static const ResamplerInfo& get(unsigned n) { return resamplers[n]; } - -private: - static const ResamplerInfo resamplers[]; - static const unsigned num_; -}; - -#endif diff --git a/src/lib/libgambatte/common/resample/subresampler.h b/src/lib/libgambatte/common/resample/subresampler.h deleted file mode 100644 index 134ec80b..00000000 --- a/src/lib/libgambatte/common/resample/subresampler.h +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SUBRESAMPLER_H -#define SUBRESAMPLER_H - -#include - -class SubResampler { -public: - virtual std::size_t resample(short *out, const short *in, std::size_t inlen) = 0; - virtual unsigned mul() const = 0; - virtual unsigned div() const = 0; - virtual void adjustDiv(unsigned /*div*/) {} - virtual ~SubResampler() {} -}; - -#endif diff --git a/src/lib/libgambatte/common/resample/u48div.cpp b/src/lib/libgambatte/common/resample/u48div.cpp deleted file mode 100644 index 077ddfd9..00000000 --- a/src/lib/libgambatte/common/resample/u48div.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "u48div.h" - -unsigned long u48div(unsigned long num1, unsigned num2, const unsigned long den) { - unsigned long res = 0; - unsigned s = 16; - - do { - if (num1 < 0x10000) { - num1 <<= s; - num1 |= num2 & ((1 << s) - 1); - s = 0; - } else { - if (num1 < 0x1000000) { - const unsigned maxs = s < 8 ? s : 8; - num1 <<= maxs; - num1 |= (num2 >> (s -= maxs)) & ((1 << maxs) - 1); - } - - if (num1 < 0x10000000) { - const unsigned maxs = s < 4 ? s : 4; - num1 <<= maxs; - num1 |= (num2 >> (s -= maxs)) & ((1 << maxs) - 1); - } - - while (num1 < den && s) { - num1 <<= 1; // if this overflows we're screwed - num1 |= num2 >> --s & 1; - } - } - - res += (num1 / den) << s; - num1 = (num1 % den); - } while (s); - - return res; -} diff --git a/src/lib/libgambatte/common/resample/u48div.h b/src/lib/libgambatte/common/resample/u48div.h deleted file mode 100644 index 26b16af4..00000000 --- a/src/lib/libgambatte/common/resample/u48div.h +++ /dev/null @@ -1,24 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef U48DIV_H -#define U48DIV_H - -unsigned long u48div(unsigned long num1, unsigned num2, unsigned long den); - -#endif diff --git a/src/lib/libgambatte/common/resample/upsampler.h b/src/lib/libgambatte/common/resample/upsampler.h deleted file mode 100644 index 8bf88d8a..00000000 --- a/src/lib/libgambatte/common/resample/upsampler.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef UPSAMPLER_H -#define UPSAMPLER_H - -#include "subresampler.h" -#include - -template -class Upsampler : public SubResampler { - unsigned mul_; - -public: - Upsampler(const unsigned mul) : mul_(mul) {} - std::size_t resample(short *out, const short *in, std::size_t inlen); - unsigned mul() const { return mul_; } - unsigned div() const { return 1; } -}; - -template -std::size_t Upsampler::resample(short *out, const short *in, std::size_t inlen) { - if (inlen) { - std::memset(out, 0, inlen * mul_ * sizeof(short) * channels); - - do { - std::memcpy(out, in, sizeof(short) * channels); - in += channels; - out += mul_ * channels; - } while (--inlen); - } - - return inlen * mul_; -} - -#endif diff --git a/src/lib/libgambatte/common/ringbuffer.h b/src/lib/libgambatte/common/ringbuffer.h deleted file mode 100644 index 34f22bfe..00000000 --- a/src/lib/libgambatte/common/ringbuffer.h +++ /dev/null @@ -1,112 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef RINGBUFFER_H -#define RINGBUFFER_H - -#include "array.h" -#include -#include -#include - -template -class RingBuffer { - Array buf; - std::size_t sz; - std::size_t rpos; - std::size_t wpos; - -public: - RingBuffer(const std::size_t sz_in = 0) : sz(0), rpos(0), wpos(0) { reset(sz_in); } - - std::size_t avail() const { - return (wpos < rpos ? 0 : sz) + rpos - wpos - 1; - } - - void clear() { - wpos = rpos = 0; - } - - void fill(T value); - - void read(T *out, std::size_t num); - - void reset(std::size_t sz_in); - - std::size_t size() const { - return sz - 1; - } - - std::size_t used() const { - return (wpos < rpos ? sz : 0) + wpos - rpos; - } - - void write(const T *in, std::size_t num); -}; - -template -void RingBuffer::fill(const T value) { - std::fill(buf + 0, buf + sz, value); - rpos = 0; - wpos = sz - 1; -} - -template -void RingBuffer::read(T *out, std::size_t num) { - if (rpos + num > sz) { - const std::size_t n = sz - rpos; - - std::memcpy(out, buf + rpos, n * sizeof(T)); - - rpos = 0; - num -= n; - out += n; - } - - std::memcpy(out, buf + rpos, num * sizeof(T)); - - if ((rpos += num) == sz) - rpos = 0; -} - -template -void RingBuffer::reset(const std::size_t sz_in) { - sz = sz_in + 1; - rpos = wpos = 0; - buf.reset(sz_in ? sz : 0); -} - -template -void RingBuffer::write(const T *in, std::size_t num) { - if (wpos + num > sz) { - const std::size_t n = sz - wpos; - - std::memcpy(buf + wpos, in, n * sizeof(T)); - - wpos = 0; - num -= n; - in += n; - } - - std::memcpy(buf + wpos, in, num * sizeof(T)); - - if ((wpos += num) == sz) - wpos = 0; -} - -#endif diff --git a/src/lib/libgambatte/common/usec.h b/src/lib/libgambatte/common/usec.h deleted file mode 100644 index 2bc889cf..00000000 --- a/src/lib/libgambatte/common/usec.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef USEC_H -#define USEC_H - -typedef unsigned long usec_t; - -static inline usec_t negate(usec_t t) { - return usec_t(0) - t; -} - -usec_t getusecs(); -void usecsleep(usec_t usecs); - -#endif diff --git a/src/lib/libgambatte/include/filterinfo.h b/src/lib/libgambatte/include/filterinfo.h deleted file mode 100644 index ab5a4726..00000000 --- a/src/lib/libgambatte/include/filterinfo.h +++ /dev/null @@ -1,32 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef GAMBATTE_FILTERINFO_H -#define GAMBATTE_FILTERINFO_H - -#include - -namespace Gambatte { -struct FilterInfo { - std::string handle; - unsigned int outWidth; - unsigned int outHeight; -}; -} - -#endif diff --git a/src/lib/libgambatte/include/gambatte.h b/src/lib/libgambatte/include/gambatte.h deleted file mode 100644 index e3c09c63..00000000 --- a/src/lib/libgambatte/include/gambatte.h +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef GAMBATTE_H -#define GAMBATTE_H - -class CPU; - -#include "videoblitter.h" -#include "inputstate.h" -#include "inputstategetter.h" -#include "memoryinterface.h" -#include "filterinfo.h" -#include "int.h" -#include - -namespace Gambatte { -class GB { - CPU *const z80; - int stateNo; - - void loadState(const char *filepath, bool osdMessage); - -public: - GB(); - ~GB(); - bool load(bool forceDmg = false); - void save(); - - /** Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer. - * There are 35112 stereo sound samples in a video frame. - * May run for uptil 2064 stereo samples too long. - * A stereo sample consists of two native endian 2s complement 16-bit PCM samples, - * with the left sample preceding the right one. Usually casting soundBuf to/from - * short* is OK and recommended. The reason for not using a short* in the interface - * is to avoid implementation defined behaviour without compromising performance. - * - * @param soundBuf buffer with space >= samples + 2064 - * @param samples number of stereo samples to produce - * @return actual number of samples produced - */ - unsigned runFor(uint32_t *soundBuf, unsigned samples); - void updateVideo(); - unsigned lyCounter(); - - void reset(); - void setVideoBlitter(VideoBlitter *vb); - void videoBufferChange(); - unsigned videoWidth() const; - unsigned videoHeight() const; - void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32); - - void setVideoFilter(unsigned n); - std::vector filterInfo() const; - void setInputStateGetter(InputStateGetter *getInput); - void setMemoryInterface(MemoryInterface *memoryInterface); - - void set_savedir(const char *sdir); - bool isCgb() const; - void saveState(); - void loadState(); - void saveState(const char *filepath); - void loadState(const char *filepath); - void selectState(int n); - int currentState() const { return stateNo; } -}; -} - -#endif diff --git a/src/lib/libgambatte/include/inputstate.h b/src/lib/libgambatte/include/inputstate.h deleted file mode 100644 index bdfec44f..00000000 --- a/src/lib/libgambatte/include/inputstate.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef GAMBATTE_INPUTSTATE_H -#define GAMBATTE_INPUTSTATE_H - -namespace Gambatte { -struct InputState { - unsigned joypadId; - bool startButton, selectButton, bButton, aButton; - bool dpadDown, dpadUp, dpadLeft, dpadRight; -}; -} - -#endif diff --git a/src/lib/libgambatte/include/inputstategetter.h b/src/lib/libgambatte/include/inputstategetter.h deleted file mode 100644 index 375dad5e..00000000 --- a/src/lib/libgambatte/include/inputstategetter.h +++ /dev/null @@ -1,30 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef GAMBATTE_INPUTSTATEGETTER_H -#define GAMBATTE_INPUTSTATEGETTER_H - -namespace Gambatte { -class InputStateGetter { -public: - virtual ~InputStateGetter() {}; - virtual const InputState& operator()() = 0; -}; -} - -#endif diff --git a/src/lib/libgambatte/include/int.h b/src/lib/libgambatte/include/int.h deleted file mode 100644 index e9f58661..00000000 --- a/src/lib/libgambatte/include/int.h +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef GAMBATTE_INT_H -#define GAMBATTE_INT_H - -#ifdef HAVE_CSTDINT - -#include - -namespace Gambatte { -using std::uint_least32_t; -using std::uint_least16_t; -} - -#elif defined(HAVE_STDINT_H) - -#include - -namespace Gambatte { -using ::uint_least32_t; -using ::uint_least16_t; -} - -#else - -namespace Gambatte { -#ifdef CHAR_LEAST_32 -typedef unsigned char uint_least32_t; -#elif defined(SHORT_LEAST_32) -typedef unsigned short uint_least32_t; -#elif defined(INT_LEAST_32) -typedef unsigned uint_least32_t; -#else -typedef unsigned long uint_least32_t; -#endif - -#ifdef CHAR_LEAST_16 -typedef unsigned char uint_least16_t; -#else -typedef unsigned short uint_least16_t; -#endif -} - -#endif - -#endif diff --git a/src/lib/libgambatte/include/memoryinterface.h b/src/lib/libgambatte/include/memoryinterface.h deleted file mode 100644 index 69f18d06..00000000 --- a/src/lib/libgambatte/include/memoryinterface.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef GAMBATTE_MEMORYINTERFACE_H -#define GAMBATTE_MEMORYINTERFACE_H - -namespace Gambatte { - -struct MemoryBuffer { - void *data; - unsigned size; -}; - -class MemoryInterface { -public: - virtual MemoryBuffer loadRomData() = 0; - virtual MemoryBuffer loadRamData() = 0; - virtual MemoryBuffer loadRtcData() = 0; - - virtual MemoryBuffer saveRamData(unsigned size) = 0; - virtual MemoryBuffer saveRtcData() = 0; - - virtual void joypWrite(bool /*p15*/, bool /*p14*/) {} -}; - -} - -#endif diff --git a/src/lib/libgambatte/include/videoblitter.h b/src/lib/libgambatte/include/videoblitter.h deleted file mode 100644 index d2a9c335..00000000 --- a/src/lib/libgambatte/include/videoblitter.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef GAMBATTE_VIDEOBLITTER_H -#define GAMBATTE_VIDEOBLITTER_H - -namespace Gambatte { - -struct PixelBuffer { - enum Format { RGB32, RGB16, UYVY }; - - void *pixels; - Format format; - unsigned pitch; - - PixelBuffer() : pixels(0), format(RGB32), pitch(0) {} -}; - -class VideoBlitter { -public: - virtual void setBufferDimensions(unsigned width, unsigned height) = 0; - virtual const PixelBuffer inBuffer() = 0; - virtual void blit() = 0; - virtual ~VideoBlitter() {} -}; - -} - -#endif diff --git a/src/lib/libgambatte/src/bitmap_font.cpp b/src/lib/libgambatte/src/bitmap_font.cpp deleted file mode 100644 index b644c06f..00000000 --- a/src/lib/libgambatte/src/bitmap_font.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -/* - The following font bitmaps (static const unsigned char *_bits[]), only used - as data and included in this source file for convenience, are derived from - the Bitstream Vera Sans font, which is distributed under the following - copyright: - - Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera - is a trademark of Bitstream, Inc. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of the fonts accompanying this license ("Fonts") and associated - documentation files (the "Font Software"), to reproduce and distribute the - Font Software, including without limitation the rights to use, copy, merge, - publish, distribute, and/or sell copies of the Font Software, and to permit - persons to whom the Font Software is furnished to do so, subject to the - following conditions: - - The above copyright and trademark notices and this permission notice shall - be included in all copies of one or more of the Font Software typefaces. - - The Font Software may be modified, altered, or added to, and in particular - the designs of glyphs or characters in the Fonts may be modified and - additional glyphs or characters may be added to the Fonts, only if the fonts - are renamed to names not containing either the words "Bitstream" or the word - "Vera". - - This License becomes null and void to the extent applicable to Fonts or Font - Software that has been modified and is distributed under the "Bitstream Vera" - names. - - The Font Software may be sold as part of a larger software package but no - copy of one or more of the Font Software typefaces may be sold by itself. - - THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM - OR THE GNOME FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR - CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM - OTHER DEALINGS IN THE FONT SOFTWARE. - - Except as contained in this notice, the names of Gnome, the Gnome - Foundation, and Bitstream Inc., shall not be used in advertising or - otherwise to promote the sale, use or other dealings in this Font Software - without prior written authorization from the Gnome Foundation or - Bitstream Inc., respectively. For further information, contact: fonts at - gnome dot org. -*/ - -#include "bitmap_font.h" - -static const unsigned char n0_bits[] = { 0x68, - 0x00, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1c }; - -static const unsigned char n1_bits[] = { 0x68, - 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x08, 0x3e }; - -static const unsigned char n2_bits[] = { 0x68, - 0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x04, 0x3e }; - -static const unsigned char n3_bits[] = { 0x68, - 0x00, 0x1c, 0x22, 0x20, 0x1c, 0x20, 0x22, 0x1c }; - -static const unsigned char n4_bits[] = { 0x68, - 0x00, 0x18, 0x18, 0x14, 0x12, 0x3e, 0x10, 0x10 }; - -static const unsigned char n5_bits[] = { 0x68, - 0x00, 0x1e, 0x02, 0x1e, 0x20, 0x20, 0x20, 0x1e }; - -static const unsigned char n6_bits[] = { 0x68, - 0x00, 0x3c, 0x06, 0x02, 0x1e, 0x22, 0x22, 0x1c }; - -static const unsigned char n7_bits[] = { 0x68, - 0x00, 0x3e, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04 }; - -static const unsigned char n8_bits[] = { 0x68, - 0x00, 0x1c, 0x22, 0x22, 0x1c, 0x22, 0x22, 0x1c }; - -static const unsigned char n9_bits[] = { 0x68, - 0x00, 0x1c, 0x22, 0x22, 0x3c, 0x20, 0x30, 0x1e }; - -static const unsigned char A_bits[] = { 0x78, - 0x00, 0x08, 0x14, 0x14, 0x22, 0x3e, 0x22, 0x41 }; - -static const unsigned char a_bits[] = { 0x68, - 0x00, 0x00, 0x00, 0x1c, 0x20, 0x3c, 0x22, 0x3e }; - -static const unsigned char B_bits[] = { 0x78, - 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x22, 0x22, 0x1e }; - -static const unsigned char b_bits[] = { 0x68, - 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x1e }; - -static const unsigned char C_bits[] = { 0x88, - 0x00, 0x38, 0x44, 0x02, 0x02, 0x02, 0x44, 0x38 }; - -static const unsigned char c_bits[] = { 0x58, - 0x00, 0x00, 0x00, 0x1c, 0x02, 0x02, 0x02, 0x1c }; - -static const unsigned char D_bits[] = { 0x88, - 0x00, 0x3e, 0x62, 0x42, 0x42, 0x42, 0x62, 0x3e }; - -static const unsigned char d_bits[] = { 0x68, - 0x20, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x22, 0x3c }; - -static const unsigned char E_bits[] = { 0x78, - 0x00, 0x3e, 0x02, 0x02, 0x3e, 0x02, 0x02, 0x3e }; - -static const unsigned char e_bits[] = { 0x68, - 0x00, 0x00, 0x00, 0x1c, 0x22, 0x3e, 0x02, 0x3c }; - -static const unsigned char F_bits[] = { 0x68, - 0x00, 0x1e, 0x02, 0x02, 0x1e, 0x02, 0x02, 0x02 }; - -static const unsigned char f_bits[] = { 0x48, - 0x0e, 0x02, 0x02, 0x07, 0x02, 0x02, 0x02, 0x02 }; - -static const unsigned char G_bits[] = { 0x88, - 0x00, 0x3c, 0x46, 0x02, 0x72, 0x42, 0x46, 0x3c }; - -static const unsigned char g_bits[] = { 0x6a, - 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x1c }; - -static const unsigned char H_bits[] = { 0x88, - 0x00, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42 }; - -static const unsigned char h_bits[] = { 0x68, - 0x02, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x22 }; - -static const unsigned char I_bits[] = { 0x38, - 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; - -static const unsigned char i_bits[] = { 0x28, - 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02 }; - -static const unsigned char J_bits[] = { 0x4a, - 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03 }; - -static const unsigned char j_bits[] = { 0x2a, - 0x02, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03 }; - -static const unsigned char K_bits[] = { 0x78, - 0x00, 0x22, 0x12, 0x0a, 0x06, 0x0a, 0x12, 0x22 }; - -static const unsigned char k_bits[] = { 0x58, - 0x02, 0x02, 0x02, 0x12, 0x0a, 0x06, 0x0a, 0x12 }; - -static const unsigned char L_bits[] = { 0x68, - 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x3e }; - -static const unsigned char l_bits[] = { 0x28, - 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; - -static const unsigned char M_bits[] = { 0x98, - 0x00, 0x00, 0x82, 0x00, 0xc6, 0x00, 0xc6, 0x00, 0xaa, 0x00, 0xaa, 0x00, - 0x92, 0x00, 0x82, 0x00 }; - -static const unsigned char m_bits[] = { 0xa8, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x01, 0x22, 0x02, 0x22, 0x02, - 0x22, 0x02, 0x22, 0x02 }; - -static const unsigned char N_bits[] = { 0x88, - 0x00, 0x42, 0x46, 0x4a, 0x4a, 0x52, 0x62, 0x42 }; - -static const unsigned char n_bits[] = { 0x68, - 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x22 }; - -static const unsigned char O_bits[] = { 0x88, - 0x00, 0x3c, 0x66, 0x42, 0x42, 0x42, 0x66, 0x3c }; - -static const unsigned char o_bits[] = { 0x68, - 0x00, 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c }; - -static const unsigned char P_bits[] = { 0x78, - 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02, 0x02 }; - -static const unsigned char p_bits[] = { 0x6a, - 0x00, 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x1e, 0x02, 0x02 }; - -static const unsigned char Q_bits[] = { 0x89, - 0x00, 0x3c, 0x66, 0x42, 0x42, 0x42, 0x26, 0x1c, 0x20 }; - -static const unsigned char q_bits[] = { 0x6a, - 0x00, 0x00, 0x00, 0x3c, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x20 }; - -static const unsigned char R_bits[] = { 0x78, - 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x12, 0x22, 0x42 }; - -static const unsigned char r_bits[] = { 0x48, - 0x00, 0x00, 0x00, 0x0e, 0x02, 0x02, 0x02, 0x02 }; - -static const unsigned char S_bits[] = { 0x78, - 0x00, 0x1c, 0x22, 0x02, 0x1c, 0x20, 0x22, 0x1c }; - -static const unsigned char s_bits[] = { 0x58, - 0x00, 0x00, 0x00, 0x1e, 0x02, 0x1c, 0x10, 0x1e }; - -static const unsigned char T_bits[] = { 0x58, - 0x00, 0x1f, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - -static const unsigned char t_bits[] = { 0x48, - 0x00, 0x02, 0x02, 0x0f, 0x02, 0x02, 0x02, 0x0e }; - -static const unsigned char U_bits[] = { 0x88, - 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c }; - -static const unsigned char u_bits[] = { 0x68, - 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x3c }; - -static const unsigned char V_bits[] = { 0x78, - 0x00, 0x41, 0x41, 0x22, 0x22, 0x14, 0x14, 0x08 }; - -static const unsigned char v_bits[] = { 0x68, - 0x00, 0x00, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08 }; - -static const unsigned char W_bits[] = { 0x98, - 0x00, 0x00, 0x11, 0x01, 0x11, 0x01, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, - 0x44, 0x00, 0x44, 0x00 }; - -static const unsigned char w_bits[] = { 0x88, - 0x00, 0x00, 0x00, 0x92, 0xaa, 0xaa, 0x44, 0x44 }; - -static const unsigned char X_bits[] = { 0x68, - 0x00, 0x21, 0x12, 0x0c, 0x0c, 0x0c, 0x12, 0x21 }; - -static const unsigned char x_bits[] = { 0x68, - 0x00, 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22 }; - -static const unsigned char Y_bits[] = { 0x78, - 0x00, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08 }; - -static const unsigned char y_bits[] = { 0x6a, - 0x00, 0x00, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x08, 0x06 }; - -static const unsigned char Z_bits[] = { 0x68, - 0x00, 0x3f, 0x10, 0x08, 0x0c, 0x04, 0x02, 0x3f }; - -static const unsigned char z_bits[] = { 0x58, - 0x00, 0x00, 0x00, 0x1e, 0x10, 0x08, 0x04, 0x1e }; - -static const unsigned char SPC_bits[] = { 0x38, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - -namespace BitmapFont { -const unsigned char *const font[] = { - 0, - n0_bits, n1_bits, n2_bits, n3_bits, n4_bits, n5_bits, n6_bits, n7_bits, n8_bits, n9_bits, - A_bits, B_bits, C_bits, D_bits, E_bits, F_bits, G_bits, H_bits, I_bits, J_bits, K_bits, L_bits, M_bits, - N_bits, O_bits, P_bits, Q_bits, R_bits, S_bits, T_bits, U_bits, V_bits, W_bits, X_bits, Y_bits, Z_bits, - a_bits, b_bits, c_bits, d_bits, e_bits, f_bits, g_bits, h_bits, i_bits, j_bits, k_bits, l_bits, m_bits, - n_bits, o_bits, p_bits, q_bits, r_bits, s_bits, t_bits, u_bits, v_bits, w_bits, x_bits, y_bits, z_bits, - SPC_bits -}; - -unsigned getWidth(const char *chars) { - unsigned w = 0; - - while (const int character = *chars++) { - w += *font[character] >> 4; - } - - return w; -} - -class Rgb32Fill { - const unsigned long color; - -public: - Rgb32Fill(unsigned long color) : color(color) {} - - void operator()(Gambatte::uint_least32_t *dest, unsigned /*pitch*/) { - *dest = color; - } -}; - -void print(Gambatte::uint_least32_t *dest, const unsigned pitch, const unsigned long color, const char *chars) { - print(dest, pitch, Rgb32Fill(color), chars); -} - -static void reverse(char *first, char *last) { - while (first < last) { - const int tmp = *first; - - *first = *last; - *last = tmp; - - ++first; - --last; - } -} - -void utoa(unsigned u, char *a) { - char *aa = a; - - while (u > 9) { - const unsigned div = u / 10; - const unsigned rem = u % 10; - - u = div; - *aa++ = rem + N0; - } - - *aa = u + N0; - - reverse(a, aa); -} -} diff --git a/src/lib/libgambatte/src/bitmap_font.h b/src/lib/libgambatte/src/bitmap_font.h deleted file mode 100644 index 8217cf61..00000000 --- a/src/lib/libgambatte/src/bitmap_font.h +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef BITMAP_FONT_H -#define BITMAP_FONT_H - -#include "int.h" - -namespace BitmapFont { -enum Char { - NUL, - N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, - A, B, C, D, E, F, G, H, I, J, K, L, M, - N, O, P, Q, R, S, T, U, V, W, X, Y, Z, - a, b, c, d, e, f, g, h, i, j, k, l, m, - n, o, p, q, r, s, t, u, v, w, x, y, z, - SPC -}; - -enum { HEIGHT = 10 }; -enum { MAX_WIDTH = 9 }; -enum { NUMBER_WIDTH = 6 }; - -unsigned getWidth(const char *chars); - -// struct Fill { void operator()(RandomAccessIterator dest, unsigned pitch) { fill pixels at dest } } -template -void print(RandomAccessIterator dest, unsigned pitch, Fill fill, const char *chars); - -void print(Gambatte::uint_least32_t *dest, unsigned pitch, unsigned long color, const char *chars); -void utoa(unsigned u, char *a); - -// --- INTERFACE END --- - - - -extern const unsigned char *const font[]; - -template -void print(RandomAccessIterator dest, const unsigned pitch, Fill fill, const char *chars) { - while (const int character = *chars++) { - RandomAccessIterator dst = dest; - const unsigned char *s = font[character]; - - const unsigned width = *s >> 4; - unsigned h = *s++ & 0xF; - - while (h--) { - RandomAccessIterator d = dst; - - unsigned line = *s++; - - if (width > 8) - line |= *s++ << 8; - - while (line) { - if (line & 1) - fill(d, pitch); - - line >>= 1; - ++d; - } - - dst += pitch; - } - - dest += width; - } -} -} - -#endif diff --git a/src/lib/libgambatte/src/colorconversion.cpp b/src/lib/libgambatte/src/colorconversion.cpp deleted file mode 100644 index d76b0aee..00000000 --- a/src/lib/libgambatte/src/colorconversion.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "colorconversion.h" -#include - -Rgb32ToUyvy::Rgb32ToUyvy() { -#ifdef WORDS_BIGENDIAN - const CacheUnit c = { 0, 128ul << 24 | 16ul << 16 | 128 << 8 | 16 }; -#else - const CacheUnit c = { 0, 16ul << 24 | 128ul << 16 | 16 << 8 | 128 }; -#endif - std::fill(cache, cache + cache_size, c); -} - -void Rgb32ToUyvy::operator()(const Gambatte::uint_least32_t *s, Gambatte::uint_least32_t *d, const unsigned w, unsigned h, const unsigned d_pitch) { - while (h--) { - for (const Gambatte::uint_least32_t *const ends = s + w; s != ends;) { - if ((cache[*s & cache_mask].rgb32 - *s) | (cache[*(s+1) & cache_mask].rgb32 - *(s+1))) { - cache[*s & cache_mask].rgb32 = *s; - cache[*(s+1) & cache_mask].rgb32 = *(s+1); - - const unsigned long r = (*s >> 16 & 0x000000FF) | (*(s+1) & 0x00FF0000); - const unsigned long g = (*s >> 8 & 0x000000FF) | (*(s+1) << 8 & 0x00FF0000); - const unsigned long b = (*s & 0x000000FF) | (*(s+1) << 16 & 0x00FF0000); - - const unsigned long y = r * 66 + g * 129 + b * 25 + (16 * 256 + 128) * 0x00010001ul; - const unsigned long u = b * 112 - r * 38 - g * 74 + (128 * 256 + 128) * 0x00010001ul; - const unsigned long v = r * 112 - g * 94 - b * 18 + (128 * 256 + 128) * 0x00010001ul; - -#ifdef WORDS_BIGENDIAN - *d++ = cache[*s & cache_mask].uyvy = (u << 16 & 0xFF000000) | (y << 8 & 0x00FF0000) | (v & 0x0000FF00) | (y >> 8 & 0x000000FF); - *d++ = cache[*(s+1) & cache_mask].uyvy = (u & 0xFF000000) | (y >> 8 & 0x00FF0000) | (v >> 16 & 0x0000FF00) | y >> 24; -#else - *d++ = cache[*s & cache_mask].uyvy = (y << 16 & 0xFF000000) | (v << 8 & 0x00FF0000) | (y & 0x0000FF00) | (u >> 8 & 0x000000FF); - *d++ = cache[*(s+1) & cache_mask].uyvy = (y & 0xFF000000) | (v >> 8 & 0x00FF0000) | (y >> 16 & 0x0000FF00) | u >> 24; -#endif - } else { - *d++ = cache[*s & cache_mask].uyvy; - *d++ = cache[*(s+1) & cache_mask].uyvy; - } - - s += 2; - } - - d += d_pitch - w; - } -} - -unsigned long rgb32ToUyvy(unsigned long rgb32) { - const unsigned r = rgb32 >> 16 & 0xFF; - const unsigned g = rgb32 >> 8 & 0xFF; - const unsigned b = rgb32 & 0xFF; - - const unsigned long y = (r * 66 + g * 129 + b * 25 + 16 * 256 + 128) >> 8; - const unsigned long u = (b * 112 - r * 38 - g * 74 + 128 * 256 + 128) >> 8; - const unsigned long v = (r * 112 - g * 94 - b * 18 + 128 * 256 + 128) >> 8; - -#ifdef WORDS_BIGENDIAN - return u << 24 | y << 16 | v << 8 | y; -#else - return y << 24 | v << 16 | y << 8 | u; -#endif -} - -void rgb32ToRgb16(const Gambatte::uint_least32_t *s, Gambatte::uint_least16_t *d, const unsigned w, unsigned h, const unsigned dstPitch) { - do { - unsigned n = w; - - do { - *d++ = (*s >> 8 & 0xF800) | (*s >> 5 & 0x07E0) | (*s >> 3 & 0x001F); - ++s; - } while (--n); - - d += dstPitch - w; - } while (--h); -} - -unsigned rgb32ToRgb16(const unsigned long rgb32) { - return (rgb32 >> 8 & 0xF800) | (rgb32 >> 5 & 0x07E0) | (rgb32 >> 3 & 0x001F); -} diff --git a/src/lib/libgambatte/src/colorconversion.h b/src/lib/libgambatte/src/colorconversion.h deleted file mode 100644 index 9323015e..00000000 --- a/src/lib/libgambatte/src/colorconversion.h +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef COLORCONVERSION_H -#define COLORCONVERSION_H - -#include "int.h" -#include - -class Rgb32ToUyvy { - struct CacheUnit { - Gambatte::uint_least32_t rgb32; - Gambatte::uint_least32_t uyvy; - }; - - enum { cache_size = 0x100 }; - enum { cache_mask = cache_size - 1 }; - - CacheUnit cache[cache_size]; - -public: - Rgb32ToUyvy(); - void operator()(const Gambatte::uint_least32_t *s, Gambatte::uint_least32_t *d, unsigned w, unsigned h, unsigned dstPitch); -}; - -unsigned long rgb32ToUyvy(unsigned long rgb32); - -void rgb32ToRgb16(const Gambatte::uint_least32_t *s, Gambatte::uint_least16_t *d, unsigned w, unsigned h, unsigned dstPitch); -unsigned rgb32ToRgb16(unsigned long rgb32); - -#endif diff --git a/src/lib/libgambatte/src/cpu.cpp b/src/lib/libgambatte/src/cpu.cpp deleted file mode 100644 index 0520f95a..00000000 --- a/src/lib/libgambatte/src/cpu.cpp +++ /dev/null @@ -1,2850 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "cpu.h" -#include "memory.h" -#include "savestate.h" - -CPU::CPU() : -memory(Interrupter(SP, PC_, halted)), -cycleCounter_(0), -PC_(0x100), -SP(0xFFFE), -HF1(0xF), -HF2(0xF), -ZF(0), -CF(0x100), -A_(0x01), -B(0x00), -C(0x13), -D(0x00), -E(0xD8), -H(0x01), -L(0x4D), -skip(false), -halted(false) -{} - -void CPU::runFor(const unsigned long cycles) { - process(cycles/* << memory.isDoubleSpeed()*/); - - if (cycleCounter_ & 0x80000000) - cycleCounter_ = memory.resetCounters(cycleCounter_); -} - -void CPU::updateVideo() { - return memory.updateVideo(cycleCounter_); -} - -unsigned CPU::lyCounter() { - return memory.lyCounter(cycleCounter_); -} - -bool CPU::load(const bool forceDmg) { - bool tmp = memory.loadROM(forceDmg); - - return tmp; -} - -/*void CPU::halt() { - while (halted) { - const uint_fast32_t cycles = memory.next_eventtime - memory.CycleCounter; - memory.CycleCounter += cycles + ((4 - (cycles & 3)) & 3); - memory.event(); - } -}*/ - -//Push address of next instruction onto stack and then jump to interrupt address (0x40-0x60): -/*unsigned CPU::interrupt(const unsigned address, unsigned cycleCounter) { - if (halted && memory.isCgb()) - cycleCounter += 4; - - halted = false; - cycleCounter += 8; - memory.write(--SP, PC_ >> 8, cycleCounter); - cycleCounter += 4; - memory.write(--SP, PC_ & 0xFF, cycleCounter); - PC_ = address; - cycleCounter += 8; - - return cycleCounter; -}*/ - -// (HF2 & 0x200) == true means HF is set. -// (HF2 & 0x400) marks the subtract flag. -// (HF2 & 0x800) is set for inc/dec. -// (HF2 & 0x100) is set if there's a carry to add. -static void calcHF(const unsigned HF1, unsigned& HF2) { - unsigned arg1 = HF1 & 0xF; - unsigned arg2 = (HF2 & 0xF) + (HF2 >> 8 & 1); - - if (HF2 & 0x800) { - arg1 = arg2; - arg2 = 1; - } - - if (HF2 & 0x400) - arg1 -= arg2; - else - arg1 = (arg1 + arg2) << 5; - - HF2 |= arg1 & 0x200; -} - -#define F() (((HF2 & 0x600) | (CF & 0x100)) >> 4 | ((ZF & 0xFF) ? 0 : 0x80)) - -#define FROM_F(f_in) do { \ - unsigned from_f_var = f_in; \ -\ - ZF = ~from_f_var & 0x80; \ - HF2 = from_f_var << 4 & 0x600; \ - CF = from_f_var << 4 & 0x100; \ -} while (0) - -void CPU::setStatePtrs(SaveState &state) { - memory.setStatePtrs(state); -} - -void CPU::saveState(SaveState &state) { - cycleCounter_ = memory.saveState(state, cycleCounter_); - - calcHF(HF1, HF2); - - state.cpu.cycleCounter = cycleCounter_; - state.cpu.PC = PC_; - state.cpu.SP = SP; - state.cpu.A = A_; - state.cpu.B = B; - state.cpu.C = C; - state.cpu.D = D; - state.cpu.E = E; - state.cpu.F = F(); - state.cpu.H = H; - state.cpu.L = L; - state.cpu.skip = skip; - state.cpu.halted = halted; -} - -void CPU::loadState(const SaveState &state) { - memory.loadState(state, cycleCounter_); - - cycleCounter_ = state.cpu.cycleCounter; - PC_ = state.cpu.PC; - SP = state.cpu.SP; - A_ = state.cpu.A; - B = state.cpu.B; - C = state.cpu.C; - D = state.cpu.D; - E = state.cpu.E; - FROM_F(state.cpu.F); - H = state.cpu.H; - L = state.cpu.L; - skip = state.cpu.skip; - halted = state.cpu.halted; -} - -#define BC() ( B << 8 | C ) -#define DE() ( D << 8 | E ) -#define HL() ( H << 8 | L ) - -#define READ(dest, addr) do { (dest) = memory.read(addr, cycleCounter); cycleCounter += 4; } while (0) -// #define PC_READ(dest, addr) do { (dest) = memory.pc_read(addr, cycleCounter); cycleCounter += 4; } while (0) -#define PC_READ(dest) do { (dest) = memory.read(PC, cycleCounter); PC = (PC + 1) & 0xFFFF; cycleCounter += 4; } while (0) -#define FF_READ(dest, addr) do { (dest) = memory.ff_read(addr, cycleCounter); cycleCounter += 4; } while (0) - -#define WRITE(addr, data) do { memory.write(addr, data, cycleCounter); cycleCounter += 4; } while (0) -#define FF_WRITE(addr, data) do { memory.ff_write(addr, data, cycleCounter); cycleCounter += 4; } while (0) - -#define PC_MOD(data) do { PC = data; cycleCounter += 4; } while (0) - -#define PUSH(r1, r2) do { \ - SP = (SP - 1) & 0xFFFF; \ - WRITE(SP, (r1)); \ - SP = (SP - 1) & 0xFFFF; \ - WRITE(SP, (r2)); \ -} while (0) - -//CB OPCODES (Shifts, rotates and bits): -//swap r (8 cycles): -//Swap upper and lower nibbles of 8-bit register, reset flags, check zero flag: -#define swap_r(r) do { \ - CF = HF2 = 0; \ - ZF = (r); \ - (r) = (ZF << 4 | ZF >> 4) & 0xFF; \ -} while (0) - -//rlc r (8 cycles): -//Rotate 8-bit register left, store old bit7 in CF. Reset SF and HCF, Check ZF: -#define rlc_r(r) do { \ - CF = (r) << 1; \ - ZF = CF | CF >> 8; \ - (r) = ZF & 0xFF; \ - HF2 = 0; \ -} while (0) - -//rl r (8 cycles): -//Rotate 8-bit register left through CF, store old bit7 in CF, old CF value becomes bit0. Reset SF and HCF, Check ZF: -#define rl_r(r) do { \ - const unsigned rl_r_var_oldcf = CF >> 8 & 1; \ - CF = (r) << 1; \ - ZF = CF | rl_r_var_oldcf; \ - (r) = ZF & 0xFF; \ - HF2 = 0; \ -} while (0) - -//rrc r (8 cycles): -//Rotate 8-bit register right, store old bit0 in CF. Reset SF and HCF, Check ZF: -#define rrc_r(r) do { \ - ZF = (r); \ - CF = ZF << 8; \ - (r) = (ZF | CF) >> 1 & 0xFF; \ - HF2 = 0; \ -} while (0) - -//rr r (8 cycles): -//Rotate 8-bit register right through CF, store old bit0 in CF, old CF value becomes bit7. Reset SF and HCF, Check ZF: -#define rr_r(r) do { \ - const unsigned rr_r_var_oldcf = CF & 0x100; \ - CF = (r) << 8; \ - (r) = ZF = ((r) | rr_r_var_oldcf) >> 1; \ - HF2 = 0; \ -} while (0) - -//sla r (8 cycles): -//Shift 8-bit register left, store old bit7 in CF. Reset SF and HCF, Check ZF: -#define sla_r(r) do { \ - ZF = CF = (r) << 1; \ - (r) = ZF & 0xFF; \ - HF2 = 0; \ -} while (0) - -//sra r (8 cycles): -//Shift 8-bit register right, store old bit0 in CF. bit7=old bit7. Reset SF and HCF, Check ZF: -#define sra_r(r) do { \ - CF = (r) << 8; \ - ZF = (r) >> 1; \ - (r) = ZF | ((r) & 0x80); \ - HF2 = 0; \ -} while (0) - -//srl r (8 cycles): -//Shift 8-bit register right, store old bit0 in CF. Reset SF and HCF, Check ZF: -#define srl_r(r) do { \ - ZF = (r); \ - CF = (r) << 8; \ - ZF >>= 1; \ - (r) = ZF; \ - HF2 = 0; \ -} while (0) - -//bit n,r (8 cycles): -//bit n,(hl) (12 cycles): -//Test bitn in 8-bit value, check ZF, unset SF, set HCF: -#define bitn_u8(bitmask, u8) do { \ - ZF = (u8) & (bitmask); \ - HF2 = 0x200; \ -} while (0) - -#define bit0_u8(u8) bitn_u8(1, (u8)) -#define bit1_u8(u8) bitn_u8(2, (u8)) -#define bit2_u8(u8) bitn_u8(4, (u8)) -#define bit3_u8(u8) bitn_u8(8, (u8)) -#define bit4_u8(u8) bitn_u8(0x10, (u8)) -#define bit5_u8(u8) bitn_u8(0x20, (u8)) -#define bit6_u8(u8) bitn_u8(0x40, (u8)) -#define bit7_u8(u8) bitn_u8(0x80, (u8)) - -//set n,r (8 cycles): -//Set bitn of 8-bit register: -#define set0_r(r) ( (r) |= 0x1 ) -#define set1_r(r) ( (r) |= 0x2 ) -#define set2_r(r) ( (r) |= 0x4 ) -#define set3_r(r) ( (r) |= 0x8 ) -#define set4_r(r) ( (r) |= 0x10 ) -#define set5_r(r) ( (r) |= 0x20 ) -#define set6_r(r) ( (r) |= 0x40 ) -#define set7_r(r) ( (r) |= 0x80 ) - -//set n,(hl) (16 cycles): -//Set bitn of value at address stored in HL: -#define setn_mem_hl(n) do { \ - const unsigned setn_mem_hl_var_addr = HL(); \ - unsigned setn_mem_hl_var_tmp; \ -\ - READ(setn_mem_hl_var_tmp, setn_mem_hl_var_addr); \ - setn_mem_hl_var_tmp |= 1 << (n); \ -\ - WRITE(setn_mem_hl_var_addr, setn_mem_hl_var_tmp); \ -} while (0) - -//res n,r (8 cycles): -//Unset bitn of 8-bit register: -#define res0_r(r) ( (r) &= 0xFE ) -#define res1_r(r) ( (r) &= 0xFD ) -#define res2_r(r) ( (r) &= 0xFB ) -#define res3_r(r) ( (r) &= 0xF7 ) -#define res4_r(r) ( (r) &= 0xEF ) -#define res5_r(r) ( (r) &= 0xDF ) -#define res6_r(r) ( (r) &= 0xBF ) -#define res7_r(r) ( (r) &= 0x7F ) - -//res n,(hl) (16 cycles): -//Unset bitn of value at address stored in HL: -#define resn_mem_hl(n) do { \ - const unsigned resn_mem_hl_var_addr = HL(); \ - unsigned resn_mem_hl_var_tmp; \ -\ - READ(resn_mem_hl_var_tmp, resn_mem_hl_var_addr); \ - resn_mem_hl_var_tmp &= ~(1 << (n)); \ -\ - WRITE(resn_mem_hl_var_addr, resn_mem_hl_var_tmp); \ -} while (0) - - -//16-BIT LOADS: -//ld rr,nn (12 cycles) -//set rr to 16-bit value of next 2 bytes in memory -#define ld_rr_nn(r1, r2) do { \ - PC_READ(r2); \ - PC_READ(r1); \ -} while (0) - -//push rr (16 cycles): -//Push value of register pair onto stack: -#define push_rr(r1, r2) do { \ - PUSH(r1, r2); \ - cycleCounter += 4; \ -} while (0) - -//pop rr (12 cycles): -//Pop two bytes off stack into register pair: -#define pop_rr(r1, r2) do { \ - READ(r2, SP); \ - SP = (SP + 1) & 0xFFFF; \ - READ(r1, SP); \ - SP = (SP + 1) & 0xFFFF; \ -} while (0) - -//8-BIT ALU: -//add a,r (4 cycles): -//add a,(addr) (8 cycles): -//Add 8-bit value to A, check flags: -#define add_a_u8(u8) do { \ - HF1 = A; \ - HF2 = u8; \ - ZF = CF = A + HF2; \ - A = ZF & 0xFF; \ -} while (0) - -//adc a,r (4 cycles): -//adc a,(addr) (8 cycles): -//Add 8-bit value+CF to A, check flags: -#define adc_a_u8(u8) do { \ - HF1 = A; \ - HF2 = (CF & 0x100) | (u8); \ - ZF = CF = (CF >> 8 & 1) + (u8) + A; \ - A = ZF & 0xFF; \ -} while (0) - -//sub a,r (4 cycles): -//sub a,(addr) (8 cycles): -//Subtract 8-bit value from A, check flags: -#define sub_a_u8(u8) do { \ - HF1 = A; \ - HF2 = u8; \ - ZF = CF = A - HF2; \ - A = ZF & 0xFF; \ - HF2 |= 0x400; \ -} while (0) - -//sbc a,r (4 cycles): -//sbc a,(addr) (8 cycles): -//Subtract CF and 8-bit value from A, check flags: -#define sbc_a_u8(u8) do { \ - HF1 = A; \ - HF2 = 0x400 | (CF & 0x100) | (u8); \ - ZF = CF = A - ((CF >> 8) & 1) - (u8); \ - A = ZF & 0xFF; \ -} while (0) - -//and a,r (4 cycles): -//and a,(addr) (8 cycles): -//bitwise and 8-bit value into A, check flags: -#define and_a_u8(u8) do { \ - HF2 = 0x200; \ - CF = 0; \ - A &= (u8); \ - ZF = A; \ -} while (0) - -//or a,r (4 cycles): -//or a,(hl) (8 cycles): -//bitwise or 8-bit value into A, check flags: -#define or_a_u8(u8) do { \ - CF = HF2 = 0; \ - A |= (u8); \ - ZF = A; \ -} while (0) - -//xor a,r (4 cycles): -//xor a,(hl) (8 cycles): -//bitwise xor 8-bit value into A, check flags: -#define xor_a_u8(u8) do { \ - CF = HF2 = 0; \ - A ^= (u8); \ - ZF = A; \ -} while (0) - -//cp a,r (4 cycles): -//cp a,(addr) (8 cycles): -//Compare (subtract without storing result) 8-bit value to A, check flags: -#define cp_a_u8(u8) do { \ - HF1 = A; \ - HF2 = u8; \ - ZF = CF = A - HF2; \ - HF2 |= 0x400; \ -} while (0) - -//inc r (4 cycles): -//Increment value of 8-bit register, check flags except CF: -#define inc_r(r) do { \ - HF2 = (r) | 0x800; \ - ZF = (r) + 1; \ - (r) = ZF & 0xFF; \ -} while (0) - -//dec r (4 cycles): -//Decrement value of 8-bit register, check flags except CF: -#define dec_r(r) do { \ - HF2 = (r) | 0xC00; \ - ZF = (r) - 1; \ - (r) = ZF & 0xFF; \ -} while (0) - -//16-BIT ARITHMETIC -//add hl,rr (8 cycles): -//add 16-bit register to HL, check flags except ZF: -/*#define add_hl_rr(rh, rl) do { \ - L = HF1 = L + (rl); \ - HF1 >>= 8; \ - HF1 += H; \ - HF2 = (rh); \ - H = CF = HF1 + (rh); \ - cycleCounter += 4; \ -} while (0)*/ - -#define add_hl_rr(rh, rl) do { \ - CF = L + (rl); \ - L = CF & 0xFF; \ - HF1 = H; \ - HF2 = (CF & 0x100) | (rh); \ - CF = H + (CF >> 8) + (rh); \ - H = CF & 0xFF; \ - cycleCounter += 4; \ -} while (0) - -//inc rr (8 cycles): -//Increment 16-bit register: -#define inc_rr(rh, rl) do { \ - const unsigned inc_rr_var_tmp = (rl) + 1; \ - (rl) = inc_rr_var_tmp & 0xFF; \ - (rh) = ((rh) + (inc_rr_var_tmp >> 8)) & 0xFF; \ - cycleCounter += 4; \ -} while (0) - -//dec rr (8 cycles): -//Decrement 16-bit register: -#define dec_rr(rh, rl) do { \ - const unsigned dec_rr_var_tmp = (rl) - 1; \ - (rl) = dec_rr_var_tmp & 0xFF; \ - (rh) = ((rh) - (dec_rr_var_tmp >> 8 & 1)) & 0xFF; \ - cycleCounter += 4; \ -} while (0) - -#define sp_plus_n(sumout) do { \ - unsigned sp_plus_n_var_n; \ - PC_READ(sp_plus_n_var_n); \ - sp_plus_n_var_n = (sp_plus_n_var_n ^ 0x80) - 0x80; \ - \ - const unsigned sp_plus_n_var_sum = SP + sp_plus_n_var_n; \ - CF = SP ^ sp_plus_n_var_n ^ sp_plus_n_var_sum; \ - HF2 = CF << 5 & 0x200; \ - ZF = 1; \ - cycleCounter += 4; \ - (sumout) = sp_plus_n_var_sum & 0xFFFF; \ -} while (0) - -//JUMPS: -//jp nn (16 cycles): -//Jump to address stored in the next two bytes in memory: -#define jp_nn() do { \ - unsigned jp_nn_var_l, jp_nn_var_h; \ -\ - PC_READ(jp_nn_var_l); \ - PC_READ(jp_nn_var_h); \ -\ - PC_MOD(jp_nn_var_h << 8 | jp_nn_var_l); \ -} while (0) - -//jr disp (12 cycles): -//Jump to value of next (signed) byte in memory+current address: -#define jr_disp() do { \ - unsigned jr_disp_var_tmp; \ -\ - PC_READ(jr_disp_var_tmp); \ - jr_disp_var_tmp = (jr_disp_var_tmp ^ 0x80) - 0x80; \ -\ - PC_MOD((PC + jr_disp_var_tmp) & 0xFFFF); \ -} while (0) - -//CALLS, RESTARTS AND RETURNS: -//call nn (24 cycles): -//Push address of next instruction onto stack and then jump to address stored in next two bytes in memory: -#define call_nn() do { \ - PUSH(((PC + 2) >> 8) & 0xFF, (PC + 2) & 0xFF); \ - jp_nn(); \ -} while (0) - -//rst n (16 Cycles): -//Push present address onto stack, jump to address n (one of 00h,08h,10h,18h,20h,28h,30h,38h): -#define rst_n(n) do { \ - PUSH(PC >> 8, PC & 0xFF); \ - PC_MOD(n); \ -} while (0) - -//ret (16 cycles): -//Pop two bytes from the stack and jump to that address: -#define ret() do { \ - unsigned ret_var_l, ret_var_h; \ -\ - pop_rr(ret_var_h, ret_var_l); \ -\ - PC_MOD(ret_var_h << 8 | ret_var_l); \ -} while (0) - -void CPU::process(const unsigned long cycles) { - memory.setEndtime(cycleCounter_, cycles); - - unsigned char A = A_; - unsigned long cycleCounter = cycleCounter_; - - while (memory.isActive()) { - unsigned short PC = PC_; - - if (halted) { - if (cycleCounter < memory.getNextEventTime()) { - const unsigned long cycles = memory.getNextEventTime() - cycleCounter; - cycleCounter += cycles + ((4 - (cycles & 3)) & 3); - } - } else while (cycleCounter < memory.getNextEventTime()) { - unsigned char opcode; - - PC_READ(opcode); - - if (skip) { - PC = (PC - 1) & 0xFFFF; - skip = false; - } - - switch (opcode) { - //nop (4 cycles): - //Do nothing for 4 cycles: - case 0x00: - break; - case 0x01: - ld_rr_nn(B, C); - break; - case 0x02: - WRITE(BC(), A); - break; - case 0x03: - inc_rr(B, C); - break; - case 0x04: - inc_r(B); - break; - case 0x05: - dec_r(B); - break; - case 0x06: - PC_READ(B); - break; - - //rlca (4 cycles): - //Rotate 8-bit register A left, store old bit7 in CF. Reset SF, HCF, ZF: - case 0x07: - CF = A << 1; - A = (CF | CF >> 8) & 0xFF; - HF2 = 0; - ZF = 1; - break; - - //ld (nn),SP (20 cycles): - //Put value of SP into address given by next 2 bytes in memory: - case 0x08: - { - unsigned l, h; - - PC_READ(l); - PC_READ(h); - - const unsigned addr = h << 8 | l; - - WRITE(addr, SP & 0xFF); - WRITE((addr + 1) & 0xFFFF, SP >> 8); - } - break; - - case 0x09: - add_hl_rr(B, C); - break; - case 0x0A: - READ(A, BC()); - break; - case 0x0B: - dec_rr(B, C); - break; - case 0x0C: - inc_r(C); - break; - case 0x0D: - dec_r(C); - break; - case 0x0E: - PC_READ(C); - break; - - //rrca (4 cycles): - //Rotate 8-bit register A right, store old bit0 in CF. Reset SF, HCF, ZF: - case 0x0F: - CF = A << 8 | A; - A = CF >> 1 & 0xFF; - HF2 = 0; - ZF = 1; - break; - - //stop (4 cycles): - //Halt CPU and LCD display until button pressed: - case 0x10: - memory.speedChange(cycleCounter); - PC = (PC + 1) & 0xFFFF; - break; - case 0x11: - ld_rr_nn(D, E); - break; - case 0x12: - WRITE(DE(), A); - break; - case 0x13: - inc_rr(D, E); - break; - case 0x14: - inc_r(D); - break; - case 0x15: - dec_r(D); - break; - case 0x16: - PC_READ(D); - break; - - //rla (4 cycles): - //Rotate 8-bit register A left through CF, store old bit7 in CF, old CF value becomes bit0. Reset SF, HCF, ZF: - case 0x17: - { - const unsigned oldcf = CF >> 8 & 1; - CF = A << 1; - A = (CF | oldcf) & 0xFF; - } - - HF2 = 0; - ZF = 1; - break; - - case 0x18: - jr_disp(); - break; - case 0x19: - add_hl_rr(D, E); - break; - case 0x1A: - READ(A, DE()); - break; - case 0x1B: - dec_rr(D, E); - break; - case 0x1C: - inc_r(E); - break; - case 0x1D: - dec_r(E); - break; - case 0x1E: - PC_READ(E); - break; - - //rra (4 cycles): - //Rotate 8-bit register A right through CF, store old bit0 in CF, old CF value becomes bit7. Reset SF, HCF, ZF: - case 0x1F: - { - const unsigned oldcf = CF & 0x100; - CF = A << 8; - A = (A | oldcf) >> 1; - } - - HF2 = 0; - ZF = 1; - break; - - //jr nz,disp (12;8 cycles): - //Jump to value of next (signed) byte in memory+current address if ZF is unset: - case 0x20: - if (ZF & 0xFF) { - jr_disp(); - } else { - PC_MOD((PC + 1) & 0xFFFF); - } - break; - - case 0x21: - ld_rr_nn(H, L); - break; - - //ldi (hl),a (8 cycles): - //Put A into memory address in hl. Increment HL: - case 0x22: - { - unsigned addr = HL(); - - WRITE(addr, A); - - addr = (addr + 1) & 0xFFFF; - L = addr; - H = addr >> 8; - } - break; - - case 0x23: - inc_rr(H, L); - break; - case 0x24: - inc_r(H); - break; - case 0x25: - dec_r(H); - break; - case 0x26: - PC_READ(H); - break; - - - //daa (4 cycles): - //Adjust register A to correctly represent a BCD. Check ZF, HF and CF: - case 0x27: - /*{ - unsigned correction = ((A > 0x99) || (CF & 0x100)) ? 0x60 : 0x00; - - calcHF(HF1, HF2); - - if ((A & 0x0F) > 0x09 || (HF2 & 0x200)) - correction |= 0x06; - - HF1 = A; - HF2 = (HF2 & 0x400) | correction; - CF = (correction & 0x40) << 2; - A = (HF2 & 0x400) ? A - correction : (A + correction); - ZF = A; - }*/ - - calcHF(HF1, HF2); - - { - unsigned correction = (CF & 0x100) ? 0x60 : 0x00; - - if (HF2 & 0x200) - correction |= 0x06; - - if (!(HF2 &= 0x400)) { - if ((A & 0x0F) > 0x09) - correction |= 0x06; - - if (A > 0x99) - correction |= 0x60; - - A += correction; - } else - A -= correction; - - CF = correction << 2 & 0x100; - ZF = A; - A &= 0xFF; - } - break; - - //jr z,disp (12;8 cycles): - //Jump to value of next (signed) byte in memory+current address if ZF is set: - case 0x28: - if (ZF & 0xFF) { - PC_MOD((PC + 1) & 0xFFFF); - } else { - jr_disp(); - } - break; - - //add hl,hl (8 cycles): - //add 16-bit register HL to HL, check flags except ZF: - case 0x29: - add_hl_rr(H, L); - break; - - //ldi a,(hl) (8 cycles): - //Put value at address in hl into A. Increment HL: - case 0x2A: - { - unsigned addr = HL(); - - READ(A, addr); - - addr = (addr + 1) & 0xFFFF; - L = addr; - H = addr >> 8; - } - break; - - case 0x2B: - dec_rr(H, L); - break; - case 0x2C: - inc_r(L); - break; - case 0x2D: - dec_r(L); - break; - case 0x2E: - PC_READ(L); - break; - - //cpl (4 cycles): - //Complement register A. (Flip all bits), set SF and HCF: - case 0x2F: /*setSubtractFlag(); setHalfCarryFlag();*/ - HF2 = 0x600; - A ^= 0xFF; - break; - - //jr nc,disp (12;8 cycles): - //Jump to value of next (signed) byte in memory+current address if CF is unset: - case 0x30: - if (CF & 0x100) { - PC_MOD((PC + 1) & 0xFFFF); - } else { - jr_disp(); - } - break; - - //ld sp,nn (12 cycles) - //set sp to 16-bit value of next 2 bytes in memory - case 0x31: - { - unsigned l, h; - - PC_READ(l); - PC_READ(h); - - SP = h << 8 | l; - } - break; - - //ldd (hl),a (8 cycles): - //Put A into memory address in hl. Decrement HL: - case 0x32: - { - unsigned addr = HL(); - - WRITE(addr, A); - - addr = (addr - 1) & 0xFFFF; - L = addr; - H = addr >> 8; - } - break; - - case 0x33: - SP = (SP + 1) & 0xFFFF; - cycleCounter += 4; - break; - - //inc (hl) (12 cycles): - //Increment value at address in hl, check flags except CF: - case 0x34: - { - const unsigned addr = HL(); - - READ(HF2, addr); - ZF = HF2 + 1; - WRITE(addr, ZF & 0xFF); - HF2 |= 0x800; - } - break; - - //dec (hl) (12 cycles): - //Decrement value at address in hl, check flags except CF: - case 0x35: - { - const unsigned addr = HL(); - - READ(HF2, addr); - ZF = HF2 - 1; - WRITE(addr, ZF & 0xFF); - HF2 |= 0xC00; - } - break; - - //ld (hl),n (12 cycles): - //set memory at address in hl to value of next byte in memory: - case 0x36: - { - unsigned tmp; - - PC_READ(tmp); - WRITE(HL(), tmp); - } - break; - - //scf (4 cycles): - //Set CF. Unset SF and HCF: - case 0x37: /*setCarryFlag(); unsetSubtractFlag(); unsetHalfCarryFlag();*/ - CF = 0x100; - HF2 = 0; - break; - - //jr c,disp (12;8 cycles): - //Jump to value of next (signed) byte in memory+current address if CF is set: - case 0x38: //PC+=(((int8_t)memory.read(PC++))*CarryFlag()); Cycles(8); break; - if (CF & 0x100) { - jr_disp(); - } else { - PC_MOD((PC + 1) & 0xFFFF); - } - break; - - //add hl,sp (8 cycles): - //add SP to HL, check flags except ZF: - case 0x39: /*add_hl_rr(SP>>8, SP); break;*/ - CF = L + SP; - L = CF & 0xFF; - HF1 = H; - HF2 = ((CF ^ SP) & 0x100) | SP >> 8; - CF >>= 8; - CF += H; - H = CF & 0xFF; - cycleCounter += 4; - break; - - //ldd a,(hl) (8 cycles): - //Put value at address in hl into A. Decrement HL: - case 0x3A: - { - unsigned addr = HL(); - - A = memory.read(addr, cycleCounter); - cycleCounter += 4; - - addr = (addr - 1) & 0xFFFF; - L = addr; - H = addr >> 8; - } - break; - - case 0x3B: - SP = (SP - 1) & 0xFFFF; - cycleCounter += 4; - break; - case 0x3C: - inc_r(A); - break; - case 0x3D: - dec_r(A); - break; - case 0x3E: - PC_READ(A); - break; - - //ccf (4 cycles): - //Complement CF (unset if set vv.) Unset SF and HCF. - case 0x3F: /*complementCarryFlag(); unsetSubtractFlag(); unsetHalfCarryFlag();*/ - CF ^= 0x100; - HF2 = 0; - break; - - //ld r,r (4 cycles):next_irqEventTime - //ld r,(r) (8 cycles): - case 0x40: - B = B; - break; - case 0x41: - B = C; - break; - case 0x42: - B = D; - break; - case 0x43: - B = E; - break; - case 0x44: - B = H; - break; - case 0x45: - B = L; - break; - case 0x46: - READ(B, HL()); - break; - case 0x47: - B = A; - break; - case 0x48: - C = B; - break; - case 0x49: - C = C; - break; - case 0x4A: - C = D; - break; - case 0x4B: - C = E; - break; - case 0x4C: - C = H; - break; - case 0x4D: - C = L; - break; - case 0x4E: - READ(C, HL()); - break; - case 0x4F: - C = A; - break; - case 0x50: - D = B; - break; - case 0x51: - D = C; - break; - case 0x52: - D = D; - break; - case 0x53: - D = E; - break; - case 0x54: - D = H; - break; - case 0x55: - D = L; - break; - case 0x56: - READ(D, HL()); - break; - case 0x57: - D = A; - break; - case 0x58: - E = B; - break; - case 0x59: - E = C; - break; - case 0x5A: - E = D; - break; - case 0x5B: - E = E; - break; - case 0x5C: - E = H; - break; - case 0x5D: - E = L; - break; - case 0x5E: - READ(E, HL()); - break; - case 0x5F: - E = A; - break; - case 0x60: - H = B; - break; - case 0x61: - H = C; - break; - case 0x62: - H = D; - break; - case 0x63: - H = E; - break; - case 0x64: - H = H; - break; - case 0x65: - H = L; - break; - case 0x66: - READ(H, HL()); - break; - case 0x67: - H = A; - break; - case 0x68: - L = B; - break; - case 0x69: - L = C; - break; - case 0x6A: - L = D; - break; - case 0x6B: - L = E; - break; - case 0x6C: - L = H; - break; - case 0x6D: - L = L; - break; - case 0x6E: - READ(L, HL()); - break; - case 0x6F: - L = A; - break; - case 0x70: - WRITE(HL(), B); - break; - case 0x71: - WRITE(HL(), C); - break; - case 0x72: - WRITE(HL(), D); - break; - case 0x73: - WRITE(HL(), E); - break; - case 0x74: - WRITE(HL(), H); - break; - case 0x75: - WRITE(HL(), L); - break; - - //halt (4 cycles): - case 0x76: -// printf("halt\n"); - if (memory.getIME()/* || memory.next_eitime*/) { - halted = 1; - - if (cycleCounter < memory.getNextEventTime()) { - const unsigned long cycles = memory.getNextEventTime() - cycleCounter; - cycleCounter += cycles + ((4 - (cycles & 3)) & 3); - } - } else { - if ((memory.ff_read(0xFF0F, cycleCounter) & memory.ff_read(0xFFFF, cycleCounter)) & 0x1F) { - if (memory.isCgb()) - cycleCounter += 8; //two nops. - else - skip = true; - } else { - memory.schedule_unhalt(); - halted = 1; - - if (cycleCounter < memory.getNextEventTime()) { - const unsigned long cycles = memory.getNextEventTime() - cycleCounter; - cycleCounter += cycles + ((4 - (cycles & 3)) & 3); - } - } - } - break; - case 0x77: - WRITE(HL(), A); - break; - case 0x78: - A = B; - break; - case 0x79: - A = C; - break; - case 0x7A: - A = D; - break; - case 0x7B: - A = E; - break; - case 0x7C: - A = H; - break; - case 0x7D: - A = L; - break; - case 0x7E: - READ(A, HL()); - break; - case 0x7F: - A = A; - break; - case 0x80: - add_a_u8(B); - break; - case 0x81: - add_a_u8(C); - break; - case 0x82: - add_a_u8(D); - break; - case 0x83: - add_a_u8(E); - break; - case 0x84: - add_a_u8(H); - break; - case 0x85: - add_a_u8(L); - break; - case 0x86: - { - unsigned data; - - READ(data, HL()); - - add_a_u8(data); - } - break; - case 0x87: - add_a_u8(A); - break; - case 0x88: - adc_a_u8(B); - break; - case 0x89: - adc_a_u8(C); - break; - case 0x8A: - adc_a_u8(D); - break; - case 0x8B: - adc_a_u8(E); - break; - case 0x8C: - adc_a_u8(H); - break; - case 0x8D: - adc_a_u8(L); - break; - case 0x8E: - { - unsigned data; - - READ(data, HL()); - - adc_a_u8(data); - } - break; - case 0x8F: - adc_a_u8(A); - break; - case 0x90: - sub_a_u8(B); - break; - case 0x91: - sub_a_u8(C); - break; - case 0x92: - sub_a_u8(D); - break; - case 0x93: - sub_a_u8(E); - break; - case 0x94: - sub_a_u8(H); - break; - case 0x95: - sub_a_u8(L); - break; - case 0x96: - { - unsigned data; - - READ(data, HL()); - - sub_a_u8(data); - } - break; - //A-A is always 0: - case 0x97: - HF2 = 0x400; - CF = ZF = A = 0; - break; - case 0x98: - sbc_a_u8(B); - break; - case 0x99: - sbc_a_u8(C); - break; - case 0x9A: - sbc_a_u8(D); - break; - case 0x9B: - sbc_a_u8(E); - break; - case 0x9C: - sbc_a_u8(H); - break; - case 0x9D: - sbc_a_u8(L); - break; - case 0x9E: - { - unsigned data; - - READ(data, HL()); - - sbc_a_u8(data); - } - break; - case 0x9F: - sbc_a_u8(A); - break; - case 0xA0: - and_a_u8(B); - break; - case 0xA1: - and_a_u8(C); - break; - case 0xA2: - and_a_u8(D); - break; - case 0xA3: - and_a_u8(E); - break; - case 0xA4: - and_a_u8(H); - break; - case 0xA5: - and_a_u8(L); - break; - case 0xA6: - { - unsigned data; - - READ(data, HL()); - - and_a_u8(data); - } - break; - //A&A will always be A: - case 0xA7: - ZF = A; - CF = 0; - HF2 = 0x200; - break; - case 0xA8: - xor_a_u8(B); - break; - case 0xA9: - xor_a_u8(C); - break; - case 0xAA: - xor_a_u8(D); - break; - case 0xAB: - xor_a_u8(E); - break; - case 0xAC: - xor_a_u8(H); - break; - case 0xAD: - xor_a_u8(L); - break; - case 0xAE: - { - unsigned data; - - READ(data, HL()); - - xor_a_u8(data); - } - break; - //A^A will always be 0: - case 0xAF: - CF = HF2 = ZF = A = 0; - break; - case 0xB0: - or_a_u8(B); - break; - case 0xB1: - or_a_u8(C); - break; - case 0xB2: - or_a_u8(D); - break; - case 0xB3: - or_a_u8(E); - break; - case 0xB4: - or_a_u8(H); - break; - case 0xB5: - or_a_u8(L); - break; - case 0xB6: - { - unsigned data; - - READ(data, HL()); - - or_a_u8(data); - } - break; - //A|A will always be A: - case 0xB7: - ZF = A; - HF2 = CF = 0; - break; - case 0xB8: - cp_a_u8(B); - break; - case 0xB9: - cp_a_u8(C); - break; - case 0xBA: - cp_a_u8(D); - break; - case 0xBB: - cp_a_u8(E); - break; - case 0xBC: - cp_a_u8(H); - break; - case 0xBD: - cp_a_u8(L); - break; - case 0xBE: - { - unsigned data; - - READ(data, HL()); - - cp_a_u8(data); - } - break; - //A always equals A: - case 0xBF: - CF = ZF = 0; - HF2 = 0x400; - break; - - //ret nz (20;8 cycles): - //Pop two bytes from the stack and jump to that address, if ZF is unset: - case 0xC0: - cycleCounter += 4; - - if (ZF & 0xFF) { - ret(); - } - break; - - case 0xC1: - pop_rr(B, C); - break; - - //jp nz,nn (16;12 cycles): - //Jump to address stored in next two bytes in memory if ZF is unset: - case 0xC2: - if (ZF & 0xFF) { - jp_nn(); - } else { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } - break; - - case 0xC3: - jp_nn(); - break; - - //call nz,nn (24;12 cycles): - //Push address of next instruction onto stack and then jump to address stored in next two bytes in memory, if ZF is unset: - case 0xC4: - if (ZF & 0xFF) { - call_nn(); - } else { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } - break; - - case 0xC5: - push_rr(B, C); - break; - case 0xC6: - { - unsigned data; - - PC_READ(data); - - add_a_u8(data); - } - break; - case 0xC7: - rst_n(0x00); - break; - - //ret z (20;8 cycles): - //Pop two bytes from the stack and jump to that address, if ZF is set: - case 0xC8: - cycleCounter += 4; - - if (!(ZF & 0xFF)) { - ret(); - } - - break; - - //ret (16 cycles): - //Pop two bytes from the stack and jump to that address: - case 0xC9: - ret(); - break; - - //jp z,nn (16;12 cycles): - //Jump to address stored in next two bytes in memory if ZF is set: - case 0xCA: - if (ZF & 0xFF) { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } else { - jp_nn(); - } - break; - - - //CB OPCODES (Shifts, rotates and bits): - case 0xCB: - PC_READ(opcode); - - switch (opcode) { - case 0x00: - rlc_r(B); - break; - case 0x01: - rlc_r(C); - break; - case 0x02: - rlc_r(D); - break; - case 0x03: - rlc_r(E); - break; - case 0x04: - rlc_r(H); - break; - case 0x05: - rlc_r(L); - break; - //rlc (hl) (16 cycles): - //Rotate 8-bit value stored at address in HL left, store old bit7 in CF. Reset SF and HCF. Check ZF: - case 0x06: - { - const unsigned addr = HL(); - - READ(CF, addr); - CF <<= 1; - - ZF = CF | (CF >> 8); - - WRITE(addr, ZF & 0xFF); - - HF2 = 0; - } - break; - case 0x07: - rlc_r(A); - break; - case 0x08: - rrc_r(B); - break; - case 0x09: - rrc_r(C); - break; - case 0x0A: - rrc_r(D); - break; - case 0x0B: - rrc_r(E); - break; - case 0x0C: - rrc_r(H); - break; - case 0x0D: - rrc_r(L); - break; - //rrc (hl) (16 cycles): - //Rotate 8-bit value stored at address in HL right, store old bit0 in CF. Reset SF and HCF. Check ZF: - case 0x0E: - { - const unsigned addr = HL(); - - READ(ZF, addr); - - CF = ZF << 8; - - WRITE(addr, (ZF | CF) >> 1 & 0xFF); - - HF2 = 0; - } - break; - case 0x0F: - rrc_r(A); - break; - case 0x10: - rl_r(B); - break; - case 0x11: - rl_r(C); - break; - case 0x12: - rl_r(D); - break; - case 0x13: - rl_r(E); - break; - case 0x14: - rl_r(H); - break; - case 0x15: - rl_r(L); - break; - //rl (hl) (16 cycles): - //Rotate 8-bit value stored at address in HL left thorugh CF, store old bit7 in CF, old CF value becoms bit0. Reset SF and HCF. Check ZF: - case 0x16: - { - const unsigned addr = HL(); - const unsigned oldcf = CF >> 8 & 1; - - READ(CF, addr); - CF <<= 1; - - ZF = CF | oldcf; - - WRITE(addr, ZF & 0xFF); - - HF2 = 0; - } - break; - case 0x17: - rl_r(A); - break; - case 0x18: - rr_r(B); - break; - case 0x19: - rr_r(C); - break; - case 0x1A: - rr_r(D); - break; - case 0x1B: - rr_r(E); - break; - case 0x1C: - rr_r(H); - break; - case 0x1D: - rr_r(L); - break; - //rr (hl) (16 cycles): - //Rotate 8-bit value stored at address in HL right thorugh CF, store old bit0 in CF, old CF value becoms bit7. Reset SF and HCF. Check ZF: - case 0x1E: - { - const unsigned addr = HL(); - - READ(ZF, addr); - - const unsigned oldcf = CF & 0x100; - CF = ZF << 8; - ZF = (ZF | oldcf) >> 1; - - WRITE(addr, ZF); - - HF2 = 0; - } - break; - case 0x1F: - rr_r(A); - break; - case 0x20: - sla_r(B); - break; - case 0x21: - sla_r(C); - break; - case 0x22: - sla_r(D); - break; - case 0x23: - sla_r(E); - break; - case 0x24: - sla_r(H); - break; - case 0x25: - sla_r(L); - break; - //sla (hl) (16 cycles): - //Shift 8-bit value stored at address in HL left, store old bit7 in CF. Reset SF and HCF. Check ZF: - case 0x26: - { - const unsigned addr = HL(); - - READ(CF, addr); - CF <<= 1; - - ZF = CF; - - WRITE(addr, ZF & 0xFF); - - HF2 = 0; - } - break; - case 0x27: - sla_r(A); - break; - case 0x28: - sra_r(B); - break; - case 0x29: - sra_r(C); - break; - case 0x2A: - sra_r(D); - break; - case 0x2B: - sra_r(E); - break; - case 0x2C: - sra_r(H); - break; - case 0x2D: - sra_r(L); - break; - //sra (hl) (16 cycles): - //Shift 8-bit value stored at address in HL right, store old bit0 in CF, bit7=old bit7. Reset SF and HCF. Check ZF: - case 0x2E: - { - const unsigned addr = HL(); - - READ(CF, addr); - - ZF = CF >> 1; - - WRITE(addr, ZF | (CF & 0x80)); - - CF <<= 8; - HF2 = 0; - } - break; - case 0x2F: - sra_r(A); - break; - case 0x30: - swap_r(B); - break; - case 0x31: - swap_r(C); - break; - case 0x32: - swap_r(D); - break; - case 0x33: - swap_r(E); - break; - case 0x34: - swap_r(H); - break; - case 0x35: - swap_r(L); - break; - //swap (hl) (16 cycles): - //Swap upper and lower nibbles of 8-bit value stored at address in HL, reset flags, check zero flag: - case 0x36: - { - const unsigned addr = HL(); - - READ(ZF, addr); - - WRITE(addr, (ZF << 4 | ZF >> 4) & 0xFF); - - CF = HF2 = 0; - } - break; - case 0x37: - swap_r(A); - break; - case 0x38: - srl_r(B); - break; - case 0x39: - srl_r(C); - break; - case 0x3A: - srl_r(D); - break; - case 0x3B: - srl_r(E); - break; - case 0x3C: - srl_r(H); - break; - case 0x3D: - srl_r(L); - break; - //srl (hl) (16 cycles): - //Shift 8-bit value stored at address in HL right, store old bit0 in CF. Reset SF and HCF. Check ZF: - case 0x3E: - { - const unsigned addr = HL(); - - READ(CF, addr); - - ZF = CF >> 1; - - WRITE(addr, ZF); - - CF <<= 8; - HF2 = 0; - } - break; - case 0x3F: - srl_r(A); - break; - case 0x40: - bit0_u8(B); - break; - case 0x41: - bit0_u8(C); - break; - case 0x42: - bit0_u8(D); - break; - case 0x43: - bit0_u8(E); - break; - case 0x44: - bit0_u8(H); - break; - case 0x45: - bit0_u8(L); - break; - case 0x46: - { - unsigned data; - - READ(data, HL()); - - bit0_u8(data); - } - break; - case 0x47: - bit0_u8(A); - break; - case 0x48: - bit1_u8(B); - break; - case 0x49: - bit1_u8(C); - break; - case 0x4A: - bit1_u8(D); - break; - case 0x4B: - bit1_u8(E); - break; - case 0x4C: - bit1_u8(H); - break; - case 0x4D: - bit1_u8(L); - break; - case 0x4E: - { - unsigned data; - - READ(data, HL()); - - bit1_u8(data); - } - break; - case 0x4F: - bit1_u8(A); - break; - case 0x50: - bit2_u8(B); - break; - case 0x51: - bit2_u8(C); - break; - case 0x52: - bit2_u8(D); - break; - case 0x53: - bit2_u8(E); - break; - case 0x54: - bit2_u8(H); - break; - case 0x55: - bit2_u8(L); - break; - case 0x56: - { - unsigned data; - - READ(data, HL()); - - bit2_u8(data); - } - break; - case 0x57: - bit2_u8(A); - break; - case 0x58: - bit3_u8(B); - break; - case 0x59: - bit3_u8(C); - break; - case 0x5A: - bit3_u8(D); - break; - case 0x5B: - bit3_u8(E); - break; - case 0x5C: - bit3_u8(H); - break; - case 0x5D: - bit3_u8(L); - break; - case 0x5E: - { - unsigned data; - - READ(data, HL()); - - bit3_u8(data); - } - break; - case 0x5F: - bit3_u8(A); - break; - case 0x60: - bit4_u8(B); - break; - case 0x61: - bit4_u8(C); - break; - case 0x62: - bit4_u8(D); - break; - case 0x63: - bit4_u8(E); - break; - case 0x64: - bit4_u8(H); - break; - case 0x65: - bit4_u8(L); - break; - case 0x66: - { - unsigned data; - - READ(data, HL()); - - bit4_u8(data); - } - break; - case 0x67: - bit4_u8(A); - break; - case 0x68: - bit5_u8(B); - break; - case 0x69: - bit5_u8(C); - break; - case 0x6A: - bit5_u8(D); - break; - case 0x6B: - bit5_u8(E); - break; - case 0x6C: - bit5_u8(H); - break; - case 0x6D: - bit5_u8(L); - break; - case 0x6E: - { - unsigned data; - - READ(data, HL()); - - bit5_u8(data); - } - break; - case 0x6F: - bit5_u8(A); - break; - case 0x70: - bit6_u8(B); - break; - case 0x71: - bit6_u8(C); - break; - case 0x72: - bit6_u8(D); - break; - case 0x73: - bit6_u8(E); - break; - case 0x74: - bit6_u8(H); - break; - case 0x75: - bit6_u8(L); - break; - case 0x76: - { - unsigned data; - - READ(data, HL()); - - bit6_u8(data); - } - break; - case 0x77: - bit6_u8(A); - break; - case 0x78: - bit7_u8(B); - break; - case 0x79: - bit7_u8(C); - break; - case 0x7A: - bit7_u8(D); - break; - case 0x7B: - bit7_u8(E); - break; - case 0x7C: - bit7_u8(H); - break; - case 0x7D: - bit7_u8(L); - break; - case 0x7E: - { - unsigned data; - - READ(data, HL()); - - bit7_u8(data); - } - break; - case 0x7F: - bit7_u8(A); - break; - case 0x80: - res0_r(B); - break; - case 0x81: - res0_r(C); - break; - case 0x82: - res0_r(D); - break; - case 0x83: - res0_r(E); - break; - case 0x84: - res0_r(H); - break; - case 0x85: - res0_r(L); - break; - case 0x86: - resn_mem_hl(0); - break; - case 0x87: - res0_r(A); - break; - case 0x88: - res1_r(B); - break; - case 0x89: - res1_r(C); - break; - case 0x8A: - res1_r(D); - break; - case 0x8B: - res1_r(E); - break; - case 0x8C: - res1_r(H); - break; - case 0x8D: - res1_r(L); - break; - case 0x8E: - resn_mem_hl(1); - break; - case 0x8F: - res1_r(A); - break; - case 0x90: - res2_r(B); - break; - case 0x91: - res2_r(C); - break; - case 0x92: - res2_r(D); - break; - case 0x93: - res2_r(E); - break; - case 0x94: - res2_r(H); - break; - case 0x95: - res2_r(L); - break; - case 0x96: - resn_mem_hl(2); - break; - case 0x97: - res2_r(A); - break; - case 0x98: - res3_r(B); - break; - case 0x99: - res3_r(C); - break; - case 0x9A: - res3_r(D); - break; - case 0x9B: - res3_r(E); - break; - case 0x9C: - res3_r(H); - break; - case 0x9D: - res3_r(L); - break; - case 0x9E: - resn_mem_hl(3); - break; - case 0x9F: - res3_r(A); - break; - case 0xA0: - res4_r(B); - break; - case 0xA1: - res4_r(C); - break; - case 0xA2: - res4_r(D); - break; - case 0xA3: - res4_r(E); - break; - case 0xA4: - res4_r(H); - break; - case 0xA5: - res4_r(L); - break; - case 0xA6: - resn_mem_hl(4); - break; - case 0xA7: - res4_r(A); - break; - case 0xA8: - res5_r(B); - break; - case 0xA9: - res5_r(C); - break; - case 0xAA: - res5_r(D); - break; - case 0xAB: - res5_r(E); - break; - case 0xAC: - res5_r(H); - break; - case 0xAD: - res5_r(L); - break; - case 0xAE: - resn_mem_hl(5); - break; - case 0xAF: - res5_r(A); - break; - case 0xB0: - res6_r(B); - break; - case 0xB1: - res6_r(C); - break; - case 0xB2: - res6_r(D); - break; - case 0xB3: - res6_r(E); - break; - case 0xB4: - res6_r(H); - break; - case 0xB5: - res6_r(L); - break; - case 0xB6: - resn_mem_hl(6); - break; - case 0xB7: - res6_r(A); - break; - case 0xB8: - res7_r(B); - break; - case 0xB9: - res7_r(C); - break; - case 0xBA: - res7_r(D); - break; - case 0xBB: - res7_r(E); - break; - case 0xBC: - res7_r(H); - break; - case 0xBD: - res7_r(L); - break; - case 0xBE: - resn_mem_hl(7); - break; - case 0xBF: - res7_r(A); - break; - case 0xC0: - set0_r(B); - break; - case 0xC1: - set0_r(C); - break; - case 0xC2: - set0_r(D); - break; - case 0xC3: - set0_r(E); - break; - case 0xC4: - set0_r(H); - break; - case 0xC5: - set0_r(L); - break; - case 0xC6: - setn_mem_hl(0); - break; - case 0xC7: - set0_r(A); - break; - case 0xC8: - set1_r(B); - break; - case 0xC9: - set1_r(C); - break; - case 0xCA: - set1_r(D); - break; - case 0xCB: - set1_r(E); - break; - case 0xCC: - set1_r(H); - break; - case 0xCD: - set1_r(L); - break; - case 0xCE: - setn_mem_hl(1); - break; - case 0xCF: - set1_r(A); - break; - case 0xD0: - set2_r(B); - break; - case 0xD1: - set2_r(C); - break; - case 0xD2: - set2_r(D); - break; - case 0xD3: - set2_r(E); - break; - case 0xD4: - set2_r(H); - break; - case 0xD5: - set2_r(L); - break; - case 0xD6: - setn_mem_hl(2); - break; - case 0xD7: - set2_r(A); - break; - case 0xD8: - set3_r(B); - break; - case 0xD9: - set3_r(C); - break; - case 0xDA: - set3_r(D); - break; - case 0xDB: - set3_r(E); - break; - case 0xDC: - set3_r(H); - break; - case 0xDD: - set3_r(L); - break; - case 0xDE: - setn_mem_hl(3); - break; - case 0xDF: - set3_r(A); - break; - case 0xE0: - set4_r(B); - break; - case 0xE1: - set4_r(C); - break; - case 0xE2: - set4_r(D); - break; - case 0xE3: - set4_r(E); - break; - case 0xE4: - set4_r(H); - break; - case 0xE5: - set4_r(L); - break; - case 0xE6: - setn_mem_hl(4); - break; - case 0xE7: - set4_r(A); - break; - case 0xE8: - set5_r(B); - break; - case 0xE9: - set5_r(C); - break; - case 0xEA: - set5_r(D); - break; - case 0xEB: - set5_r(E); - break; - case 0xEC: - set5_r(H); - break; - case 0xED: - set5_r(L); - break; - case 0xEE: - setn_mem_hl(5); - break; - case 0xEF: - set5_r(A); - break; - case 0xF0: - set6_r(B); - break; - case 0xF1: - set6_r(C); - break; - case 0xF2: - set6_r(D); - break; - case 0xF3: - set6_r(E); - break; - case 0xF4: - set6_r(H); - break; - case 0xF5: - set6_r(L); - break; - case 0xF6: - setn_mem_hl(6); - break; - case 0xF7: - set6_r(A); - break; - case 0xF8: - set7_r(B); - break; - case 0xF9: - set7_r(C); - break; - case 0xFA: - set7_r(D); - break; - case 0xFB: - set7_r(E); - break; - case 0xFC: - set7_r(H); - break; - case 0xFD: - set7_r(L); - break; - case 0xFE: - setn_mem_hl(7); - break; - case 0xFF: - set7_r(A); - break; -// default: break; - } - break; - - - //call z,nn (24;12 cycles): - //Push address of next instruction onto stack and then jump to address stored in next two bytes in memory, if ZF is set: - case 0xCC: - if (ZF & 0xFF) { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } else { - call_nn(); - } - break; - - case 0xCD: - call_nn(); - break; - case 0xCE: - { - unsigned data; - - PC_READ(data); - - adc_a_u8(data); - } - break; - case 0xCF: - rst_n(0x08); - break; - - //ret nc (20;8 cycles): - //Pop two bytes from the stack and jump to that address, if CF is unset: - case 0xD0: - cycleCounter += 4; - - if (!(CF & 0x100)) { - ret(); - } - - break; - - case 0xD1: - pop_rr(D, E); - break; - - //jp nc,nn (16;12 cycles): - //Jump to address stored in next two bytes in memory if CF is unset: - case 0xD2: - if (CF & 0x100) { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } else { - jp_nn(); - } - break; - - case 0xD3: /*doesn't exist*/ - break; - - //call nc,nn (24;12 cycles): - //Push address of next instruction onto stack and then jump to address stored in next two bytes in memory, if CF is unset: - case 0xD4: - if (CF & 0x100) { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } else { - call_nn(); - } - break; - - case 0xD5: - push_rr(D, E); - break; - case 0xD6: - { - unsigned data; - - PC_READ(data); - - sub_a_u8(data); - } - break; - case 0xD7: - rst_n(0x10); - break; - - //ret c (20;8 cycles): - //Pop two bytes from the stack and jump to that address, if CF is set: - case 0xD8: - cycleCounter += 4; - - if (CF & 0x100) { - ret(); - } - - break; - - //reti (16 cycles): - //Pop two bytes from the stack and jump to that address, then enable interrupts: - case 0xD9: - { - unsigned l, h; - - pop_rr(h, l); - - memory.ei(cycleCounter); - - PC_MOD(h << 8 | l); - } - break; - - //jp c,nn (16;12 cycles): - //Jump to address stored in next two bytes in memory if CF is set: - case 0xDA: //PC=( ((PC+2)*(1-CarryFlag())) + (((memory.read(PC+1)<<8)+memory.read(PC))*CarryFlag()) ); Cycles(12); break; - if (CF & 0x100) { - jp_nn(); - } else { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } - break; - - case 0xDB: /*doesn't exist*/ - break; - - //call z,nn (24;12 cycles): - //Push address of next instruction onto stack and then jump to address stored in next two bytes in memory, if CF is set: - case 0xDC: - if (CF & 0x100) { - call_nn(); - } else { - PC_MOD((PC + 2) & 0xFFFF); - cycleCounter += 4; - } - break; - - case 0xDE: - { - unsigned data; - - PC_READ(data); - - sbc_a_u8(data); - } - break; - case 0xDF: - rst_n(0x18); - break; - - //ld ($FF00+n),a (12 cycles): - //Put value in A into address (0xFF00 + next byte in memory): - case 0xE0: - { - unsigned tmp; - - PC_READ(tmp); - - FF_WRITE(0xFF00 | tmp, A); - } - break; - - case 0xE1: - pop_rr(H, L); - break; - - //ld ($FF00+C),a (8 ycles): - //Put A into address (0xFF00 + register C): - case 0xE2: - FF_WRITE(0xFF00 | C, A); - break; - case 0xE3: /*doesn't exist*/ - break; - case 0xE4: /*doesn't exist*/ - break; - case 0xE5: - push_rr(H, L); - break; - case 0xE6: - { - unsigned data; - - PC_READ(data); - - and_a_u8(data); - } - break; - case 0xE7: - rst_n(0x20); - break; - - //add sp,n (16 cycles): - //Add next (signed) byte in memory to SP, reset ZF and SF, check HCF and CF: - case 0xE8: - /*{ - int8_t tmp = int8_t(memory.pc_read(PC++, cycleCounter)); - HF2 = (((SP & 0xFFF) + tmp) >> 3) & 0x200; - CF = SP + tmp; - SP = CF; - CF >>= 8; - ZF = 1; - cycleCounter += 12; - }*/ - sp_plus_n(SP); - cycleCounter += 4; - break; - - //jp hl (4 cycles): - //Jump to address in hl: - case 0xE9: - PC = HL(); - break; - - //ld (nn),a (16 cycles): - //set memory at address given by the next 2 bytes to value in A: - //Incrementing PC before call, because of possible interrupt. - case 0xEA: - { - unsigned l, h; - - PC_READ(l); - PC_READ(h); - - WRITE(h << 8 | l, A); - } - break; - - case 0xEB: /*doesn't exist*/ - break; - case 0xEC: /*doesn't exist*/ - break; - case 0xED: /*doesn't exist*/ - break; - case 0xEE: - { - unsigned data; - - PC_READ(data); - - xor_a_u8(data); - } - break; - case 0xEF: - rst_n(0x28); - break; - - //ld a,($FF00+n) (12 cycles): - //Put value at address (0xFF00 + next byte in memory) into A: - case 0xF0: - { - unsigned tmp; - - PC_READ(tmp); - - FF_READ(A, 0xFF00 | tmp); - } - break; - - case 0xF1: /*pop_rr(A, F); Cycles(12); break;*/ - { - unsigned F; - - pop_rr(A, F); - - FROM_F(F); - } - break; - - //ld a,($FF00+C) (8 cycles): - //Put value at address (0xFF00 + register C) into A: - case 0xF2: - FF_READ(A, 0xFF00 | C); - break; - - //di (4 cycles): - case 0xF3: - memory.di(); - break; - - case 0xF4: /*doesn't exist*/ - break; - case 0xF5: /*push_rr(A, F); Cycles(16); break;*/ - calcHF(HF1, HF2); - - { - unsigned F = F(); - - push_rr(A, F); - } - break; - - case 0xF6: - { - unsigned data; - - PC_READ(data); - - or_a_u8(data); - } - break; - case 0xF7: - rst_n(0x30); - break; - - //ldhl sp,n (12 cycles): - //Put (sp+next (signed) byte in memory) into hl (unsets ZF and SF, may enable HF and CF): - case 0xF8: - /*{ - int8_t tmp = int8_t(memory.pc_read(PC++, cycleCounter)); - HF2 = (((SP & 0xFFF) + tmp) >> 3) & 0x200; - CF = SP + tmp; - L = CF; - CF >>= 8; - H = CF; - ZF = 1; - cycleCounter += 8; - }*/ - { - unsigned sum; - sp_plus_n(sum); - L = sum & 0xFF; - H = sum >> 8; - } - break; - - //ld sp,hl (8 cycles): - //Put value in HL into SP - case 0xF9: - SP = HL(); - cycleCounter += 4; - break; - - //ld a,(nn) (16 cycles): - //set A to value in memory at address given by the 2 next bytes. - case 0xFA: - { - unsigned l, h; - - PC_READ(l); - PC_READ(h); - - READ(A, h << 8 | l); - } - break; - - //ei (4 cycles): - //Enable Interrupts after next instruction: - case 0xFB: - memory.ei(cycleCounter); - break; - - case 0xFC: /*doesn't exist*/ - break; - case 0xFD: /*doesn't exist*/ - break; - case 0xFE: - { - unsigned data; - - PC_READ(data); - - cp_a_u8(data); - } - break; - case 0xFF: - rst_n(0x38); - break; -// default: break; - } - } - - PC_ = PC; - cycleCounter = memory.event(cycleCounter); - } - - A_ = A; - cycleCounter_ = cycleCounter; -} diff --git a/src/lib/libgambatte/src/cpu.h b/src/lib/libgambatte/src/cpu.h deleted file mode 100644 index 985b6771..00000000 --- a/src/lib/libgambatte/src/cpu.h +++ /dev/null @@ -1,117 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CPU_H -#define CPU_H - -class SaveState; - -#include "int.h" -#include "memory.h" - -class CPU { - Memory memory; - - unsigned long cycleCounter_; - - unsigned short PC_; - unsigned short SP; - - unsigned HF1, HF2, ZF, CF; - - unsigned char A_, B, C, D, E, /*F,*/ H, L; - - bool skip; - bool halted; - - void process(unsigned long cycles); - -public: - - CPU(); -// void halt(); - -// unsigned interrupt(unsigned address, unsigned cycleCounter); - - void runFor(unsigned long cycles); - void updateVideo(); - unsigned lyCounter(); - void setStatePtrs(SaveState &state); - void saveState(SaveState &state); - void loadState(const SaveState &state); - - void loadSavedata() { memory.loadSavedata(); } - void saveSavedata() { memory.saveSavedata(); } - - void setVideoBlitter(Gambatte::VideoBlitter *vb) { - memory.setVideoBlitter(vb); - } - - void videoBufferChange() { - memory.videoBufferChange(); - } - - unsigned int videoWidth() const { - return memory.videoWidth(); - } - - unsigned int videoHeight() const { - return memory.videoHeight(); - } - - void setVideoFilter(const unsigned int n) { - memory.setVideoFilter(n); - } - - std::vector filterInfo() const { - return memory.filterInfo(); - } - - void setInputStateGetter(Gambatte::InputStateGetter *getInput) { - memory.setInputStateGetter(getInput); - } - - void setMemoryInterface(Gambatte::MemoryInterface *memoryInterface) { - memory.setMemoryInterface(memoryInterface); - } - - void set_savedir(const char *sdir) { - memory.set_savedir(sdir); - } - - const std::string saveBasePath() const { - return memory.saveBasePath(); - } - - void setOsdElement(std::auto_ptr osdElement) { - memory.setOsdElement(osdElement); - } - - bool load(bool forceDmg); - - void setSoundBuffer(Gambatte::uint_least32_t *const buf) { memory.setSoundBuffer(buf); } - unsigned fillSoundBuffer() { return memory.fillSoundBuffer(cycleCounter_); } - - bool isCgb() const { return memory.isCgb(); } - - void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) { - memory.setDmgPaletteColor(palNum, colorNum, rgb32); - } -}; - -#endif diff --git a/src/lib/libgambatte/src/event_queue.h b/src/lib/libgambatte/src/event_queue.h deleted file mode 100644 index 94fbebcf..00000000 --- a/src/lib/libgambatte/src/event_queue.h +++ /dev/null @@ -1,160 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#ifndef EVENT_QUEUE_H -#define EVENT_QUEUE_H - -#include - -template -class event_queue { - Comparer comparer; - T *const a; - const std::size_t capacity_; - std::size_t size_; - - - std::size_t indexOf(T e); - void internalDec(std::size_t i, T e); - template void internalInc(std::size_t i, T e); - -public: - event_queue(std::size_t capacity, const Comparer &comparer); - ~event_queue(); - - std::size_t capacity() const { - return capacity_; - } - - void clear() { - size_ = 0; - } - - void dec(const T oldE, const T newE) { - internalDec(indexOf(oldE), newE); - } - - bool empty() const { - return size_ == 0; - } - - void inc(const T oldE, const T newE) { - internalInc(indexOf(oldE), newE); - } - - void modify_root(const T newRoot) { - internalInc(0, newRoot); - } - - void pop() { - internalInc(0, a[--size_]); - } - - void push(const T e) { - internalDec(size_++, e); - } - - void remove(T e); - - std::size_t size() const { - return size_; - } - - T top() const { - return a[0]; - } -}; - -template -event_queue::event_queue(const std::size_t capacity, const Comparer &comparer_in) : - comparer(comparer_in), - a(new T[capacity]), - capacity_(capacity), - size_(0) -{} - -template -event_queue::~event_queue() { - delete[] a; -} - -template -std::size_t event_queue::indexOf(const T e) { - std::size_t i = 0; - - while (a[i] != e) - ++i; - - return i; -} - -template -void event_queue::internalDec(std::size_t i, const T e) { - a[i] = e; - - while (i != 0) { - const std::size_t parentI = (i - 1) >> 1; - - if (!comparer.less(e, a[parentI])) - break; - - a[i] = a[parentI]; - a[parentI] = e; - i = parentI; - } -} - -template -template -void event_queue::internalInc(std::size_t i, const T e) { - a[i] = e; - - for (;;) { - std::size_t childI = i * 2 + 1; - - if (childI >= size_) - break; - - if ((!child2BoundsCheck || childI + 1 < size_) && comparer.less(a[childI + 1], a[childI])) - ++childI; - - if (!comparer.less(a[childI], e)) - break; - - a[i] = a[childI]; - a[childI] = e; - i = childI; - } -} - -template -void event_queue::remove(const T e) { - std::size_t i = indexOf(e); - - while (i != 0) { - const std::size_t parentI = (i - 1) >> 1; - - a[i] = a[parentI]; - a[parentI] = e; - i = parentI; - } - - pop(); -} - -#endif diff --git a/src/lib/libgambatte/src/file/file.cpp b/src/lib/libgambatte/src/file/file.cpp deleted file mode 100644 index 7a8f9966..00000000 --- a/src/lib/libgambatte/src/file/file.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** -Copyright (C) 2007 by Nach -http://nsrt.edgeemu.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License version 2 for more details. - -You should have received a copy of the GNU General Public License -version 2 along with this program; if not, write to the -Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -***************************************************************************/ - -#include "file.h" - -using namespace std; - -static const unsigned int MAX_FILE_NAME = 512; - -File::File(const char *filename) : stream(filename, ios::in | ios::binary), is_zip(false), fsize(0), count(0) -{ - if (stream) - { - stream.seekg(0, ios::end); - fsize = stream.tellg(); - stream.seekg(0, ios::beg); - } -} - -File::~File() -{ - close(); -} - -void File::rewind() -{ - if (is_open()) - { - stream.seekg(0, ios::beg); - } -} - -bool File::is_open() -{ - return(stream.is_open()); -} - -void File::close() -{ - if (is_open()) - { - stream.close(); - } -} - -void File::read(char *buffer, size_t amount) -{ - if (is_open()) - { - stream.read(buffer, amount); - count = stream.gcount(); - } - else - { - count = 0; - } -} diff --git a/src/lib/libgambatte/src/file/file.h b/src/lib/libgambatte/src/file/file.h deleted file mode 100644 index 3435ef16..00000000 --- a/src/lib/libgambatte/src/file/file.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************** -Copyright (C) 2007 by Nach -http://nsrt.edgeemu.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License version 2 for more details. - -You should have received a copy of the GNU General Public License -version 2 along with this program; if not, write to the -Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -***************************************************************************/ - -#include - -class File { - private: - std::ifstream stream; - bool is_zip; //Change this to an enum later - std::size_t fsize, count; - void *zipfile; - bool zip_sub_open; - - void zip(const char *filename); - - public: - File(const char *filename); - ~File(); - void rewind(); - bool is_open(); - void close(); - std::size_t size() const { return fsize; }; - void read(char *buffer, std::size_t amount); - std::size_t gcount() const { return count; } - bool fail() const { return stream.fail(); } -}; diff --git a/src/lib/libgambatte/src/file/file_zip.cpp b/src/lib/libgambatte/src/file/file_zip.cpp deleted file mode 100644 index c7fae6db..00000000 --- a/src/lib/libgambatte/src/file/file_zip.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** -Copyright (C) 2007 by Nach -http://nsrt.edgeemu.com - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License version 2 as -published by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License version 2 for more details. - -You should have received a copy of the GNU General Public License -version 2 along with this program; if not, write to the -Free Software Foundation, Inc., -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -***************************************************************************/ - -#include "file.h" - -#include - -namespace zlib { -#include "unzip/unzip.h" -} - -using namespace std; -using namespace zlib; - -static const unsigned int MAX_FILE_NAME = 512; - -File::File(const char *filename) : stream(filename, ios::in | ios::binary), is_zip(false), fsize(0), count(0) -{ - if (stream) - { - char temp[4]; - stream.read(temp, sizeof(temp)); - - //check for standard zip 'magic number' - if ((temp[0] == 'P') && (temp[1] == 'K') && (temp[2] == 3) && (temp[3] == 4)) - { - stream.close(); - is_zip = true; - zip(filename); - } - else - { - stream.seekg(0, ios::end); - fsize = stream.tellg(); - stream.seekg(0, ios::beg); - } - } -} - -void File::zip(const char *filename) -{ - zipfile = unzOpen(filename); - if (zipfile) - { - zip_sub_open = false; - - unz_file_info cFileInfo; - char ourFile[MAX_FILE_NAME] = { '\n' }; - - for (int cFile = unzGoToFirstFile((unzFile)zipfile); cFile == UNZ_OK; cFile = unzGoToNextFile((unzFile)zipfile)) - { - //Temporary char array for file name - char cFileName[MAX_FILE_NAME]; - - //Gets info on current file, and places it in cFileInfo - unzGetCurrentFileInfo((unzFile)zipfile, &cFileInfo, cFileName, MAX_FILE_NAME, 0, 0, 0, 0); - - //Check for largest file which should be the ROM - if ((size_t)cFileInfo.uncompressed_size > fsize) - { - strcpy(ourFile, cFileName); - fsize = (size_t)cFileInfo.uncompressed_size; - } - } - - if (ourFile[0] != '\n') - { - //Sets current file to the file we liked before - unzLocateFile((unzFile)zipfile, ourFile, 1); - - if (unzOpenCurrentFile((unzFile)zipfile) == UNZ_OK) - { - zip_sub_open = true; - } - } - - if (!zip_sub_open) - { - unzClose((unzFile)zipfile); - zipfile = 0; - } - } -} - -File::~File() -{ - close(); -} - -void File::rewind() -{ - if (is_open()) - { - if (!is_zip) - { - stream.seekg(0, ios::beg); - } - else - { - unzCloseCurrentFile((unzFile)zipfile); - unzOpenCurrentFile((unzFile)zipfile); - } - } -} - -bool File::is_open() -{ - if (!is_zip) - { - return(stream.is_open()); - } - return(zipfile && zip_sub_open); -} - -void File::close() -{ - if (is_open()) - { - if (!is_zip) - { - stream.close(); - } - else - { - unzOpenCurrentFile((unzFile)zipfile); - unzClose((unzFile)zipfile); - zipfile = 0; - zip_sub_open = false; - } - } -} - -void File::read(char *buffer, size_t amount) -{ - if (is_open()) - { - if (!is_zip) - { - stream.read(buffer, amount); - count = stream.gcount(); - } - else - { - count = (size_t)unzReadCurrentFile((unzFile)zipfile, buffer, amount); - } - } - else - { - count = 0; - } -} diff --git a/src/lib/libgambatte/src/file/unzip/crypt.h b/src/lib/libgambatte/src/file/unzip/crypt.h deleted file mode 100644 index 622f4bc2..00000000 --- a/src/lib/libgambatte/src/file/unzip/crypt.h +++ /dev/null @@ -1,132 +0,0 @@ -/* crypt.h -- base code for crypt/uncrypt ZIPfile - - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This code is a modified version of crypting code in Infozip distribution - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - - If you don't need crypting in your application, just define symbols - NOCRYPT and NOUNCRYPT. - - This code support the "Traditional PKWARE Encryption". - - The new AES encryption added on Zip format by Winzip (see the page - http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong - Encryption is not supported. -*/ - -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - -/*********************************************************************** - * Return the next byte in the pseudo-random sequence - */ -static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) -{ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -/*********************************************************************** - * Update the encryption keys with the next byte of plain text - */ -static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) -{ - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; -} - - -/*********************************************************************** - * Initialize the encryption keys and the random header according to - * the given password. - */ -static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) -{ - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } -} - -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) - -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) - -#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED - -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif - -static int crypthead(passwd, buf, bufSize, pkeys, pcrc_32_tab, crcForCrypting) - const char *passwd; /* password string */ - unsigned char *buf; /* where to write header */ - int bufSize; - unsigned long* pkeys; - const unsigned long* pcrc_32_tab; - unsigned long crcForCrypting; -{ - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ - - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; -} - -#endif diff --git a/src/lib/libgambatte/src/file/unzip/ioapi.c b/src/lib/libgambatte/src/file/unzip/ioapi.c deleted file mode 100644 index 05b5ef15..00000000 --- a/src/lib/libgambatte/src/file/unzip/ioapi.c +++ /dev/null @@ -1,177 +0,0 @@ -/* ioapi.c -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#include -#include -#include - -#include -#include "ioapi.h" - - - -/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - -#ifndef SEEK_CUR -#define SEEK_CUR 1 -#endif - -#ifndef SEEK_END -#define SEEK_END 2 -#endif - -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif - -voidpf ZCALLBACK fopen_file_func OF(( - voidpf opaque, - const char* filename, - int mode)); - -uLong ZCALLBACK fread_file_func OF(( - voidpf opaque, - voidpf stream, - void* buf, - uLong size)); - -uLong ZCALLBACK fwrite_file_func OF(( - voidpf opaque, - voidpf stream, - const void* buf, - uLong size)); - -long ZCALLBACK ftell_file_func OF(( - voidpf opaque, - voidpf stream)); - -long ZCALLBACK fseek_file_func OF(( - voidpf opaque, - voidpf stream, - uLong offset, - int origin)); - -int ZCALLBACK fclose_file_func OF(( - voidpf opaque, - voidpf stream)); - -int ZCALLBACK ferror_file_func OF(( - voidpf opaque, - voidpf stream)); - - -voidpf ZCALLBACK fopen_file_func (opaque, filename, mode) - voidpf opaque; - const char* filename; - int mode; -{ - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; - - if ((filename!=NULL) && (mode_fopen != NULL)) - file = fopen(filename, mode_fopen); - return file; -} - - -uLong ZCALLBACK fread_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - void* buf; - uLong size; -{ - uLong ret; - ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - - -uLong ZCALLBACK fwrite_file_func (opaque, stream, buf, size) - voidpf opaque; - voidpf stream; - const void* buf; - uLong size; -{ - uLong ret; - ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); - return ret; -} - -long ZCALLBACK ftell_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - long ret; - ret = ftell((FILE *)stream); - return ret; -} - -long ZCALLBACK fseek_file_func (opaque, stream, offset, origin) - voidpf opaque; - voidpf stream; - uLong offset; - int origin; -{ - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; - fseek((FILE *)stream, offset, fseek_origin); - return ret; -} - -int ZCALLBACK fclose_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - int ret; - ret = fclose((FILE *)stream); - return ret; -} - -int ZCALLBACK ferror_file_func (opaque, stream) - voidpf opaque; - voidpf stream; -{ - int ret; - ret = ferror((FILE *)stream); - return ret; -} - -void fill_fopen_filefunc (pzlib_filefunc_def) - zlib_filefunc_def* pzlib_filefunc_def; -{ - pzlib_filefunc_def->zopen_file = fopen_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell_file = ftell_file_func; - pzlib_filefunc_def->zseek_file = fseek_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; -} diff --git a/src/lib/libgambatte/src/file/unzip/ioapi.h b/src/lib/libgambatte/src/file/unzip/ioapi.h deleted file mode 100644 index 7d457baa..00000000 --- a/src/lib/libgambatte/src/file/unzip/ioapi.h +++ /dev/null @@ -1,75 +0,0 @@ -/* ioapi.h -- IO base function header for compress/uncompress .zip - files using zlib + zip or unzip API - - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant -*/ - -#ifndef _ZLIBIOAPI_H -#define _ZLIBIOAPI_H - - -#define ZLIB_FILEFUNC_SEEK_CUR (1) -#define ZLIB_FILEFUNC_SEEK_END (2) -#define ZLIB_FILEFUNC_SEEK_SET (0) - -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) -#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) - -#define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - - -#ifndef ZCALLBACK - -#if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) -#define ZCALLBACK CALLBACK -#else -#define ZCALLBACK -#endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); - -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; - - - -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -#define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) -#define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) -#define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) -#define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) -#define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) - - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/lib/libgambatte/src/file/unzip/unzip.c b/src/lib/libgambatte/src/file/unzip/unzip.c deleted file mode 100644 index 325f3d08..00000000 --- a/src/lib/libgambatte/src/file/unzip/unzip.c +++ /dev/null @@ -1,1605 +0,0 @@ -/* unzip.c -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - Read unzip.h for more info -*/ - -/* Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of -compatibility with older software. The following is from the original crypt.c. Code -woven in by Terry Thorsen 1/2003. -*/ -/* - Copyright (c) 1990-2000 Info-ZIP. All rights reserved. - - See the accompanying file LICENSE, version 2000-Apr-09 or later - (the contents of which are also included in zip.h) for terms of use. - If, for some reason, all these files are missing, the Info-ZIP license - also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html -*/ -/* - crypt.c (full version) by Info-ZIP. Last revised: [see crypt.h] - - The encryption/decryption parts of this source code (as opposed to the - non-echoing password parts) were originally written in Europe. The - whole source package can be freely distributed, including from the USA. - (Prior to January 2000, re-export from the US was a violation of US law.) - */ - -/* - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). - */ - - -#include -#include -#include -#include -#include "unzip.h" - -#ifdef STDC -# include -# include -# include -#endif -#ifdef NO_ERRNO_H - extern int errno; -#else -# include -#endif - - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - - -#ifndef CASESENSITIVITYDEFAULT_NO -# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) -# define CASESENSITIVITYDEFAULT_NO -# endif -#endif - - -#ifndef UNZ_BUFSIZE -#define UNZ_BUFSIZE (16384) -#endif - -#ifndef UNZ_MAXFILENAMEINZIP -#define UNZ_MAXFILENAMEINZIP (256) -#endif - -#ifndef ALLOC -# define ALLOC(size) (malloc(size)) -#endif -#ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} -#endif - -#define SIZECENTRALDIRITEM (0x2e) -#define SIZEZIPLOCALHEADER (0x1e) - - - - -const char unz_copyright[] = - " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; - -/* unz_file_info_interntal contain internal info about a file in zipfile*/ -typedef struct unz_file_info_internal_s -{ - uLong offset_curfile;/* relative offset of local header 4 bytes */ -} unz_file_info_internal; - - -/* file_in_zip_read_info_s contain internal information about a file in zipfile, - when reading and decompress it */ -typedef struct -{ - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ - - uLong pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ - uLong stream_initialised; /* flag set if stream structure is initialised*/ - - uLong offset_local_extrafield;/* offset of the local extra field */ - uInt size_local_extrafield;/* size of the local extra field */ - uLong pos_local_extrafield; /* position in the local extra field in read*/ - - uLong crc32; /* crc32 of all data uncompressed */ - uLong crc32_wait; /* crc32 we must obtain after decompress all */ - uLong rest_read_compressed; /* number of byte to be decompressed */ - uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - uLong compression_method; /* compression method (0==store) */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - int raw; -} file_in_zip_read_info_s; - - -/* unz_s contain internal information about the zipfile -*/ -typedef struct -{ - zlib_filefunc_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - unz_global_info gi; /* public global information */ - uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - uLong num_file; /* number of the current file in the zipfile*/ - uLong pos_in_central_dir; /* pos of the current file in the central dir*/ - uLong current_file_ok; /* flag about the usability of the current file*/ - uLong central_pos; /* position of the beginning of the central dir*/ - - uLong size_central_dir; /* size of the central directory */ - uLong offset_central_dir; /* offset of start of central directory with - respect to the starting disk number */ - - unz_file_info cur_file_info; /* public info about the current file in zip*/ - unz_file_info_internal cur_file_info_internal; /* private info about it*/ - file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current - file if we are decompressing it */ - int encrypted; -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; -# endif -} unz_s; - - -#ifndef NOUNCRYPT -#include "crypt.h" -#endif - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ - - -local int unzlocal_getByte OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); - -local int unzlocal_getByte(pzlib_filefunc_def,filestream,pi) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - int *pi; -{ - unsigned char c; - int err = (int)ZREAD(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return UNZ_OK; - } - else - { - if (ZERROR(*pzlib_filefunc_def,filestream)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } -} - - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets -*/ -local int unzlocal_getShort OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i = 0; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - -local int unzlocal_getLong OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); - -local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; - uLong *pX; -{ - uLong x ; - int i = 0; - int err; - - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<16; - - if (err==UNZ_OK) - err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; - - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; -} - - -/* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (fileName1,fileName2) - const char* fileName1; - const char* fileName2; -{ - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } -} - - -#ifdef CASESENSITIVITYDEFAULT_NO -#define CASESENSITIVITYDEFAULTVALUE 2 -#else -#define CASESENSITIVITYDEFAULTVALUE 1 -#endif - -#ifndef STRCMPCASENOSENTIVEFUNCTION -#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal -#endif - -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) - -*/ -extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity) - const char* fileName1; - const char* fileName2; - int iCaseSensitivity; -{ - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; - - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); - - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); -} - -#ifndef BUFREADCOMMENT -#define BUFREADCOMMENT (0x400) -#endif - -/* - Locate the Central directory of a zipfile (at the end, just before - the global comment) -*/ -local uLong unzlocal_SearchCentralDir OF(( - const zlib_filefunc_def* pzlib_filefunc_def, - voidpf filestream)); - -local uLong unzlocal_SearchCentralDir(pzlib_filefunc_def,filestream) - const zlib_filefunc_def* pzlib_filefunc_def; - voidpf filestream; -{ - unsigned char* buf; - uLong uSizeFile; - uLong uBackRead; - uLong uMaxBack=0xffff; /* maximum size of global comment */ - uLong uPosFound=0; - - if (ZSEEK(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; - - - uSizeFile = ZTELL(*pzlib_filefunc_def,filestream); - - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; - - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; - - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; - - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uSizeFile-uReadPos); - if (ZSEEK(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; - - if (ZREAD(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; - - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; -} - -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer - "zlib/zlib114.zip". - If the zipfile cannot be opened (file doesn't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ -extern unzFile ZEXPORT unzOpen2 (path, pzlib_filefunc_def) - const char *path; - zlib_filefunc_def* pzlib_filefunc_def; -{ - unz_s us; - unz_s *s; - uLong central_pos,uL; - - uLong number_disk; /* number of the current dist, used for - spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used - for spaning ZIP, unsupported, always 0*/ - uLong number_entry_CD; /* total number of entries in - the central dir - (same than number_entry on nospan) */ - - int err=UNZ_OK; - - if (unz_copyright[0]!=' ') - return NULL; - - if (pzlib_filefunc_def==NULL) - fill_fopen_filefunc(&us.z_filefunc); - else - us.z_filefunc = *pzlib_filefunc_def; - - us.filestream= (*(us.z_filefunc.zopen_file))(us.z_filefunc.opaque, - path, - ZLIB_FILEFUNC_MODE_READ | - ZLIB_FILEFUNC_MODE_EXISTING); - if (us.filestream==NULL) - return NULL; - - central_pos = unzlocal_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) - err=UNZ_ERRNO; - - if (ZSEEK(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - /* the signature, already checked */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; - - /* number of the disk with the start of the central directory */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir on this disk */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; - - /* total number of entries in the central dir */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* offset of start of central directory with respect to the - starting disk number */ - if (unzlocal_getLong(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* zipfile comment length */ - if (unzlocal_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) - err=UNZ_ERRNO; - - if ((central_pospfile_in_zip_read!=NULL) - unzCloseCurrentFile(file); - - ZCLOSE(s->z_filefunc, s->filestream); - TRYFREE(s); - return UNZ_OK; -} - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info) - unzFile file; - unz_global_info *pglobal_info; -{ - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - *pglobal_info=s->gi; - return UNZ_OK; -} - - -/* - Translate date/time from Dos format to tm_unz (readable more easilty) -*/ -local void unzlocal_DosDateToTmuDate (ulDosDate, ptm) - uLong ulDosDate; - tm_unz* ptm; -{ - uLong uDate; - uDate = (uLong)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; - - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; -} - -/* - Get Info about the current file in the zipfile, with internal only info -*/ -local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file, - unz_file_info *pfile_info, - unz_file_info_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -local int unzlocal_GetCurrentFileInfoInternal (file, - pfile_info, - pfile_info_internal, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - unz_file_info_internal *pfile_info_internal; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - unz_s* s; - unz_file_info file_info; - unz_file_info_internal file_info_internal; - int err=UNZ_OK; - uLong uMagic; - long lSeek=0; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (ZSEEK(s->z_filefunc, s->filestream, - s->pos_in_central_dir+s->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; - - - /* we check the magic */ - if (err==UNZ_OK) - { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; - } - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; - - unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_filename0) && (fileNameBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek -= uSizeRead; - } - - - if ((err==UNZ_OK) && (extraField!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_extraz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,extraField,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek += file_info.size_file_extra - uSizeRead; - } - else - lSeek+=file_info.size_file_extra; - - - if ((err==UNZ_OK) && (szComment!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek+=file_info.size_file_comment - uSizeRead; - } - else - lSeek+=file_info.size_file_comment; - - if ((err==UNZ_OK) && (pfile_info!=NULL)) - *pfile_info=file_info; - - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) - *pfile_info_internal=file_info_internal; - - return err; -} - - - -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. -*/ -extern int ZEXPORT unzGetCurrentFileInfo (file, - pfile_info, - szFileName, fileNameBufferSize, - extraField, extraFieldBufferSize, - szComment, commentBufferSize) - unzFile file; - unz_file_info *pfile_info; - char *szFileName; - uLong fileNameBufferSize; - void *extraField; - uLong extraFieldBufferSize; - char *szComment; - uLong commentBufferSize; -{ - return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); -} - -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ -extern int ZEXPORT unzGoToFirstFile (file) - unzFile file; -{ - int err=UNZ_OK; - unz_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ -extern int ZEXPORT unzGoToNextFile (file) - unzFile file; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; - - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} - - -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzipStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ -extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity) - unzFile file; - const char *szFileName; - int iCaseSensitivity; -{ - unz_s* s; - int err; - - /* We remember the 'current' position in the file so that we can jump - * back there if we fail. - */ - unz_file_info cur_file_infoSaved; - unz_file_info_internal cur_file_info_internalSaved; - uLong num_fileSaved; - uLong pos_in_central_dirSaved; - - - if (file==NULL) - return UNZ_PARAMERROR; - - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; - - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - /* Save the current state */ - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - cur_file_infoSaved = s->cur_file_info; - cur_file_info_internalSaved = s->cur_file_info_internal; - - err = unzGoToFirstFile(file); - - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - err = unzGetCurrentFileInfo(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (err == UNZ_OK) - { - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - } - - /* We failed, so restore the state of the 'current file' to where we - * were. - */ - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - s->cur_file_info = cur_file_infoSaved; - s->cur_file_info_internal = cur_file_info_internalSaved; - return err; -} - - -/* -/////////////////////////////////////////// -// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) -// I need random access -// -// Further optimization could be realized by adding an ability -// to cache the directory in memory. The goal being a single -// comprehensive file read to put the file I need in a memory. -*/ - -/* -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; // offset in file - uLong num_of_file; // # of file -} unz_file_pos; -*/ - -extern int ZEXPORT unzGetFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - - file_pos->pos_in_zip_directory = s->pos_in_central_dir; - file_pos->num_of_file = s->num_file; - - return UNZ_OK; -} - -extern int ZEXPORT unzGoToFilePos(file, file_pos) - unzFile file; - unz_file_pos* file_pos; -{ - unz_s* s; - int err; - - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - /* jump to the right spot */ - s->pos_in_central_dir = file_pos->pos_in_zip_directory; - s->num_file = file_pos->num_of_file; - - /* set the current file */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - /* return results */ - s->current_file_ok = (err == UNZ_OK); - return err; -} - -/* -// Unzip Helper Functions - should be here? -/////////////////////////////////////////// -*/ - -/* - Read the local header of the current zipfile - Check the coherency of the local header and info in the end of central - directory about this file - store in *piSizeVar the size of extra info in local header - (filename and size of extra field data) -*/ -local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar, - poffset_local_extrafield, - psize_local_extrafield) - unz_s* s; - uInt* piSizeVar; - uLong *poffset_local_extrafield; - uInt *psize_local_extrafield; -{ - uLong uMagic,uData,uFlags; - uLong size_filename; - uLong size_extra_field; - int err=UNZ_OK; - - *piSizeVar = 0; - *poffset_local_extrafield = 0; - *psize_local_extrafield = 0; - - if (ZSEEK(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - - if (err==UNZ_OK) - { - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; - } - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) - err=UNZ_BADZIPFILE; -*/ - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; - - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - if (unzlocal_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && - ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; - - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; - - *piSizeVar += (uInt)size_filename; - - if (unzlocal_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; - *psize_local_extrafield = (uInt)size_extra_field; - - *piSizeVar += (uInt)size_extra_field; - - return err; -} - -/* - Open for reading data the current file in the zipfile. - If there is no error and the file is opened, the return value is UNZ_OK. -*/ -extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password) - unzFile file; - int* method; - int* level; - int raw; - const char* password; -{ - int err=UNZ_OK; - uInt iSizeVar; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uLong offset_local_extrafield; /* offset of the local extra field */ - uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT - char source[12]; -# else - if (password != NULL) - return UNZ_PARAMERROR; -# endif - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return UNZ_PARAMERROR; - - if (s->pfile_in_zip_read != NULL) - unzCloseCurrentFile(file); - - if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar, - &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) - return UNZ_BADZIPFILE; - - pfile_in_zip_read_info = (file_in_zip_read_info_s*) - ALLOC(sizeof(file_in_zip_read_info_s)); - if (pfile_in_zip_read_info==NULL) - return UNZ_INTERNALERROR; - - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); - pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; - pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - pfile_in_zip_read_info->raw=raw; - - if (pfile_in_zip_read_info->read_buffer==NULL) - { - TRYFREE(pfile_in_zip_read_info); - return UNZ_INTERNALERROR; - } - - pfile_in_zip_read_info->stream_initialised=0; - - if (method!=NULL) - *method = (int)s->cur_file_info.compression_method; - - if (level!=NULL) - { - *level = 6; - switch (s->cur_file_info.flag & 0x06) - { - case 6 : *level = 1; break; - case 4 : *level = 2; break; - case 2 : *level = 9; break; - } - } - - if ((s->cur_file_info.compression_method!=0) && - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->compression_method = - s->cur_file_info.compression_method; - pfile_in_zip_read_info->filestream=s->filestream; - pfile_in_zip_read_info->z_filefunc=s->z_filefunc; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if ((s->cur_file_info.compression_method==Z_DEFLATED) && - (!raw)) - { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=1; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. - * In unzip, i don't wait absolutely Z_STREAM_END because I known the - * size of both compressed and uncompressed data - */ - } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; - - - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; - - pfile_in_zip_read_info->stream.avail_in = (uInt)0; - - s->pfile_in_zip_read = pfile_in_zip_read_info; - -# ifndef NOUNCRYPT - if (password != NULL) - { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); - if (ZSEEK(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD(s->z_filefunc, s->filestream,source, 12)<12) - return UNZ_INTERNALERROR; - - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); - - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; - } -# endif - - - return UNZ_OK; -} - -extern int ZEXPORT unzOpenCurrentFile (file) - unzFile file; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); -} - -extern int ZEXPORT unzOpenCurrentFilePassword (file, password) - unzFile file; - const char* password; -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, password); -} - -extern int ZEXPORT unzOpenCurrentFile2 (file,method,level,raw) - unzFile file; - int* method; - int* level; - int raw; -{ - return unzOpenCurrentFile3(file, method, level, raw, NULL); -} - -/* - Read bytes from the current file. - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ -extern int ZEXPORT unzReadCurrentFile (file, buf, len) - unzFile file; - voidp buf; - unsigned len; -{ - int err=UNZ_OK; - uInt iRead = 0; - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->read_buffer == NULL)) - return UNZ_END_OF_LIST_OF_FILE; - if (len==0) - return 0; - - pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; - - pfile_in_zip_read_info->stream.avail_out = (uInt)len; - - if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && - (!(pfile_in_zip_read_info->raw))) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - - if ((len>pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in) && - (pfile_in_zip_read_info->raw)) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in; - - while (pfile_in_zip_read_info->stream.avail_out>0) - { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) - { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) - return UNZ_EOF; - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->read_buffer, - uReadThis)!=uReadThis) - return UNZ_ERRNO; - - -# ifndef NOUNCRYPT - if(s->encrypted) - { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); - } -# endif - - - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Bytef*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; - } - - if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) - { - uInt uDoCopy,i ; - - if ((pfile_in_zip_read_info->stream.avail_in == 0) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - return (iRead==0) ? UNZ_EOF : iRead; - - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - - for (i=0;istream.next_out+i) = - *(pfile_in_zip_read_info->stream.next_in+i); - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; - } - else - { - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; - int flush=Z_SYNC_FLUSH; - - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; - - /* - if ((pfile_in_zip_read_info->rest_read_uncompressed == - pfile_in_zip_read_info->stream.avail_out) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - flush = Z_FINISH; - */ - err=inflate(&pfile_in_zip_read_info->stream,flush); - - if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) - err = Z_DATA_ERROR; - - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->crc32 = - crc32(pfile_in_zip_read_info->crc32,bufBefore, - (uInt)(uOutThis)); - - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; - - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) - break; - } - } - - if (err==Z_OK) - return iRead; - return err; -} - - -/* - Give the current position in uncompressed data -*/ -extern z_off_t ZEXPORT unztell (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - return (z_off_t)pfile_in_zip_read_info->stream.total_out; -} - - -/* - return 1 if the end of file was reached, 0 elsewhere -*/ -extern int ZEXPORT unzeof (file) - unzFile file; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; -} - - - -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field that can be read - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ -extern int ZEXPORT unzGetLocalExtrafield (file,buf,len) - unzFile file; - voidp buf; - unsigned len; -{ - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - uInt read_now; - uLong size_to_read; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); - - if (buf==NULL) - return (int)size_to_read; - - if (len>size_to_read) - read_now = (uInt)size_to_read; - else - read_now = (uInt)len ; - - if (read_now==0) - return 0; - - if (ZSEEK(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (ZREAD(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - buf,read_now)!=read_now) - return UNZ_ERRNO; - - return (int)read_now; -} - -/* - Close the file in zip opened with unzipOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ -extern int ZEXPORT unzCloseCurrentFile (file) - unzFile file; -{ - int err=UNZ_OK; - - unz_s* s; - file_in_zip_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; - - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; - - - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && - (!pfile_in_zip_read_info->raw)) - { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; - } - - - TRYFREE(pfile_in_zip_read_info->read_buffer); - pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised) - inflateEnd(&pfile_in_zip_read_info->stream); - - pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); - - s->pfile_in_zip_read=NULL; - - return err; -} - - -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ -extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf) - unzFile file; - char *szComment; - uLong uSizeBuf; -{ - unz_s* s; - uLong uReadThis ; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; - - if (ZSEEK(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - - if (uReadThis>0) - { - *szComment='\0'; - if (ZREAD(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) - return UNZ_ERRNO; - } - - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; -} - -/* Additions by RX '2004 */ -extern uLong ZEXPORT unzGetOffset (file) - unzFile file; -{ - unz_s* s; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - if (!s->current_file_ok) - return 0; - if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) - if (s->num_file==s->gi.number_entry) - return 0; - return s->pos_in_central_dir; -} - -extern int ZEXPORT unzSetOffset (file, pos) - unzFile file; - uLong pos; -{ - unz_s* s; - int err; - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz_s*)file; - - s->pos_in_central_dir = pos; - s->num_file = s->gi.number_entry; /* hack */ - err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; -} diff --git a/src/lib/libgambatte/src/file/unzip/unzip.h b/src/lib/libgambatte/src/file/unzip/unzip.h deleted file mode 100644 index 5bb6a696..00000000 --- a/src/lib/libgambatte/src/file/unzip/unzip.h +++ /dev/null @@ -1,354 +0,0 @@ -/* unzip.h -- IO for uncompress .zip files using zlib - Version 1.01e, February 12th, 2005 - - Copyright (C) 1998-2005 Gilles Vollant - - This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g - WinZip, InfoZip tools and compatible. - - Multi volume ZipFile (span) are not supported. - Encryption compatible with pkzip 2.04g only supported - Old compressions used by old PKZip 1.x are not supported - - - I WAIT FEEDBACK at mail info@winimage.com - Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution - - Condition of use and distribution are the same than zlib : - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - -*/ - -/* for more info about .ZIP format, see - http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - http://www.info-zip.org/pub/infozip/doc/ - PkWare has also a specification at : - ftp://ftp.pkware.com/probdesc.zip -*/ - -#ifndef _unz_H -#define _unz_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef _ZLIB_H -#include -#endif - -#ifndef _ZLIBIOAPI_H -#include "ioapi.h" -#endif - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; -#else -typedef voidp unzFile; -#endif - - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) - -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile - These data comes from the end of central dir */ -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in - the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; - - -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ - - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ - - tm_unz tmu_date; -} unz_file_info; - -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* - Compare two filename (fileName1,fileName2). - If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) - If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi - or strcasecmp) - If iCaseSenisivity = 0, case sensitivity is defaut of your operating system - (like 1 on Unix, 2 on Windows) -*/ - - -extern unzFile ZEXPORT unzOpen OF((const char *path)); -/* - Open a Zip file. path contain the full pathname (by example, - on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer - "zlib/zlib113.zip". - If the zipfile cannot be opened (file don't exist or in not valid), the - return value is NULL. - Else, the return value is a unzFile Handle, usable with other function - of this unzip package. -*/ - -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); -/* - Open a Zip file, like unzOpen, but provide a set of file low level API - for read/write the zip file (see ioapi.h) -*/ - -extern int ZEXPORT unzClose OF((unzFile file)); -/* - Close a ZipFile opened with unzipOpen. - If there is files inside the .Zip opened with unzOpenCurrentFile (see later), - these files MUST be closed with unzipCloseCurrentFile before call unzipClose. - return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); -/* - Write info about the ZipFile in the *pglobal_info structure. - No preparation of the structure is needed - return UNZ_OK if there is no problem. */ - - -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* - Get the global comment string of the ZipFile, in the szComment buffer. - uSizeBuf is the size of the szComment buffer. - return the number of byte copied or an error code <0 -*/ - - -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* - Set the current file of the zipfile to the first file. - return UNZ_OK if there is no problem -*/ - -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* - Set the current file of the zipfile to the next file. - return UNZ_OK if there is no problem - return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. -*/ - -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* - Try locate the file szFileName in the zipfile. - For the iCaseSensitivity signification, see unzStringFileNameCompare - - return value : - UNZ_OK if the file is found. It becomes the current file. - UNZ_END_OF_LIST_OF_FILE if the file is not found -*/ - - -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; - -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); - -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); - -/* ****************************************** */ - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* - Get Info about the current file - if pfile_info!=NULL, the *pfile_info structure will contain somes info about - the current file - if szFileName!=NULL, the filemane string will be copied in szFileName - (fileNameBufferSize is the size of the buffer) - if extraField!=NULL, the extra field information will be copied in extraField - (extraFieldBufferSize is the size of the buffer). - This is the Central-header version of the extra field - if szComment!=NULL, the comment string of the file will be copied in szComment - (commentBufferSize is the size of the buffer) -*/ - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data - from it, and close it (you can close it before reading all the file) - */ - -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* - Open for reading data the current file in the zipfile. - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* - Open for reading data the current file in the zipfile. - password is a crypting password - If there is no error, the return value is UNZ_OK. -*/ - -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* - Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) - if raw==1 - *method will receive method of compression, *level will receive level of - compression - note : you can set level parameter as NULL (if you did not want known level, - but you CANNOT set method parameter as NULL -*/ - - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* - Close the file in zip opened with unzOpenCurrentFile - Return UNZ_CRCERROR if all the file was read but the CRC is not good -*/ - -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read bytes from the current file (opened by unzOpenCurrentFile) - buf contain buffer where data must be copied - len the size of buf. - - return the number of byte copied if somes bytes are copied - return 0 if the end of file was reached - return <0 with error code if there is an error - (UNZ_ERRNO for IO error, or zLib error for uncompress error) -*/ - -extern z_off_t ZEXPORT unztell OF((unzFile file)); -/* - Give the current position in uncompressed data -*/ - -extern int ZEXPORT unzeof OF((unzFile file)); -/* - return 1 if the end of file was reached, 0 elsewhere -*/ - -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* - Read extra field from the current file (opened by unzOpenCurrentFile) - This is the local-header version of the extra field (sometimes, there is - more info in the local-header version than in the central-header) - - if buf==NULL, it return the size of the local extra field - - if buf!=NULL, len is the size of the buffer, the extra header is copied in - buf. - the return value is the number of bytes copied in buf, or (if <0) - the error code -*/ - -/***************************************************************************/ - -/* Get the current file offset */ -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); - - - -#ifdef __cplusplus -} -#endif - -#endif /* _unz_H */ diff --git a/src/lib/libgambatte/src/gambatte.cpp b/src/lib/libgambatte/src/gambatte.cpp deleted file mode 100644 index 03322a1a..00000000 --- a/src/lib/libgambatte/src/gambatte.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "gambatte.h" -#include "cpu.h" -#include "savestate.h" -#include "statesaver.h" -#include "initstate.h" -#include "state_osd_elements.h" -#include -#include - -static const std::string itos(int i) { - std::stringstream ss; - - ss << i; - - std::string out; - - ss >> out; - - return out; -} - -static const std::string statePath(const std::string &basePath, int stateNo) { - return basePath + "_" + itos(stateNo) + ".gqs"; -} - -namespace Gambatte { -GB::GB() : z80(new CPU), stateNo(1) {} - -GB::~GB() { - delete z80; -} - -unsigned GB::runFor(Gambatte::uint_least32_t *const soundBuf, const unsigned samples) { - z80->setSoundBuffer(soundBuf); - z80->runFor(samples * 2); - - return z80->fillSoundBuffer(); -} - -void GB::updateVideo() { - return z80->updateVideo(); -} - -unsigned GB::lyCounter() { - return z80->lyCounter(); -} - -void GB::reset() { - z80->saveSavedata(); - - SaveState state; - z80->setStatePtrs(state); - setInitState(state, z80->isCgb()); - z80->loadState(state); - z80->loadSavedata(); - -// z80->reset(); -} - -void GB::setVideoBlitter(VideoBlitter *vb) { - z80->setVideoBlitter(vb); -} - -void GB::videoBufferChange() { - z80->videoBufferChange(); -} - -unsigned GB::videoWidth() const { - return z80->videoWidth(); -} - -unsigned GB::videoHeight() const { - return z80->videoHeight(); -} - -void GB::setVideoFilter(const unsigned n) { - z80->setVideoFilter(n); -} - -std::vector GB::filterInfo() const { - return z80->filterInfo(); -} - -void GB::setInputStateGetter(InputStateGetter *getInput) { - z80->setInputStateGetter(getInput); -} - -void GB::setMemoryInterface(MemoryInterface *memoryInterface) { - z80->setMemoryInterface(memoryInterface); -} - -void GB::set_savedir(const char *sdir) { - z80->set_savedir(sdir); -} - -bool GB::load(const bool forceDmg) { - z80->saveSavedata(); - - const bool failed = z80->load(forceDmg); - - if (!failed) { - SaveState state; - z80->setStatePtrs(state); - setInitState(state, z80->isCgb()); - z80->loadState(state); - z80->loadSavedata(); - - stateNo = 1; - z80->setOsdElement(std::auto_ptr()); - } - - return failed; -} - -void GB::save() { - z80->saveSavedata(); -} - -bool GB::isCgb() const { - return z80->isCgb(); -} - -void GB::setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) { - z80->setDmgPaletteColor(palNum, colorNum, rgb32); -} - -void GB::loadState(const char *const filepath, const bool osdMessage) { - z80->saveSavedata(); - - SaveState state; - z80->setStatePtrs(state); - - if (StateSaver::loadState(state, filepath)) { - z80->loadState(state); - - if (osdMessage) - z80->setOsdElement(newStateLoadedOsdElement(stateNo)); - } -} - -void GB::saveState() { - saveState(statePath(z80->saveBasePath(), stateNo).c_str()); - z80->setOsdElement(newStateSavedOsdElement(stateNo)); -} - -void GB::loadState() { - loadState(statePath(z80->saveBasePath(), stateNo).c_str(), true); -} - -void GB::saveState(const char *filepath) { - SaveState state; - z80->setStatePtrs(state); - z80->saveState(state); - StateSaver::saveState(state, filepath); -} - -void GB::loadState(const char *const filepath) { - loadState(filepath, false); -} - -void GB::selectState(int n) { - n -= (n / 10) * 10; - stateNo = n < 0 ? n + 10 : n; - z80->setOsdElement(newSaveStateOsdElement(statePath(z80->saveBasePath(), stateNo).c_str(), stateNo)); -} -} diff --git a/src/lib/libgambatte/src/initstate.cpp b/src/lib/libgambatte/src/initstate.cpp deleted file mode 100644 index c16d48b4..00000000 --- a/src/lib/libgambatte/src/initstate.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "initstate.h" -#include "savestate.h" -#include -#include -#include "sound/sound_unit.h" -#include "memory.h" - -void setInitState(SaveState &state, const bool cgb) { - static const unsigned char feaxDump[0x60] = { - 0x18, 0x01, 0xEF, 0xDE, 0x06, 0x4A, 0xCD, 0xBD, - 0x18, 0x01, 0xEF, 0xDE, 0x06, 0x4A, 0xCD, 0xBD, - 0x18, 0x01, 0xEF, 0xDE, 0x06, 0x4A, 0xCD, 0xBD, - 0x18, 0x01, 0xEF, 0xDE, 0x06, 0x4A, 0xCD, 0xBD, - 0x00, 0x90, 0xF7, 0x7F, 0xC0, 0xB1, 0xB4, 0xFB, - 0x00, 0x90, 0xF7, 0x7F, 0xC0, 0xB1, 0xB4, 0xFB, - 0x00, 0x90, 0xF7, 0x7F, 0xC0, 0xB1, 0xB4, 0xFB, - 0x00, 0x90, 0xF7, 0x7F, 0xC0, 0xB1, 0xB4, 0xFB, - 0x24, 0x1B, 0xFD, 0x3A, 0x10, 0x12, 0xAD, 0x45, - 0x24, 0x1B, 0xFD, 0x3A, 0x10, 0x12, 0xAD, 0x45, - 0x24, 0x1B, 0xFD, 0x3A, 0x10, 0x12, 0xAD, 0x45, - 0x24, 0x1B, 0xFD, 0x3A, 0x10, 0x12, 0xAD, 0x45 - }; - - static const unsigned char ffxxDump[0x100] = { - 0xCF, 0x00, 0x7C, 0xFF, 0x43, 0x00, 0x00, 0xF8, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, - 0x80, 0xBF, 0xF3, 0xFF, 0xBF, 0xFF, 0x3F, 0x00, - 0xFF, 0xBF, 0x7F, 0xFF, 0x9F, 0xFF, 0xBF, 0xFF, - 0xFF, 0x00, 0x00, 0xBF, 0x77, 0xF3, 0xF1, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, - 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, - 0x00, 0x00, 0x00, 0x00, 0xFF, 0x7E, 0xFF, 0xFE, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xC0, 0xFF, 0xC1, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, - 0xF8, 0xFF, 0x00, 0x00, 0x00, 0x8F, 0x00, 0x00, - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - 0xCE, 0xED, 0x66, 0x66, 0xCC, 0x0D, 0x00, 0x0B, - 0x03, 0x73, 0x00, 0x83, 0x00, 0x0C, 0x00, 0x0D, - 0x00, 0x08, 0x11, 0x1F, 0x88, 0x89, 0x00, 0x0E, - 0xDC, 0xCC, 0x6E, 0xE6, 0xDD, 0xDD, 0xD9, 0x99, - 0xBB, 0xBB, 0x67, 0x63, 0x6E, 0x0E, 0xEC, 0xCC, - 0xDD, 0xDC, 0x99, 0x9F, 0xBB, 0xB9, 0x33, 0x3E, - 0x45, 0xEC, 0x52, 0xFA, 0x08, 0xB7, 0x07, 0x5D, - 0x01, 0xFD, 0xC0, 0xFF, 0x08, 0xFC, 0x00, 0xE5, - 0x0B, 0xF8, 0xC2, 0xCE, 0xF4, 0xF9, 0x0F, 0x7F, - 0x45, 0x6D, 0x3D, 0xFE, 0x46, 0x97, 0x33, 0x5E, - 0x08, 0xEF, 0xF1, 0xFF, 0x86, 0x83, 0x24, 0x74, - 0x12, 0xFC, 0x00, 0x9F, 0xB4, 0xB7, 0x06, 0xD5, - 0xD0, 0x7A, 0x00, 0x9E, 0x04, 0x5F, 0x41, 0x2F, - 0x1D, 0x77, 0x36, 0x75, 0x81, 0xAA, 0x70, 0x3A, - 0x98, 0xD1, 0x71, 0x02, 0x4D, 0x01, 0xC1, 0xFF, - 0x0D, 0x00, 0xD3, 0x05, 0xF9, 0x00, 0x0B, 0x00 - }; - - static const unsigned char cgbObjpDump[0x40] = { - 0x00, 0x00, 0xF2, 0xAB, - 0x61, 0xC2, 0xD9, 0xBA, - 0x88, 0x6E, 0xDD, 0x63, - 0x28, 0x27, 0xFB, 0x9F, - 0x35, 0x42, 0xD6, 0xD4, - 0x50, 0x48, 0x57, 0x5E, - 0x23, 0x3E, 0x3D, 0xCA, - 0x71, 0x21, 0x37, 0xC0, - 0xC6, 0xB3, 0xFB, 0xF9, - 0x08, 0x00, 0x8D, 0x29, - 0xA3, 0x20, 0xDB, 0x87, - 0x62, 0x05, 0x5D, 0xD4, - 0x0E, 0x08, 0xFE, 0xAF, - 0x20, 0x02, 0xD7, 0xFF, - 0x07, 0x6A, 0x55, 0xEC, - 0x83, 0x40, 0x0B, 0x77 - }; - - state.cpu.cycleCounter = 0x102A0; - state.cpu.PC = 0x100; - state.cpu.SP = 0xFFFE; - state.cpu.A = (cgb * 0x10) | 0x01; - state.cpu.B = 0x00; - state.cpu.C = 0x13; - state.cpu.D = 0x00; - state.cpu.E = 0xD8; - state.cpu.F = 0xB0; - state.cpu.H = 0x01; - state.cpu.L = 0x4D; - state.cpu.skip = false; - state.cpu.halted = false; - - - std::memset(state.mem.vram.ptr, 0, state.mem.vram.getSz()); - std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.getSz()); - - for (unsigned addr = 0x0000; addr < 0x0800; addr += 0x10) { - std::memset(state.mem.wram.ptr + addr + 0x00, 0xFF, 0x08); - std::memset(state.mem.wram.ptr + addr + 0x08, 0x00, 0x08); - } - - for (unsigned addr = 0x0800; addr < 0x1000; addr += 0x10) { - std::memset(state.mem.wram.ptr + addr + 0x00, 0x00, 0x08); - std::memset(state.mem.wram.ptr + addr + 0x08, 0xFF, 0x08); - } - - for (unsigned addr = 0x0E00; addr < 0x1000; addr += 0x10) { - state.mem.wram.ptr[addr + 0x02] = 0xFF; - state.mem.wram.ptr[addr + 0x0A] = 0x00; - } - - for (unsigned addr = 0x1000; addr < state.mem.wram.getSz(); addr += 0x1000) - std::memcpy(state.mem.wram.ptr + addr, state.mem.wram.ptr, 0x1000); - - std::memset(state.mem.ioamhram.ptr, 0x00, state.mem.ioamhram.getSz()); - std::memcpy(state.mem.ioamhram.ptr + 0xA0, feaxDump, sizeof(feaxDump)); - std::memcpy(state.mem.ioamhram.ptr + 0x100, ffxxDump, sizeof(ffxxDump)); - - state.mem.ioamhram.ptr[0x104] = 0x1C; - state.mem.ioamhram.ptr[0x140] = 0x91; - state.mem.ioamhram.ptr[0x144] = 0x00; - - if (!cgb) { - state.mem.ioamhram.ptr[0x130] = 0xAC; - state.mem.ioamhram.ptr[0x131] = 0xDD; - state.mem.ioamhram.ptr[0x132] = 0xDA; - state.mem.ioamhram.ptr[0x133] = 0x48; - state.mem.ioamhram.ptr[0x134] = 0x36; - state.mem.ioamhram.ptr[0x135] = 0x02; - state.mem.ioamhram.ptr[0x136] = 0xCF; - state.mem.ioamhram.ptr[0x137] = 0x16; - state.mem.ioamhram.ptr[0x138] = 0x2C; - state.mem.ioamhram.ptr[0x139] = 0x04; - state.mem.ioamhram.ptr[0x13A] = 0xE5; - state.mem.ioamhram.ptr[0x13B] = 0x2C; - state.mem.ioamhram.ptr[0x13C] = 0xAC; - state.mem.ioamhram.ptr[0x13D] = 0xDD; - state.mem.ioamhram.ptr[0x13E] = 0xDA; - state.mem.ioamhram.ptr[0x13F] = 0x48; - - state.mem.ioamhram.ptr[0x14D] = 0xFF; - state.mem.ioamhram.ptr[0x14F] = 0xFF; - state.mem.ioamhram.ptr[0x156] = 0xFF; - state.mem.ioamhram.ptr[0x168] = 0xFF; - state.mem.ioamhram.ptr[0x16A] = 0xFF; - state.mem.ioamhram.ptr[0x16B] = 0xFF; - state.mem.ioamhram.ptr[0x16C] = 0xFF; - state.mem.ioamhram.ptr[0x170] = 0xFF; - state.mem.ioamhram.ptr[0x172] = 0xFF; - state.mem.ioamhram.ptr[0x173] = 0xFF; - state.mem.ioamhram.ptr[0x174] = 0xFF; - state.mem.ioamhram.ptr[0x175] = 0xFF; - state.mem.ioamhram.ptr[0x176] = 0xFF; - state.mem.ioamhram.ptr[0x177] = 0xFF; - } - - state.mem.div_lastUpdate = 0; - state.mem.tima_lastUpdate = 0; - state.mem.tmatime = Memory::COUNTER_DISABLED; - state.mem.next_serialtime = Memory::COUNTER_DISABLED; - state.mem.lastOamDmaUpdate = Memory::COUNTER_DISABLED; - state.mem.minIntTime = 0; - state.mem.rombank = 1; - state.mem.dmaSource = 0; - state.mem.dmaDestination = 0; - state.mem.rambank = 0; - state.mem.oamDmaPos = 0xFE; - state.mem.IME = false; - state.mem.enable_ram = false; - state.mem.rambank_mode = false; - state.mem.hdma_transfer = false; - - - for (unsigned i = 0x00; i < 0x40; i += 0x02) { - state.ppu.bgpData.ptr[i] = 0xFF; - state.ppu.bgpData.ptr[i + 1] = 0x7F; - } - - std::memcpy(state.ppu.objpData.ptr, cgbObjpDump, sizeof(cgbObjpDump)); - - if (!cgb) { - state.ppu.bgpData.ptr[0] = state.mem.ioamhram.get()[0x147]; - state.ppu.objpData.ptr[0] = state.mem.ioamhram.get()[0x148]; - state.ppu.objpData.ptr[1] = state.mem.ioamhram.get()[0x149]; - } - - for (unsigned pos = 0; pos < 80; ++pos) - state.ppu.oamReaderBuf.ptr[pos] = state.mem.ioamhram.ptr[((pos * 2) & ~3) | (pos & 1)]; - - std::fill_n(state.ppu.oamReaderSzbuf.ptr, 40, false); - - state.ppu.videoCycles = 144*456ul + 164; - state.ppu.enableDisplayM0Time = state.cpu.cycleCounter - state.ppu.videoCycles + 159; - state.ppu.winYPos = 0xFF; - state.ppu.drawStartCycle = 90; - state.ppu.scReadOffset = 90; - state.ppu.lcdc = state.mem.ioamhram.get()[0x140]; - state.ppu.scx[1] = state.ppu.scx[0] = 0; - state.ppu.scy[1] = state.ppu.scy[0] = 0; - state.ppu.scxAnd7 = 0; - state.ppu.weMaster = false; - state.ppu.wx = 0; - state.ppu.wy = 0; - state.ppu.lycIrqSkip = false; - - - state.spu.cycleCounter = 0x1000 | ((state.cpu.cycleCounter >> 1) & 0xFFF); // spu.cycleCounter >> 12 & 7 represents the frame sequencer position. - - state.spu.ch1.sweep.counter = SoundUnit::COUNTER_DISABLED; - state.spu.ch1.sweep.shadow = 0; - state.spu.ch1.sweep.nr0 = 0; - state.spu.ch1.sweep.negging = false; - state.spu.ch1.duty.nextPosUpdate = (state.spu.cycleCounter & ~1) + 2048 * 2; - state.spu.ch1.duty.nr3 = 0; - state.spu.ch1.duty.pos = 0; - state.spu.ch1.env.counter = SoundUnit::COUNTER_DISABLED; - state.spu.ch1.env.volume = 0; - state.spu.ch1.lcounter.counter = SoundUnit::COUNTER_DISABLED; - state.spu.ch1.lcounter.lengthCounter = 0x40; - state.spu.ch1.nr4 = 0; - state.spu.ch1.master = true; - - state.spu.ch2.duty.nextPosUpdate = (state.spu.cycleCounter & ~1) + 2048 * 2; - state.spu.ch2.duty.nr3 = 0; - state.spu.ch2.duty.pos = 0; - state.spu.ch2.env.counter = state.spu.cycleCounter - ((state.spu.cycleCounter - 0x1000) & 0x7FFF) + 8ul * 0x8000; - state.spu.ch2.env.volume = 0; - state.spu.ch2.lcounter.counter = SoundUnit::COUNTER_DISABLED; - state.spu.ch2.lcounter.lengthCounter = 0x40; - state.spu.ch2.nr4 = 0; - state.spu.ch2.master = false; - - for (unsigned i = 0; i < 0x10; ++i) - state.spu.ch3.waveRam.ptr[i] = state.mem.ioamhram.get()[0x130 + i]; - - state.spu.ch3.lcounter.counter = SoundUnit::COUNTER_DISABLED; - state.spu.ch3.lcounter.lengthCounter = 0x100; - state.spu.ch3.waveCounter = SoundUnit::COUNTER_DISABLED; - state.spu.ch3.lastReadTime = SoundUnit::COUNTER_DISABLED; - state.spu.ch3.nr3 = 0; - state.spu.ch3.nr4 = 0; - state.spu.ch3.wavePos = 0; - state.spu.ch3.sampleBuf = 0; - state.spu.ch3.master = false; - - state.spu.ch4.lfsr.counter = state.spu.cycleCounter + 4; - state.spu.ch4.lfsr.reg = 0xFF; - state.spu.ch4.env.counter = state.spu.cycleCounter - ((state.spu.cycleCounter - 0x1000) & 0x7FFF) + 8ul * 0x8000; - state.spu.ch4.env.volume = 0; - state.spu.ch4.lcounter.counter = SoundUnit::COUNTER_DISABLED; - state.spu.ch4.lcounter.lengthCounter = 0x40; - state.spu.ch4.nr4 = 0; - state.spu.ch4.master = false; - - state.rtc.baseTime = std::time(0); - state.rtc.haltTime = state.rtc.baseTime; - state.rtc.index = 5; - state.rtc.dataDh = 0; - state.rtc.dataDl = 0; - state.rtc.dataH = 0; - state.rtc.dataM = 0; - state.rtc.dataS = 0; - state.rtc.lastLatchData = false; -} diff --git a/src/lib/libgambatte/src/initstate.h b/src/lib/libgambatte/src/initstate.h deleted file mode 100644 index d550eed5..00000000 --- a/src/lib/libgambatte/src/initstate.h +++ /dev/null @@ -1,26 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef INITSTATE_H -#define INITSTATE_H - -class SaveState; - -void setInitState(SaveState &state, bool cgb); - -#endif diff --git a/src/lib/libgambatte/src/insertion_sort.h b/src/lib/libgambatte/src/insertion_sort.h deleted file mode 100644 index 939ba074..00000000 --- a/src/lib/libgambatte/src/insertion_sort.h +++ /dev/null @@ -1,51 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#ifndef INSERTION_SORT_H -#define INSERTION_SORT_H - -#include - -template -void insertionSort(T *const start, T *const end, Less less) { - if (start >= end) - return; - - T *a = start; - - while (++a < end) { - const T e = *a; - - T *b = a; - - while (b != start && less(e, *(b - 1))) { - *b = *(b - 1); - b = b - 1; - } - - *b = e; - } -} - -template -inline void insertionSort(T *const start, T *const end) { - insertionSort(start, end, std::less()); -} - -#endif /*INSERTION_SORT_H*/ diff --git a/src/lib/libgambatte/src/interrupter.cpp b/src/lib/libgambatte/src/interrupter.cpp deleted file mode 100644 index aea9df41..00000000 --- a/src/lib/libgambatte/src/interrupter.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "interrupter.h" - -#include "memory.h" - -Interrupter::Interrupter(unsigned short &SP_in, unsigned short &PC_in, bool &halted_in) : - SP(SP_in), - PC(PC_in), - halted(halted_in) -{} - -unsigned long Interrupter::interrupt(const unsigned address, unsigned long cycleCounter, Memory &memory) { - if (halted && memory.isCgb()) - cycleCounter += 4; - - halted = false; - cycleCounter += 8; - SP = (SP - 1) & 0xFFFF; - memory.write(SP, PC >> 8, cycleCounter); - cycleCounter += 4; - SP = (SP - 1) & 0xFFFF; - memory.write(SP, PC & 0xFF, cycleCounter); - PC = address; - cycleCounter += 8; - - return cycleCounter; -} diff --git a/src/lib/libgambatte/src/interrupter.h b/src/lib/libgambatte/src/interrupter.h deleted file mode 100644 index 18e0d9e1..00000000 --- a/src/lib/libgambatte/src/interrupter.h +++ /dev/null @@ -1,38 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef INTERRUPTER_H -#define INTERRUPTER_H - -class Memory; - -class Interrupter { - unsigned short &SP; - unsigned short &PC; - bool &halted; - -public: - Interrupter(unsigned short &SP, unsigned short &PC, bool &halted); - unsigned long interrupt(const unsigned address, unsigned long cycleCounter, Memory &memory); - - void unhalt() { - halted = false; - } -}; - -#endif diff --git a/src/lib/libgambatte/src/memory.cpp b/src/lib/libgambatte/src/memory.cpp deleted file mode 100644 index 1d39c884..00000000 --- a/src/lib/libgambatte/src/memory.cpp +++ /dev/null @@ -1,1937 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "memory.h" -#include "video.h" -#include "sound.h" -#include "inputstate.h" -#include "inputstategetter.h" -#include "memoryinterface.h" -#include "savestate.h" -#include "file/file.h" -#include - -// static const uint32_t timaClock[4]={ 1024, 16, 64, 256 }; -static const unsigned char timaClock[4] = { 10, 4, 6, 8 }; - -Memory::Memory(const Interrupter &interrupter_in) : -memchunk(NULL), -rambankdata(NULL), -rdisabled_ram(NULL), -wdisabled_ram(NULL), -oamDmaSrc(NULL), -vrambank(vram), -rsrambankptr(NULL), -wsrambankptr(NULL), -getInput(NULL), -memoryInterface(NULL), -div_lastUpdate(0), -tima_lastUpdate(0), -next_timatime(COUNTER_DISABLED), -next_blittime(144*456ul), -nextIntTime(COUNTER_DISABLED), -minIntTime(0), -next_dmatime(COUNTER_DISABLED), -next_hdmaReschedule(COUNTER_DISABLED), -next_unhalttime(COUNTER_DISABLED), -next_endtime(0), -tmatime(COUNTER_DISABLED), -next_serialtime(COUNTER_DISABLED), -lastOamDmaUpdate(COUNTER_DISABLED), -nextOamEventTime(COUNTER_DISABLED), -display(ioamhram, vram), -interrupter(interrupter_in), -romtype(plain), -rombanks(1), -rombank(1), -dmaSource(0), -dmaDestination(0), -rambank(0), -rambanks(1), -oamDmaArea1Lower(0), -oamDmaArea1Width(0), -oamDmaArea2Upper(0), -oamDmaPos(0xFE), -cgb(false), -doubleSpeed(false), -IME(false), -enable_ram(false), -rambank_mode(false), -battery(false), -rtcRom(false), -hdma_transfer(false), -active(false) -{ - romdata[1] = romdata[0] = NULL; - wramdata[1] = wramdata[0] = NULL; - std::fill_n(rmem, 0x10, static_cast(NULL)); - std::fill_n(wmem, 0x10, static_cast(NULL)); - set_irqEvent(); - set_event(); -} - -void Memory::setStatePtrs(SaveState &state) { - state.mem.vram.set(vram, sizeof vram); - state.mem.sram.set(rambankdata, rambanks * 0x2000ul); - state.mem.wram.set(wramdata[0], isCgb() ? 0x8000 : 0x2000); - state.mem.ioamhram.set(ioamhram, sizeof ioamhram); - - display.setStatePtrs(state); - sound.setStatePtrs(state); -} - -unsigned long Memory::saveState(SaveState &state, unsigned long cycleCounter) { - cycleCounter = resetCounters(cycleCounter); - nontrivial_ff_read(0xFF0F, cycleCounter); - nontrivial_ff_read(0xFF26, cycleCounter); - - state.mem.div_lastUpdate = div_lastUpdate; - state.mem.tima_lastUpdate = tima_lastUpdate; - state.mem.tmatime = tmatime; - state.mem.next_serialtime = next_serialtime; - state.mem.lastOamDmaUpdate = lastOamDmaUpdate; - state.mem.minIntTime = minIntTime; - state.mem.rombank = rombank; - state.mem.dmaSource = dmaSource; - state.mem.dmaDestination = dmaDestination; - state.mem.rambank = rambank; - state.mem.oamDmaPos = oamDmaPos; - state.mem.IME = IME; - state.mem.enable_ram = enable_ram; - state.mem.rambank_mode = rambank_mode; - state.mem.hdma_transfer = hdma_transfer; - - rtc.saveState(state); - display.saveState(state); - sound.saveState(state); - - return cycleCounter; -} - -void Memory::loadState(const SaveState &state, const unsigned long oldCc) { - sound.loadState(state); - display.loadState(state, state.mem.oamDmaPos < 0xA0 ? rdisabled_ram : ioamhram); - rtc.loadState(state, rtcRom ? state.mem.enable_ram : false); - - div_lastUpdate = state.mem.div_lastUpdate; - tima_lastUpdate = state.mem.tima_lastUpdate; - tmatime = state.mem.tmatime; - next_serialtime = state.mem.next_serialtime; - lastOamDmaUpdate = state.mem.lastOamDmaUpdate; - minIntTime = state.mem.minIntTime; - rombank = state.mem.rombank & (rombanks - 1); - dmaSource = state.mem.dmaSource; - dmaDestination = state.mem.dmaDestination; - rambank = state.mem.rambank & (rambanks - 1); - oamDmaPos = state.mem.oamDmaPos; - IME = state.mem.IME; - enable_ram = state.mem.enable_ram; - rambank_mode = state.mem.rambank_mode; - hdma_transfer = state.mem.hdma_transfer; - - const bool oldDs = doubleSpeed; - doubleSpeed = isCgb() & ioamhram[0x14D] >> 7; - oamDmaArea2Upper = oamDmaArea1Width = oamDmaArea1Lower = 0; - vrambank = vram + (ioamhram[0x14F] & 0x01 & isCgb()) * 0x2000; - wramdata[1] = wramdata[0] + ((isCgb() && (ioamhram[0x170] & 0x07)) ? (ioamhram[0x170] & 0x07) : 1) * 0x1000; - std::fill_n(rmem, 0x10, static_cast(NULL)); - std::fill_n(wmem, 0x10, static_cast(NULL)); - setBanks(); - - if (lastOamDmaUpdate != COUNTER_DISABLED) { - oamDmaInitSetup(); - - unsigned oamEventPos = 0x100; - - if (oamDmaPos < 0xA0) { - setOamDmaArea(); - oamEventPos = 0xA0; - } - - nextOamEventTime = lastOamDmaUpdate + (oamEventPos - oamDmaPos) * 4; - setOamDmaSrc(); - } - - if (!IME && state.cpu.halted) - schedule_unhalt(); - - next_blittime = (ioamhram[0x140] & 0x80) ? display.nextMode1IrqTime() : static_cast(COUNTER_DISABLED); - - const unsigned long cycleCounter = state.cpu.cycleCounter; - - if (hdma_transfer) { - next_dmatime = display.nextHdmaTime(cycleCounter); - next_hdmaReschedule = display.nextHdmaTimeInvalid(); - } else { - next_hdmaReschedule = next_dmatime = COUNTER_DISABLED; - } - - next_timatime = (ioamhram[0x107] & 4) ? tima_lastUpdate + ((256u - ioamhram[0x105]) << timaClock[ioamhram[0x107] & 3]) + 1 : static_cast(COUNTER_DISABLED); - set_irqEvent(); - rescheduleIrq(cycleCounter); - - if (oldDs != isDoubleSpeed()) - next_endtime = cycleCounter - (isDoubleSpeed() ?( oldCc - next_endtime) << 1 :( oldCc - next_endtime) >> 1); - else - next_endtime = cycleCounter - (oldCc - next_endtime); - -// set_event(); -} - -void Memory::schedule_unhalt() { - next_unhalttime = std::min(next_irqEventTime, display.nextIrqEvent()); - - if (next_unhalttime != COUNTER_DISABLED) - next_unhalttime += isCgb() * 4; - - set_event(); -} - -void Memory::rescheduleIrq(const unsigned long cycleCounter) { - if (IME) { - ioamhram[0x10F] |= display.getIfReg(cycleCounter) & 3; - - nextIntTime = (ioamhram[0x10F] & ioamhram[0x1FF] & 0x1F) ? cycleCounter : std::min(next_irqEventTime, display.nextIrqEvent()); - - if (nextIntTime < minIntTime) - nextIntTime = minIntTime; - - set_event(); - } -} - -void Memory::rescheduleHdmaReschedule() { - if (hdma_transfer && (ioamhram[0x140] & 0x80)) { - const unsigned long newTime = display.nextHdmaTimeInvalid(); - - if (newTime < next_hdmaReschedule) { - next_hdmaReschedule = newTime; - - if (newTime < next_eventtime) { - next_eventtime = newTime; - next_event = HDMA_RESCHEDULE; - } - } - } -} - -void Memory::ei(const unsigned long cycleCounter) { - IME = 1; - minIntTime = cycleCounter + 1; - rescheduleIrq(cycleCounter); -} - -void Memory::incEndtime(const unsigned long inc) { - active = true; - next_endtime += inc << isDoubleSpeed(); - set_event(); -} - -void Memory::setEndtime(const unsigned long cycleCounter, const unsigned long inc) { - next_endtime = cycleCounter; - incEndtime(inc); -} - -void Memory::set_irqEvent() { - next_irqEventTime = next_timatime; - next_irqEvent = TIMA; - - if (next_serialtime < next_irqEventTime) { - next_irqEvent = SERIAL; - next_irqEventTime = next_serialtime; - } -} - -void Memory::update_irqEvents(const unsigned long cc) { - while (next_irqEventTime <= cc) { - switch (next_irqEvent) { - case TIMA: - ioamhram[0x10F] |= 4; - next_timatime += (256u - ioamhram[0x106]) << timaClock[ioamhram[0x107] & 3]; - break; - case SERIAL: - next_serialtime = COUNTER_DISABLED; - ioamhram[0x101] = 0xFF; - ioamhram[0x102] &= 0x7F; - ioamhram[0x10F] |= 8; - break; - } - - set_irqEvent(); - } -} - -void Memory::set_event() { - next_event = INTERRUPTS; - next_eventtime = nextIntTime; - if (next_hdmaReschedule < next_eventtime) { - next_eventtime = next_hdmaReschedule; - next_event = HDMA_RESCHEDULE; - } - if (next_dmatime < next_eventtime) { - next_eventtime = next_dmatime; - next_event = DMA; - } - if (next_unhalttime < next_eventtime) { - next_eventtime = next_unhalttime; - next_event = UNHALT; - } - if (nextOamEventTime < next_eventtime) { - next_eventtime = nextOamEventTime; - next_event = OAM; - } - if (next_blittime < next_eventtime) { - next_event = BLIT; - next_eventtime = next_blittime; - } - if (next_endtime < next_eventtime) { - next_eventtime = next_endtime; - next_event = END; - } -} - -unsigned long Memory::event(unsigned long cycleCounter) { - if (lastOamDmaUpdate != COUNTER_DISABLED) - updateOamDma(cycleCounter); - - switch (next_event) { - case HDMA_RESCHEDULE: -// printf("hdma_reschedule\n"); - next_dmatime = display.nextHdmaTime(cycleCounter); - next_hdmaReschedule = display.nextHdmaTimeInvalid(); - break; - case DMA: -// printf("dma\n"); - { - const bool doubleSpeed = isDoubleSpeed(); - unsigned dmaSrc = dmaSource; - unsigned dmaDest = dmaDestination; - unsigned dmaLength = ((ioamhram[0x155] & 0x7F) + 0x1) * 0x10; - - unsigned length = hdma_transfer ? 0x10 : dmaLength; - - if ((static_cast(dmaDest) + length) & 0x10000) { - length = 0x10000 - dmaDest; - ioamhram[0x155] |= 0x80; - } - - dmaLength -= length; - - if (!(ioamhram[0x140] & 0x80)) - dmaLength = 0; - - { - unsigned long lOamDmaUpdate = lastOamDmaUpdate; - lastOamDmaUpdate = COUNTER_DISABLED; - - while (length--) { - const unsigned src = dmaSrc++ & 0xFFFF; - const unsigned data = ((src & 0xE000) == 0x8000 || src > 0xFDFF) ? 0xFF : read(src, cycleCounter); - - cycleCounter += 2 << doubleSpeed; - - if (cycleCounter - 3 > lOamDmaUpdate) { - oamDmaPos = (oamDmaPos + 1) & 0xFF; - lOamDmaUpdate += 4; - - if (oamDmaPos < 0xA0) { - if (oamDmaPos == 0) - startOamDma(lOamDmaUpdate - 2); - - ioamhram[src & 0xFF] = data; - } else if (oamDmaPos == 0xA0) { - endOamDma(lOamDmaUpdate - 2); - lOamDmaUpdate = COUNTER_DISABLED; - } - } - - nontrivial_write(0x8000 | (dmaDest++ & 0x1FFF), data, cycleCounter); - } - - lastOamDmaUpdate = lOamDmaUpdate; - } - - cycleCounter += 4; - - dmaSource = dmaSrc; - dmaDestination = dmaDest; - ioamhram[0x155] = ((dmaLength / 0x10 - 0x1) & 0xFF) | (ioamhram[0x155] & 0x80); - - if (ioamhram[0x155] & 0x80) { - next_hdmaReschedule = next_dmatime = COUNTER_DISABLED; - hdma_transfer = 0; - } - - if (hdma_transfer) { - if (lastOamDmaUpdate != COUNTER_DISABLED) - updateOamDma(cycleCounter); - - next_dmatime = display.nextHdmaTime(cycleCounter); - } - } - - break; - case INTERRUPTS: -// printf("interrupts\n"); - update_irqEvents(cycleCounter); - ioamhram[0x10F] |= display.getIfReg(cycleCounter) & 3; - - { - /*unsigned interrupt = ioamhram[0x10F] & ioamhram[0x1FF]; - interrupt |= interrupt << 1; - interrupt |= interrupt << 2; - interrupt |= interrupt << 1; - interrupt = ~interrupt; - ++interrupt; - interrupt &= 0x1F; - - if (interrupt) { - ioamhram[0x10F] &= ~interrupt; - display.setIfReg(ioamhram[0x10F], CycleCounter); - IME = false; - - unsigned address = interrupt; - interrupt >>= 1; - address -= interrupt & 0x0C; - interrupt >>= 1; - address -= interrupt & 5; - address += interrupt >> 2; - - address <<= 3; - address += 0x38; - - z80.interrupt(address); - }*/ - - const unsigned interrupt = ioamhram[0x10F] & ioamhram[0x1FF] & 0x1F; - - if (interrupt) { - unsigned n; - unsigned address; - - if ((n = interrupt & 0x01)) - address = 0x40; - else if ((n = interrupt & 0x02)) - address = 0x48; - else if ((n = interrupt & 0x04)) - address = 0x50; - else if ((n = interrupt & 0x08)) - address = 0x58; - else { - n = 0x10; - address = 0x60; - } - - ioamhram[0x10F] &= ~n; - display.setIfReg(ioamhram[0x10F], cycleCounter); - IME = false; - cycleCounter = interrupter.interrupt(address, cycleCounter, *this); - } - } - - nextIntTime = IME ? std::min(next_irqEventTime, display.nextIrqEvent()) : static_cast(COUNTER_DISABLED); - break; - case BLIT: -// printf("blit\n"); - display.updateScreen(next_blittime); - - if (ioamhram[0x140] & 0x80) - next_blittime += 70224 << isDoubleSpeed(); - else - next_blittime = COUNTER_DISABLED; - - break; - case UNHALT: -// printf("unhalt\n"); - update_irqEvents(cycleCounter); - ioamhram[0x10F] |= display.getIfReg(cycleCounter) & 3; - - if (ioamhram[0x10F] & ioamhram[0x1FF] & 0x1F) { - next_unhalttime = COUNTER_DISABLED; - interrupter.unhalt(); - } else - next_unhalttime = std::min(next_irqEventTime, display.nextIrqEvent()) + isCgb() * 4; - - break; - case OAM: - nextOamEventTime = lastOamDmaUpdate == COUNTER_DISABLED ? static_cast(COUNTER_DISABLED) : nextOamEventTime + 0xA0 * 4; - break; - case END: - { - const unsigned long endtime = next_endtime; - next_endtime = COUNTER_DISABLED; - set_event(); - - while (cycleCounter >= next_eventtime) - cycleCounter = event(cycleCounter); - - next_endtime = endtime; - active = false; - } - - break; - } - - set_event(); - - return cycleCounter; -} - -void Memory::speedChange(const unsigned long cycleCounter) { - if (isCgb() && (ioamhram[0x14D] & 0x1)) { - std::printf("speedChange\n"); - - update_irqEvents(cycleCounter); - sound.generate_samples(cycleCounter, isDoubleSpeed()); - display.preSpeedChange(cycleCounter); - - ioamhram[0x14D] = ~ioamhram[0x14D] & 0x80; - doubleSpeed = ioamhram[0x14D] >> 7; - - display.postSpeedChange(cycleCounter); - - if (hdma_transfer) { - next_dmatime = display.nextHdmaTime(cycleCounter); - next_hdmaReschedule = display.nextHdmaTimeInvalid(); - } - - next_blittime = (ioamhram[0x140] & 0x80) ? display.nextMode1IrqTime() : static_cast(COUNTER_DISABLED); - next_endtime = cycleCounter + (isDoubleSpeed() ?( next_endtime - cycleCounter) << 1 : ((next_endtime - cycleCounter) >> 1)); - set_irqEvent(); - rescheduleIrq(cycleCounter); - set_event(); - } -} - -static void decCycles(unsigned long &counter, const unsigned long dec) { - if (counter != Memory::COUNTER_DISABLED) - counter -= dec; -} - -unsigned long Memory::resetCounters(unsigned long cycleCounter) { - std::printf("resetting counters\n"); - - if (lastOamDmaUpdate != COUNTER_DISABLED) - updateOamDma(cycleCounter); - - update_irqEvents(cycleCounter); - rescheduleIrq(cycleCounter); - display.preResetCounter(cycleCounter); - - const unsigned long oldCC = cycleCounter; - - { - const unsigned long divinc = (cycleCounter - div_lastUpdate) >> 8; - ioamhram[0x104] = (ioamhram[0x104] + divinc) & 0xFF; - div_lastUpdate += divinc << 8; - } - - if (ioamhram[0x107] & 0x04) { - update_tima(cycleCounter); - } - - const unsigned long dec = cycleCounter < 0x10000 ? 0 : (cycleCounter & ~0x7FFFul) - 0x8000; - - minIntTime = minIntTime < cycleCounter ? 0 : minIntTime - dec; - - if (ioamhram[0x107] & 0x04) - decCycles(tima_lastUpdate, dec); - - decCycles(div_lastUpdate, dec); - decCycles(lastOamDmaUpdate, dec); - decCycles(next_eventtime, dec); - decCycles(next_irqEventTime, dec); - decCycles(next_timatime, dec); - decCycles(next_blittime, dec); - decCycles(nextOamEventTime, dec); - decCycles(next_endtime, dec); - decCycles(next_dmatime, dec); - decCycles(next_hdmaReschedule, dec); - decCycles(nextIntTime, dec); - decCycles(next_serialtime, dec); - decCycles(tmatime, dec); - decCycles(next_unhalttime, dec); - - cycleCounter -= dec; - - display.postResetCounter(oldCC, cycleCounter); - sound.resetCounter(cycleCounter, oldCC, isDoubleSpeed()); - - return cycleCounter; -} - -void Memory::updateVideo(unsigned cycleCounter) { - return display.update(cycleCounter); -} - -unsigned Memory::lyCounter(unsigned cycleCounter) { - return display.getLyReg(cycleCounter); -} - -void Memory::updateInput() { - unsigned joypadId = 0x0F; - unsigned button = 0xFF; - unsigned dpad = 0xFF; - - if (getInput) { - const Gambatte::InputState &is = (*getInput)(); - - joypadId = is.joypadId; - - button ^= is.startButton << 3; - button ^= is.selectButton << 2; - button ^= is.bButton << 1; - button ^= is.aButton; - - dpad ^= is.dpadDown << 3; - dpad ^= is.dpadUp << 2; - dpad ^= is.dpadLeft << 1; - dpad ^= is.dpadRight; - } - - ioamhram[0x100] |= 0xF; - - if ((ioamhram[0x100] & 0x30) == 0x30) { - ioamhram[0x100] &= 0xf0; - ioamhram[0x100] |= joypadId; - } else { - if (!(ioamhram[0x100] & 0x10)) - ioamhram[0x100] &= dpad; - - if (!(ioamhram[0x100] & 0x20)) - ioamhram[0x100] &= button; - } -} - -void Memory::setRombank() { - unsigned bank = rombank; - - if ((romtype == mbc1 && !(bank & 0x1F)) || (romtype == mbc5 && !bank)) - ++bank; - - romdata[1] = romdata[0] + bank * 0x4000ul - 0x4000; - - if (oamDmaArea1Lower != 0xA0) { - rmem[0x7] = rmem[0x6] = rmem[0x5] = rmem[0x4] = romdata[1]; - } else - setOamDmaSrc(); -} - -void Memory::setRambank() { - rmem[0xB] = rmem[0xA] = rsrambankptr = rdisabled_ram - 0xA000; - wmem[0xB] = wmem[0xA] = wsrambankptr = wdisabled_ram - 0xA000; - - if (enable_ram) { - if (rtc.getActive()) { - wmem[0xB] = wmem[0xA] = rmem[0xB] = rmem[0xA] = wsrambankptr = rsrambankptr = NULL; - } else if (rambanks) { - wmem[0xB] = rmem[0xB] = wmem[0xA] = rmem[0xA] = wsrambankptr = rsrambankptr = rambankdata + rambank * 0x2000ul - 0xA000; - } - } - - if (oamDmaArea1Lower == 0xA0) { - wmem[0xB] = wmem[0xA] = rmem[0xB] = rmem[0xA] = NULL; - setOamDmaSrc(); - } -} - -void Memory::setBanks() { - rmem[0x3] = rmem[0x2] = rmem[0x1] = rmem[0x0] = romdata[0]; - - setRombank(); - setRambank(); - - rmem[0xC] = wmem[0xC] = wramdata[0] - 0xC000; - rmem[0xD] = wmem[0xD] = wramdata[1] - 0xD000; - rmem[0xE] = wmem[0xE] = wramdata[0] - 0xE000; -} - -void Memory::updateOamDma(const unsigned long cycleCounter) { - unsigned cycles = (cycleCounter - lastOamDmaUpdate) >> 2; - - while (cycles--) { - oamDmaPos = (oamDmaPos + 1) & 0xFF; - lastOamDmaUpdate += 4; - - //TODO: reads from vram while the ppu is reading vram should return whatever the ppu is reading. - if (oamDmaPos < 0xA0) { - if (oamDmaPos == 0) - startOamDma(lastOamDmaUpdate - 2); - - ioamhram[oamDmaPos] = oamDmaSrc ? oamDmaSrc[oamDmaPos] : *rtc.getActive(); - } else if (oamDmaPos == 0xA0) { - endOamDma(lastOamDmaUpdate - 2); - lastOamDmaUpdate = COUNTER_DISABLED; - break; - } - } -} - -void Memory::setOamDmaArea() { - if (ioamhram[0x146] < 0xC0) { - if ((ioamhram[0x146] & 0xE0) != 0x80) - oamDmaArea2Upper = 0x80; - - oamDmaArea1Width = 0x20; - } else if (ioamhram[0x146] < 0xE0) - oamDmaArea1Width = 0x3E; -} - -void Memory::oamDmaInitSetup() { - if (ioamhram[0x146] < 0xC0) { - if ((ioamhram[0x146] & 0xE0) == 0x80) { - oamDmaArea1Lower = 0x80; - } else { - oamDmaArea1Lower = 0xA0; - std::fill_n(rmem, 0x8, static_cast(NULL)); - rmem[0xB] = rmem[0xA] = NULL; - wmem[0xB] = wmem[0xA] = NULL; - } - } else if (ioamhram[0x146] < 0xE0) { - oamDmaArea1Lower = 0xC0; - rmem[0xE] = rmem[0xD] = rmem[0xC] = NULL; - wmem[0xE] = wmem[0xD] = wmem[0xC] = NULL; - } -} - -void Memory::setOamDmaSrc() { - oamDmaSrc = NULL; - - if (ioamhram[0x146] < 0xC0) { - if ((ioamhram[0x146] & 0xE0) == 0x80) { - oamDmaSrc = vrambank + (ioamhram[0x146] << 8 & 0x1FFF); - } else { - if (ioamhram[0x146] < 0x80) - oamDmaSrc = romdata[ioamhram[0x146] >> 6] + (ioamhram[0x146] << 8); - else if (rsrambankptr) - oamDmaSrc = rsrambankptr + (ioamhram[0x146] << 8); - } - } else if (ioamhram[0x146] < 0xE0) { - oamDmaSrc = wramdata[ioamhram[0x146] >> 4 & 1] + (ioamhram[0x146] << 8 & 0xFFF); - } else - oamDmaSrc = rdisabled_ram; -} - -void Memory::startOamDma(const unsigned long cycleCounter) { - setOamDmaArea(); - display.oamChange(rdisabled_ram, cycleCounter); - - if (next_unhalttime != COUNTER_DISABLED) - schedule_unhalt(); - else - rescheduleIrq(cycleCounter); - - rescheduleHdmaReschedule(); -} - -void Memory::endOamDma(const unsigned long cycleCounter) { - oamDmaArea2Upper = oamDmaArea1Width = oamDmaArea1Lower = 0; - oamDmaPos = 0xFE; - setBanks(); - display.oamChange(ioamhram, cycleCounter); - - if (next_unhalttime != COUNTER_DISABLED) - schedule_unhalt(); - else - rescheduleIrq(cycleCounter); - - rescheduleHdmaReschedule(); -} - -void Memory::update_tima(const unsigned long cycleCounter) { - const unsigned long ticks = (cycleCounter - tima_lastUpdate) >> timaClock[ioamhram[0x107] & 3]; - - tima_lastUpdate += ticks << timaClock[ioamhram[0x107] & 3]; - - if (cycleCounter >= tmatime) { - if (cycleCounter >= tmatime + 4) - tmatime = COUNTER_DISABLED; - - ioamhram[0x105] = ioamhram[0x106]; - } - - unsigned long tmp = ioamhram[0x105] + ticks; - - while (tmp > 0x100) - tmp -= 0x100 - ioamhram[0x106]; - - if (tmp == 0x100) { - tmp = 0; - tmatime = tima_lastUpdate + 3; - - if (cycleCounter >= tmatime) { - if (cycleCounter >= tmatime + 4) - tmatime = COUNTER_DISABLED; - - tmp = ioamhram[0x106]; - } - } - - ioamhram[0x105] = tmp; -} - -unsigned Memory::nontrivial_ff_read(const unsigned P, const unsigned long cycleCounter) { - if (lastOamDmaUpdate != COUNTER_DISABLED) - updateOamDma(cycleCounter); - - switch (P & 0x7F) { - case 0x00: - updateInput(); - break; - case 0x04: -// printf("div read\n"); - { - const unsigned long divcycles = (cycleCounter - div_lastUpdate) >> 8; - ioamhram[0x104] = (ioamhram[0x104] + divcycles) & 0xFF; - div_lastUpdate += divcycles << 8; - } - - break; - case 0x05: -// printf("tima read\n"); - if (ioamhram[0x107] & 0x04) - update_tima(cycleCounter); - - break; - case 0x0F: - update_irqEvents(cycleCounter); - ioamhram[0x10F] |= display.getIfReg(cycleCounter) & 3; -// rescheduleIrq(cycleCounter); - break; - case 0x26: -// printf("sound status read\n"); - if (ioamhram[0x126] & 0x80) { - sound.generate_samples(cycleCounter, isDoubleSpeed()); - ioamhram[0x126] = 0xF0 | sound.getStatus(); - } else - ioamhram[0x126] = 0x70; - - break; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - sound.generate_samples(cycleCounter, isDoubleSpeed()); - return sound.waveRamRead(P & 0xF); - case 0x41: - return ioamhram[0x141] | display.get_stat(ioamhram[0x145], cycleCounter); - case 0x44: - return display.getLyReg(cycleCounter/*+4*/); - case 0x69: - return display.cgbBgColorRead(ioamhram[0x168] & 0x3F, cycleCounter); - case 0x6B: - return display.cgbSpColorRead(ioamhram[0x16A] & 0x3F, cycleCounter); - default: break; - } - - return ioamhram[P - 0xFE00]; -} - -unsigned Memory::nontrivial_read(const unsigned P, const unsigned long cycleCounter) { - if (P < 0xFF80) { - if (lastOamDmaUpdate != COUNTER_DISABLED) { - updateOamDma(cycleCounter); - - if ((P >> 8) - oamDmaArea1Lower < oamDmaArea1Width || P >> 8 < oamDmaArea2Upper) - return ioamhram[oamDmaPos]; - } - - if (P < 0xC000) { - if (P < 0x8000) - return romdata[P >> 14][P]; - - if (P < 0xA000) { - if (!display.vramAccessible(cycleCounter)) - return 0xFF; - - return vrambank[P & 0x1FFF]; - } - - if (rsrambankptr) - return rsrambankptr[P]; - - return *rtc.getActive(); - } - - if (P < 0xFE00) - return wramdata[P >> 12 & 1][P & 0xFFF]; - - if (P & 0x100) - return nontrivial_ff_read(P, cycleCounter); - - if (!display.oamAccessible(cycleCounter) || oamDmaPos < 0xA0) - return 0xFF; - } - - return ioamhram[P - 0xFE00]; -} - -void Memory::nontrivial_ff_write(const unsigned P, unsigned data, const unsigned long cycleCounter) { -// printf("mem[0x%X] = 0x%X\n", P, data); - - if (lastOamDmaUpdate != COUNTER_DISABLED) - updateOamDma(cycleCounter); - - switch (P & 0xFF) { - case 0x00: - data = (ioamhram[0x100] & 0xCF) | (data & 0xF0); - if(memoryInterface) memoryInterface->joypWrite(data & 0x20, data & 0x10); - break; - case 0x01: - update_irqEvents(cycleCounter); - break; - case 0x02: - update_irqEvents(cycleCounter); - - if ((data & 0x81) == 0x81) { - next_serialtime = cycleCounter; - next_serialtime += (isCgb() && (data & 0x2)) ? 128 : 4096; - set_irqEvent(); - } - - rescheduleIrq(cycleCounter); - data |= 0x7C; - break; - //If rom is trying to write to DIV register, reset it to 0. - case 0x04: -// printf("DIV write\n"); - ioamhram[0x104] = 0; - div_lastUpdate = cycleCounter; - return; - case 0x05: - // printf("tima write\n"); - if (ioamhram[0x107] & 0x04) { - update_irqEvents(cycleCounter); - update_tima(cycleCounter); - - if (tmatime - cycleCounter < 4) - tmatime = COUNTER_DISABLED; - - next_timatime = tima_lastUpdate + ((256u - data) << timaClock[ioamhram[0x107] & 3]) + 1; - set_irqEvent(); - rescheduleIrq(cycleCounter); - } - - break; - case 0x06: - if (ioamhram[0x107] & 0x04) { - update_irqEvents(cycleCounter); - update_tima(cycleCounter); - } - - break; - case 0x07: - // printf("tac write: %i\n", data); - data |= 0xF8; - - if (ioamhram[0x107] ^ data) { - if (ioamhram[0x107] & 0x04) { - update_irqEvents(cycleCounter); - update_tima(cycleCounter); - - tima_lastUpdate -= (1u << (timaClock[ioamhram[0x107] & 3] - 1)) + 3; - tmatime -= (1u << (timaClock[ioamhram[0x107] & 3] - 1)) + 3; - next_timatime -= (1u << (timaClock[ioamhram[0x107] & 3] - 1)) + 3; - set_irqEvent(); - update_tima(cycleCounter); - update_irqEvents(cycleCounter); - - tmatime = COUNTER_DISABLED; - next_timatime = COUNTER_DISABLED; - } - - if (data & 4) { - tima_lastUpdate = (cycleCounter >> timaClock[data & 3]) << timaClock[data & 3]; - next_timatime = tima_lastUpdate + ((256u - ioamhram[0x105]) << timaClock[data & 3]) + 1; - } - - set_irqEvent(); - rescheduleIrq(cycleCounter); - } - - break; - case 0x0F: - update_irqEvents(cycleCounter); - display.setIfReg(data, cycleCounter); - ioamhram[0x10F] = 0xE0 | data; - rescheduleIrq(cycleCounter); - return; - case 0x10: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr10(data); - data |= 0x80; - break; - case 0x11: - if(!sound.isEnabled()) { - if (isCgb()) - return; - - data &= 0x3F; - } - - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr11(data); - data |= 0x3F; - break; - case 0x12: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr12(data); - break; - case 0x13: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr13(data); - return; - case 0x14: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr14(data); - data |= 0xBF; - break; - case 0x16: - if(!sound.isEnabled()) { - if (isCgb()) - return; - - data &= 0x3F; - } - - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr21(data); - data |= 0x3F; - break; - case 0x17: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr22(data); - break; - case 0x18: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr23(data); - return; - case 0x19: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr24(data); - data |= 0xBF; - break; - case 0x1A: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr30(data); - data |= 0x7F; - break; - case 0x1B: - if(!sound.isEnabled() && isCgb()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr31(data); - return; - case 0x1C: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr32(data); - data |= 0x9F; - break; - case 0x1D: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr33(data); - return; - case 0x1E: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr34(data); - data |= 0xBF; - break; - case 0x20: - if(!sound.isEnabled() && isCgb()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr41(data); - return; - case 0x21: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr42(data); - break; - case 0x22: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr43(data); - break; - case 0x23: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_nr44(data); - data |= 0xBF; - break; - case 0x24: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.set_so_volume(data); - break; - case 0x25: - if(!sound.isEnabled()) return; - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.map_so(data); - break; - case 0x26: - if ((ioamhram[0x126] ^ data) & 0x80) { - sound.generate_samples(cycleCounter, isDoubleSpeed()); - - if (!(data & 0x80)) { - for (unsigned i = 0xFF10; i < 0xFF26; ++i) - ff_write(i, 0, cycleCounter); - -// std::memcpy(memory + 0xFF10, soundRegInitValues, sizeof(soundRegInitValues)); - sound.setEnabled(false); - } else { - sound.reset(/*memory + 0xFF00, isDoubleSpeed()*/); - sound.setEnabled(true); - } - } - - data = (data & 0x80) | (ioamhram[0x126] & 0x7F); - break; - case 0x30: - case 0x31: - case 0x32: - case 0x33: - case 0x34: - case 0x35: - case 0x36: - case 0x37: - case 0x38: - case 0x39: - case 0x3A: - case 0x3B: - case 0x3C: - case 0x3D: - case 0x3E: - case 0x3F: - sound.generate_samples(cycleCounter, isDoubleSpeed()); - sound.waveRamWrite(P & 0xF, data); - break; - case 0x40: - if (ioamhram[0x140] != data) { - if ((ioamhram[0x140] ^ data) & 0x80) { - update_irqEvents(cycleCounter); - const unsigned lyc = display.get_stat(ioamhram[0x145], cycleCounter) & 4; - display.enableChange(cycleCounter); - ioamhram[0x144] = 0; -// enable_display = bool(data & 0x80); - ioamhram[0x141] &= 0xF8; - - if (data & 0x80) { - next_blittime = display.nextMode1IrqTime() + (70224 << isDoubleSpeed()); - } else { - ioamhram[0x141] |= lyc; //Mr. Do! needs conicidence flag preserved. - next_blittime = cycleCounter + (456 * 4 << isDoubleSpeed()); - - if (hdma_transfer) - next_dmatime = cycleCounter; - - next_hdmaReschedule = COUNTER_DISABLED; - } - - set_event(); - } - - if ((ioamhram[0x140] ^ data) & 0x4) { - display.spriteSizeChange(data & 0x4, cycleCounter); - } - - if ((ioamhram[0x140] ^ data) & 0x20) { -// printf("%u: weChange to %u\n", CycleCounter, (data & 0x20) != 0); - display.weChange(data & 0x20, cycleCounter); - } - - if ((ioamhram[0x140] ^ data) & 0x40) - display.wdTileMapSelectChange(data & 0x40, cycleCounter); - - if ((ioamhram[0x140] ^ data) & 0x08) - display.bgTileMapSelectChange(data & 0x08, cycleCounter); - - if ((ioamhram[0x140] ^ data) & 0x10) - display.bgTileDataSelectChange(data & 0x10, cycleCounter); - - if ((ioamhram[0x140] ^ data) & 0x02) - display.spriteEnableChange(data & 0x02, cycleCounter); - - if ((ioamhram[0x140] ^ data) & 0x01) - display.bgEnableChange(data & 0x01, cycleCounter); - - ioamhram[0x140] = data; - rescheduleIrq(cycleCounter); - rescheduleHdmaReschedule(); - } - - return; - case 0x41: - display.lcdstatChange(data, cycleCounter); - rescheduleIrq(cycleCounter); - data = (ioamhram[0x141] & 0x87) | (data & 0x78); - break; - case 0x42: - display.scyChange(data, cycleCounter); - break; - case 0x43: - display.scxChange(data, cycleCounter); - rescheduleIrq(cycleCounter); - rescheduleHdmaReschedule(); - break; - //If rom is trying to write to LY register, reset it to 0. - case 0x44: - if (ioamhram[0x140] & 0x80) { - std::printf("ly write\n"); - display.lyWrite(cycleCounter); - rescheduleIrq(cycleCounter); - rescheduleHdmaReschedule(); - } - - return; - case 0x45: - display.lycRegChange(data, cycleCounter); - rescheduleIrq(cycleCounter); - break; - case 0x46: - if (lastOamDmaUpdate != COUNTER_DISABLED) - endOamDma(cycleCounter); - - lastOamDmaUpdate = cycleCounter; - nextOamEventTime = cycleCounter + 8; - ioamhram[0x146] = data; - oamDmaInitSetup(); - setOamDmaSrc(); - return; - case 0x47: - if (!isCgb()) { - display.dmgBgPaletteChange(data, cycleCounter); - } - - break; - case 0x48: - if (!isCgb()) { - display.dmgSpPalette1Change(data, cycleCounter); - } - - break; - case 0x49: - if (!isCgb()) { - display.dmgSpPalette2Change(data, cycleCounter); - } - - break; - case 0x4A: -// printf("%u: wyChange to %u\n", CycleCounter, data); - display.wyChange(data, cycleCounter); - rescheduleIrq(cycleCounter); - rescheduleHdmaReschedule(); - break; - case 0x4B: -// printf("%u: wxChange to %u\n", CycleCounter, data); - display.wxChange(data, cycleCounter); - rescheduleIrq(cycleCounter); - rescheduleHdmaReschedule(); - break; - - //cgb stuff: - case 0x4D: - ioamhram[0x14D] |= data & 0x01; - return; - //Select vram bank - case 0x4F: - if (isCgb()) { - vrambank = vram + (data & 0x01) * 0x2000; - - if (oamDmaArea1Lower == 0x80) - setOamDmaSrc(); - - ioamhram[0x14F] = 0xFE | data; - } - - return; - case 0x51: - dmaSource = data << 8 | (dmaSource & 0xFF); - return; - case 0x52: - dmaSource = (dmaSource & 0xFF00) | (data & 0xF0); - return; - case 0x53: - dmaDestination = data << 8 | (dmaDestination & 0xFF); - return; - case 0x54: - dmaDestination = (dmaDestination & 0xFF00) | (data & 0xF0); - return; - case 0x55: - if (!isCgb()) - return; - - ioamhram[0x155] = data & 0x7F; - - if (hdma_transfer) { - if (!(data & 0x80)) { - ioamhram[0x155] |= 0x80; - - if (next_dmatime > cycleCounter) { - hdma_transfer = 0; - next_hdmaReschedule = next_dmatime = COUNTER_DISABLED; - set_event(); - } - } - - return; - } - - if (data & 0x80) { - hdma_transfer = 1; - - if (!(ioamhram[0x140] & 0x80) || display.isHdmaPeriod(cycleCounter)) { - next_dmatime = cycleCounter; - next_hdmaReschedule = COUNTER_DISABLED; - } else { - next_dmatime = display.nextHdmaTime(cycleCounter); - next_hdmaReschedule = display.nextHdmaTimeInvalid(); - } - } else - next_dmatime = cycleCounter; - - set_event(); - return; - case 0x56: - if (isCgb()) { - ioamhram[0x156] = data | 0x3E; - } - - return; - //Set bg palette index - case 0x68: - if (isCgb()) - ioamhram[0x168] = data | 0x40; - - return; - //Write to bg palette data - case 0x69: - if (isCgb()) { - const unsigned index = ioamhram[0x168] & 0x3F; - - display.cgbBgColorChange(index, data, cycleCounter); - - ioamhram[0x168] = (ioamhram[0x168] & ~0x3F) | ((index + (ioamhram[0x168] >> 7)) & 0x3F); - } - - return; - case 0x6A: - if (isCgb()) - ioamhram[0x16A] = data | 0x40; - - return; - //Write to obj palette data. - case 0x6B: - if (isCgb()) { - const unsigned index = ioamhram[0x16A] & 0x3F; - - display.cgbSpColorChange(index, data, cycleCounter); - - ioamhram[0x16A] = (ioamhram[0x16A] & ~0x3F) | ((index + (ioamhram[0x16A] >> 7)) & 0x3F); - } - - return; - case 0x6C: - if (isCgb()) - ioamhram[0x16C] = data | 0xFE; - - return; - case 0x70: - if (isCgb()) { - wramdata[1] = wramdata[0] + ((data & 0x07) ? (data & 0x07) : 1) * 0x1000; - - if (oamDmaArea1Lower == 0xC0) - setOamDmaSrc(); - else - wmem[0xD] = rmem[0xD] = wramdata[1] - 0xD000; - - ioamhram[0x170] = data | 0xF8; - } - - return; - case 0x72: - case 0x73: - case 0x74: - if (isCgb()) - break; - - return; - case 0x75: - if (isCgb()) - ioamhram[0x175] = data | 0x8F; - - return; - case 0xFF: - ioamhram[0x1FF] = data; - rescheduleIrq(cycleCounter); - return; - default: -// if (P < 0xFF80) - return; - } - - ioamhram[P - 0xFE00] = data; -} - -void Memory::mbc_write(const unsigned P, const unsigned data) { -// printf("mem[0x%X] = 0x%X\n", P, data); - - switch (P >> 12 & 0x7) { - case 0x0: - case 0x1: //Most MBCs write 0x?A to addresses lower than 0x2000 to enable ram. - if (romtype == mbc2 && (P & 0x0100)) break; - - enable_ram = (data & 0x0F) == 0xA; - - if (rtcRom) - rtc.setEnabled(enable_ram); - - setRambank(); - break; - //MBC1 writes ???n nnnn to address area 0x2000-0x3FFF, ???n nnnn makes up the lower digits to determine which rombank to load. - //MBC3 writes ?nnn nnnn to address area 0x2000-0x3FFF, ?nnn nnnn makes up the lower digits to determine which rombank to load. - //MBC5 writes nnnn nnnn to address area 0x2000-0x2FFF, nnnn nnnn makes up the lower digits to determine which rombank to load. - //MBC5 writes bit8 of the number that determines which rombank to load to address 0x3000-0x3FFF. - case 0x2: - switch (romtype) { - case plain: - return; - case mbc5: - rombank = (rombank & 0x100) | data; - rombank = rombank & (rombanks - 1); - setRombank(); - return; - default: - break; //Only supposed to break one level. - } - case 0x3: - switch (romtype) { - case mbc1: - rombank = rambank_mode ? data & 0x1F : ((rombank & 0x60) | (data & 0x1F)); - break; - case mbc2: - if (P & 0x0100) { - rombank = data & 0x0F; - break; - } - - return; - case mbc3: - rombank = data & 0x7F; - break; - case mbc5: - rombank = (data & 0x1) << 8 | (rombank & 0xFF); - break; - default: - return; - } - - rombank = rombank & (rombanks - 1); - setRombank(); - break; - //MBC1 writes ???? ??nn to area 0x4000-0x5FFF either to determine rambank to load, or upper 2 bits of the rombank number to load, depending on rom-mode. - //MBC3 writes ???? ??nn to area 0x4000-0x5FFF to determine rambank to load - //MBC5 writes ???? nnnn to area 0x4000-0x5FFF to determine rambank to load - case 0x4: - case 0x5: - switch (romtype) { - case mbc1: - if (rambank_mode) { - rambank = data & 0x03; - break; - } - - rombank = (data & 0x03) << 5 | (rombank & 0x1F); - rombank = rombank & (rombanks - 1); - setRombank(); - return; - case mbc3: - if (rtcRom) - rtc.swapActive(data); - - rambank = data & 0x03; - break; - case mbc5: - rambank = data & 0x0F; - break; - default: - return; - } - - rambank &= rambanks - 1; - setRambank(); - break; - //MBC1: If ???? ???1 is written to area 0x6000-0x7FFFF rom will be set to rambank mode. - case 0x6: - case 0x7: - switch (romtype) { - case mbc1: - rambank_mode = data & 0x01; - break; - case mbc3: - rtc.latch(data); - break; - default: - break; - } - - break; -// default: break; - } -} - -void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { - if (lastOamDmaUpdate != COUNTER_DISABLED) { - updateOamDma(cycleCounter); - - if ((P >> 8) - oamDmaArea1Lower < oamDmaArea1Width || P >> 8 < oamDmaArea2Upper) { - ioamhram[oamDmaPos] = data; - return; - } - } - - if (P < 0xFE00) { - if (P < 0xA000) { - if (P < 0x8000) { - mbc_write(P, data); - } else if (display.vramAccessible(cycleCounter)) { - display.vramChange(cycleCounter); - vrambank[P & 0x1FFF] = data; - } - } else if (P < 0xC000) { - if (wsrambankptr) - wsrambankptr[P] = data; - else - rtc.write(data); - } else - wramdata[P >> 12 & 1][P & 0xFFF] = data; - } else if (((P + 1) & 0xFFFF) < 0xFF81) { - if (P < 0xFF00) { - if (display.oamAccessible(cycleCounter) && oamDmaPos >= 0xA0) { - display.oamChange(cycleCounter); - rescheduleIrq(cycleCounter); - rescheduleHdmaReschedule(); - ioamhram[P - 0xFE00] = data; - } - } else - nontrivial_ff_write(P, data, cycleCounter); - } else - ioamhram[P - 0xFE00] = data; -} - -static const std::string stripExtension(const std::string &str) { - const std::string::size_type lastDot = str.find_last_of('.'); - const std::string::size_type lastSlash = str.find_last_of('/'); - - if (lastDot != std::string::npos && (lastSlash == std::string::npos || lastSlash < lastDot)) - return str.substr(0, lastDot); - - return str; -} - -static const std::string stripDir(const std::string &str) { - const std::string::size_type lastSlash = str.find_last_of('/'); - - if (lastSlash != std::string::npos) - return str.substr(lastSlash + 1); - - return str; -} - -const std::string Memory::saveBasePath() const { - return saveDir.empty() ? defaultSaveBasePath : saveDir + stripDir(defaultSaveBasePath); -} - -void Memory::set_savedir(const char *dir) { - saveDir = dir ? dir : ""; - - if (!saveDir.empty() && saveDir[saveDir.length() - 1] != '/') { - saveDir += '/'; - } -} - -static void enforce8bit(unsigned char *data, unsigned long sz) { - if (static_cast(0x100)) - while (sz--) - *data++ &= 0xFF; -} - -static unsigned pow2ceil(unsigned n) { - --n; - n |= n >> 1; - n |= n >> 2; - n |= n >> 4; - n |= n >> 8; - ++n; - - return n; -} - -bool Memory::loadROM(const bool forceDmg) { - if (!memoryInterface) return 1; - - defaultSaveBasePath = stripExtension(""); //(romfile); - - File rom(""); - - //if (!rom.is_open()) { - // return 1; - //} - - Gambatte::MemoryBuffer romBuffer = memoryInterface->loadRomData(); - if(romBuffer.size < 0x150) return 1; - - { - unsigned char *header = (unsigned char*)romBuffer.data; - //rom.read(reinterpret_cast(header), sizeof(header)); - - cgb = header[0x0143] >> 7 & 1; - - if (cgb & forceDmg) { - cgb = false; - //defaultSaveBasePath += "_dmg"; - } - - switch (header[0x0147]) { - case 0x00: //std::printf("Plain ROM loaded.\n"); - romtype = plain; - break; - case 0x01: //std::printf("MBC1 ROM loaded.\n"); - romtype = mbc1; - break; - case 0x02: //std::printf("MBC1 ROM+RAM loaded.\n"); - romtype = mbc1; - break; - case 0x03: //std::printf("MBC1 ROM+RAM+BATTERY loaded.\n"); - romtype = mbc1; - battery = 1; - break; - case 0x05: //std::printf("MBC2 ROM loaded.\n"); - romtype = mbc2; - break; - case 0x06: //std::printf("MBC2 ROM+BATTERY loaded.\n"); - romtype = mbc2; - battery = 1; - break; - case 0x08: //std::printf("Plain ROM with additional RAM loaded.\n"); - break; - case 0x09: //std::printf("Plain ROM with additional RAM and Battery loaded.\n"); - battery = 1; - break; - case 0x0B: /*cout << "MM01 ROM not supported.\n";*/ - return 1; - break; - case 0x0C: /*cout << "MM01 ROM not supported.\n";*/ - return 1; - break; - case 0x0D: /*cout << "MM01 ROM not supported.\n";*/ - return 1; - break; - case 0x0F: //std::printf("MBC3 ROM+TIMER+BATTERY loaded.\n"); - romtype = mbc3; - battery = true; - rtcRom = true; - break; - case 0x10: //std::printf("MBC3 ROM+TIMER+RAM+BATTERY loaded.\n"); - romtype = mbc3; - battery = true; - rtcRom = true; - break; - case 0x11: //std::printf("MBC3 ROM loaded.\n"); - romtype = mbc3; - break; - case 0x12: //std::printf("MBC3 ROM+RAM loaded.\n"); - romtype = mbc3; - break; - case 0x13: //std::printf("MBC3 ROM+RAM+BATTERY loaded.\n"); - romtype = mbc3; - battery = 1; - break; - case 0x15: /*cout << "MBC4 ROM not supported.\n";*/ - return 1; - break; - case 0x16: /*cout << "MBC4 ROM not supported.\n";*/ - return 1; - break; - case 0x17: /*cout << "MBC4 ROM not supported.\n";*/ - return 1; - break; - case 0x19: //std::printf("MBC5 ROM loaded.\n"); - romtype = mbc5; - break; - case 0x1A: //std::printf("MBC5 ROM+RAM loaded.\n"); - romtype = mbc5; - break; - case 0x1B: //std::printf("MBC5 ROM+RAM+BATTERY loaded.\n"); - romtype = mbc5; - battery = 1; - break; - case 0x1C: //std::printf("MBC5+RUMLE ROM not supported.\n"); - romtype = mbc5; - break; - case 0x1D: //std::printf("MBC5+RUMLE+RAM ROM not suported.\n"); - romtype = mbc5; - break; - case 0x1E: //std::printf("MBC5+RUMLE+RAM+BATTERY ROM not supported.\n"); - romtype = mbc5; - battery = 1; - break; - case 0xFC: /*cout << "Pocket Camera ROM not supported.\n";*/ - return 1; - break; - case 0xFD: /*cout << "Bandai TAMA5 ROM not supported.\n";*/ - return 1; - break; - case 0xFE: /*cout << "HuC3 ROM not supported.\n";*/ - return 1; - break; - case 0xFF: /*cout << "HuC1 ROM not supported.\n";*/ - return 1; - break; - default: /*cout << "Wrong data-format, corrupt or unsupported ROM loaded.\n";*/ - return 1; - } - - /*switch (header[0x0148]) { - case 0x00: - rombanks = 2; - break; - case 0x01: - rombanks = 4; - break; - case 0x02: - rombanks = 8; - break; - case 0x03: - rombanks = 16; - break; - case 0x04: - rombanks = 32; - break; - case 0x05: - rombanks = 64; - break; - case 0x06: - rombanks = 128; - break; - case 0x07: - rombanks = 256; - break; - case 0x08: - rombanks = 512; - break; - case 0x52: - rombanks = 72; - break; - case 0x53: - rombanks = 80; - break; - case 0x54: - rombanks = 96; - break; - default: - return 1; - } - - printf("rombanks: %u\n", rombanks);*/ - - switch (header[0x0149]) { - case 0x00: /*cout << "No RAM\n";*/ rambanks = romtype == mbc2; break; - case 0x01: /*cout << "2kB RAM\n";*/ /*rambankrom=1; break;*/ - case 0x02: /*cout << "8kB RAM\n";*/ - rambanks = 1; - break; - case 0x03: /*cout << "32kB RAM\n";*/ - rambanks = 4; - break; - case 0x04: /*cout << "128kB RAM\n";*/ - rambanks = 16; - break; - case 0x05: /*cout << "undocumented kB RAM\n";*/ - rambanks = 16; - break; - default: /*cout << "Wrong data-format, corrupt or unsupported ROM loaded.\n";*/ - rambanks = 16; - break; - } - } - - //std::printf("rambanks: %u\n", rambanks); - - rombanks = pow2ceil(romBuffer.size / 0x4000); - //std::printf("rombanks: %u\n", romBuffer.size / 0x4000); - - delete []memchunk; - memchunk = new unsigned char[0x4000 + rombanks * 0x4000ul + rambanks * 0x2000ul + (isCgb() ? 0x8000 : 0x2000) + 0x4000]; - - romdata[0] = memchunk + 0x4000; - rambankdata = romdata[0] + rombanks * 0x4000ul; - wramdata[0] = rambankdata + rambanks * 0x2000; - rdisabled_ram = wramdata[0] + (isCgb() ? 0x8000 : 0x2000); - wdisabled_ram = rdisabled_ram + 0x2000; - - wramdata[1] = wramdata[0] + 0x1000; - std::memset(rdisabled_ram, 0xFF, 0x2000); - - //rom.rewind(); - //rom.read(reinterpret_cast(romdata[0]), (romBuffer.size / 0x4000) * 0x4000ul); - memcpy(romdata[0], romBuffer.data, - std::min( romBuffer.size, (unsigned)((romBuffer.size / 0x4000) * 0x4000ul) ) - ); - - // In case rombanks isn't a power of 2, allocate a disabled area for invalid rombank addresses. This is only based on speculation. - std::memset(romdata[0] + (romBuffer.size / 0x4000) * 0x4000ul, 0xFF, (rombanks - romBuffer.size / 0x4000) * 0x4000ul); - enforce8bit(romdata[0], rombanks * 0x4000ul); - - //if (rom.fail()) - // return 1; - - sound.init(isCgb()); - display.reset(ioamhram, isCgb()); - - return 0; -} - -void Memory::loadSavedata() { - //const std::string &sbp = saveBasePath(); - - if (battery && memoryInterface) { -/* std::ifstream file((sbp + ".sav").c_str(), std::ios::binary | std::ios::in); - - if (file.is_open()) { - file.read(reinterpret_cast(rambankdata), rambanks * 0x2000ul); - enforce8bit(rambankdata, rambanks * 0x2000ul); - } */ - - Gambatte::MemoryBuffer buffer = memoryInterface->loadRamData(); - if (buffer.data) { - memcpy(rambankdata, buffer.data, std::min(buffer.size, (unsigned)(rambanks * 0x2000ul))); - enforce8bit(rambankdata, rambanks * 0x2000ul); - } - } - - if (rtcRom && memoryInterface) { -/* std::ifstream file((sbp + ".rtc").c_str(), std::ios::binary | std::ios::in); - - if (file.is_open()) { - unsigned long basetime = file.get() & 0xFF; - - basetime = basetime << 8 | (file.get() & 0xFF); - basetime = basetime << 8 | (file.get() & 0xFF); - basetime = basetime << 8 | (file.get() & 0xFF); - - rtc.setBaseTime(basetime); - } */ - - Gambatte::MemoryBuffer buffer = memoryInterface->loadRtcData(); - if (buffer.data && buffer.size >= 4) { - unsigned long basetime = 0; - uint8_t *data = (uint8_t*)buffer.data; - - basetime = basetime << 8 | (data[0]); - basetime = basetime << 8 | (data[1]); - basetime = basetime << 8 | (data[2]); - basetime = basetime << 8 | (data[3]); - - rtc.setBaseTime(basetime); - } - } -} - -void Memory::saveSavedata() { - //const std::string &sbp = saveBasePath(); - - if (battery && memoryInterface) { -/* std::ofstream file((sbp + ".sav").c_str(), std::ios::binary | std::ios::out); - - file.write(reinterpret_cast(rambankdata), rambanks * 0x2000ul); */ - - Gambatte::MemoryBuffer buffer = memoryInterface->saveRamData(rambanks * 0x2000ul); - if (buffer.data) { - memcpy(buffer.data, rambankdata, std::min(buffer.size, (unsigned)(rambanks * 0x2000ul))); - } - } - - if (rtcRom && memoryInterface) { -/* std::ofstream file((sbp + ".rtc").c_str(), std::ios::binary | std::ios::out); - const unsigned long basetime = rtc.getBaseTime(); - - file.put(basetime >> 24 & 0xFF); - file.put(basetime >> 16 & 0xFF); - file.put(basetime >> 8 & 0xFF); - file.put(basetime & 0xFF); */ - - Gambatte::MemoryBuffer buffer = memoryInterface->saveRtcData(); - if (buffer.data && buffer.size >= 4) { - const unsigned long basetime = rtc.getBaseTime(); - uint8_t *data = (uint8_t*)buffer.data; - - data[0] = basetime >> 24; - data[1] = basetime >> 16; - data[2] = basetime >> 8; - data[3] = basetime >> 0; - } - } -} - -unsigned Memory::fillSoundBuffer(const unsigned long cycleCounter) { - sound.generate_samples(cycleCounter, isDoubleSpeed()); - return sound.fillBuffer(); -} - -void Memory::setVideoBlitter(Gambatte::VideoBlitter *const vb) { - display.setVideoBlitter(vb); -} - -void Memory::videoBufferChange() { - display.videoBufferChange(); -} - -void Memory::setVideoFilter(const unsigned int n) { - display.setVideoFilter(n); -} - -void Memory::setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32) { - display.setDmgPaletteColor(palNum, colorNum, rgb32); -} - -Memory::~Memory() { - saveSavedata(); - - delete []memchunk; -} diff --git a/src/lib/libgambatte/src/memory.h b/src/lib/libgambatte/src/memory.h deleted file mode 100644 index 90c665c1..00000000 --- a/src/lib/libgambatte/src/memory.h +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef MEMORY_H -#define MEMORY_H - -class SaveState; - -#include "int.h" -#include "video.h" -#include "sound.h" - -#include "interrupter.h" -#include "rtc.h" -#include - -namespace Gambatte { -class InputStateGetter; -class MemoryInterface; -class FilterInfo; -} - -class Memory { -public: - enum { COUNTER_DISABLED = 0xFFFFFFFFu }; - -private: - enum cartridgetype { plain, mbc1, mbc2, mbc3, mbc5 }; - enum events { HDMA_RESCHEDULE, DMA, INTERRUPTS, BLIT, UNHALT, OAM, END }; - enum irqEvents { /*MODE0, MODE1, MODE2, LYC,*/ TIMA, /*M0RESC,*/ SERIAL }; - - unsigned char ioamhram[0x200]; - unsigned char vram[0x2000 * 2]; - unsigned char *rmem[0x10]; - unsigned char *wmem[0x10]; - - unsigned char *memchunk; - unsigned char *romdata[2]; - unsigned char *wramdata[2]; - unsigned char *rambankdata; - unsigned char *rdisabled_ram; - unsigned char *wdisabled_ram; - unsigned char *oamDmaSrc; - unsigned char *vrambank; - unsigned char *rsrambankptr; - unsigned char *wsrambankptr; - - Gambatte::InputStateGetter *getInput; - Gambatte::MemoryInterface *memoryInterface; - - unsigned long div_lastUpdate; - unsigned long tima_lastUpdate; - unsigned long next_timatime; - unsigned long next_blittime; - unsigned long nextIntTime; - unsigned long minIntTime; - unsigned long next_dmatime; - unsigned long next_hdmaReschedule; - unsigned long next_unhalttime; - unsigned long next_endtime; - unsigned long next_irqEventTime; - unsigned long tmatime; - unsigned long next_serialtime; - unsigned long next_eventtime; - unsigned long lastOamDmaUpdate; - unsigned long nextOamEventTime; - - LCD display; - PSG sound; - Interrupter interrupter; - Rtc rtc; - - events next_event; - irqEvents next_irqEvent; - cartridgetype romtype; - - std::string defaultSaveBasePath; - std::string saveDir; - - unsigned short rombanks; - unsigned short rombank; - unsigned short dmaSource; - unsigned short dmaDestination; - - unsigned char rambank; - unsigned char rambanks; - unsigned char oamDmaArea1Lower; - unsigned char oamDmaArea1Width; - unsigned char oamDmaArea2Upper; - unsigned char oamDmaPos; - - bool cgb; - bool doubleSpeed; - bool IME; - bool enable_ram; - bool rambank_mode; - bool battery, rtcRom; - bool hdma_transfer; - bool active; - - void updateInput(); - - void setRombank(); - void setRambank(); - void setBanks(); - void oamDmaInitSetup(); - void setOamDmaArea(); - void updateOamDma(unsigned long cycleCounter); - void startOamDma(unsigned long cycleCounter); - void endOamDma(unsigned long cycleCounter); - void setOamDmaSrc(); - - unsigned nontrivial_ff_read(unsigned P, unsigned long cycleCounter); - unsigned nontrivial_read(unsigned P, unsigned long cycleCounter); - void nontrivial_ff_write(unsigned P, unsigned data, unsigned long cycleCounter); - void mbc_write(unsigned P, unsigned data); - void nontrivial_write(unsigned P, unsigned data, unsigned long cycleCounter); - - void set_event(); - void set_irqEvent(); - void update_irqEvents(unsigned long cc); - void update_tima(unsigned long cycleCounter); - - void rescheduleIrq(unsigned long cycleCounter); - void rescheduleHdmaReschedule(); - - bool isDoubleSpeed() const { return doubleSpeed; } - -public: - Memory(const Interrupter &interrupter); - ~Memory(); - - void setStatePtrs(SaveState &state); - unsigned long saveState(SaveState &state, unsigned long cc); - void loadState(const SaveState &state, unsigned long oldCc); - void loadSavedata(); - void saveSavedata(); - const std::string saveBasePath() const; - - void setOsdElement(std::auto_ptr osdElement) { - display.setOsdElement(osdElement); - } - - void speedChange(unsigned long cycleCounter); - bool isCgb() const { return cgb; } - bool getIME() const { return IME; } - unsigned long getNextEventTime() const { return next_eventtime; } - - bool isActive() const { return active; } - - void ei(unsigned long cycleCounter); - - void di() { - IME = 0; - nextIntTime = COUNTER_DISABLED; - - if (next_event == INTERRUPTS) - set_event(); - -// next_eitime=0; -// if(next_event==EI) set_event(); - } - - unsigned ff_read(const unsigned P, const unsigned long cycleCounter) { - return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00]; - } - - unsigned read(const unsigned P, const unsigned long cycleCounter) { - return rmem[P >> 12] ? rmem[P >> 12][P] : nontrivial_read(P, cycleCounter); - } - - void write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { - if (wmem[P >> 12]) - wmem[P >> 12][P] = data; - else - nontrivial_write(P, data, cycleCounter); - } - - void ff_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { - if (((P + 1) & 0xFF) < 0x81) - nontrivial_ff_write(P, data, cycleCounter); - else - ioamhram[P - 0xFE00] = data; - } - - unsigned long event(unsigned long cycleCounter); - unsigned long resetCounters(unsigned long cycleCounter); - void updateVideo(unsigned cycleCounter); - unsigned lyCounter(unsigned cycleCounter); - - bool loadROM(bool forceDmg); - void set_savedir(const char *dir); - - void setInputStateGetter(Gambatte::InputStateGetter *getInput) { - this->getInput = getInput; - } - - void setMemoryInterface(Gambatte::MemoryInterface *memoryInterface) { - this->memoryInterface = memoryInterface; - } - - void schedule_unhalt(); - void incEndtime(unsigned long inc); - void setEndtime(unsigned long cc, unsigned long inc); - - void setSoundBuffer(Gambatte::uint_least32_t *const buf) { sound.setBuffer(buf); } - unsigned fillSoundBuffer(unsigned long cc); - void setVideoBlitter(Gambatte::VideoBlitter * vb); - void setVideoFilter(unsigned int n); - - void videoBufferChange(); - - unsigned videoWidth() const { - return display.videoWidth(); - } - - unsigned videoHeight() const { - return display.videoHeight(); - } - - std::vector filterInfo() const { - return display.filterInfo(); - } - - void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32); -}; - -#endif diff --git a/src/lib/libgambatte/src/osd_element.h b/src/lib/libgambatte/src/osd_element.h deleted file mode 100644 index 2517d34f..00000000 --- a/src/lib/libgambatte/src/osd_element.h +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef OSD_ELEMENT_H -#define OSD_ELEMENT_H - -#include "int.h" - -class OsdElement { -public: - enum Opacity { SEVEN_EIGHTHS, THREE_FOURTHS }; - -private: - Opacity opacity_; - unsigned x_; - unsigned y_; - unsigned w_; - unsigned h_; - -protected: - OsdElement(unsigned x = 0, unsigned y = 0, unsigned w = 0, unsigned h = 0, Opacity opacity = SEVEN_EIGHTHS) { - setPos(x, y); - setSize(w, h); - setOpacity(opacity); - } - - void setPos(unsigned x, unsigned y) { - x_ = x; - y_ = y; - } - - void setSize(unsigned w, unsigned h) { - w_ = w; - h_ = h; - } - - void setOpacity(Opacity opacity) { opacity_ = opacity; } - -public: - virtual ~OsdElement() {} - unsigned x() const { return x_; } - unsigned y() const { return y_; } - unsigned w() const { return w_; } - unsigned h() const { return h_; } - Opacity opacity() const { return opacity_; } - - virtual const Gambatte::uint_least32_t* update() = 0; -}; - -#endif diff --git a/src/lib/libgambatte/src/rtc.cpp b/src/lib/libgambatte/src/rtc.cpp deleted file mode 100644 index 75164919..00000000 --- a/src/lib/libgambatte/src/rtc.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "rtc.h" -#include "savestate.h" - -using namespace std; - -Rtc::Rtc() : -activeData(NULL), -activeSet(NULL), -baseTime(0), -haltTime(0), -index(5), -dataDh(0), -dataDl(0), -dataH(0), -dataM(0), -dataS(0), -enabled(false), -lastLatchData(false) { -} - -void Rtc::doLatch() { - time_t tmp = ((dataDh & 0x40) ? haltTime : time(NULL)) - baseTime; - - while (tmp > 0x1FF * 86400) { - baseTime += 0x1FF * 86400; - tmp -= 0x1FF * 86400; - dataDh |= 0x80; - } - - dataDl = (tmp / 86400) & 0xFF; - dataDh &= 0xFE; - dataDh |= ((tmp / 86400) & 0x100) >> 8; - tmp %= 86400; - - dataH = tmp / 3600; - tmp %= 3600; - - dataM = tmp / 60; - tmp %= 60; - - dataS = tmp; -} - -void Rtc::doSwapActive() { - if (!enabled || index > 4) { - activeData = NULL; - activeSet = NULL; - } else switch (index) { - case 0x00: - activeData = &dataS; - activeSet = &Rtc::setS; - break; - case 0x01: - activeData = &dataM; - activeSet = &Rtc::setM; - break; - case 0x02: - activeData = &dataH; - activeSet = &Rtc::setH; - break; - case 0x03: - activeData = &dataDl; - activeSet = &Rtc::setDl; - break; - case 0x04: - activeData = &dataDh; - activeSet = &Rtc::setDh; - break; - } -} - -void Rtc::saveState(SaveState &state) const { - state.rtc.baseTime = baseTime; - state.rtc.haltTime = haltTime; - state.rtc.index = index; - state.rtc.dataDh = dataDh; - state.rtc.dataDl = dataDl; - state.rtc.dataH = dataH; - state.rtc.dataM = dataM; - state.rtc.dataS = dataS; - state.rtc.lastLatchData = lastLatchData; -} - -void Rtc::loadState(const SaveState &state, const bool enabled) { - this->enabled = enabled; - - baseTime = state.rtc.baseTime; - haltTime = state.rtc.haltTime; - index = state.rtc.index; - dataDh = state.rtc.dataDh; - dataDl = state.rtc.dataDl; - dataH = state.rtc.dataH; - dataM = state.rtc.dataM; - dataS = state.rtc.dataS; - lastLatchData = state.rtc.lastLatchData; - - doSwapActive(); -} - -void Rtc::setDh(const unsigned new_dh) { - const time_t unixtime = (dataDh & 0x40) ? haltTime : time(NULL); - const time_t old_highdays = ((unixtime - baseTime) / 86400) & 0x100; - baseTime += old_highdays * 86400; - baseTime -= ((new_dh & 0x1) << 8) * 86400; - - if ((dataDh ^ new_dh) & 0x40) { - if (new_dh & 0x40) - haltTime = time(NULL); - else - baseTime += time(NULL) - haltTime; - } -} - -void Rtc::setDl(const unsigned new_lowdays) { - const time_t unixtime = (dataDh & 0x40) ? haltTime : time(NULL); - const time_t old_lowdays = ((unixtime - baseTime) / 86400) & 0xFF; - baseTime += old_lowdays * 86400; - baseTime -= new_lowdays * 86400; -} - -void Rtc::setH(const unsigned new_hours) { - const time_t unixtime = (dataDh & 0x40) ? haltTime : time(NULL); - const time_t old_hours = ((unixtime - baseTime) / 3600) % 24; - baseTime += old_hours * 3600; - baseTime -= new_hours * 3600; -} - -void Rtc::setM(const unsigned new_minutes) { - const time_t unixtime = (dataDh & 0x40) ? haltTime : time(NULL); - const time_t old_minutes = ((unixtime - baseTime) / 60) % 60; - baseTime += old_minutes * 60; - baseTime -= new_minutes * 60; -} - -void Rtc::setS(const unsigned new_seconds) { - const time_t unixtime = (dataDh & 0x40) ? haltTime : time(NULL); - baseTime += (unixtime - baseTime) % 60; - baseTime -= new_seconds; -} diff --git a/src/lib/libgambatte/src/rtc.h b/src/lib/libgambatte/src/rtc.h deleted file mode 100644 index 40905c18..00000000 --- a/src/lib/libgambatte/src/rtc.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef RTC_H -#define RTC_H - -class SaveState; - -#include - -class Rtc { -private: - unsigned char *activeData; - void (Rtc::*activeSet)(unsigned); - std::time_t baseTime; - std::time_t haltTime; - unsigned char index; - unsigned char dataDh; - unsigned char dataDl; - unsigned char dataH; - unsigned char dataM; - unsigned char dataS; - bool enabled; - bool lastLatchData; - - void doLatch(); - void doSwapActive(); - void setDh(unsigned new_dh); - void setDl(unsigned new_lowdays); - void setH(unsigned new_hours); - void setM(unsigned new_minutes); - void setS(unsigned new_seconds); - -public: - Rtc(); - - const unsigned char* getActive() const { - return activeData; - } - - std::time_t getBaseTime() const { - return baseTime; - } - - void setBaseTime(const std::time_t baseTime) { - this->baseTime = baseTime; -// doLatch(); - } - - void latch(const unsigned data) { - if (!lastLatchData && data == 1) - doLatch(); - - lastLatchData = data; - } - - void saveState(SaveState &state) const; - void loadState(const SaveState &state, bool enabled); - - void setEnabled(const bool enabled) { - this->enabled = enabled; - - doSwapActive(); - } - - void swapActive(unsigned index) { - index &= 0xF; - index -= 8; - - this->index = index; - - doSwapActive(); - } - - void write(const unsigned data) { -// if (activeSet) - (this->*activeSet)(data); - *activeData = data; - } -}; - -#endif diff --git a/src/lib/libgambatte/src/savestate.h b/src/lib/libgambatte/src/savestate.h deleted file mode 100644 index c4b245fd..00000000 --- a/src/lib/libgambatte/src/savestate.h +++ /dev/null @@ -1,184 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SAVESTATE_H -#define SAVESTATE_H - -#include "int.h" - -struct SaveState { - template - class Ptr { - T *ptr; - unsigned long sz; - - public: - Ptr() : ptr(0), sz(0) {} - const T* get() const { return ptr; } - unsigned long getSz() const { return sz; } - void set(T *ptr, const unsigned long sz) { this->ptr = ptr; this->sz = sz; } - - friend class SaverList; - friend void setInitState(SaveState &, bool); - }; - - struct CPU { - unsigned long cycleCounter; - unsigned short PC; - unsigned short SP; - unsigned char A; - unsigned char B; - unsigned char C; - unsigned char D; - unsigned char E; - unsigned char F; - unsigned char H; - unsigned char L; - bool skip; - bool halted; - } cpu; - - struct Mem { - Ptr vram; - Ptr sram; - Ptr wram; - Ptr ioamhram; - unsigned long div_lastUpdate; - unsigned long tima_lastUpdate; - unsigned long tmatime; - unsigned long next_serialtime; - unsigned long lastOamDmaUpdate; - unsigned long minIntTime; - unsigned short rombank; - unsigned short dmaSource; - unsigned short dmaDestination; - unsigned char rambank; - unsigned char oamDmaPos; - bool IME; - bool enable_ram; - bool rambank_mode; - bool hdma_transfer; - } mem; - - struct PPU { - Ptr drawBuffer; - Ptr bgpData; - Ptr objpData; - //SpriteMapper::OamReader - Ptr oamReaderBuf; - Ptr oamReaderSzbuf; - - unsigned long videoCycles; - unsigned long enableDisplayM0Time; - unsigned char winYPos; - unsigned char drawStartCycle; - unsigned char scReadOffset; - unsigned char lcdc; - //ScReader - unsigned char scx[2]; - unsigned char scy[2]; - //ScxReader - unsigned char scxAnd7; - //WeMasterChecker - bool weMaster; - //WxReader - unsigned char wx; - //Wy - unsigned char wy; - bool lycIrqSkip; - } ppu; - - struct SPU { - struct Duty { - unsigned long nextPosUpdate; - unsigned char nr3; - unsigned char pos; - }; - - struct Env { - unsigned long counter; - unsigned char volume; - }; - - struct LCounter { - unsigned long counter; - unsigned short lengthCounter; - }; - - struct { - struct { - unsigned long counter; - unsigned short shadow; - unsigned char nr0; - bool negging; - } sweep; - Duty duty; - Env env; - LCounter lcounter; - unsigned char nr4; - bool master; - } ch1; - - struct { - Duty duty; - Env env; - LCounter lcounter; - unsigned char nr4; - bool master; - } ch2; - - struct { - Ptr waveRam; - LCounter lcounter; - unsigned long waveCounter; - unsigned long lastReadTime; - unsigned char nr3; - unsigned char nr4; - unsigned char wavePos; - unsigned char sampleBuf; - bool master; - } ch3; - - struct { - struct { - unsigned long counter; - unsigned short reg; - } lfsr; - Env env; - LCounter lcounter; - unsigned char nr4; - bool master; - } ch4; - - unsigned long cycleCounter; - } spu; - - struct RTC { - unsigned long baseTime; - unsigned long haltTime; - unsigned char index; - unsigned char dataDh; - unsigned char dataDl; - unsigned char dataH; - unsigned char dataM; - unsigned char dataS; - bool lastLatchData; - } rtc; -}; - -#endif diff --git a/src/lib/libgambatte/src/sound.cpp b/src/lib/libgambatte/src/sound.cpp deleted file mode 100644 index 3ff8063f..00000000 --- a/src/lib/libgambatte/src/sound.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "sound.h" - -#include "savestate.h" -#include -#include - -/* - Frame Sequencer - - Step Length Ctr Vol Env Sweep - - - - - - - - - - - - - - - - - - - - - - 0 Clock - Clock -S 1 - Clock - - 2 Clock - - - 3 - - - - 4 Clock - Clock - 5 - - - - 6 Clock - - - 7 - - - - - - - - - - - - - - - - - - - - - - - - - Rate 256 Hz 64 Hz 128 Hz - -S) start step on sound power on. -*/ - -// static const unsigned bufferSize = 35112 + 16 + 2048; //FIXME: DMA can prevent process from returning for up to 4096 cycles. - -PSG::PSG() : -buffer(NULL), -lastUpdate(0), -soVol(0), -rsum(0x8000), // initialize to 0x8000 to prevent borrows from high word, xor away later -bufferPos(0), -enabled(false) -{} - -void PSG::init(const bool cgb) { - ch1.init(cgb); - ch2.init(cgb); - ch3.init(cgb); - ch4.init(cgb); -} - -void PSG::reset() { - ch1.reset(); - ch2.reset(); - ch3.reset(); - ch4.reset(); -} - -void PSG::setStatePtrs(SaveState &state) { - ch3.setStatePtrs(state); -} - -void PSG::saveState(SaveState &state) { - ch1.saveState(state); - ch2.saveState(state); - ch3.saveState(state); - ch4.saveState(state); -} - -void PSG::loadState(const SaveState &state) { - ch1.loadState(state); - ch2.loadState(state); - ch3.loadState(state); - ch4.loadState(state); - - lastUpdate = state.cpu.cycleCounter; - set_so_volume(state.mem.ioamhram.get()[0x124]); - map_so(state.mem.ioamhram.get()[0x125]); - enabled = state.mem.ioamhram.get()[0x126] >> 7 & 1; -} - -void PSG::accumulate_channels(const unsigned long cycles) { - Gambatte::uint_least32_t *const buf = buffer + bufferPos; - - std::memset(buf, 0, cycles * sizeof(Gambatte::uint_least32_t)); - ch1.update(buf, soVol, cycles); - ch2.update(buf, soVol, cycles); - ch3.update(buf, soVol, cycles); - ch4.update(buf, soVol, cycles); -} - -void PSG::generate_samples(const unsigned long cycleCounter, const unsigned doubleSpeed) { - const unsigned long cycles = (cycleCounter - lastUpdate) >> (1 + doubleSpeed); - lastUpdate += cycles << (1 + doubleSpeed); - - if (cycles) - accumulate_channels(cycles); - - bufferPos += cycles; -} - -void PSG::resetCounter(const unsigned long newCc, const unsigned long oldCc, const unsigned doubleSpeed) { - generate_samples(oldCc, doubleSpeed); - lastUpdate = newCc - (oldCc - lastUpdate); -} - -unsigned PSG::fillBuffer() { - Gambatte::uint_least32_t sum = rsum; - Gambatte::uint_least32_t *b = buffer; - unsigned n = bufferPos; - - while (n--) { - sum += *b; - *b++ = sum ^ 0x8000; // xor away the initial rsum value of 0x8000 (which prevents borrows from the high word) from the low word - } - - rsum = sum; - - return bufferPos; -} - -#ifdef WORDS_BIGENDIAN -static const unsigned long so1Mul = 0x00000001; -static const unsigned long so2Mul = 0x00010000; -#else -static const unsigned long so1Mul = 0x00010000; -static const unsigned long so2Mul = 0x00000001; -#endif - -void PSG::set_so_volume(const unsigned nr50) { - soVol = (((nr50 & 0x7) + 1) * so1Mul + ((nr50 >> 4 & 0x7) + 1) * so2Mul) * 64; -} - -void PSG::map_so(const unsigned nr51) { - const unsigned long tmp = nr51 * so1Mul + (nr51 >> 4) * so2Mul; - - ch1.setSo((tmp & 0x00010001) * 0xFFFF); - ch2.setSo((tmp >> 1 & 0x00010001) * 0xFFFF); - ch3.setSo((tmp >> 2 & 0x00010001) * 0xFFFF); - ch4.setSo((tmp >> 3 & 0x00010001) * 0xFFFF); -} - -unsigned PSG::getStatus() const { - return ch1.isActive() | (ch2.isActive() << 1) | (ch3.isActive() << 2) | (ch4.isActive() << 3); -} diff --git a/src/lib/libgambatte/src/sound.h b/src/lib/libgambatte/src/sound.h deleted file mode 100644 index 06916846..00000000 --- a/src/lib/libgambatte/src/sound.h +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SOUND_H -#define SOUND_H - -class SaveState; - -#include "int.h" - -#include "sound/channel1.h" -#include "sound/channel2.h" -#include "sound/channel3.h" -#include "sound/channel4.h" - -class PSG { - Channel1 ch1; - Channel2 ch2; - Channel3 ch3; - Channel4 ch4; - - Gambatte::uint_least32_t *buffer; - - unsigned long lastUpdate; - unsigned long soVol; - - Gambatte::uint_least32_t rsum; - - unsigned bufferPos; - - bool enabled; - - void accumulate_channels(unsigned long cycles); - -public: - PSG(); - void init(bool cgb); - void reset(); - void setStatePtrs(SaveState &state); - void saveState(SaveState &state); - void loadState(const SaveState &state); - - void generate_samples(unsigned long cycleCounter, unsigned doubleSpeed); - void resetCounter(unsigned long newCc, unsigned long oldCc, unsigned doubleSpeed); - unsigned fillBuffer(); - void setBuffer(Gambatte::uint_least32_t *const buf) { buffer = buf; bufferPos = 0; } - - bool isEnabled() const { return enabled; } - void setEnabled(bool value) { enabled = value; } - - void set_nr10(unsigned data) { ch1.setNr0(data); } - void set_nr11(unsigned data) { ch1.setNr1(data); } - void set_nr12(unsigned data) { ch1.setNr2(data); } - void set_nr13(unsigned data) { ch1.setNr3(data); } - void set_nr14(unsigned data) { ch1.setNr4(data); } - - void set_nr21(unsigned data) { ch2.setNr1(data); } - void set_nr22(unsigned data) { ch2.setNr2(data); } - void set_nr23(unsigned data) { ch2.setNr3(data); } - void set_nr24(unsigned data) { ch2.setNr4(data); } - - void set_nr30(unsigned data) { ch3.setNr0(data); } - void set_nr31(unsigned data) { ch3.setNr1(data); } - void set_nr32(unsigned data) { ch3.setNr2(data); } - void set_nr33(unsigned data) { ch3.setNr3(data); } - void set_nr34(unsigned data) { ch3.setNr4(data); } - unsigned waveRamRead(unsigned index) const { return ch3.waveRamRead(index); } - void waveRamWrite(unsigned index, unsigned data) { ch3.waveRamWrite(index, data); } - - void set_nr41(unsigned data) { ch4.setNr1(data); } - void set_nr42(unsigned data) { ch4.setNr2(data); } - void set_nr43(unsigned data) { ch4.setNr3(data); } - void set_nr44(unsigned data) { ch4.setNr4(data); } - - void set_so_volume(unsigned nr50); - void map_so(unsigned nr51); - unsigned getStatus() const; -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/channel1.cpp b/src/lib/libgambatte/src/sound/channel1.cpp deleted file mode 100644 index 5e112eb2..00000000 --- a/src/lib/libgambatte/src/sound/channel1.cpp +++ /dev/null @@ -1,257 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "channel1.h" -#include "../savestate.h" -#include - -Channel1::SweepUnit::SweepUnit(MasterDisabler &disabler, DutyUnit &dutyUnit) : - disableMaster(disabler), - dutyUnit(dutyUnit), - shadow(0), - nr0(0), - negging(false) -{} - -unsigned Channel1::SweepUnit::calcFreq() { - unsigned freq = shadow >> (nr0 & 0x07); - - if (nr0 & 0x08) { - freq = shadow - freq; - negging = true; - } else - freq = shadow + freq; - - if (freq & 2048) - disableMaster(); - - return freq; -} - -void Channel1::SweepUnit::event() { - const unsigned long period = nr0 >> 4 & 0x07; - - if (period) { - const unsigned freq = calcFreq(); - - if (!(freq & 2048) && (nr0 & 0x07)) { - shadow = freq; - dutyUnit.setFreq(freq, counter); - calcFreq(); - } - - counter += period << 14; - } else - counter += 8ul << 14; -} - -void Channel1::SweepUnit::nr0Change(const unsigned newNr0) { - if (negging && !(newNr0 & 0x08)) - disableMaster(); - - nr0 = newNr0; -} - -void Channel1::SweepUnit::nr4Init(const unsigned long cc) { - negging = false; - shadow = dutyUnit.getFreq(); - - const unsigned period = nr0 >> 4 & 0x07; - const unsigned shift = nr0 & 0x07; - - if (period | shift) - counter = ((cc >> 14) + (period ? period : 8)) << 14; - else - counter = COUNTER_DISABLED; - - if (shift) - calcFreq(); -} - -void Channel1::SweepUnit::reset() { - counter = COUNTER_DISABLED; -} - -void Channel1::SweepUnit::saveState(SaveState &state) const { - state.spu.ch1.sweep.counter = counter; - state.spu.ch1.sweep.shadow = shadow; - state.spu.ch1.sweep.nr0 = nr0; - state.spu.ch1.sweep.negging = negging; -} - -void Channel1::SweepUnit::loadState(const SaveState &state) { - counter = std::max(state.spu.ch1.sweep.counter, state.spu.cycleCounter); - shadow = state.spu.ch1.sweep.shadow; - nr0 = state.spu.ch1.sweep.nr0; - negging = state.spu.ch1.sweep.negging; -} - -Channel1::Channel1() : - staticOutputTest(*this, dutyUnit), - disableMaster(master, dutyUnit), - lengthCounter(disableMaster, 0x3F), - envelopeUnit(staticOutputTest), - sweepUnit(disableMaster, dutyUnit), - cycleCounter(0), - soMask(0), - prevOut(0), - nr4(0), - master(false) -{ - setEvent(); -} - -void Channel1::setEvent() { -// nextEventUnit = &dutyUnit; -// if (sweepUnit.getCounter() < nextEventUnit->getCounter()) - nextEventUnit = &sweepUnit; - if (envelopeUnit.getCounter() < nextEventUnit->getCounter()) - nextEventUnit = &envelopeUnit; - if (lengthCounter.getCounter() < nextEventUnit->getCounter()) - nextEventUnit = &lengthCounter; -} - -void Channel1::setNr0(const unsigned data) { - sweepUnit.nr0Change(data); - setEvent(); -} - -void Channel1::setNr1(const unsigned data) { - lengthCounter.nr1Change(data, nr4, cycleCounter); - dutyUnit.nr1Change(data, cycleCounter); - - setEvent(); -} - -void Channel1::setNr2(const unsigned data) { - if (envelopeUnit.nr2Change(data)) - disableMaster(); - else - staticOutputTest(cycleCounter); - - setEvent(); -} - -void Channel1::setNr3(const unsigned data) { - dutyUnit.nr3Change(data, cycleCounter); - setEvent(); -} - -void Channel1::setNr4(const unsigned data) { - lengthCounter.nr4Change(nr4, data, cycleCounter); - - nr4 = data; - - dutyUnit.nr4Change(data, cycleCounter); - - if (data & 0x80) { //init-bit - nr4 &= 0x7F; - master = !envelopeUnit.nr4Init(cycleCounter); - sweepUnit.nr4Init(cycleCounter); - staticOutputTest(cycleCounter); - } - - setEvent(); -} - -void Channel1::setSo(const unsigned long soMask) { - this->soMask = soMask; - staticOutputTest(cycleCounter); - setEvent(); -} - -void Channel1::reset() { - cycleCounter = 0x1000 | (cycleCounter & 0xFFF); // cycleCounter >> 12 & 7 represents the frame sequencer position. - -// lengthCounter.reset(); - dutyUnit.reset(); - envelopeUnit.reset(); - sweepUnit.reset(); - - setEvent(); -} - -void Channel1::init(const bool cgb) { - lengthCounter.init(cgb); -} - -void Channel1::saveState(SaveState &state) { - sweepUnit.saveState(state); - dutyUnit.saveState(state.spu.ch1.duty, cycleCounter); - envelopeUnit.saveState(state.spu.ch1.env); - lengthCounter.saveState(state.spu.ch1.lcounter); - - state.spu.cycleCounter = cycleCounter; - state.spu.ch1.nr4 = nr4; - state.spu.ch1.master = master; -} - -void Channel1::loadState(const SaveState &state) { - sweepUnit.loadState(state); - dutyUnit.loadState(state.spu.ch1.duty, state.mem.ioamhram.get()[0x111], state.spu.ch1.nr4, state.spu.cycleCounter); - envelopeUnit.loadState(state.spu.ch1.env, state.mem.ioamhram.get()[0x112], state.spu.cycleCounter); - lengthCounter.loadState(state.spu.ch1.lcounter, state.spu.cycleCounter); - - cycleCounter = state.spu.cycleCounter; - nr4 = state.spu.ch1.nr4; - master = state.spu.ch1.master; -} - -void Channel1::update(Gambatte::uint_least32_t *buf, const unsigned long soBaseVol, unsigned long cycles) { - const unsigned long outBase = envelopeUnit.dacIsOn() ? soBaseVol & soMask : 0; - const unsigned long outLow = outBase * (0 - 15ul); - const unsigned long endCycles = cycleCounter + cycles; - - for (;;) { - const unsigned long outHigh = master ? outBase * (envelopeUnit.getVolume() * 2 - 15ul) : outLow; - const unsigned long nextMajorEvent = nextEventUnit->getCounter() < endCycles ? nextEventUnit->getCounter() : endCycles; - unsigned long out = dutyUnit.isHighState() ? outHigh : outLow; - - while (dutyUnit.getCounter() <= nextMajorEvent) { - *buf = out - prevOut; - prevOut = out; - buf += dutyUnit.getCounter() - cycleCounter; - cycleCounter = dutyUnit.getCounter(); - - dutyUnit.event(); - out = dutyUnit.isHighState() ? outHigh : outLow; - } - - if (cycleCounter < nextMajorEvent) { - *buf = out - prevOut; - prevOut = out; - buf += nextMajorEvent - cycleCounter; - cycleCounter = nextMajorEvent; - } - - if (nextEventUnit->getCounter() == nextMajorEvent) { - nextEventUnit->event(); - setEvent(); - } else - break; - } - - if (cycleCounter & SoundUnit::COUNTER_MAX) { - dutyUnit.resetCounters(cycleCounter); - lengthCounter.resetCounters(cycleCounter); - envelopeUnit.resetCounters(cycleCounter); - sweepUnit.resetCounters(cycleCounter); - - cycleCounter -= SoundUnit::COUNTER_MAX; - } -} diff --git a/src/lib/libgambatte/src/sound/channel1.h b/src/lib/libgambatte/src/sound/channel1.h deleted file mode 100644 index d790e0ec..00000000 --- a/src/lib/libgambatte/src/sound/channel1.h +++ /dev/null @@ -1,91 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SOUND_CHANNEL1_H -#define SOUND_CHANNEL1_H - -class SaveState; - -#include "int.h" - -#include "master_disabler.h" -#include "length_counter.h" -#include "duty_unit.h" -#include "envelope_unit.h" -#include "static_output_tester.h" - -class Channel1 { - class SweepUnit : public SoundUnit { - MasterDisabler &disableMaster; - DutyUnit &dutyUnit; - unsigned short shadow; - unsigned char nr0; - bool negging; - - unsigned calcFreq(); - - public: - SweepUnit(MasterDisabler &disabler, DutyUnit &dutyUnit); - void event(); - void nr0Change(unsigned newNr0); - void nr4Init(unsigned long cycleCounter); - void reset(); - void saveState(SaveState &state) const; - void loadState(const SaveState &state); - }; - - friend class StaticOutputTester; - - StaticOutputTester staticOutputTest; - DutyMasterDisabler disableMaster; - LengthCounter lengthCounter; - DutyUnit dutyUnit; - EnvelopeUnit envelopeUnit; - SweepUnit sweepUnit; - - SoundUnit *nextEventUnit; - - unsigned long cycleCounter; - unsigned long soMask; - unsigned long prevOut; - - unsigned char nr4; - bool master; - - void setEvent(); - -public: - Channel1(); - void setNr0(unsigned data); - void setNr1(unsigned data); - void setNr2(unsigned data); - void setNr3(unsigned data); - void setNr4(unsigned data); - - void setSo(unsigned long soMask); - bool isActive() const { return master; } - - void update(Gambatte::uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); - - void reset(); - void init(bool cgb); - void saveState(SaveState &state); - void loadState(const SaveState &state); -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/channel2.cpp b/src/lib/libgambatte/src/sound/channel2.cpp deleted file mode 100644 index 2db30658..00000000 --- a/src/lib/libgambatte/src/sound/channel2.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "channel2.h" -#include "../savestate.h" - -Channel2::Channel2() : - staticOutputTest(*this, dutyUnit), - disableMaster(master, dutyUnit), - lengthCounter(disableMaster, 0x3F), - envelopeUnit(staticOutputTest), - cycleCounter(0), - soMask(0), - prevOut(0), - nr4(0), - master(false) -{ - setEvent(); -} - -void Channel2::setEvent() { -// nextEventUnit = &dutyUnit; -// if (envelopeUnit.getCounter() < nextEventUnit->getCounter()) - nextEventUnit = &envelopeUnit; - if (lengthCounter.getCounter() < nextEventUnit->getCounter()) - nextEventUnit = &lengthCounter; -} - -void Channel2::setNr1(const unsigned data) { - lengthCounter.nr1Change(data, nr4, cycleCounter); - dutyUnit.nr1Change(data, cycleCounter); - - setEvent(); -} - -void Channel2::setNr2(const unsigned data) { - if (envelopeUnit.nr2Change(data)) - disableMaster(); - else - staticOutputTest(cycleCounter); - - setEvent(); -} - -void Channel2::setNr3(const unsigned data) { - dutyUnit.nr3Change(data, cycleCounter); - setEvent(); -} - -void Channel2::setNr4(const unsigned data) { - lengthCounter.nr4Change(nr4, data, cycleCounter); - - nr4 = data; - - if (data & 0x80) { //init-bit - nr4 &= 0x7F; - master = !envelopeUnit.nr4Init(cycleCounter); - staticOutputTest(cycleCounter); - } - - dutyUnit.nr4Change(data, cycleCounter); - - setEvent(); -} - -void Channel2::setSo(const unsigned long soMask) { - this->soMask = soMask; - staticOutputTest(cycleCounter); - setEvent(); -} - -void Channel2::reset() { - cycleCounter = 0x1000 | (cycleCounter & 0xFFF); // cycleCounter >> 12 & 7 represents the frame sequencer position. - -// lengthCounter.reset(); - dutyUnit.reset(); - envelopeUnit.reset(); - - setEvent(); -} - -void Channel2::init(const bool cgb) { - lengthCounter.init(cgb); -} - -void Channel2::saveState(SaveState &state) { - dutyUnit.saveState(state.spu.ch2.duty, cycleCounter); - envelopeUnit.saveState(state.spu.ch2.env); - lengthCounter.saveState(state.spu.ch2.lcounter); - - state.spu.ch2.nr4 = nr4; - state.spu.ch2.master = master; -} - -void Channel2::loadState(const SaveState &state) { - dutyUnit.loadState(state.spu.ch2.duty, state.mem.ioamhram.get()[0x116], state.spu.ch2.nr4,state.spu.cycleCounter); - envelopeUnit.loadState(state.spu.ch2.env, state.mem.ioamhram.get()[0x117], state.spu.cycleCounter); - lengthCounter.loadState(state.spu.ch2.lcounter, state.spu.cycleCounter); - - cycleCounter = state.spu.cycleCounter; - nr4 = state.spu.ch2.nr4; - master = state.spu.ch2.master; -} - -void Channel2::update(Gambatte::uint_least32_t *buf, const unsigned long soBaseVol, unsigned long cycles) { - const unsigned long outBase = envelopeUnit.dacIsOn() ? soBaseVol & soMask : 0; - const unsigned long outLow = outBase * (0 - 15ul); - const unsigned long endCycles = cycleCounter + cycles; - - for (;;) { - const unsigned long outHigh = master ? outBase * (envelopeUnit.getVolume() * 2 - 15ul) : outLow; - const unsigned long nextMajorEvent = nextEventUnit->getCounter() < endCycles ? nextEventUnit->getCounter() : endCycles; - unsigned long out = dutyUnit.isHighState() ? outHigh : outLow; - - while (dutyUnit.getCounter() <= nextMajorEvent) { - *buf += out - prevOut; - prevOut = out; - buf += dutyUnit.getCounter() - cycleCounter; - cycleCounter = dutyUnit.getCounter(); - - dutyUnit.event(); - out = dutyUnit.isHighState() ? outHigh : outLow; - } - - if (cycleCounter < nextMajorEvent) { - *buf += out - prevOut; - prevOut = out; - buf += nextMajorEvent - cycleCounter; - cycleCounter = nextMajorEvent; - } - - if (nextEventUnit->getCounter() == nextMajorEvent) { - nextEventUnit->event(); - setEvent(); - } else - break; - } - - if (cycleCounter & SoundUnit::COUNTER_MAX) { - dutyUnit.resetCounters(cycleCounter); - lengthCounter.resetCounters(cycleCounter); - envelopeUnit.resetCounters(cycleCounter); - - cycleCounter -= SoundUnit::COUNTER_MAX; - } -} diff --git a/src/lib/libgambatte/src/sound/channel2.h b/src/lib/libgambatte/src/sound/channel2.h deleted file mode 100644 index 24bc66a4..00000000 --- a/src/lib/libgambatte/src/sound/channel2.h +++ /dev/null @@ -1,70 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SOUND_CHANNEL2_H -#define SOUND_CHANNEL2_H - -class SaveState; - -#include "int.h" - -#include "length_counter.h" -#include "duty_unit.h" -#include "envelope_unit.h" -#include "static_output_tester.h" - -class Channel2 { - friend class StaticOutputTester; - - StaticOutputTester staticOutputTest; - DutyMasterDisabler disableMaster; - LengthCounter lengthCounter; - DutyUnit dutyUnit; - EnvelopeUnit envelopeUnit; - - SoundUnit *nextEventUnit; - - unsigned long cycleCounter; - unsigned long soMask; - unsigned long prevOut; - - unsigned char nr4; - bool master; - - void setEvent(); - -public: - Channel2(); - void setNr1(unsigned data); - void setNr2(unsigned data); - void setNr3(unsigned data); - void setNr4(unsigned data); - - void setSo(unsigned long soMask); - // void deactivate() { disableMaster(); setEvent(); } - bool isActive() const { return master; } - - void update(Gambatte::uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); - - void reset(); - void init(bool cgb); - void saveState(SaveState &state); - void loadState(const SaveState &state); -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/channel3.cpp b/src/lib/libgambatte/src/sound/channel3.cpp deleted file mode 100644 index 944271e3..00000000 --- a/src/lib/libgambatte/src/sound/channel3.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "channel3.h" -#include "../savestate.h" -#include -#include - -static inline unsigned toPeriod(const unsigned nr3, const unsigned nr4) { - return 0x800 - ((nr4 << 8 & 0x700) | nr3); -} - -Channel3::Channel3() : - disableMaster(master, waveCounter), - lengthCounter(disableMaster, 0xFF), - cycleCounter(0), - soMask(0), - prevOut(0), - waveCounter(SoundUnit::COUNTER_DISABLED), - lastReadTime(0), - nr0(0), - nr3(0), - nr4(0), - wavePos(0), - rShift(4), - sampleBuf(0), - master(false), - cgb(false) -{} - -void Channel3::setNr0(const unsigned data) { - nr0 = data & 0x80; - - if (!(data & 0x80)) - disableMaster(); -} - -void Channel3::setNr2(const unsigned data) { - rShift = (data >> 5 & 3U) - 1; - - if (rShift > 3) - rShift = 4; -} - -void Channel3::setNr4(const unsigned data) { - lengthCounter.nr4Change(nr4, data, cycleCounter); - - nr4 = data & 0x7F; - - if (data & nr0/* & 0x80*/) { - if (!cgb && waveCounter == cycleCounter + 1) { - const unsigned pos = ((wavePos + 1) & 0x1F) >> 1; - - if (pos < 4) - waveRam[0] = waveRam[pos]; - else - std::memcpy(waveRam, waveRam + (pos & ~3), 4); - } - - master = true; - wavePos = 0; - lastReadTime = waveCounter = cycleCounter + toPeriod(nr3, data) + 3; - } -} - -void Channel3::setSo(const unsigned long soMask) { - this->soMask = soMask; -} - -void Channel3::reset() { - cycleCounter = 0x1000 | (cycleCounter & 0xFFF); // cycleCounter >> 12 & 7 represents the frame sequencer position. - -// lengthCounter.reset(); - sampleBuf = 0; -} - -void Channel3::init(const bool cgb) { - this->cgb = cgb; - lengthCounter.init(cgb); -} - -void Channel3::setStatePtrs(SaveState &state) { - state.spu.ch3.waveRam.set(waveRam, sizeof waveRam); -} - -void Channel3::saveState(SaveState &state) const { - lengthCounter.saveState(state.spu.ch3.lcounter); - - state.spu.ch3.waveCounter = waveCounter; - state.spu.ch3.lastReadTime = lastReadTime; - state.spu.ch3.nr3 = nr3; - state.spu.ch3.nr4 = nr4; - state.spu.ch3.wavePos = wavePos; - state.spu.ch3.sampleBuf = sampleBuf; - state.spu.ch3.master = master; -} - -void Channel3::loadState(const SaveState &state) { - lengthCounter.loadState(state.spu.ch3.lcounter, state.spu.cycleCounter); - - cycleCounter = state.spu.cycleCounter; - waveCounter = std::max(state.spu.ch3.waveCounter, state.spu.cycleCounter); - lastReadTime = state.spu.ch3.lastReadTime; - nr3 = state.spu.ch3.nr3; - nr4 = state.spu.ch3.nr4; - wavePos = state.spu.ch3.wavePos & 0x1F; - sampleBuf = state.spu.ch3.sampleBuf; - master = state.spu.ch3.master; - - nr0 = state.mem.ioamhram.get()[0x11A] & 0x80; - setNr2(state.mem.ioamhram.get()[0x11C]); -} - -void Channel3::updateWaveCounter(const unsigned long cc) { - if (cc >= waveCounter) { - const unsigned period = toPeriod(nr3, nr4); - const unsigned long periods = (cc - waveCounter) / period; - - lastReadTime = waveCounter + periods * period; - waveCounter = lastReadTime + period; - - wavePos += periods + 1; - wavePos &= 0x1F; - - sampleBuf = waveRam[wavePos >> 1]; - } -} - -void Channel3::update(Gambatte::uint_least32_t *buf, const unsigned long soBaseVol, unsigned long cycles) { - const unsigned long outBase = (nr0/* & 0x80*/) ? soBaseVol & soMask : 0; - - if (outBase && rShift != 4) { - const unsigned long endCycles = cycleCounter + cycles; - - for (;;) { - const unsigned long nextMajorEvent = lengthCounter.getCounter() < endCycles ? lengthCounter.getCounter() : endCycles; - unsigned long out = outBase * (master ? ((sampleBuf >> (~wavePos << 2 & 4) & 0xF) >> rShift) * 2 - 15ul : 0 - 15ul); - - while (waveCounter <= nextMajorEvent) { - *buf += out - prevOut; - prevOut = out; - buf += waveCounter - cycleCounter; - cycleCounter = waveCounter; - - lastReadTime = waveCounter; - waveCounter += toPeriod(nr3, nr4); - ++wavePos; - wavePos &= 0x1F; - sampleBuf = waveRam[wavePos >> 1]; - out = outBase * (/*master ? */((sampleBuf >> (~wavePos << 2 & 4) & 0xF) >> rShift) * 2 - 15ul/* : 0 - 15ul*/); - } - - if (cycleCounter < nextMajorEvent) { - *buf += out - prevOut; - prevOut = out; - buf += nextMajorEvent - cycleCounter; - cycleCounter = nextMajorEvent; - } - - if (lengthCounter.getCounter() == nextMajorEvent) { - lengthCounter.event(); - } else - break; - } - } else { - if (outBase) { - const unsigned long out = outBase * (0 - 15ul); - - *buf += out - prevOut; - prevOut = out; - } - - cycleCounter += cycles; - - while (lengthCounter.getCounter() <= cycleCounter) { - updateWaveCounter(lengthCounter.getCounter()); - lengthCounter.event(); - } - - updateWaveCounter(cycleCounter); - } - - if (cycleCounter & SoundUnit::COUNTER_MAX) { - lengthCounter.resetCounters(cycleCounter); - - if (waveCounter != SoundUnit::COUNTER_DISABLED) - waveCounter -= SoundUnit::COUNTER_MAX; - - lastReadTime -= SoundUnit::COUNTER_MAX; - cycleCounter -= SoundUnit::COUNTER_MAX; - } -} diff --git a/src/lib/libgambatte/src/sound/channel3.h b/src/lib/libgambatte/src/sound/channel3.h deleted file mode 100644 index 8ec8688d..00000000 --- a/src/lib/libgambatte/src/sound/channel3.h +++ /dev/null @@ -1,100 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SOUND_CHANNEL3_H -#define SOUND_CHANNEL3_H - -class SaveState; - -#include "int.h" - -#include "master_disabler.h" -#include "length_counter.h" - -class Channel3 { - class Ch3MasterDisabler : public MasterDisabler { - unsigned long &waveCounter; - - public: - Ch3MasterDisabler(bool &m, unsigned long &wC) : MasterDisabler(m), waveCounter(wC) {} - void operator()() { MasterDisabler::operator()(); waveCounter = SoundUnit::COUNTER_DISABLED; } - }; - - unsigned char waveRam[0x10]; - - Ch3MasterDisabler disableMaster; - LengthCounter lengthCounter; - - unsigned long cycleCounter; - unsigned long soMask; - unsigned long prevOut; - unsigned long waveCounter; - unsigned long lastReadTime; - - unsigned char nr0; - unsigned char nr3; - unsigned char nr4; - unsigned char wavePos; - unsigned char rShift; - unsigned char sampleBuf; - - bool master; - bool cgb; - - void updateWaveCounter(unsigned long cc); - -public: - Channel3(); - bool isActive() const { return master; } - void reset(); - void init(bool cgb); - void setStatePtrs(SaveState &state); - void saveState(SaveState &state) const; - void loadState(const SaveState &state); - void setNr0(unsigned data); - void setNr1(unsigned data) { lengthCounter.nr1Change(data, nr4, cycleCounter); } - void setNr2(unsigned data); - void setNr3(unsigned data) { nr3 = data; } - void setNr4(unsigned data); - void setSo(unsigned long soMask); - void update(Gambatte::uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); - - unsigned waveRamRead(unsigned index) const { - if (master) { - if (!cgb && cycleCounter != lastReadTime) - return 0xFF; - - index = wavePos >> 1; - } - - return waveRam[index]; - } - - void waveRamWrite(unsigned index, unsigned data) { - if (master) { - if (!cgb && cycleCounter != lastReadTime) - return; - - index = wavePos >> 1; - } - - waveRam[index] = data; - } -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/channel4.cpp b/src/lib/libgambatte/src/sound/channel4.cpp deleted file mode 100644 index c1efcf28..00000000 --- a/src/lib/libgambatte/src/sound/channel4.cpp +++ /dev/null @@ -1,300 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "channel4.h" -#include "../savestate.h" -#include - -static unsigned long toPeriod(const unsigned nr3) { - unsigned s = (nr3 >> 4) + 3; - unsigned r = nr3 & 7; - - if (!r) { - r = 1; - --s; - } - - return r << s; -} - -Channel4::Lfsr::Lfsr() : -backupCounter(COUNTER_DISABLED), -reg(0xFF), -nr3(0), -master(false) -{} - -void Channel4::Lfsr::updateBackupCounter(const unsigned long cc) { - /*if (backupCounter <= cc) { - const unsigned long period = toPeriod(nr3); - backupCounter = cc - (cc - backupCounter) % period + period; - }*/ - - if (backupCounter <= cc) { - const unsigned long period = toPeriod(nr3); - unsigned long periods = (cc - backupCounter) / period + 1; - - backupCounter += periods * period; - - if (master && nr3 < 0xE0) { - if (nr3 & 8) { - while (periods > 6) { - const unsigned xored = (reg << 1 ^ reg) & 0x7E; - reg = (reg >> 6 & ~0x7E) | xored | xored << 8; - periods -= 6; - } - - const unsigned xored = ((reg ^ reg >> 1) << (7 - periods)) & 0x7F; - reg = (reg >> periods & ~(0x80 - (0x80 >> periods))) | xored | xored << 8; - } else { - while (periods > 15) { - reg = reg ^ reg >> 1; - periods -= 15; - } - - reg = reg >> periods | (((reg ^ reg >> 1) << (15 - periods)) & 0x7FFF); - } - } - } -} - -void Channel4::Lfsr::reviveCounter(const unsigned long cc) { - updateBackupCounter(cc); - counter = backupCounter; -} - -/*static const unsigned char nextStateDistance[0x40] = { - 6, 1, 1, 2, 2, 1, 1, 3, - 3, 1, 1, 2, 2, 1, 1, 4, - 4, 1, 1, 2, 2, 1, 1, 3, - 3, 1, 1, 2, 2, 1, 1, 5, - 5, 1, 1, 2, 2, 1, 1, 3, - 3, 1, 1, 2, 2, 1, 1, 4, - 4, 1, 1, 2, 2, 1, 1, 3, - 3, 1, 1, 2, 2, 1, 1, 6, -};*/ - -inline void Channel4::Lfsr::event() { - if (nr3 < 0xE0) { - const unsigned shifted = reg >> 1; - const unsigned xored = (reg ^ shifted) & 1; - - reg = shifted | xored << 14; - - if (nr3 & 8) - reg = (reg & ~0x40) | xored << 6; - } - - counter += toPeriod(nr3); - backupCounter = counter; - - - /*if (nr3 < 0xE0) { - const unsigned periods = nextStateDistance[reg & 0x3F]; - const unsigned xored = ((reg ^ reg >> 1) << (7 - periods)) & 0x7F; - - reg = reg >> periods | xored << 8; - - if (nr3 & 8) - reg = reg & ~(0x80 - (0x80 >> periods)) | xored; - } - - const unsigned long period = toPeriod(nr3); - backupCounter = counter + period; - counter += period * nextStateDistance[reg & 0x3F];*/ -} - -void Channel4::Lfsr::nr3Change(const unsigned newNr3, const unsigned long cc) { - updateBackupCounter(cc); - nr3 = newNr3; - -// if (counter != COUNTER_DISABLED) -// counter = backupCounter + toPeriod(nr3) * (nextStateDistance[reg & 0x3F] - 1); -} - -void Channel4::Lfsr::nr4Init(unsigned long cc) { - disableMaster(); - updateBackupCounter(cc); - master = true; - backupCounter += 4; - counter = backupCounter; -// counter = backupCounter + toPeriod(nr3) * (nextStateDistance[reg & 0x3F] - 1); -} - -void Channel4::Lfsr::reset(const unsigned long cc) { - nr3 = 0; - disableMaster(); - backupCounter = cc + toPeriod(nr3); -} - -void Channel4::Lfsr::resetCounters(const unsigned long oldCc) { - updateBackupCounter(oldCc); - backupCounter -= COUNTER_MAX; - SoundUnit::resetCounters(oldCc); -} - -void Channel4::Lfsr::saveState(SaveState &state, const unsigned long cc) { - updateBackupCounter(cc); - state.spu.ch4.lfsr.counter = backupCounter; - state.spu.ch4.lfsr.reg = reg; -} - -void Channel4::Lfsr::loadState(const SaveState &state) { - counter = backupCounter = std::max(state.spu.ch4.lfsr.counter, state.spu.cycleCounter); - reg = state.spu.ch4.lfsr.reg; - master = state.spu.ch4.master; - nr3 = state.mem.ioamhram.get()[0x122]; -} - -Channel4::Channel4() : - staticOutputTest(*this, lfsr), - disableMaster(master, lfsr), - lengthCounter(disableMaster, 0x3F), - envelopeUnit(staticOutputTest), - cycleCounter(0), - soMask(0), - prevOut(0), - nr4(0), - master(false) -{ - setEvent(); -} - -void Channel4::setEvent() { -// nextEventUnit = &lfsr; -// if (envelopeUnit.getCounter() < nextEventUnit->getCounter()) - nextEventUnit = &envelopeUnit; - if (lengthCounter.getCounter() < nextEventUnit->getCounter()) - nextEventUnit = &lengthCounter; -} - -void Channel4::setNr1(const unsigned data) { - lengthCounter.nr1Change(data, nr4, cycleCounter); - - setEvent(); -} - -void Channel4::setNr2(const unsigned data) { - if (envelopeUnit.nr2Change(data)) - disableMaster(); - else - staticOutputTest(cycleCounter); - - setEvent(); -} - -void Channel4::setNr4(const unsigned data) { - lengthCounter.nr4Change(nr4, data, cycleCounter); - - nr4 = data; - - if (data & 0x80) { //init-bit - nr4 &= 0x7F; - - master = !envelopeUnit.nr4Init(cycleCounter); - - if (master) - lfsr.nr4Init(cycleCounter); - - staticOutputTest(cycleCounter); - } - - setEvent(); -} - -void Channel4::setSo(const unsigned long soMask) { - this->soMask = soMask; - staticOutputTest(cycleCounter); - setEvent(); -} - -void Channel4::reset() { - cycleCounter = 0x1000 | (cycleCounter & 0xFFF); // cycleCounter >> 12 & 7 represents the frame sequencer position. - -// lengthCounter.reset(); - lfsr.reset(cycleCounter); - envelopeUnit.reset(); - - setEvent(); -} - -void Channel4::init(const bool cgb) { - lengthCounter.init(cgb); -} - -void Channel4::saveState(SaveState &state) { - lfsr.saveState(state, cycleCounter); - envelopeUnit.saveState(state.spu.ch4.env); - lengthCounter.saveState(state.spu.ch4.lcounter); - - state.spu.ch4.nr4 = nr4; - state.spu.ch4.master = master; -} - -void Channel4::loadState(const SaveState &state) { - lfsr.loadState(state); - envelopeUnit.loadState(state.spu.ch4.env, state.mem.ioamhram.get()[0x121], state.spu.cycleCounter); - lengthCounter.loadState(state.spu.ch4.lcounter, state.spu.cycleCounter); - - cycleCounter = state.spu.cycleCounter; - nr4 = state.spu.ch4.nr4; - master = state.spu.ch4.master; -} - -void Channel4::update(Gambatte::uint_least32_t *buf, const unsigned long soBaseVol, unsigned long cycles) { - const unsigned long outBase = envelopeUnit.dacIsOn() ? soBaseVol & soMask : 0; - const unsigned long outLow = outBase * (0 - 15ul); - const unsigned long endCycles = cycleCounter + cycles; - - for (;;) { - const unsigned long outHigh = /*master ? */outBase * (envelopeUnit.getVolume() * 2 - 15ul)/* : outLow*/; - const unsigned long nextMajorEvent = nextEventUnit->getCounter() < endCycles ? nextEventUnit->getCounter() : endCycles; - unsigned long out = lfsr.isHighState() ? outHigh : outLow; - - while (lfsr.getCounter() <= nextMajorEvent) { - *buf += out - prevOut; - prevOut = out; - buf += lfsr.getCounter() - cycleCounter; - cycleCounter = lfsr.getCounter(); - - lfsr.event(); - out = lfsr.isHighState() ? outHigh : outLow; - } - - if (cycleCounter < nextMajorEvent) { - *buf += out - prevOut; - prevOut = out; - buf += nextMajorEvent - cycleCounter; - cycleCounter = nextMajorEvent; - } - - if (nextEventUnit->getCounter() == nextMajorEvent) { - nextEventUnit->event(); - setEvent(); - } else - break; - } - - if (cycleCounter & SoundUnit::COUNTER_MAX) { - lengthCounter.resetCounters(cycleCounter); - lfsr.resetCounters(cycleCounter); - envelopeUnit.resetCounters(cycleCounter); - - cycleCounter -= SoundUnit::COUNTER_MAX; - } -} diff --git a/src/lib/libgambatte/src/sound/channel4.h b/src/lib/libgambatte/src/sound/channel4.h deleted file mode 100644 index 7563dc2c..00000000 --- a/src/lib/libgambatte/src/sound/channel4.h +++ /dev/null @@ -1,99 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SOUND_CHANNEL4_H -#define SOUND_CHANNEL4_H - -class SaveState; - -#include "int.h" - -#include "master_disabler.h" -#include "length_counter.h" -#include "envelope_unit.h" -#include "static_output_tester.h" - -class Channel4 { - class Lfsr : public SoundUnit { - unsigned long backupCounter; - unsigned short reg; - unsigned char nr3; - bool master; - - void updateBackupCounter(unsigned long cc); - - public: - Lfsr(); - void event(); - bool isHighState() const { return ~reg & 1; } - void nr3Change(unsigned newNr3, unsigned long cc); - void nr4Init(unsigned long cc); - void reset(unsigned long cc); - void saveState(SaveState &state, const unsigned long cc); - void loadState(const SaveState &state); - void resetCounters(unsigned long oldCc); - void disableMaster() { killCounter(); master = false; reg = 0xFF; } - void killCounter() { counter = COUNTER_DISABLED; } - void reviveCounter(unsigned long cc); - }; - - class Ch4MasterDisabler : public MasterDisabler { - Lfsr &lfsr; - public: - Ch4MasterDisabler(bool &m, Lfsr &lfsr) : MasterDisabler(m), lfsr(lfsr) {} - void operator()() { MasterDisabler::operator()(); lfsr.disableMaster(); } - }; - - friend class StaticOutputTester; - - StaticOutputTester staticOutputTest; - Ch4MasterDisabler disableMaster; - LengthCounter lengthCounter; - EnvelopeUnit envelopeUnit; - Lfsr lfsr; - - SoundUnit *nextEventUnit; - - unsigned long cycleCounter; - unsigned long soMask; - unsigned long prevOut; - - unsigned char nr4; - bool master; - - void setEvent(); - -public: - Channel4(); - void setNr1(unsigned data); - void setNr2(unsigned data); - void setNr3(unsigned data) { lfsr.nr3Change(data, cycleCounter); /*setEvent();*/ } - void setNr4(unsigned data); - - void setSo(unsigned long soMask); - bool isActive() const { return master; } - - void update(Gambatte::uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); - - void reset(); - void init(bool cgb); - void saveState(SaveState &state); - void loadState(const SaveState &state); -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/duty_unit.cpp b/src/lib/libgambatte/src/sound/duty_unit.cpp deleted file mode 100644 index d3de6abd..00000000 --- a/src/lib/libgambatte/src/sound/duty_unit.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "duty_unit.h" -#include - -static inline bool toOutState(const unsigned duty, const unsigned pos) { - static const unsigned char duties[4] = { 0x80, 0x81, 0xE1, 0x7E }; - - return duties[duty] >> pos & 1; -} - -static inline unsigned toPeriod(const unsigned freq) { - return (2048 - freq) << 1; -} - -void DutyUnit::updatePos(const unsigned long cc) { - if (cc >= nextPosUpdate) { - const unsigned long inc = (cc - nextPosUpdate) / period + 1; - nextPosUpdate += period * inc; - pos += inc; - pos &= 7; - } -} - -void DutyUnit::setDuty(const unsigned nr1) { - duty = nr1 >> 6; - high = toOutState(duty, pos); -} - -void DutyUnit::setCounter() { - static const unsigned char nextStateDistance[4 * 8] = { - 6, 5, 4, 3, 2, 1, 0, 0, - 0, 5, 4, 3, 2, 1, 0, 1, - 0, 3, 2, 1, 0, 3, 2, 1, - 0, 5, 4, 3, 2, 1, 0, 1 - }; - - if (enableEvents && nextPosUpdate != COUNTER_DISABLED) - counter = nextPosUpdate + period * nextStateDistance[(duty * 8) | pos]; - else - counter = COUNTER_DISABLED; -} - -void DutyUnit::setFreq(const unsigned newFreq, const unsigned long cc) { - updatePos(cc); - period = toPeriod(newFreq); - setCounter(); -} - -void DutyUnit::event() { - unsigned inc = period << duty; - - if (duty == 3) - inc -= period * 2; - - if (!(high ^= true)) - inc = period * 8 - inc; - - counter += inc; -} - -void DutyUnit::nr1Change(const unsigned newNr1, const unsigned long cc) { - updatePos(cc); - setDuty(newNr1); - setCounter(); -} - -void DutyUnit::nr3Change(const unsigned newNr3, const unsigned long cc) { - setFreq((getFreq() & 0x700) | newNr3, cc); -} - -void DutyUnit::nr4Change(const unsigned newNr4, const unsigned long cc) { - setFreq((newNr4 << 8 & 0x700) | (getFreq() & 0xFF), cc); - - if (newNr4 & 0x80) { - nextPosUpdate = (cc & ~1) + period; - setCounter(); - } -} - -DutyUnit::DutyUnit() : -nextPosUpdate(COUNTER_DISABLED), -period(4096), -pos(0), -duty(0), -high(false), -enableEvents(true) -{} - -void DutyUnit::reset() { - pos = 0; - high = toOutState(duty, pos); - nextPosUpdate = COUNTER_DISABLED; - setCounter(); -} - -void DutyUnit::saveState(SaveState::SPU::Duty &dstate, const unsigned long cc) { - updatePos(cc); - dstate.nextPosUpdate = nextPosUpdate; - dstate.nr3 = getFreq() & 0xFF; - dstate.pos = pos; -} - -void DutyUnit::loadState(const SaveState::SPU::Duty &dstate, const unsigned nr1, const unsigned nr4, const unsigned long cc) { - nextPosUpdate = std::max(dstate.nextPosUpdate, cc); - pos = dstate.pos & 7; - setDuty(nr1); - period = toPeriod((nr4 << 8 & 0x700) | dstate.nr3); - enableEvents = true; - setCounter(); -} - -void DutyUnit::resetCounters(const unsigned long oldCc) { - if (nextPosUpdate == COUNTER_DISABLED) - return; - - updatePos(oldCc); - nextPosUpdate -= COUNTER_MAX; - SoundUnit::resetCounters(oldCc); -} - -void DutyUnit::killCounter() { - enableEvents = false; - setCounter(); -} - -void DutyUnit::reviveCounter(const unsigned long cc) { - updatePos(cc); - high = toOutState(duty, pos); - enableEvents = true; - setCounter(); -} diff --git a/src/lib/libgambatte/src/sound/duty_unit.h b/src/lib/libgambatte/src/sound/duty_unit.h deleted file mode 100644 index e55cec59..00000000 --- a/src/lib/libgambatte/src/sound/duty_unit.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef DUTY_UNIT_H -#define DUTY_UNIT_H - -#include "sound_unit.h" -#include "master_disabler.h" -#include "../savestate.h" - -class DutyUnit : public SoundUnit { - unsigned long nextPosUpdate; - unsigned short period; - unsigned char pos; - unsigned char duty; - bool high; - bool enableEvents; - - void setCounter(); - void setDuty(unsigned nr1); - void updatePos(unsigned long cc); - -public: - DutyUnit(); - void event(); - bool isHighState() const { return high; } - void nr1Change(unsigned newNr1, unsigned long cc); - void nr3Change(unsigned newNr3, unsigned long cc); - void nr4Change(unsigned newNr4, unsigned long cc); - void reset(); - void saveState(SaveState::SPU::Duty &dstate, unsigned long cc); - void loadState(const SaveState::SPU::Duty &dstate, unsigned nr1, unsigned nr4, unsigned long cc); - void resetCounters(unsigned long oldCc); - void killCounter(); - void reviveCounter(unsigned long cc); - - //intended for use by SweepUnit only. - unsigned getFreq() const { return 2048 - (period >> 1); } - void setFreq(unsigned newFreq, unsigned long cc); -}; - -class DutyMasterDisabler : public MasterDisabler { - DutyUnit &dutyUnit; -public: - DutyMasterDisabler(bool &m, DutyUnit &dutyUnit) : MasterDisabler(m), dutyUnit(dutyUnit) {} - void operator()() { MasterDisabler::operator()(); dutyUnit.killCounter(); } -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/envelope_unit.cpp b/src/lib/libgambatte/src/sound/envelope_unit.cpp deleted file mode 100644 index ed526eb5..00000000 --- a/src/lib/libgambatte/src/sound/envelope_unit.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "envelope_unit.h" -#include - -EnvelopeUnit::VolOnOffEvent EnvelopeUnit::nullEvent; - -void EnvelopeUnit::event() { - const unsigned long period = nr2 & 7; - - if (period) { - unsigned newVol = volume; - - if (nr2 & 8) - ++newVol; - else - --newVol; - - if (newVol < 0x10U) { - volume = newVol; - - if (volume < 2) - volOnOffEvent(counter); - - counter += period << 15; - } else - counter = COUNTER_DISABLED; - } else - counter += 8ul << 15; -} - -bool EnvelopeUnit::nr2Change(const unsigned newNr2) { - if (!(nr2 & 7) && counter != COUNTER_DISABLED) - ++volume; - else if (!(nr2 & 8)) - volume += 2; - - if ((nr2 ^ newNr2) & 8) - volume = 0x10 - volume; - - volume &= 0xF; - - nr2 = newNr2; - - return !(newNr2 & 0xF8); -} - -bool EnvelopeUnit::nr4Init(const unsigned long cc) { - { - unsigned long period = nr2 & 7; - - if (!period) - period = 8; - - if (!(cc & 0x7000)) - ++period; - - counter = cc - ((cc - 0x1000) & 0x7FFF) + period * 0x8000; - } - - volume = nr2 >> 4; - - return !(nr2 & 0xF8); -} - -EnvelopeUnit::EnvelopeUnit(VolOnOffEvent &volOnOffEvent) : -volOnOffEvent(volOnOffEvent), -nr2(0), -volume(0) -{} - -void EnvelopeUnit::reset() { - counter = COUNTER_DISABLED; -} - -void EnvelopeUnit::saveState(SaveState::SPU::Env &estate) const { - estate.counter = counter; - estate.volume = volume; -} - -void EnvelopeUnit::loadState(const SaveState::SPU::Env &estate, const unsigned nr2, const unsigned long cc) { - counter = std::max(estate.counter, cc); - volume = estate.volume; - this->nr2 = nr2; -} diff --git a/src/lib/libgambatte/src/sound/envelope_unit.h b/src/lib/libgambatte/src/sound/envelope_unit.h deleted file mode 100644 index e9bae2f0..00000000 --- a/src/lib/libgambatte/src/sound/envelope_unit.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef ENVELOPE_UNIT_H -#define ENVELOPE_UNIT_H - -#include "sound_unit.h" -#include "../savestate.h" - -class EnvelopeUnit : public SoundUnit { -public: - struct VolOnOffEvent { - virtual ~VolOnOffEvent() {} - virtual void operator()(unsigned long /*cc*/) {} - }; - -private: - static VolOnOffEvent nullEvent; - VolOnOffEvent &volOnOffEvent; - unsigned char nr2; - unsigned char volume; - -public: - EnvelopeUnit(VolOnOffEvent &volOnOffEvent = nullEvent); - void event(); - bool dacIsOn() const { return nr2 & 0xF8; } - unsigned getVolume() const { return volume; } - bool nr2Change(unsigned newNr2); - bool nr4Init(unsigned long cycleCounter); - void reset(); - void saveState(SaveState::SPU::Env &estate) const; - void loadState(const SaveState::SPU::Env &estate, unsigned nr2, unsigned long cc); -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/length_counter.cpp b/src/lib/libgambatte/src/sound/length_counter.cpp deleted file mode 100644 index 8bbe85e1..00000000 --- a/src/lib/libgambatte/src/sound/length_counter.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#include "length_counter.h" -#include "master_disabler.h" -#include - -LengthCounter::LengthCounter(MasterDisabler &disabler, const unsigned mask) : - disableMaster(disabler), - lengthMask(mask) -{ - init(false); - nr1Change(0, 0, 0); -} - -void LengthCounter::event() { - counter = COUNTER_DISABLED; - lengthCounter = 0; - disableMaster(); -} - -void LengthCounter::nr1Change(const unsigned newNr1, const unsigned nr4, const unsigned long cycleCounter) { - lengthCounter = (~newNr1 & lengthMask) + 1; - counter = (nr4 & 0x40) ?( (cycleCounter >> 13) + lengthCounter) << 13 : static_cast(COUNTER_DISABLED); -} - -void LengthCounter::nr4Change(const unsigned oldNr4, const unsigned newNr4, const unsigned long cycleCounter) { - if (counter != COUNTER_DISABLED) - lengthCounter = (counter >> 13) - (cycleCounter >> 13); - - { - unsigned dec = 0; - - if (newNr4 & 0x40) { - dec = ~cycleCounter >> 12 & 1; - - if (!(oldNr4 & 0x40) && lengthCounter) { - if (!(lengthCounter -= dec)) - disableMaster(); - } - } - - if ((newNr4 & 0x80) && !lengthCounter) - lengthCounter = lengthMask + 1 - dec; - } - - if ((newNr4 & 0x40) && lengthCounter) - counter = ((cycleCounter >> 13) + lengthCounter) << 13; - else - counter = COUNTER_DISABLED; -} - -/*void LengthCounter::reset() { - counter = COUNTER_DISABLED; - - if (cgb) - lengthCounter = lengthMask + 1; -}*/ - -void LengthCounter::init(const bool cgb) { - this->cgb = cgb; -} - -void LengthCounter::saveState(SaveState::SPU::LCounter &lstate) const { - lstate.counter = counter; - lstate.lengthCounter = lengthCounter; -} - -void LengthCounter::loadState(const SaveState::SPU::LCounter &lstate, const unsigned long cc) { - counter = std::max(lstate.counter, cc); - lengthCounter = lstate.lengthCounter; -} diff --git a/src/lib/libgambatte/src/sound/length_counter.h b/src/lib/libgambatte/src/sound/length_counter.h deleted file mode 100644 index 2d9451d7..00000000 --- a/src/lib/libgambatte/src/sound/length_counter.h +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#ifndef LENGTH_COUNTER_H -#define LENGTH_COUNTER_H - -#include "sound_unit.h" -#include "../savestate.h" - -class MasterDisabler; - -class LengthCounter : public SoundUnit { - MasterDisabler &disableMaster; - unsigned short lengthCounter; - const unsigned char lengthMask; - bool cgb; - -public: - LengthCounter(MasterDisabler &disabler, unsigned lengthMask); - void event(); - void nr1Change(unsigned newNr1, unsigned nr4, unsigned long cc); - void nr4Change(unsigned oldNr4, unsigned newNr4, unsigned long cc); -// void reset(); - void init(bool cgb); - void saveState(SaveState::SPU::LCounter &lstate) const; - void loadState(const SaveState::SPU::LCounter &lstate, unsigned long cc); -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/master_disabler.h b/src/lib/libgambatte/src/sound/master_disabler.h deleted file mode 100644 index 7dd588c5..00000000 --- a/src/lib/libgambatte/src/sound/master_disabler.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#ifndef MASTER_DISABLER_H -#define MASTER_DISABLER_H - -class MasterDisabler { - bool &master; - -public: - MasterDisabler(bool &m) : master(m) {} - virtual ~MasterDisabler() {} - virtual void operator()() { master = false; } -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/sound_unit.h b/src/lib/libgambatte/src/sound/sound_unit.h deleted file mode 100644 index 2857c0c1..00000000 --- a/src/lib/libgambatte/src/sound/sound_unit.h +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#ifndef SOUND_UNIT_H -#define SOUND_UNIT_H - -class SoundUnit { -protected: - unsigned long counter; -public: - enum { COUNTER_MAX = 0x80000000u, COUNTER_DISABLED = 0xFFFFFFFFu }; - - SoundUnit() : counter(COUNTER_DISABLED) {} - virtual ~SoundUnit() {} - virtual void event() = 0; - unsigned long getCounter() const { return counter; } - virtual void resetCounters(unsigned long /*oldCc*/) { if (counter != COUNTER_DISABLED) counter -= COUNTER_MAX; } -}; - -#endif diff --git a/src/lib/libgambatte/src/sound/static_output_tester.h b/src/lib/libgambatte/src/sound/static_output_tester.h deleted file mode 100644 index 3dbe216e..00000000 --- a/src/lib/libgambatte/src/sound/static_output_tester.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef STATIC_OUTPUT_TESTER_H -#define STATIC_OUTPUT_TESTER_H - -#include "envelope_unit.h" - -template -class StaticOutputTester : public EnvelopeUnit::VolOnOffEvent { - const Channel &ch; - Unit &unit; -public: - StaticOutputTester(const Channel &ch, Unit &unit) : ch(ch), unit(unit) {} - void operator()(unsigned long cc); -}; - -template -void StaticOutputTester::operator()(const unsigned long cc) { - if (ch.soMask && ch.master && ch.envelopeUnit.getVolume()) - unit.reviveCounter(cc); - else - unit.killCounter(); -} - -#endif diff --git a/src/lib/libgambatte/src/state_osd_elements.cpp b/src/lib/libgambatte/src/state_osd_elements.cpp deleted file mode 100644 index 44740d16..00000000 --- a/src/lib/libgambatte/src/state_osd_elements.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "state_osd_elements.h" -#include "bitmap_font.h" -#include "statesaver.h" -#include -#include - -using namespace BitmapFont; - -static const char stateLoadedTxt[] = { S,t,a,t,e,SPC,N0,SPC,l,o,a,d,e,d,0 }; -static const char stateSavedTxt[] = { S,t,a,t,e,SPC,N0,SPC,s,a,v,e,d,0 }; -static const unsigned stateLoadedTxtWidth = getWidth(stateLoadedTxt); -static const unsigned stateSavedTxtWidth = getWidth(stateSavedTxt); - -class ShadedTextOsdElment : public OsdElement { - struct ShadeFill { - void operator()(Gambatte::uint_least32_t *dest, const unsigned pitch) { - dest[2] = dest[1] = dest[0] = 0x000000ul; - dest += pitch; - dest[2] = dest[0] = 0x000000ul; - dest += pitch; - dest[2] = dest[1] = dest[0] = 0x000000ul; - } - }; - - Gambatte::uint_least32_t *const pixels; - unsigned life; - -public: - ShadedTextOsdElment(unsigned w, const char *txt); - ~ShadedTextOsdElment(); - const Gambatte::uint_least32_t* update(); -}; - -ShadedTextOsdElment::ShadedTextOsdElment(unsigned width, const char *txt) : -OsdElement(MAX_WIDTH, 144 - HEIGHT - HEIGHT, width + 2, HEIGHT + 2, THREE_FOURTHS), -pixels(new Gambatte::uint_least32_t[w() * h()]), -life(4 * 60) { - std::memset(pixels, 0xFF, w() * h() * sizeof(Gambatte::uint_least32_t)); - - /*print(pixels + 0 * w() + 0, w(), 0x000000ul, txt); - print(pixels + 0 * w() + 1, w(), 0x000000ul, txt); - print(pixels + 0 * w() + 2, w(), 0x000000ul, txt); - print(pixels + 1 * w() + 0, w(), 0x000000ul, txt); - print(pixels + 1 * w() + 2, w(), 0x000000ul, txt); - print(pixels + 2 * w() + 0, w(), 0x000000ul, txt); - print(pixels + 2 * w() + 1, w(), 0x000000ul, txt); - print(pixels + 2 * w() + 2, w(), 0x000000ul, txt); - print(pixels + 1 * w() + 1, w(), 0xE0E0E0ul, txt);*/ - - print(pixels, w(), ShadeFill(), txt); - print(pixels + 1 * w() + 1, w(), 0xE0E0E0ul, txt); -} - -ShadedTextOsdElment::~ShadedTextOsdElment() { - delete []pixels; -} - -const Gambatte::uint_least32_t* ShadedTextOsdElment::update() { - if (life--) - return pixels; - - return 0; -} - -/*class FramedTextOsdElment : public OsdElement { - Gambatte::uint_least32_t *const pixels; - unsigned life; - -public: - FramedTextOsdElment(unsigned w, const char *txt); - ~FramedTextOsdElment(); - const Gambatte::uint_least32_t* update(); -}; - -FramedTextOsdElment::FramedTextOsdElment(unsigned width, const char *txt) : -OsdElement(NUMBER_WIDTH, 144 - HEIGHT * 2 - HEIGHT / 2, width + NUMBER_WIDTH * 2, HEIGHT * 2), -pixels(new Gambatte::uint_least32_t[w() * h()]), -life(4 * 60) { - std::memset(pixels, 0x00, w() * h() * sizeof(Gambatte::uint_least32_t)); - print(pixels + (w() - width) / 2 + ((h() - HEIGHT) / 2) * w(), w(), 0xA0A0A0ul, txt); -} - -FramedTextOsdElment::~FramedTextOsdElment() { - delete []pixels; -} - -const Gambatte::uint_least32_t* FramedTextOsdElment::update() { - if (life--) - return pixels; - - return 0; -}*/ - -std::auto_ptr newStateLoadedOsdElement(unsigned stateNo) { - char txt[sizeof(stateLoadedTxt)]; - - std::memcpy(txt, stateLoadedTxt, sizeof(stateLoadedTxt)); - utoa(stateNo, txt + 6); - - return std::auto_ptr(new ShadedTextOsdElment(stateLoadedTxtWidth, txt)); -} - -std::auto_ptr newStateSavedOsdElement(unsigned stateNo) { - char txt[sizeof(stateSavedTxt)]; - - std::memcpy(txt, stateSavedTxt, sizeof(stateSavedTxt)); - utoa(stateNo, txt + 6); - - return std::auto_ptr(new ShadedTextOsdElment(stateSavedTxtWidth, txt)); -} - -class SaveStateOsdElement : public OsdElement { - Gambatte::uint_least32_t pixels[StateSaver::SS_WIDTH * StateSaver::SS_HEIGHT]; - unsigned life; - -public: - SaveStateOsdElement(const char *fileName, unsigned stateNo); - const Gambatte::uint_least32_t* update(); -}; - -SaveStateOsdElement::SaveStateOsdElement(const char *fileName, unsigned stateNo) : -OsdElement((stateNo ? stateNo - 1 : 9) * ((160 - StateSaver::SS_WIDTH) / 10) + ((160 - StateSaver::SS_WIDTH) / 10) / 2, 4, StateSaver::SS_WIDTH, StateSaver::SS_HEIGHT), -life(4 * 60) { - std::ifstream file(fileName, std::ios_base::binary); - - if (file.is_open()) { - file.ignore(5); - file.read(reinterpret_cast(pixels), sizeof(pixels)); - } else { - std::memset(pixels, 0, sizeof(pixels)); - - { - using namespace BitmapFont; - - static const char txt[] = { E,m,p,t,BitmapFont::y,0 }; - - print(pixels + 3 + (StateSaver::SS_HEIGHT / 2 - BitmapFont::HEIGHT / 2) * StateSaver::SS_WIDTH, StateSaver::SS_WIDTH, 0x808080ul, txt); - } - } -} - -const Gambatte::uint_least32_t* SaveStateOsdElement::update() { - if (life--) - return pixels; - - return 0; -} - -std::auto_ptr newSaveStateOsdElement(const char *fileName, unsigned stateNo) { - return std::auto_ptr(new SaveStateOsdElement(fileName, stateNo)); -} diff --git a/src/lib/libgambatte/src/state_osd_elements.h b/src/lib/libgambatte/src/state_osd_elements.h deleted file mode 100644 index c10344d2..00000000 --- a/src/lib/libgambatte/src/state_osd_elements.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef STATE_OSD_ELEMENTS_H -#define STATE_OSD_ELEMENTS_H - -#include "osd_element.h" -#include - -std::auto_ptr newStateLoadedOsdElement(unsigned stateNo); -std::auto_ptr newStateSavedOsdElement(unsigned stateNo); -std::auto_ptr newSaveStateOsdElement(const char *fileName, unsigned stateNo); - -#endif diff --git a/src/lib/libgambatte/src/statesaver.cpp b/src/lib/libgambatte/src/statesaver.cpp deleted file mode 100644 index 9b113ee6..00000000 --- a/src/lib/libgambatte/src/statesaver.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "statesaver.h" -#include "savestate.h" -#include "array.h" -#include -#include -#include -#include - -enum AsciiChar { - NUL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS, TAB, LF, VT, FF, CR, SO, SI, - DLE, DC1, DC2, DC3, DC4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS, GS, RS, US, - SP, XCL, QOT, HSH, DLR, PRC, AMP, APO, LPA, RPA, AST, PLU, COM, HYP, STP, DIV, - NO0, NO1, NO2, NO3, NO4, NO5, NO6, NO7, NO8, NO9, CLN, SCL, LT, EQL, GT, QTN, - AT, A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, - P, Q, R, S, T, U, V, W, X, Y, Z, LBX, BSL, RBX, CAT, UND, - ACN, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, - p, q, r, s, t, u, v, w, x, y, z, LBR, BAR, RBR, TLD, DEL -}; - -struct Saver { - const char *label; - void (*save)(std::ofstream &file, const SaveState &state); - void (*load)(std::ifstream &file, SaveState &state); - unsigned char labelsize; -}; - -static inline bool operator<(const Saver &l, const Saver &r) { - return std::strcmp(l.label, r.label) < 0; -} - -static void put24(std::ofstream &file, const unsigned long data) { - file.put(data >> 16 & 0xFF); - file.put(data >> 8 & 0xFF); - file.put(data & 0xFF); -} - -static void put32(std::ofstream &file, const unsigned long data) { - file.put(data >> 24 & 0xFF); - file.put(data >> 16 & 0xFF); - file.put(data >> 8 & 0xFF); - file.put(data & 0xFF); -} - -static void write(std::ofstream &file, const unsigned char data) { - static const char inf[] = { 0x00, 0x00, 0x01 }; - - file.write(inf, sizeof(inf)); - file.put(data & 0xFF); -} - -static void write(std::ofstream &file, const unsigned short data) { - static const char inf[] = { 0x00, 0x00, 0x02 }; - - file.write(inf, sizeof(inf)); - file.put(data >> 8 & 0xFF); - file.put(data & 0xFF); -} - -static void write(std::ofstream &file, const unsigned long data) { - static const char inf[] = { 0x00, 0x00, 0x04 }; - - file.write(inf, sizeof(inf)); - put32(file, data); -} - -static inline void write(std::ofstream &file, const bool data) { - write(file, static_cast(data)); -} - -static void write(std::ofstream &file, const unsigned char *data, const unsigned long sz) { - put24(file, sz); - file.write(reinterpret_cast(data), sz); -} - -static void write(std::ofstream &file, const bool *data, const unsigned long sz) { - put24(file, sz); - - for (unsigned long i = 0; i < sz; ++i) - file.put(data[i]); -} - -static unsigned long get24(std::ifstream &file) { - unsigned long tmp = file.get() & 0xFF; - - tmp = tmp << 8 | (file.get() & 0xFF); - - return tmp << 8 | (file.get() & 0xFF); -} - -static unsigned long read(std::ifstream &file) { - unsigned long size = get24(file); - - if (size > 4) { - file.ignore(size - 4); - size = 4; - } - - unsigned long out = 0; - - switch (size) { - case 4: out = (out | (file.get() & 0xFF)) << 8; - case 3: out = (out | (file.get() & 0xFF)) << 8; - case 2: out = (out | (file.get() & 0xFF)) << 8; - case 1: out = out | (file.get() & 0xFF); - } - - return out; -} - -static inline void read(std::ifstream &file, unsigned char &data) { - data = read(file) & 0xFF; -} - -static inline void read(std::ifstream &file, unsigned short &data) { - data = read(file) & 0xFFFF; -} - -static inline void read(std::ifstream &file, unsigned long &data) { - data = read(file); -} - -static inline void read(std::ifstream &file, bool &data) { - data = read(file); -} - -static void read(std::ifstream &file, unsigned char *data, unsigned long sz) { - const unsigned long size = get24(file); - - if (size < sz) - sz = size; - - file.read(reinterpret_cast(data), sz); - file.ignore(size - sz); - - if (static_cast(0x100)) { - for (unsigned long i = 0; i < sz; ++i) - data[i] &= 0xFF; - } -} - -static void read(std::ifstream &file, bool *data, unsigned long sz) { - const unsigned long size = get24(file); - - if (size < sz) - sz = size; - - for (unsigned long i = 0; i < sz; ++i) - data[i] = file.get(); - - file.ignore(size - sz); -} - -class SaverList { -public: - typedef std::vector list_t; - typedef list_t::const_iterator const_iterator; - -private: - list_t list; - unsigned char maxLabelsize_; - -public: - SaverList(); - const_iterator begin() const { return list.begin(); } - const_iterator end() const { return list.end(); } - unsigned maxLabelsize() const { return maxLabelsize_; } -}; - -SaverList::SaverList() { -#define ADD(arg) do { \ - struct Func { \ - static void save(std::ofstream &file, const SaveState &state) { write(file, state.arg); } \ - static void load(std::ifstream &file, SaveState &state) { read(file, state.arg); } \ - }; \ - \ - Saver saver = { label, Func::save, Func::load, sizeof label }; \ - list.push_back(saver); \ -} while (0) - -#define ADDPTR(arg) do { \ - struct Func { \ - static void save(std::ofstream &file, const SaveState &state) { write(file, state.arg.get(), state.arg.getSz()); } \ - static void load(std::ifstream &file, SaveState &state) { read(file, state.arg.ptr, state.arg.getSz()); } \ - }; \ - \ - Saver saver = { label, Func::save, Func::load, sizeof label }; \ - list.push_back(saver); \ -} while (0) - - { static const char label[] = { c,c, NUL }; ADD(cpu.cycleCounter); } - { static const char label[] = { p,c, NUL }; ADD(cpu.PC); } - { static const char label[] = { s,p, NUL }; ADD(cpu.SP); } - { static const char label[] = { a, NUL }; ADD(cpu.A); } - { static const char label[] = { b, NUL }; ADD(cpu.B); } - { static const char label[] = { c, NUL }; ADD(cpu.C); } - { static const char label[] = { d, NUL }; ADD(cpu.D); } - { static const char label[] = { e, NUL }; ADD(cpu.E); } - { static const char label[] = { f, NUL }; ADD(cpu.F); } - { static const char label[] = { h, NUL }; ADD(cpu.H); } - { static const char label[] = { l, NUL }; ADD(cpu.L); } - { static const char label[] = { s,k,i,p, NUL }; ADD(cpu.skip); } - { static const char label[] = { h,a,l,t, NUL }; ADD(cpu.halted); } - { static const char label[] = { v,r,a,m, NUL }; ADDPTR(mem.vram); } - { static const char label[] = { s,r,a,m, NUL }; ADDPTR(mem.sram); } - { static const char label[] = { w,r,a,m, NUL }; ADDPTR(mem.wram); } - { static const char label[] = { h,r,a,m, NUL }; ADDPTR(mem.ioamhram); } - { static const char label[] = { l,d,i,v,u,p, NUL }; ADD(mem.div_lastUpdate); } - { static const char label[] = { l,t,i,m,a,u,p, NUL }; ADD(mem.tima_lastUpdate); } - { static const char label[] = { t,m,a,t,i,m,e, NUL }; ADD(mem.tmatime); } - { static const char label[] = { s,e,r,i,a,l,t, NUL }; ADD(mem.next_serialtime); } - { static const char label[] = { l,o,d,m,a,u,p, NUL }; ADD(mem.lastOamDmaUpdate); } - { static const char label[] = { m,i,n,i,n,t,t, NUL }; ADD(mem.minIntTime); } - { static const char label[] = { r,o,m,b,a,n,k, NUL }; ADD(mem.rombank); } - { static const char label[] = { d,m,a,s,r,c, NUL }; ADD(mem.dmaSource); } - { static const char label[] = { d,m,a,d,s,t, NUL }; ADD(mem.dmaDestination); } - { static const char label[] = { r,a,m,b,a,n,k, NUL }; ADD(mem.rambank); } - { static const char label[] = { o,d,m,a,p,o,s, NUL }; ADD(mem.oamDmaPos); } - { static const char label[] = { i,m,e, NUL }; ADD(mem.IME); } - { static const char label[] = { s,r,a,m,o,n, NUL }; ADD(mem.enable_ram); } - { static const char label[] = { r,a,m,b,m,o,d, NUL }; ADD(mem.rambank_mode); } - { static const char label[] = { h,d,m,a, NUL }; ADD(mem.hdma_transfer); } - { static const char label[] = { b,g,p, NUL }; ADDPTR(ppu.bgpData); } - { static const char label[] = { o,b,j,p, NUL }; ADDPTR(ppu.objpData); } - { static const char label[] = { s,p,o,s,b,u,f, NUL }; ADDPTR(ppu.oamReaderBuf); } - { static const char label[] = { s,p,s,z,b,u,f, NUL }; ADDPTR(ppu.oamReaderSzbuf); } - { static const char label[] = { v,c,y,c,l,e,s, NUL }; ADD(ppu.videoCycles); } - { static const char label[] = { e,d,M,NO0,t,i,m, NUL }; ADD(ppu.enableDisplayM0Time); } - { static const char label[] = { w,i,n,y,p,o,s, NUL }; ADD(ppu.winYPos); } - { static const char label[] = { d,r,a,w,c,y,c, NUL }; ADD(ppu.drawStartCycle); } - { static const char label[] = { s,c,r,d,c,y,c, NUL }; ADD(ppu.scReadOffset); } - { static const char label[] = { l,c,d,c, NUL }; ADD(ppu.lcdc); } - { static const char label[] = { s,c,x,NO0, NUL }; ADD(ppu.scx[0]); } - { static const char label[] = { s,c,x,NO1, NUL }; ADD(ppu.scx[1]); } - { static const char label[] = { s,c,y,NO0, NUL }; ADD(ppu.scy[0]); } - { static const char label[] = { s,c,y,NO1, NUL }; ADD(ppu.scy[1]); } - { static const char label[] = { s,c,x,AMP,NO7, NUL }; ADD(ppu.scxAnd7); } - { static const char label[] = { w,e,m,a,s,t,r, NUL }; ADD(ppu.weMaster); } - { static const char label[] = { w,x, NUL }; ADD(ppu.wx); } - { static const char label[] = { w,y, NUL }; ADD(ppu.wy); } - { static const char label[] = { l,y,c,s,k,i,p, NUL }; ADD(ppu.lycIrqSkip); } - { static const char label[] = { s,p,u,c,n,t,r, NUL }; ADD(spu.cycleCounter); } - { static const char label[] = { s,w,p,c,n,t,r, NUL }; ADD(spu.ch1.sweep.counter); } - { static const char label[] = { s,w,p,s,h,d,w, NUL }; ADD(spu.ch1.sweep.shadow); } - { static const char label[] = { s,w,p,n,e,g, NUL }; ADD(spu.ch1.sweep.negging); } - { static const char label[] = { d,u,t,NO1,c,t,r, NUL }; ADD(spu.ch1.duty.nextPosUpdate); } - { static const char label[] = { d,u,t,NO1,p,o,s, NUL }; ADD(spu.ch1.duty.pos); } - { static const char label[] = { e,n,v,NO1,c,t,r, NUL }; ADD(spu.ch1.env.counter); } - { static const char label[] = { e,n,v,NO1,v,o,l, NUL }; ADD(spu.ch1.env.volume); } - { static const char label[] = { l,e,n,NO1,c,t,r, NUL }; ADD(spu.ch1.lcounter.counter); } - { static const char label[] = { l,e,n,NO1,v,a,l, NUL }; ADD(spu.ch1.lcounter.lengthCounter); } - { static const char label[] = { n,r,NO1,NO0, NUL }; ADD(spu.ch1.sweep.nr0); } - { static const char label[] = { n,r,NO1,NO3, NUL }; ADD(spu.ch1.duty.nr3); } - { static const char label[] = { n,r,NO1,NO4, NUL }; ADD(spu.ch1.nr4); } - { static const char label[] = { c,NO1,m,a,s,t,r, NUL }; ADD(spu.ch1.master); } - { static const char label[] = { d,u,t,NO2,c,t,r, NUL }; ADD(spu.ch2.duty.nextPosUpdate); } - { static const char label[] = { d,u,t,NO2,p,o,s, NUL }; ADD(spu.ch2.duty.pos); } - { static const char label[] = { e,n,v,NO2,c,t,r, NUL }; ADD(spu.ch2.env.counter); } - { static const char label[] = { e,n,v,NO2,v,o,l, NUL }; ADD(spu.ch2.env.volume); } - { static const char label[] = { l,e,n,NO2,c,t,r, NUL }; ADD(spu.ch2.lcounter.counter); } - { static const char label[] = { l,e,n,NO2,v,a,l, NUL }; ADD(spu.ch2.lcounter.lengthCounter); } - { static const char label[] = { n,r,NO2,NO3, NUL }; ADD(spu.ch2.duty.nr3); } - { static const char label[] = { n,r,NO2,NO4, NUL }; ADD(spu.ch2.nr4); } - { static const char label[] = { c,NO2,m,a,s,t,r, NUL }; ADD(spu.ch2.master); } - { static const char label[] = { w,a,v,e,r,a,m, NUL }; ADDPTR(spu.ch3.waveRam); } - { static const char label[] = { l,e,n,NO3,c,t,r, NUL }; ADD(spu.ch3.lcounter.counter); } - { static const char label[] = { l,e,n,NO3,v,a,l, NUL }; ADD(spu.ch3.lcounter.lengthCounter); } - { static const char label[] = { w,a,v,e,c,t,r, NUL }; ADD(spu.ch3.waveCounter); } - { static const char label[] = { l,w,a,v,r,d,t, NUL }; ADD(spu.ch3.lastReadTime); } - { static const char label[] = { w,a,v,e,p,o,s, NUL }; ADD(spu.ch3.wavePos); } - { static const char label[] = { w,a,v,s,m,p,l, NUL }; ADD(spu.ch3.sampleBuf); } - { static const char label[] = { n,r,NO3,NO3, NUL }; ADD(spu.ch3.nr3); } - { static const char label[] = { n,r,NO3,NO4, NUL }; ADD(spu.ch3.nr4); } - { static const char label[] = { c,NO3,m,a,s,t,r, NUL }; ADD(spu.ch3.master); } - { static const char label[] = { l,f,s,r,c,t,r, NUL }; ADD(spu.ch4.lfsr.counter); } - { static const char label[] = { l,f,s,r,r,e,g, NUL }; ADD(spu.ch4.lfsr.reg); } - { static const char label[] = { e,n,v,NO4,c,t,r, NUL }; ADD(spu.ch4.env.counter); } - { static const char label[] = { e,n,v,NO4,v,o,l, NUL }; ADD(spu.ch4.env.volume); } - { static const char label[] = { l,e,n,NO4,c,t,r, NUL }; ADD(spu.ch4.lcounter.counter); } - { static const char label[] = { l,e,n,NO4,v,a,l, NUL }; ADD(spu.ch4.lcounter.lengthCounter); } - { static const char label[] = { n,r,NO4,NO4, NUL }; ADD(spu.ch4.nr4); } - { static const char label[] = { c,NO4,m,a,s,t,r, NUL }; ADD(spu.ch4.master); } - { static const char label[] = { r,t,c,b,a,s,e, NUL }; ADD(rtc.baseTime); } - { static const char label[] = { r,t,c,h,a,l,t, NUL }; ADD(rtc.haltTime); } - { static const char label[] = { r,t,c,i,n,d,x, NUL }; ADD(rtc.index); } - { static const char label[] = { r,t,c,d,h, NUL }; ADD(rtc.dataDh); } - { static const char label[] = { r,t,c,d,l, NUL }; ADD(rtc.dataDl); } - { static const char label[] = { r,t,c,h, NUL }; ADD(rtc.dataH); } - { static const char label[] = { r,t,c,m, NUL }; ADD(rtc.dataM); } - { static const char label[] = { r,t,c,s, NUL }; ADD(rtc.dataS); } - { static const char label[] = { r,t,c,l,l,d, NUL }; ADD(rtc.lastLatchData); } - -#undef ADD -#undef ADDPTR -#undef ADDTIME - - list.resize(list.size()); - std::sort(list.begin(), list.end()); - - maxLabelsize_ = 0; - - for (std::size_t i = 0; i < list.size(); ++i) { - if (list[i].labelsize > maxLabelsize_) - maxLabelsize_ = list[i].labelsize; - } -} - -static void writeSnapShot(std::ofstream &file, const Gambatte::uint_least32_t *pixels, const unsigned pitch) { - put24(file, pixels ? StateSaver::SS_WIDTH * StateSaver::SS_HEIGHT * sizeof(Gambatte::uint_least32_t) : 0); - - if (pixels) { - Gambatte::uint_least32_t buf[StateSaver::SS_WIDTH]; - - for (unsigned h = StateSaver::SS_HEIGHT; h--;) { - for (unsigned x = 0; x < StateSaver::SS_WIDTH; ++x) { - unsigned long rb = 0; - unsigned long g = 0; - - static const unsigned w[StateSaver::SS_DIV] = { 3, 5, 5, 3 }; - - for (unsigned y = 0; y < StateSaver::SS_DIV; ++y) - for (unsigned xx = 0; xx < StateSaver::SS_DIV; ++xx) { - rb += (pixels[x * StateSaver::SS_DIV + y * pitch + xx] & 0xFF00FF) * w[y] * w[xx]; - g += (pixels[x * StateSaver::SS_DIV + y * pitch + xx] & 0x00FF00) * w[y] * w[xx]; - } - - buf[x] = (rb >> 8 & 0xFF00FF) | (g >> 8 & 0x00FF00); - } - - file.write(reinterpret_cast(buf), sizeof(buf)); - pixels += pitch * StateSaver::SS_DIV; - } - } -} - -static SaverList list; - -void StateSaver::saveState(const SaveState &state, const char *filename) { - std::ofstream file(filename, std::ios_base::binary); - - if (file.fail()) - return; - - { static const char ver[] = { 0, 0 }; file.write(ver, sizeof(ver)); } - - writeSnapShot(file, state.ppu.drawBuffer.get(), state.ppu.drawBuffer.getSz() / 144); - - for (SaverList::const_iterator it = list.begin(); it != list.end(); ++it) { - file.write(it->label, it->labelsize); - (*it->save)(file, state); - } -} - -bool StateSaver::loadState(SaveState &state, const char *filename) { - std::ifstream file(filename, std::ios_base::binary); - - if (file.fail() || file.get() != 0) - return false; - - file.ignore(); - file.ignore(get24(file)); - - Array labelbuf(list.maxLabelsize()); - const Saver labelbufSaver = { label: labelbuf, save: 0, load: 0, labelsize: list.maxLabelsize() }; - - SaverList::const_iterator done = list.begin(); - - while (file.good() && done != list.end()) { - file.getline(labelbuf, list.maxLabelsize(), NUL); - - SaverList::const_iterator it = done; - - if (std::strcmp(labelbuf, it->label)) { - it = std::lower_bound(it + 1, list.end(), labelbufSaver); - - if (it == list.end() || std::strcmp(labelbuf, it->label)) { - file.ignore(get24(file)); - continue; - } - } else - ++done; - - (*it->load)(file, state); - } - - state.cpu.cycleCounter &= 0x7FFFFFFF; - state.spu.cycleCounter &= 0x7FFFFFFF; - - return true; -} diff --git a/src/lib/libgambatte/src/statesaver.h b/src/lib/libgambatte/src/statesaver.h deleted file mode 100644 index ea9ce8b3..00000000 --- a/src/lib/libgambatte/src/statesaver.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef STATESAVER_H -#define STATESAVER_H - -class SaveState; - -class StateSaver { - StateSaver(); - -public: - enum { SS_SHIFT = 2 }; - enum { SS_DIV = 1 << 2 }; - enum { SS_WIDTH = 160 >> SS_SHIFT }; - enum { SS_HEIGHT = 144 >> SS_SHIFT }; - - static void saveState(const SaveState &state, const char *filename); - static bool loadState(SaveState &state, const char *filename); -}; - -#endif diff --git a/src/lib/libgambatte/src/video.cpp b/src/lib/libgambatte/src/video.cpp deleted file mode 100644 index 875afa43..00000000 --- a/src/lib/libgambatte/src/video.cpp +++ /dev/null @@ -1,1474 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "video.h" -#include "videoblitter.h" -#include "video/filters/filter.h" -#include "video/filters/catrom2x.h" -#include "video/filters/catrom3x.h" -#include "video/filters/kreed2xsai.h" -#include "video/filters/maxsthq2x.h" -#include "video/filters/maxsthq3x.h" -#include "filterinfo.h" -#include "savestate.h" -#include "video/basic_add_event.h" -#include -#include - -static void addEventIfActivated(event_queue &q, VideoEvent *const e, const unsigned long newTime) { - e->setTime(newTime); - - if (newTime != VideoEvent::DISABLED_TIME) - q.push(e); -} - -void LCD::setDmgPalette(unsigned long *const palette, const unsigned long *const dmgColors, const unsigned data) { - palette[0] = dmgColors[data & 3]; - palette[1] = dmgColors[data >> 2 & 3]; - palette[2] = dmgColors[data >> 4 & 3]; - palette[3] = dmgColors[data >> 6 & 3]; -} - -unsigned long LCD::gbcToRgb32(const unsigned bgr15) { - const unsigned long r = bgr15 & 0x1F; - const unsigned long g = bgr15 >> 5 & 0x1F; - const unsigned long b = bgr15 >> 10 & 0x1F; - - return ((r * 13 + g * 2 + b) >> 1) << 16 | ((g * 3 + b) << 9) | ((r * 3 + g * 2 + b * 11) >> 1); -} - -unsigned long LCD::gbcToRgb16(const unsigned bgr15) { - const unsigned r = bgr15 & 0x1F; - const unsigned g = bgr15 >> 5 & 0x1F; - const unsigned b = bgr15 >> 10 & 0x1F; - - return (((r * 13 + g * 2 + b + 8) << 7) & 0xF800) | ((g * 3 + b + 1) >> 1) << 5 | ((r * 3 + g * 2 + b * 11 + 8) >> 4); -} - -unsigned long LCD::gbcToUyvy(const unsigned bgr15) { - const unsigned r5 = bgr15 & 0x1F; - const unsigned g5 = bgr15 >> 5 & 0x1F; - const unsigned b5 = bgr15 >> 10 & 0x1F; - - // y = (r5 * 926151 + g5 * 1723530 + b5 * 854319) / 510000 + 16; - // u = (b5 * 397544 - r5 * 68824 - g5 * 328720) / 225930 + 128; - // v = (r5 * 491176 - g5 * 328720 - b5 * 162456) / 178755 + 128; - - const unsigned long y = (r5 * 116 + g5 * 216 + b5 * 107 + 16 * 64 + 32) >> 6; - const unsigned long u = (b5 * 225 - r5 * 39 - g5 * 186 + 128 * 128 + 64) >> 7; - const unsigned long v = (r5 * 176 - g5 * 118 - b5 * 58 + 128 * 64 + 32) >> 6; - -#ifdef WORDS_BIGENDIAN - return u << 24 | y << 16 | v << 8 | y; -#else - return y << 24 | v << 16 | y << 8 | u; -#endif -} - -LCD::LCD(const unsigned char *const oamram, const unsigned char *const vram_in) : - vram(vram_in), - bgTileData(vram), - bgTileMap(vram + 0x1800), - wdTileMap(bgTileMap), - vBlitter(NULL), - filter(NULL), - dbuffer(NULL), - draw(NULL), - gbcToFormat(gbcToRgb32), - dmgColors(dmgColorsRgb32), - lastUpdate(0), - videoCycles(0), - dpitch(0), - winYPos(0), - m3EventQueue(11, VideoEventComparer()), - irqEventQueue(4, VideoEventComparer()), - vEventQueue(5, VideoEventComparer()), - win(m3EventQueue, lyCounter, m3ExtraCycles), - scxReader(m3EventQueue, /*wyReg.reader3(),*/ win.wxReader, win.we.enableChecker(), win.we.disableChecker(), m3ExtraCycles), - spriteMapper(m3ExtraCycles, lyCounter, oamram), - m3ExtraCycles(spriteMapper, scxReader, win), - breakEvent(drawStartCycle, scReadOffset), - mode3Event(m3EventQueue, vEventQueue, mode0Irq, irqEvent), - lycIrq(ifReg), - mode0Irq(lyCounter, lycIrq, m3ExtraCycles, ifReg), - mode1Irq(ifReg), - mode2Irq(lyCounter, lycIrq, ifReg), - irqEvent(irqEventQueue), - drawStartCycle(90), - scReadOffset(90), - ifReg(0), - tileIndexSign(0), - statReg(0), - doubleSpeed(false), - enabled(false), - cgb(false), - bgEnable(false), - spriteEnable(false) -{ - std::memset(bgpData, 0, sizeof(bgpData)); - std::memset(objpData, 0, sizeof(objpData)); - - for (unsigned i = 0; i < sizeof(dmgColorsRgb32) / sizeof(unsigned long); ++i) { - setDmgPaletteColor(i, (3 - (i & 3)) * 85 * 0x010101); - } - - filters.push_back(NULL); - filters.push_back(new Catrom2x); - filters.push_back(new Catrom3x); - filters.push_back(new Kreed_2xSaI); - filters.push_back(new MaxSt_Hq2x); - filters.push_back(new MaxSt_Hq3x); - - reset(oamram, false); - setDoubleSpeed(false); - - setVideoFilter(0); -} - -LCD::~LCD() { -// delete []filter_buffer; - for (std::size_t i = 0; i < filters.size(); ++i) - delete filters[i]; -} - -void LCD::reset(const unsigned char *const oamram, const bool cgb_in) { - cgb = cgb_in; - spriteMapper.reset(oamram, cgb_in); - setDBuffer(); -} - -void LCD::resetVideoState(const unsigned long cycleCounter) { - vEventQueue.clear(); - m3EventQueue.clear(); - irqEventQueue.clear(); - - lyCounter.reset(videoCycles, lastUpdate); - vEventQueue.push(&lyCounter); - - spriteMapper.resetVideoState(); - m3ExtraCycles.invalidateCache(); - - addEventIfActivated(m3EventQueue, &scxReader, ScxReader::schedule(lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.wxReader, WxReader::schedule(scxReader.scxAnd7(), lyCounter, win.wxReader, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.wyReg.reader1(), Wy::WyReader1::schedule(lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.wyReg.reader2(), Wy::WyReader2::schedule(lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.wyReg.reader3(), Wy::WyReader3::schedule(win.wxReader.getSource(), scxReader, lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.wyReg.reader4(), Wy::WyReader4::schedule(lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &spriteMapper, SpriteMapper::schedule(lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.we.enableChecker(), We::WeEnableChecker::schedule(scxReader.scxAnd7(), win.wxReader.wx(), lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.we.disableChecker(), We::WeDisableChecker::schedule(scxReader.scxAnd7(), win.wxReader.wx(), lyCounter, cycleCounter)); - addEventIfActivated(m3EventQueue, &win.weMasterChecker, WeMasterChecker::schedule(win.wyReg.getSource(), win.we.getSource(), lyCounter, cycleCounter)); - - addEventIfActivated(irqEventQueue, &lycIrq, LycIrq::schedule(statReg, lycIrq.lycReg(), lyCounter, cycleCounter)); - addEventIfActivated(irqEventQueue, &mode0Irq, Mode0Irq::schedule(statReg, m3ExtraCycles, lyCounter, cycleCounter)); - addEventIfActivated(irqEventQueue, &mode1Irq, Mode1Irq::schedule(lyCounter, cycleCounter)); - addEventIfActivated(irqEventQueue, &mode2Irq, Mode2Irq::schedule(statReg, lyCounter, cycleCounter)); - - addEventIfActivated(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); - addEventIfActivated(vEventQueue, &irqEvent, IrqEvent::schedule(irqEventQueue)); - addEventIfActivated(vEventQueue, &scReader, ScReader::schedule(lastUpdate, videoCycles, scReadOffset, doubleSpeed)); - addEventIfActivated(vEventQueue, &breakEvent, BreakEvent::schedule(lyCounter)); -} - -void LCD::setDoubleSpeed(const bool ds) { - doubleSpeed = ds; - lyCounter.setDoubleSpeed(doubleSpeed); - scxReader.setDoubleSpeed(doubleSpeed); - win.wxReader.setDoubleSpeed(doubleSpeed); - scReader.setDoubleSpeed(doubleSpeed); - breakEvent.setDoubleSpeed(doubleSpeed); - lycIrq.setDoubleSpeed(doubleSpeed); - mode1Irq.setDoubleSpeed(doubleSpeed); -} - -void LCD::setStatePtrs(SaveState &state) { - state.ppu.drawBuffer.set(static_cast(dbuffer), dpitch * 144); - state.ppu.bgpData.set(bgpData, sizeof bgpData); - state.ppu.objpData.set(objpData, sizeof objpData); - spriteMapper.setStatePtrs(state); -} - -void LCD::saveState(SaveState &state) const { - state.ppu.videoCycles = videoCycles; - state.ppu.winYPos = winYPos; - state.ppu.drawStartCycle = drawStartCycle; - state.ppu.scReadOffset = scReadOffset; - state.ppu.lcdc = enabled << 7 | ((wdTileMap - vram - 0x1800) >> 4) | (tileIndexSign ^ 0x80) >> 3 | ((bgTileMap - vram - 0x1800) >> 7) | spriteEnable << 1 | bgEnable; - state.ppu.lycIrqSkip = lycIrq.skips(); - - spriteMapper.saveState(state); - scReader.saveState(state); - scxReader.saveState(state); - win.weMasterChecker.saveState(state); - win.wxReader.saveState(state); - win.wyReg.saveState(state); - win.we.saveState(state); -} - -void LCD::loadState(const SaveState &state, const unsigned char *oamram) { - statReg = state.mem.ioamhram.get()[0x141]; - ifReg = 0; - - setDoubleSpeed(cgb & state.mem.ioamhram.get()[0x14D] >> 7); - - lastUpdate = state.cpu.cycleCounter; - videoCycles = std::min(state.ppu.videoCycles, 70223ul); - winYPos = state.ppu.winYPos > 143 ? 0xFF : state.ppu.winYPos; - drawStartCycle = state.ppu.drawStartCycle; - scReadOffset = state.ppu.scReadOffset; - enabled = state.ppu.lcdc >> 7 & 1; - wdTileMap = vram + 0x1800 + (state.ppu.lcdc >> 6 & 1) * 0x400; - tileIndexSign = ((state.ppu.lcdc >> 4 & 1) ^ 1) * 0x80; - bgTileData = vram + ((state.ppu.lcdc >> 4 & 1) ^ 1) * 0x1000; - bgTileMap = vram + 0x1800 + (state.ppu.lcdc >> 3 & 1) * 0x400; - spriteEnable = state.ppu.lcdc >> 1 & 1; - bgEnable = state.ppu.lcdc & 1; - - lycIrq.setM2IrqEnabled(statReg >> 5 & 1); - lycIrq.setLycReg(state.mem.ioamhram.get()[0x145]); - lycIrq.setSkip(state.ppu.lycIrqSkip); - mode1Irq.setM1StatIrqEnabled(statReg >> 4 & 1); - - win.we.setSource(state.mem.ioamhram.get()[0x140] >> 5 & 1); - spriteMapper.setLargeSpritesSource(state.mem.ioamhram.get()[0x140] >> 2 & 1); - scReader.setScySource(state.mem.ioamhram.get()[0x142]); - scxReader.setSource(state.mem.ioamhram.get()[0x143]); - breakEvent.setScxSource(state.mem.ioamhram.get()[0x143]); - scReader.setScxSource(state.mem.ioamhram.get()[0x143]); - win.wyReg.setSource(state.mem.ioamhram.get()[0x14A]); - win.wxReader.setSource(state.mem.ioamhram.get()[0x14B]); - - spriteMapper.loadState(state); - scReader.loadState(state); - scxReader.loadState(state); - win.weMasterChecker.loadState(state); - win.wxReader.loadState(state); - win.wyReg.loadState(state); - win.we.loadState(state); - - resetVideoState(lastUpdate); - spriteMapper.oamChange(oamram, lastUpdate); - refreshPalettes(); -} - -void LCD::refreshPalettes() { - if (cgb) { - for (unsigned i = 0; i < 8 * 8; i += 2) { - bgPalette[i >> 1] = (*gbcToFormat)(bgpData[i] | bgpData[i + 1] << 8); - spPalette[i >> 1] = (*gbcToFormat)(objpData[i] | objpData[i + 1] << 8); - } - } else { - setDmgPalette(bgPalette, dmgColors, bgpData[0]); - setDmgPalette(spPalette, dmgColors + 4, objpData[0]); - setDmgPalette(spPalette + 4, dmgColors + 8, objpData[1]); - } -} - -void LCD::setVideoBlitter(Gambatte::VideoBlitter *vb) { - vBlitter = vb; - - if (vBlitter) { - vBlitter->setBufferDimensions(videoWidth(), videoHeight()); - pb = vBlitter->inBuffer(); - } - - setDBuffer(); -} - -void LCD::videoBufferChange() { - if (vBlitter) { - pb = vBlitter->inBuffer(); - setDBuffer(); - } -} - -void LCD::setVideoFilter(const unsigned n) { - const unsigned oldw = videoWidth(); - const unsigned oldh = videoHeight(); - - if (filter) - filter->outit(); - - filter = filters.at(n < filters.size() ? n : 0); - - if (filter) { - filter->init(); - } - - if (vBlitter && (oldw != videoWidth() || oldh != videoHeight())) { - vBlitter->setBufferDimensions(videoWidth(), videoHeight()); - pb = vBlitter->inBuffer(); - } - - setDBuffer(); -} - -std::vector LCD::filterInfo() const { - std::vector v; - - static Gambatte::FilterInfo noInfo = { "None", 160, 144 }; - v.push_back(&noInfo); - - for (std::size_t i = 1; i < filters.size(); ++i) - v.push_back(&filters[i]->info()); - - return v; -} - -unsigned int LCD::videoWidth() const { - return filter ? filter->info().outWidth : 160; -} - -unsigned int LCD::videoHeight() const { - return filter ? filter->info().outHeight : 144; -} - -template -static void blitOsdElement(Gambatte::uint_least32_t *d, const Gambatte::uint_least32_t *s, const unsigned width, unsigned h, const unsigned dpitch, Blend blend) { - while (h--) { - for (unsigned w = width; w--;) { - if (*s != 0xFFFFFFFF) - *d = blend(*s, *d); - - ++d; - ++s; - } - - d += dpitch - width; - } -} - -template -struct Blend { - enum { SW = weight - 1 }; - enum { LOWMASK = SW * 0x010101ul }; - Gambatte::uint_least32_t operator()(const Gambatte::uint_least32_t s, const Gambatte::uint_least32_t d) const { - return (s * SW + d - (((s & LOWMASK) * SW + (d & LOWMASK)) & LOWMASK)) / weight; - } -}; - -void LCD::updateScreen(const unsigned long cycleCounter) { - update(cycleCounter); - - if (pb.pixels) { - if (dbuffer && osdElement.get()) { - const Gambatte::uint_least32_t *s = osdElement->update(); - - if (s) { - Gambatte::uint_least32_t *d = static_cast(dbuffer) + osdElement->y() * dpitch + osdElement->x(); - - switch (osdElement->opacity()) { - case OsdElement::SEVEN_EIGHTHS: blitOsdElement(d, s, osdElement->w(), osdElement->h(), dpitch, Blend<8>()); break; - case OsdElement::THREE_FOURTHS: blitOsdElement(d, s, osdElement->w(), osdElement->h(), dpitch, Blend<4>()); break; - } - } else - osdElement.reset(); - } - - if (filter) { - filter->filter(static_cast(tmpbuf ? tmpbuf : pb.pixels), (tmpbuf ? videoWidth() : pb.pitch)); - } - - if (tmpbuf) { - switch (pb.format) { - case Gambatte::PixelBuffer::RGB16: - rgb32ToRgb16(tmpbuf, static_cast(pb.pixels), videoWidth(), videoHeight(), pb.pitch); - break; - case Gambatte::PixelBuffer::UYVY: - rgb32ToUyvy(tmpbuf, static_cast(pb.pixels), videoWidth(), videoHeight(), pb.pitch); - break; - default: break; - } - } - - if (vBlitter) - vBlitter->blit(); - } -} - -template -static void clear(T *buf, const unsigned long color, const unsigned dpitch) { - unsigned lines = 144; - - while (lines--) { - std::fill_n(buf, 160, color); - buf += dpitch; - } -} - -void LCD::enableChange(const unsigned long cycleCounter) { - update(cycleCounter); - enabled = !enabled; - - if (enabled) { - lycIrq.setSkip(false); - videoCycles = 0; - lastUpdate = cycleCounter; - winYPos = 0xFF; - win.weMasterChecker.unset(); - spriteMapper.enableDisplay(cycleCounter); - resetVideoState(cycleCounter); - } - - if (!enabled && dbuffer) { - const unsigned long color = cgb ? (*gbcToFormat)(0xFFFF) : dmgColors[0]; - - clear(static_cast(dbuffer), color, dpitch); - -// updateScreen(cycleCounter); - } -} - -//FIXME: needs testing -void LCD::lyWrite(const unsigned long cycleCounter) { - update(cycleCounter); - lycIrq.setSkip(false); - videoCycles = 0; - lastUpdate = cycleCounter; - winYPos = 0xFF; - win.weMasterChecker.unset(); - resetVideoState(cycleCounter); - -// if ((statReg & 0x40) && lycIrq.lycReg() == 0) -// ifReg |= 2; -} - -void LCD::preResetCounter(const unsigned long cycleCounter) { - preSpeedChange(cycleCounter); -} - -void LCD::postResetCounter(const unsigned long oldCC, const unsigned long cycleCounter) { - lastUpdate = cycleCounter - (oldCC - lastUpdate); - spriteMapper.resetCycleCounter(oldCC, cycleCounter); - resetVideoState(cycleCounter); -} - -void LCD::preSpeedChange(const unsigned long cycleCounter) { - update(cycleCounter); - spriteMapper.preCounterChange(cycleCounter); -} - -void LCD::postSpeedChange(const unsigned long cycleCounter) { - setDoubleSpeed(!doubleSpeed); - - resetVideoState(cycleCounter); -} - -bool LCD::isMode0IrqPeriod(const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - const unsigned timeToNextLy = lyCounter.time() - cycleCounter; - - return /*memory.enable_display && */lyCounter.ly() < 144 && timeToNextLy <= (456U - (169 + doubleSpeed * 3U + 80 + m3ExtraCycles(lyCounter.ly()) + 1 - doubleSpeed)) << doubleSpeed && timeToNextLy > 4; -} - -bool LCD::isMode2IrqPeriod(const unsigned long cycleCounter) { - if (cycleCounter >= lyCounter.time()) - update(cycleCounter); - - const unsigned nextLy = lyCounter.time() - cycleCounter; - - return /*memory.enable_display && */lyCounter.ly() < 143 && nextLy <= 4; -} - -bool LCD::isLycIrqPeriod(const unsigned lycReg, const unsigned endCycles, const unsigned long cycleCounter) { - if (cycleCounter >= lyCounter.time()) - update(cycleCounter); - - const unsigned timeToNextLy = lyCounter.time() - cycleCounter; - - return (lyCounter.ly() == lycReg && timeToNextLy > endCycles) || (lycReg == 0 && lyCounter.ly() == 153 && timeToNextLy <= (456U - 8U) << doubleSpeed); -} - -bool LCD::isMode1IrqPeriod(const unsigned long cycleCounter) { - if (cycleCounter >= lyCounter.time()) - update(cycleCounter); - - const unsigned timeToNextLy = lyCounter.time() - cycleCounter; - - return lyCounter.ly() > 143 && (lyCounter.ly() < 153 || timeToNextLy > 4U - doubleSpeed * 4U); -} - -bool LCD::isHdmaPeriod(const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - const unsigned timeToNextLy = lyCounter.time() - cycleCounter; - - return /*memory.enable_display && */lyCounter.ly() < 144 && timeToNextLy <= ((456U - (169U + doubleSpeed * 3U + 80U + m3ExtraCycles(lyCounter.ly()) + 2 - doubleSpeed)) << doubleSpeed) && timeToNextLy > 4; -} - -unsigned long LCD::nextHdmaTime(const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - unsigned line = lyCounter.ly(); - int next = static_cast(169 + doubleSpeed * 3U + 80 + 2 - doubleSpeed) - static_cast(lyCounter.lineCycles(cycleCounter)); - - if (line < 144 && next + static_cast(m3ExtraCycles(line)) <= 0) { - next += 456; - ++line; - } - - if (line > 143) { - next += (154 - line) * 456; - line = 0; - } - - next += m3ExtraCycles(line); - - return cycleCounter + (static_cast(next) << doubleSpeed); -} - -bool LCD::vramAccessible(const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - bool accessible = true; - - if (enabled && lyCounter.ly() < 144) { - const unsigned lineCycles = lyCounter.lineCycles(cycleCounter); - - if (lineCycles > 79 && lineCycles < 80 + 169 + doubleSpeed * 3U + m3ExtraCycles(lyCounter.ly())) - accessible = false; - } - - return accessible; -} - -bool LCD::cgbpAccessible(const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - bool accessible = true; - - if (enabled && lyCounter.ly() < 144) { - const unsigned lineCycles = lyCounter.lineCycles(cycleCounter); - - if (lineCycles > 79U + doubleSpeed && lineCycles < 80U + 169U + doubleSpeed * 3U + m3ExtraCycles(lyCounter.ly()) + 4U - doubleSpeed * 2U) - accessible = false; - } - - return accessible; -} - -bool LCD::oamAccessible(const unsigned long cycleCounter) { - bool accessible = true; - - if (enabled) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - accessible = spriteMapper.oamAccessible(cycleCounter); - } - - return accessible; -} - -void LCD::weChange(const bool newValue, const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - win.we.setSource(newValue); - addFixedtimeEvent(m3EventQueue, &win.weMasterChecker, WeMasterChecker::schedule(win.wyReg.getSource(), newValue, lyCounter, cycleCounter)); - addFixedtimeEvent(m3EventQueue, &win.we.disableChecker(), We::WeDisableChecker::schedule(scxReader.scxAnd7(), win.wxReader.wx(), lyCounter, cycleCounter)); - addFixedtimeEvent(m3EventQueue, &win.we.enableChecker(), We::WeEnableChecker::schedule(scxReader.scxAnd7(), win.wxReader.wx(), lyCounter, cycleCounter)); - addUnconditionalEvent(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); -} - -void LCD::wxChange(const unsigned newValue, const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - win.wxReader.setSource(newValue); - addEvent(m3EventQueue, &win.wxReader, WxReader::schedule(scxReader.scxAnd7(), lyCounter, win.wxReader, cycleCounter)); - - if (win.wyReg.reader3().time() != VideoEvent::DISABLED_TIME) - addEvent(m3EventQueue, &win.wyReg.reader3(), Wy::WyReader3::schedule(win.wxReader.getSource(), scxReader, lyCounter, cycleCounter)); - - addUnconditionalEvent(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); -} - -void LCD::wyChange(const unsigned newValue, const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - win.wyReg.setSource(newValue); - addFixedtimeEvent(m3EventQueue, &win.wyReg.reader1(), Wy::WyReader1::schedule(lyCounter, cycleCounter)); - addFixedtimeEvent(m3EventQueue, &win.wyReg.reader2(), Wy::WyReader2::schedule(lyCounter, cycleCounter)); - addFixedtimeEvent(m3EventQueue, &win.wyReg.reader3(), Wy::WyReader3::schedule(win.wxReader.getSource(), scxReader, lyCounter, cycleCounter)); - addFixedtimeEvent(m3EventQueue, &win.wyReg.reader4(), Wy::WyReader4::schedule(lyCounter, cycleCounter)); - addEvent(m3EventQueue, &win.weMasterChecker, WeMasterChecker::schedule(win.wyReg.getSource(), win.we.getSource(), lyCounter, cycleCounter)); - addUnconditionalEvent(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); -} - -void LCD::scxChange(const unsigned newScx, const unsigned long cycleCounter) { - update(cycleCounter); - - scxReader.setSource(newScx); - breakEvent.setScxSource(newScx); - scReader.setScxSource(newScx); - - addFixedtimeEvent(m3EventQueue, &scxReader, ScxReader::schedule(lyCounter, cycleCounter)); - - if (win.wyReg.reader3().time() != VideoEvent::DISABLED_TIME) - addEvent(m3EventQueue, &win.wyReg.reader3(), Wy::WyReader3::schedule(win.wxReader.getSource(), scxReader, lyCounter, cycleCounter)); - - addUnconditionalEvent(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); - - const unsigned lineCycles = lyCounter.lineCycles(cycleCounter); - - if (lineCycles < 82U + doubleSpeed * 4U) - drawStartCycle = 90 + doubleSpeed * 4U + (newScx & 7); - else - addFixedtimeEvent(vEventQueue, &breakEvent, BreakEvent::schedule(lyCounter)); - - if (lineCycles < 86U + doubleSpeed * 2U) - scReadOffset = std::max(drawStartCycle - (newScx & 7), 90U + doubleSpeed * 4U); - - addEvent(vEventQueue, &scReader, ScReader::schedule(lastUpdate, videoCycles, scReadOffset, doubleSpeed)); -} - -void LCD::scyChange(const unsigned newValue, const unsigned long cycleCounter) { - update(cycleCounter); - - scReader.setScySource(newValue); - addFixedtimeEvent(vEventQueue, &scReader, ScReader::schedule(lastUpdate, videoCycles, scReadOffset, doubleSpeed)); -} - -void LCD::spriteSizeChange(const bool newLarge, const unsigned long cycleCounter) { - update(cycleCounter); - - spriteMapper.oamChange(cycleCounter); - spriteMapper.setLargeSpritesSource(newLarge); - addFixedtimeEvent(m3EventQueue, &spriteMapper, SpriteMapper::schedule(lyCounter, cycleCounter)); - addUnconditionalEvent(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); -} - -void LCD::oamChange(const unsigned long cycleCounter) { - update(cycleCounter); - - spriteMapper.oamChange(cycleCounter); - addFixedtimeEvent(m3EventQueue, &spriteMapper, SpriteMapper::schedule(lyCounter, cycleCounter)); - addUnconditionalEvent(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); -} - -void LCD::oamChange(const unsigned char *const oamram, const unsigned long cycleCounter) { - update(cycleCounter); - - spriteMapper.oamChange(oamram, cycleCounter); - addFixedtimeEvent(m3EventQueue, &spriteMapper, SpriteMapper::schedule(lyCounter, cycleCounter)); - addUnconditionalEvent(vEventQueue, &mode3Event, Mode3Event::schedule(m3EventQueue)); -} - -void LCD::wdTileMapSelectChange(const bool newValue, const unsigned long cycleCounter) { - update(cycleCounter); - - wdTileMap = vram + 0x1800 + newValue * 0x400; -} - -void LCD::bgTileMapSelectChange(const bool newValue, const unsigned long cycleCounter) { - update(cycleCounter); - - bgTileMap = vram + 0x1800 + newValue * 0x400; -} - -void LCD::bgTileDataSelectChange(const bool newValue, const unsigned long cycleCounter) { - update(cycleCounter); - - tileIndexSign = (newValue ^ 1) * 0x80; - bgTileData = vram + (newValue ^ 1) * 0x1000; -} - -void LCD::spriteEnableChange(const bool newValue, const unsigned long cycleCounter) { - update(cycleCounter); - - spriteEnable = newValue; -} - -void LCD::bgEnableChange(const bool newValue, const unsigned long cycleCounter) { - update(cycleCounter); - - bgEnable = newValue; -} - -void LCD::lcdstatChange(const unsigned data, const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - const unsigned old = statReg; - statReg = data; - mode1Irq.setM1StatIrqEnabled(data & 0x10); - lycIrq.setM2IrqEnabled(data & 0x20); - - if (!enabled) - return; - - const bool lycIrqPeriod = isLycIrqPeriod(lycIrq.lycReg(), lycIrq.lycReg() == 153 ? lyCounter.lineTime() - (4 << (doubleSpeed*2)) : 4 - doubleSpeed * 4U, cycleCounter); - - if (lycIrq.lycReg() < 154 && ((data ^ old) & 0x40)) { - if (data & 0x40) { - if (lycIrqPeriod) - ifReg |= 2; - } else { - if (!doubleSpeed && lycIrq.time() - cycleCounter < 5 && (!(old & 0x20) || lycIrq.lycReg() > 143 || lycIrq.lycReg() == 0)) - ifReg |= 2; - } - - addFixedtimeEvent(irqEventQueue, &lycIrq, LycIrq::schedule(data, lycIrq.lycReg(), lyCounter, cycleCounter)); - } - - if ((((data & 0x10) && !(old & 0x10)) || !cgb) && !((old & 0x40) && lycIrqPeriod) && isMode1IrqPeriod(cycleCounter)) - ifReg |= 2; - - if ((data ^ old) & 0x08) { - if (data & 0x08) { - if (!((old & 0x40) && lycIrqPeriod) && isMode0IrqPeriod(cycleCounter)) - ifReg |= 2; - } else { - if (mode0Irq.time() - cycleCounter < 3 && (lycIrq.time() == VideoEvent::DISABLED_TIME || lyCounter.ly() != lycIrq.lycReg())) - ifReg |= 2; - } - - addFixedtimeEvent(irqEventQueue, &mode0Irq, Mode0Irq::schedule(data, m3ExtraCycles, lyCounter, cycleCounter)); - } - - if ((data & 0x28) == 0x20 && (old & 0x28) != 0x20 && isMode2IrqPeriod(cycleCounter)) { - ifReg |= 2; - } - - addFixedtimeEvent(irqEventQueue, &mode2Irq, Mode2Irq::schedule(data, lyCounter, cycleCounter)); - - addEvent(vEventQueue, &irqEvent, IrqEvent::schedule(irqEventQueue)); -} - -void LCD::lycRegChange(const unsigned data, const unsigned long cycleCounter) { - if (data == lycIrq.lycReg()) - return; - - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - const unsigned old = lycIrq.lycReg(); - lycIrq.setLycReg(data); - - if (!(enabled && (statReg & 0x40))) - return; - - if (!doubleSpeed && lycIrq.time() - cycleCounter < 5 && (!(statReg & 0x20) || old > 143 || old == 0)) - ifReg |= 2; - - addEvent(irqEventQueue, &lycIrq, LycIrq::schedule(statReg, lycIrq.lycReg(), lyCounter, cycleCounter)); - - if (data < 154) { - if (isLycIrqPeriod(data, data == 153 ? lyCounter.lineTime() - doubleSpeed * 8U : 8, cycleCounter)) - ifReg |= 2; - - if (lycIrq.isSkipPeriod(cycleCounter, doubleSpeed)) - lycIrq.setSkip(true); - } - - addEvent(vEventQueue, &irqEvent, IrqEvent::schedule(irqEventQueue)); -} - -unsigned long LCD::nextIrqEvent() const { - if (!enabled) - return VideoEvent::DISABLED_TIME; - - if (mode0Irq.time() != VideoEvent::DISABLED_TIME && mode3Event.time() < irqEvent.time()) - return mode3Event.time(); - - return irqEvent.time(); -} - -unsigned LCD::getIfReg(const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - return ifReg; -} - -void LCD::setIfReg(const unsigned ifReg_in, const unsigned long cycleCounter) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - ifReg = ifReg_in; -} - -unsigned LCD::get_stat(const unsigned lycReg, const unsigned long cycleCounter) { - unsigned stat = 0; - - if (enabled) { - if (cycleCounter >= vEventQueue.top()->time()) - update(cycleCounter); - - const unsigned timeToNextLy = lyCounter.time() - cycleCounter; - - if (lyCounter.ly() > 143) { - if (lyCounter.ly() < 153 || timeToNextLy > 4 - doubleSpeed * 4U) - stat = 1; - } else { - const unsigned lineCycles = 456 - (timeToNextLy >> doubleSpeed); - - if (lineCycles < 80) { - if (!spriteMapper.inactivePeriodAfterDisplayEnable(cycleCounter)) - stat = 2; - } else if (lineCycles < 80 + 169 + doubleSpeed * 3U + m3ExtraCycles(lyCounter.ly())) - stat = 3; - } - - if ((lyCounter.ly() == lycReg && timeToNextLy > 4 - doubleSpeed * 4U) || - (lycReg == 0 && lyCounter.ly() == 153 && timeToNextLy >> doubleSpeed <= 456 - 8)) { - stat |= 4; - } - } - - return stat; -} - -void LCD::do_update(unsigned cycles) { - if (lyCounter.ly() < 144) { - const unsigned lineCycles = lyCounter.lineCycles(lastUpdate); - const unsigned xpos = lineCycles < drawStartCycle ? 0 : lineCycles - drawStartCycle; - - const unsigned endLineCycles = lineCycles + cycles; - unsigned endX = endLineCycles < drawStartCycle ? 0 : endLineCycles - drawStartCycle; - - if (endX > 160) - endX = 160; - - if (xpos < endX) - (this->*draw)(xpos, lyCounter.ly(), endX); - } else if (lyCounter.ly() == 144) { - winYPos = 0xFF; - //scy[0] = scy[1] = memory.fastread(0xFF42); - //scx[0] = scx[1] = memory.fastread(0xFF43); - win.weMasterChecker.unset(); - } - - videoCycles += cycles; - - if (videoCycles >= 70224U) - videoCycles -= 70224U; -} - -inline void LCD::event() { - vEventQueue.top()->doEvent(); - - if (vEventQueue.top()->time() == VideoEvent::DISABLED_TIME) - vEventQueue.pop(); - else - vEventQueue.modify_root(vEventQueue.top()); -} - -void LCD::update(const unsigned long cycleCounter) { - if (!enabled) - return; - - for (;;) { - const unsigned cycles = (std::max(std::min(cycleCounter, static_cast(vEventQueue.top()->time())), lastUpdate) - lastUpdate) >> doubleSpeed; - do_update(cycles); - lastUpdate += cycles << doubleSpeed; - - if (cycleCounter >= vEventQueue.top()->time()) - event(); - else - break; - } -} - -void LCD::setDBuffer() { - tmpbuf.reset(pb.format == Gambatte::PixelBuffer::RGB32 ? 0 : videoWidth() * videoHeight()); - - if (cgb) - draw = &LCD::cgb_draw; - else - draw = &LCD::dmg_draw; - - gbcToFormat = &gbcToRgb32; - dmgColors = dmgColorsRgb32; - - if (filter) { - dbuffer = filter->inBuffer(); - dpitch = filter->inPitch(); - } else if (pb.format == Gambatte::PixelBuffer::RGB32) { - dbuffer = pb.pixels; - dpitch = pb.pitch; - } else { - dbuffer = tmpbuf; - dpitch = 160; - } - - if (dbuffer == NULL) - draw = &LCD::null_draw; - - refreshPalettes(); -} - -void LCD::setDmgPaletteColor(const unsigned index, const unsigned long rgb32) { - dmgColorsRgb32[index] = rgb32; - dmgColorsRgb16[index] = rgb32ToRgb16(rgb32); - dmgColorsUyvy[index] = ::rgb32ToUyvy(rgb32); -} - -void LCD::setDmgPaletteColor(const unsigned palNum, const unsigned colorNum, const unsigned long rgb32) { - if (palNum > 2 || colorNum > 3) - return; - - setDmgPaletteColor((palNum * 4) | colorNum, rgb32); - refreshPalettes(); -} - -void LCD::null_draw(unsigned /*xpos*/, const unsigned ypos, const unsigned endX) { - const bool enableWindow = win.enabled(ypos); - - if (enableWindow && winYPos == 0xFF) - winYPos = /*ypos - wyReg.value()*/ 0; - - if (endX == 160) { - if (enableWindow) - ++winYPos; - } -} - -template -void LCD::cgb_draw(unsigned xpos, const unsigned ypos, const unsigned endX) { - const unsigned effectiveScx = scReader.scx(); - - const bool enableWindow = win.enabled(ypos); - - if (enableWindow && winYPos == 0xFF) - winYPos = /*ypos - wyReg.value()*/ 0; - - T *const bufLine = static_cast(dbuffer) + ypos * static_cast(dpitch); - - if (!(enableWindow && win.wxReader.wx() <= xpos + 7)) { - const unsigned fby = scReader.scy() + ypos /*& 0xFF*/; - const unsigned end = std::min(enableWindow ? win.wxReader.wx() - 7 : 160U, endX); - - cgb_bg_drawPixels(bufLine, xpos, end, scxReader.scxAnd7(), ((xpos + effectiveScx) & ~7) + ((xpos + drawStartCycle - scReadOffset) & 7), - bgTileMap + (fby & 0xF8) * 4, bgTileData, fby & 7); - } - - if (enableWindow && endX + 7 > win.wxReader.wx()) { - const unsigned start = std::max(win.wxReader.wx() < 7 ? 0U : (win.wxReader.wx() - 7), xpos); - - cgb_bg_drawPixels(bufLine, start, endX, 7u - win.wxReader.wx(), start + (7u - win.wxReader.wx()), - wdTileMap + (winYPos & 0xF8) * 4, bgTileData, winYPos & 7); - } - - if (endX == 160) { - if (spriteEnable) - cgb_drawSprites(bufLine, ypos); - - if (enableWindow) - ++winYPos; - } -} - -template -void LCD::dmg_draw(unsigned xpos, const unsigned ypos, const unsigned endX) { - const unsigned effectiveScx = scReader.scx(); - - const bool enableWindow = win.enabled(ypos); - - if (enableWindow && winYPos == 0xFF) - winYPos = /*ypos - wyReg.value()*/ 0; - - T *const bufLine = static_cast(dbuffer) + ypos * static_cast(dpitch); - - if (bgEnable) { - if (!(enableWindow && win.wxReader.wx() <= xpos + 7)) { - const unsigned fby = scReader.scy() + ypos /*& 0xFF*/; - const unsigned end = std::min(enableWindow ? win.wxReader.wx() - 7 : 160U, endX); - - bg_drawPixels(bufLine, xpos, end, scxReader.scxAnd7(), ((xpos + effectiveScx) & ~7) + ((xpos + drawStartCycle - scReadOffset) & 7), - bgTileMap + (fby & 0xF8) * 4, bgTileData + (fby & 7) * 2); - } - - if (enableWindow && endX + 7 > win.wxReader.wx()) { - const unsigned start = std::max(win.wxReader.wx() < 7 ? 0U : (win.wxReader.wx() - 7), xpos); - - bg_drawPixels(bufLine, start, endX, 7u - win.wxReader.wx(), start + (7u - win.wxReader.wx()), - wdTileMap + (winYPos & 0xF8) * 4, bgTileData + (winYPos & 7) * 2); - } - } else - std::fill_n(bufLine + xpos, endX - xpos, bgPalette[0]); - - if (endX == 160) { - if (spriteEnable) - drawSprites(bufLine, ypos); - - if (enableWindow) - ++winYPos; - } -} - -#define FLIP(u8) ( (((u8) & 0x01) << 7) | (((u8) & 0x02) << 5) | (((u8) & 0x04) << 3) | (((u8) & 0x08) << 1) | \ -(((u8) & 0x10) >> 1) | (((u8) & 0x20) >> 3) | (((u8) & 0x40) >> 5) | (((u8) & 0x80) >> 7) ) - -#define FLIP_ROW(n) FLIP((n)|0x0), FLIP((n)|0x1), FLIP((n)|0x2), FLIP((n)|0x3), FLIP((n)|0x4), FLIP((n)|0x5), FLIP((n)|0x6), FLIP((n)|0x7), \ -FLIP((n)|0x8), FLIP((n)|0x9), FLIP((n)|0xA), FLIP((n)|0xB), FLIP((n)|0xC), FLIP((n)|0xD), FLIP((n)|0xE), FLIP((n)|0xF) - -static const unsigned char xflipt[0x100] = { - FLIP_ROW(0x00), FLIP_ROW(0x10), FLIP_ROW(0x20), FLIP_ROW(0x30), - FLIP_ROW(0x40), FLIP_ROW(0x50), FLIP_ROW(0x60), FLIP_ROW(0x70), - FLIP_ROW(0x80), FLIP_ROW(0x90), FLIP_ROW(0xA0), FLIP_ROW(0xB0), - FLIP_ROW(0xC0), FLIP_ROW(0xD0), FLIP_ROW(0xE0), FLIP_ROW(0xF0) -}; - -#undef FLIP_ROW -#undef FLIP - -#define PREP(u8) (u8) - -#define EXPAND(u8) ((PREP(u8) << 7 & 0x4000) | (PREP(u8) << 6 & 0x1000) | (PREP(u8) << 5 & 0x0400) | (PREP(u8) << 4 & 0x0100) | \ - (PREP(u8) << 3 & 0x0040) | (PREP(u8) << 2 & 0x0010) | (PREP(u8) << 1 & 0x0004) | (PREP(u8) & 0x0001)) - -#define EXPAND_ROW(n) EXPAND((n)|0x0), EXPAND((n)|0x1), EXPAND((n)|0x2), EXPAND((n)|0x3), \ - EXPAND((n)|0x4), EXPAND((n)|0x5), EXPAND((n)|0x6), EXPAND((n)|0x7), \ - EXPAND((n)|0x8), EXPAND((n)|0x9), EXPAND((n)|0xA), EXPAND((n)|0xB), \ - EXPAND((n)|0xC), EXPAND((n)|0xD), EXPAND((n)|0xE), EXPAND((n)|0xF) - -#define EXPAND_TABLE EXPAND_ROW(0x00), EXPAND_ROW(0x10), EXPAND_ROW(0x20), EXPAND_ROW(0x30), \ - EXPAND_ROW(0x40), EXPAND_ROW(0x50), EXPAND_ROW(0x60), EXPAND_ROW(0x70), \ - EXPAND_ROW(0x80), EXPAND_ROW(0x90), EXPAND_ROW(0xA0), EXPAND_ROW(0xB0), \ - EXPAND_ROW(0xC0), EXPAND_ROW(0xD0), EXPAND_ROW(0xE0), EXPAND_ROW(0xF0) - -static const unsigned short expand_lut[0x200] = { - EXPAND_TABLE, - -#undef PREP -#define PREP(u8) (((u8) << 7 & 0x80) | ((u8) << 5 & 0x40) | ((u8) << 3 & 0x20) | ((u8) << 1 & 0x10) | \ - ((u8) >> 1 & 0x08) | ((u8) >> 3 & 0x04) | ((u8) >> 5 & 0x02) | ((u8) >> 7 & 0x01)) - - EXPAND_TABLE -}; - -#undef EXPAND_TABLE -#undef EXPAND_ROW -#undef EXPAND -#undef PREP - -//shoud work for the window too, if -wx is passed as scx. -//tilemap and tiledata must point to the areas in the first vram bank -//the second vram bank has to be placed immediately after the first one in memory (0x4000 continous bytes that cover both). -//tilemap needs to be offset to the right line -template -void LCD::cgb_bg_drawPixels(T * const buffer_line, unsigned xpos, const unsigned end, const unsigned scx, unsigned tilemappos, - const unsigned char *const tilemap, const unsigned char *const tiledata, const unsigned tileline) -{ - const unsigned sign = tileIndexSign; - unsigned shift = (7 - ((scx + xpos) & 7)) * 2; - T *buf = buffer_line + xpos; - T *const bufend = buffer_line + end; - - while (buf < bufend) { - if ((tilemappos & 7) || bufend - buf < 8) { - const unsigned char *const maptmp = tilemap + (tilemappos >> 3 & 0x1F); - const unsigned attributes = maptmp[0x2000]; - const unsigned char *const dataptr = tiledata + (attributes << 10 & 0x2000) + - maptmp[0] * 16 - (maptmp[0] & sign) * 32 + ((attributes & 0x40) ? 7 - tileline : tileline) * 2; - const unsigned short *const exp_lut = expand_lut + (attributes << 3 & 0x100); - - const unsigned data = exp_lut[dataptr[0]] + exp_lut[dataptr[1]] * 2; - const unsigned long *const palette = bgPalette + (attributes & 7) * 4; - - do { - *buf++ = palette[data >> shift & 3]; - shift = (shift - 2) & 15; - } while ((++tilemappos & 7) && buf < bufend); - } - - while (bufend - buf > 7) { - const unsigned char *const maptmp = tilemap + (tilemappos >> 3 & 0x1F); - const unsigned attributes = maptmp[0x2000]; - const unsigned char *const dataptr = tiledata + (attributes << 10 & 0x2000) + - maptmp[0] * 16 - (maptmp[0] & sign) * 32 + ((attributes & 0x40) ? 7 - tileline : tileline) * 2; - const unsigned short *const exp_lut = expand_lut + (attributes << 3 & 0x100); - - const unsigned data = exp_lut[dataptr[0]] + exp_lut[dataptr[1]] * 2; - const unsigned long *const palette = bgPalette + (attributes & 7) * 4; - - buf[0] = palette[data >> shift & 3]; - buf[1] = palette[data >> ((shift - 2) & 15) & 3]; - buf[2] = palette[data >> ((shift - 4) & 15) & 3]; - buf[3] = palette[data >> ((shift - 6) & 15) & 3]; - buf[4] = palette[data >> ((shift - 8) & 15) & 3]; - buf[5] = palette[data >> ((shift - 10) & 15) & 3]; - buf[6] = palette[data >> ((shift - 12) & 15) & 3]; - buf[7] = palette[data >> ((shift - 14) & 15) & 3]; - - buf += 8; - tilemappos += 8; - } - } -} - -static unsigned cgb_prioritizedBG_mask(const unsigned spx, const unsigned bgStart, const unsigned bgEnd, const unsigned scx, - const unsigned char *const tilemap, const unsigned char *const tiledata, const unsigned tileline, const unsigned sign) { - const unsigned spStart = spx < bgStart + 8 ? bgStart + 8 - spx : 0; - - unsigned bgbyte; - - { - const unsigned pos = scx + spx - 8 + spStart; - const unsigned char *maptmp = tilemap + (pos >> 3 & 0x1F); - unsigned tile = maptmp[0]; - unsigned attributes = maptmp[0x2000]; - - const unsigned char *const data = tiledata + (attributes << 10 & 0x2000) + - tile * 16 - (tile & sign) * 32 + ((attributes & 0x40) ? 7 - tileline : tileline) * 2; - - bgbyte = (attributes & 0x20) ? xflipt[data[0] | data[1]] : (data[0] | data[1]); - - const unsigned offset = pos & 7; - - if (offset) { - bgbyte <<= offset; - maptmp = tilemap + (((pos >> 3) + 1) & 0x1F); - tile = maptmp[0]; - attributes = maptmp[0x2000]; - - const unsigned char *const data = tiledata + (attributes << 10 & 0x2000) + - tile * 16 - (tile & sign) * 32 + ((attributes & 0x40) ? 7 - tileline : tileline) * 2; - - bgbyte |= ((attributes & 0x20) ? xflipt[data[0] | data[1]] : (data[0] | data[1])) >> (8 - offset); - } - } - - bgbyte >>= spStart; - const unsigned spEnd = spx > bgEnd ? bgEnd + 8 - spx : 8; - const unsigned mask = ~bgbyte | 0xFF >> spEnd; - - return mask; -} - -static unsigned cgb_toplayerBG_mask(const unsigned spx, const unsigned bgStart, const unsigned bgEnd, const unsigned scx, - const unsigned char *const tilemap, const unsigned char *const tiledata, const unsigned tileline, const unsigned sign) { - const unsigned spStart = spx < bgStart + 8 ? bgStart + 8 - spx : 0; - - unsigned bgbyte = 0; - - { - const unsigned pos = scx + spx - 8 + spStart; - const unsigned char *maptmp = tilemap + (pos >> 3 & 0x1F); - unsigned attributes = maptmp[0x2000]; - - if (attributes & 0x80) { - const unsigned tile = maptmp[0]; - - const unsigned char *const data = tiledata + (attributes << 10 & 0x2000) + - tile * 16 - (tile & sign) * 32 + ((attributes & 0x40) ? 7 - tileline : tileline) * 2; - - bgbyte = (attributes & 0x20) ? xflipt[data[0] | data[1]] : (data[0] | data[1]); - } - - const unsigned offset = pos & 7; - - if (offset) { - bgbyte <<= offset; - maptmp = tilemap + (((pos >> 3) + 1) & 0x1F); - attributes = maptmp[0x2000]; - - if (attributes & 0x80) { - const unsigned tile = maptmp[0]; - - const unsigned char *const data = tiledata + (attributes << 10 & 0x2000) + - tile * 16 - (tile & sign) * 32 + ((attributes & 0x40) ? 7 - tileline : tileline) * 2; - - bgbyte |= ((attributes & 0x20) ? xflipt[data[0] | data[1]] : (data[0] | data[1])) >> (8 - offset); - } - } - } - - bgbyte >>= spStart; - const unsigned spEnd = spx > bgEnd ? bgEnd + 8 - spx : 8; - const unsigned mask = ~bgbyte | 0xFF >> spEnd; - - return mask; -} - -template -void LCD::cgb_drawSprites(T * const buffer_line, const unsigned ypos) { - const unsigned scy = scReader.scy() + ypos /*& 0xFF*/; - const unsigned wx = win.wxReader.wx() < 7 ? 0 : win.wxReader.wx() - 7; - const bool enableWindow = win.enabled(ypos); - const unsigned char *const spriteMapLine = spriteMapper.sprites(ypos); - - for (int i = spriteMapper.numSprites(ypos) - 1; i >= 0; --i) { - const unsigned spNrX2 = spriteMapLine[i]; - const unsigned spx = spriteMapper.posbuf()[spNrX2 + 1]; - - if (spx < 168 && spx) { - unsigned spLine = ypos + 16 - spriteMapper.posbuf()[spNrX2]; - unsigned spTile = spriteMapper.oamram()[spNrX2 * 2 + 2]; - const unsigned attributes = spriteMapper.oamram()[spNrX2 * 2 + 3]; - - if (spriteMapper.largeSprites(spNrX2 >> 1)) { - if (attributes & 0x40) //yflip - spLine = 15 - spLine; - - if (spLine < 8) - spTile &= 0xFE; - else { - spLine -= 8; - spTile |= 0x01; - } - } else { - if (attributes & 0x40) //yflip - spLine = 7 - spLine; - } - - const unsigned char *const data = vram + ((attributes * 0x400) & 0x2000) + spTile * 16 + spLine * 2; - - unsigned byte1 = data[0]; - unsigned byte2 = data[1]; - - if (attributes & 0x20) { - byte1 = xflipt[byte1]; - byte2 = xflipt[byte2]; - } - - //(Sprites with priority-bit are still allowed to cover other sprites according to GBdev-faq.) - if (bgEnable) { - unsigned mask = 0xFF; - - if (attributes & 0x80) { - if (!(enableWindow && (wx == 0 || spx >= wx + 8u))) - mask = cgb_prioritizedBG_mask(spx, 0, enableWindow ? wx : 160, scReader.scx(), - bgTileMap + ((scy & 0xF8) << 2), bgTileData, scy & 7, tileIndexSign); - if (enableWindow && spx > wx) - mask &= cgb_prioritizedBG_mask(spx, wx, 160, 0u - wx, wdTileMap + ((winYPos & 0xF8) << 2), bgTileData, winYPos & 7, tileIndexSign); - } else { - if (!(enableWindow && (wx == 0 || spx >= wx + 8u))) - mask = cgb_toplayerBG_mask(spx, 0, enableWindow ? wx : 160, scReader.scx(), - bgTileMap + ((scy & 0xF8) << 2), bgTileData, scy & 7, tileIndexSign); - if (enableWindow && spx > wx) - mask &= cgb_toplayerBG_mask(spx, wx, 160, 0u - wx, wdTileMap + ((winYPos & 0xF8) << 2), bgTileData, winYPos & 7, tileIndexSign); - } - - byte1 &= mask; - byte2 &= mask; - } - - const unsigned bytes = expand_lut[byte1] + expand_lut[byte2] * 2; - const unsigned long *const palette = spPalette + (attributes & 7) * 4; - - if (spx > 7 && spx < 161) { - T * const buf = buffer_line + spx - 8; - unsigned color; - - if ((color = bytes >> 14 )) - buf[0] = palette[color]; - if ((color = bytes >> 12 & 3)) - buf[1] = palette[color]; - if ((color = bytes >> 10 & 3)) - buf[2] = palette[color]; - if ((color = bytes >> 8 & 3)) - buf[3] = palette[color]; - if ((color = bytes >> 6 & 3)) - buf[4] = palette[color]; - if ((color = bytes >> 4 & 3)) - buf[5] = palette[color]; - if ((color = bytes >> 2 & 3)) - buf[6] = palette[color]; - if ((color = bytes & 3)) - buf[7] = palette[color]; - } else { - const unsigned end = spx >= 160 ? 160 : spx; - unsigned xpos = spx <= 8 ? 0 : (spx - 8); - unsigned shift = (7 - (xpos + 8 - spx)) * 2; - - while (xpos < end) { - if (const unsigned color = bytes >> shift & 3) - buffer_line[xpos] = palette[color]; - - shift -= 2; - ++xpos; - } - } - } - } -} - - -//shoud work for the window too, if -wx is passed as scx. -//tilemap and tiledata need to be offset to the right line -template -void LCD::bg_drawPixels(T * const buffer_line, unsigned xpos, const unsigned end, const unsigned scx, unsigned tilemappos, - const unsigned char *const tilemap, const unsigned char *const tiledata) -{ - const unsigned sign = tileIndexSign; - unsigned shift = (7 - ((scx + xpos) & 7)) * 2; - T *buf = buffer_line + xpos; - T *const bufend = buffer_line + end; - - while (buf < bufend) { - if ((tilemappos & 7) || bufend - buf < 8) { - const unsigned tile = tilemap[tilemappos >> 3 & 0x1F]; - const unsigned char *const dataptr = tiledata + tile * 16 - (tile & sign) * 32; - const unsigned data = expand_lut[dataptr[0]] + expand_lut[dataptr[1]] * 2; - - do { - *buf++ = bgPalette[data >> shift & 3]; - shift = (shift - 2) & 15; - } while ((++tilemappos & 7) && buf < bufend); - } - - while (bufend - buf > 7) { - const unsigned tile = tilemap[tilemappos >> 3 & 0x1F]; - const unsigned char *const dataptr = tiledata + tile * 16 - (tile & sign) * 32; - const unsigned data = expand_lut[dataptr[0]] + expand_lut[dataptr[1]] * 2; - buf[0] = bgPalette[data >> shift & 3]; - buf[1] = bgPalette[data >> ((shift - 2) & 15) & 3]; - buf[2] = bgPalette[data >> ((shift - 4) & 15) & 3]; - buf[3] = bgPalette[data >> ((shift - 6) & 15) & 3]; - buf[4] = bgPalette[data >> ((shift - 8) & 15) & 3]; - buf[5] = bgPalette[data >> ((shift - 10) & 15) & 3]; - buf[6] = bgPalette[data >> ((shift - 12) & 15) & 3]; - buf[7] = bgPalette[data >> ((shift - 14) & 15) & 3]; - buf += 8; - tilemappos += 8; - } - } -} - -static unsigned prioritizedBG_mask(const unsigned spx, const unsigned bgStart, const unsigned bgEnd, const unsigned scx, - const unsigned char *const tilemap, const unsigned char *const tiledata, const unsigned sign) { - const unsigned spStart = spx < bgStart + 8 ? bgStart + 8 - spx : 0; - - unsigned bgbyte; - - { - const unsigned pos = scx + spx - 8 + spStart; - unsigned tile = tilemap[pos >> 3 & 0x1F]; - const unsigned char *data = tiledata + tile * 16 - (tile & sign) * 32; - bgbyte = data[0] | data[1]; - const unsigned offset = pos & 7; - - if (offset) { - bgbyte <<= offset; - tile = tilemap[((pos >> 3) + 1) & 0x1F]; - data = tiledata + tile * 16 - (tile & sign) * 32; - bgbyte |= (data[0] | data[1]) >> (8 - offset); - } - } - - bgbyte >>= spStart; - const unsigned spEnd = spx > bgEnd ? bgEnd + 8 - spx : 8; - const unsigned mask = ~bgbyte | 0xFF >> spEnd; - - return mask; -} - -template -void LCD::drawSprites(T * const buffer_line, const unsigned ypos) { - const unsigned scy = scReader.scy() + ypos /*& 0xFF*/; - const unsigned wx = win.wxReader.wx() < 7 ? 0 : win.wxReader.wx() - 7; - const bool enableWindow = win.enabled(ypos); - const unsigned char *const spriteMapLine = spriteMapper.sprites(ypos); - - for (int i = spriteMapper.numSprites(ypos) - 1; i >= 0; --i) { - const unsigned spNrX2 = spriteMapLine[i]; - const unsigned spx = spriteMapper.posbuf()[spNrX2 + 1]; - - if (spx < 168 && spx) { - unsigned spLine = ypos + 16 - spriteMapper.posbuf()[spNrX2]; - unsigned spTile = spriteMapper.oamram()[spNrX2 * 2 + 2]; - const unsigned attributes = spriteMapper.oamram()[spNrX2 * 2 + 3]; - - if (spriteMapper.largeSprites(spNrX2 >> 1)) { - if (attributes & 0x40) //yflip - spLine = 15 - spLine; - - if (spLine < 8) - spTile &= 0xFE; - else { - spLine -= 8; - spTile |= 0x01; - } - } else { - if (attributes & 0x40) //yflip - spLine = 7 - spLine; - } - - const unsigned char *const data = vram + spTile * 16 + spLine * 2; - - unsigned byte1 = data[0]; - unsigned byte2 = data[1]; - - if (attributes & 0x20) { - byte1 = xflipt[byte1]; - byte2 = xflipt[byte2]; - } - - //(Sprites with priority-bit are still allowed to cover other sprites according to GBdev-faq.) - if (attributes & 0x80) { - unsigned mask = 0xFF; - - if (bgEnable && !(enableWindow && (wx == 0 || spx >= wx + 8u))) - mask = prioritizedBG_mask(spx, 0, enableWindow ? wx : 160, scReader.scx(), - bgTileMap + ((scy & 0xF8) << 2), bgTileData + ((scy & 7) << 1), tileIndexSign); - if (enableWindow && spx > wx) - mask &= prioritizedBG_mask(spx, wx, 160, 0u - wx, wdTileMap + ((winYPos & 0xF8) << 2), bgTileData + ((winYPos & 7) << 1), tileIndexSign); - - byte1 &= mask; - byte2 &= mask; - } - - const unsigned bytes = expand_lut[byte1] + expand_lut[byte2] * 2; - const unsigned long *const palette = spPalette + ((attributes >> 2) & 4); - - if (spx > 7 && spx < 161) { - T * const buf = buffer_line + spx - 8; - unsigned color; - - if ((color = bytes >> 14 )) - buf[0] = palette[color]; - if ((color = bytes >> 12 & 3)) - buf[1] = palette[color]; - if ((color = bytes >> 10 & 3)) - buf[2] = palette[color]; - if ((color = bytes >> 8 & 3)) - buf[3] = palette[color]; - if ((color = bytes >> 6 & 3)) - buf[4] = palette[color]; - if ((color = bytes >> 4 & 3)) - buf[5] = palette[color]; - if ((color = bytes >> 2 & 3)) - buf[6] = palette[color]; - if ((color = bytes & 3)) - buf[7] = palette[color]; - } else { - const unsigned end = spx >= 160 ? 160 : spx; - unsigned xpos = spx <= 8 ? 0 : (spx - 8); - unsigned shift = (7 - (xpos + 8 - spx)) * 2; - - while (xpos < end) { - if (const unsigned color = bytes >> shift & 3) - buffer_line[xpos] = palette[color]; - - shift -= 2; - ++xpos; - } - } - } - } -} diff --git a/src/lib/libgambatte/src/video.h b/src/lib/libgambatte/src/video.h deleted file mode 100644 index d3228320..00000000 --- a/src/lib/libgambatte/src/video.h +++ /dev/null @@ -1,292 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_H -#define VIDEO_H - -namespace Gambatte { -class VideoBlitter; -struct FilterInfo; -} - -class Filter; -class SaveState; - -#include -#include -#include "event_queue.h" -#include "videoblitter.h" -#include "array.h" -#include "int.h" -#include "colorconversion.h" -#include "osd_element.h" - -#include "video/video_event_comparer.h" -#include "video/ly_counter.h" -#include "video/window.h" -#include "video/scx_reader.h" -#include "video/sprite_mapper.h" -#include "video/sc_reader.h" -#include "video/break_event.h" -#include "video/mode3_event.h" - -#include "video/lyc_irq.h" -#include "video/mode0_irq.h" -#include "video/mode1_irq.h" -#include "video/mode2_irq.h" -#include "video/irq_event.h" -#include "video/m3_extra_cycles.h" - -class LCD { - //static const uint8_t xflipt[0x100]; - unsigned long dmgColorsRgb32[3 * 4]; - unsigned long dmgColorsRgb16[3 * 4]; - unsigned long dmgColorsUyvy[3 * 4]; - - unsigned long bgPalette[8 * 4]; - unsigned long spPalette[8 * 4]; - - unsigned char bgpData[8 * 8]; - unsigned char objpData[8 * 8]; - - const unsigned char *const vram; - const unsigned char *bgTileData; - const unsigned char *bgTileMap; - const unsigned char *wdTileMap; - - Gambatte::VideoBlitter *vBlitter; - Filter *filter; - - void *dbuffer; - void (LCD::*draw)(unsigned xpos, unsigned ypos, unsigned endX); - unsigned long (*gbcToFormat)(unsigned bgr15); - const unsigned long *dmgColors; - - unsigned long lastUpdate; - unsigned long videoCycles; - - unsigned dpitch; - unsigned winYPos; - - event_queue m3EventQueue; - event_queue irqEventQueue; - event_queue vEventQueue; - - LyCounter lyCounter; - Window win; - ScxReader scxReader; - SpriteMapper spriteMapper; - M3ExtraCycles m3ExtraCycles; - ScReader scReader; - BreakEvent breakEvent; - Mode3Event mode3Event; - - LycIrq lycIrq; - Mode0Irq mode0Irq; - Mode1Irq mode1Irq; - Mode2Irq mode2Irq; - IrqEvent irqEvent; - - Gambatte::PixelBuffer pb; - Array tmpbuf; - Rgb32ToUyvy rgb32ToUyvy; - std::auto_ptr osdElement; - - std::vector filters; - - unsigned char drawStartCycle; - unsigned char scReadOffset; - unsigned char ifReg; - unsigned char tileIndexSign; - unsigned char statReg; - - bool doubleSpeed; - bool enabled; - bool cgb; - bool bgEnable; - bool spriteEnable; - - static void setDmgPalette(unsigned long *palette, const unsigned long *dmgColors, unsigned data); - void setDmgPaletteColor(unsigned index, unsigned long rgb32); - static unsigned long gbcToRgb32(unsigned bgr15); - static unsigned long gbcToRgb16(unsigned bgr15); - static unsigned long gbcToUyvy(unsigned bgr15); - - void refreshPalettes(); - void setDBuffer(); - void resetVideoState(unsigned long cycleCounter); - - void setDoubleSpeed(bool enabled); - - void event(); - - bool cgbpAccessible(unsigned long cycleCounter); - bool isMode0IrqPeriod(unsigned long cycleCounter); - bool isMode2IrqPeriod(unsigned long cycleCounter); - bool isLycIrqPeriod(unsigned lycReg, unsigned endCycles, unsigned long cycleCounter); - bool isMode1IrqPeriod(unsigned long cycleCounter); - - template void bg_drawPixels(T *buffer_line, unsigned xpos, unsigned end, unsigned scx, unsigned tilemappos, - const unsigned char *tilemap, const unsigned char *tiledata); - template void drawSprites(T *buffer_line, unsigned ypos); - - template void cgb_bg_drawPixels(T *buffer_line, unsigned xpos, unsigned end, unsigned scx, unsigned tilemappos, - const unsigned char *tilemap, const unsigned char *tiledata, unsigned tileline); - template void cgb_drawSprites(T *buffer_line, unsigned ypos); - - void null_draw(unsigned xpos, unsigned ypos, unsigned endX); - template void dmg_draw(unsigned xpos, unsigned ypos, unsigned endX); - template void cgb_draw(unsigned xpos, unsigned ypos, unsigned endX); - - void do_update(unsigned cycles); - -public: - LCD(const unsigned char *oamram, const unsigned char *vram_in); - ~LCD(); - void update(unsigned long cycleCounter); - void reset(const unsigned char *oamram, bool cgb); - void setStatePtrs(SaveState &state); - void saveState(SaveState &state) const; - void loadState(const SaveState &state, const unsigned char *oamram); - void setVideoBlitter(Gambatte::VideoBlitter *vb); - void videoBufferChange(); - void setVideoFilter(unsigned n); - std::vector filterInfo() const; - unsigned videoWidth() const; - unsigned videoHeight() const; - void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32); - - void setOsdElement(std::auto_ptr osdElement) { - this->osdElement = osdElement; - } - - void wdTileMapSelectChange(bool newValue, unsigned long cycleCounter); - void bgTileMapSelectChange(bool newValue, unsigned long cycleCounter); - void bgTileDataSelectChange(bool newValue, unsigned long cycleCounter); - void bgEnableChange(bool newValue, unsigned long cycleCounter); - void spriteEnableChange(bool newValue, unsigned long cycleCounter); - - void dmgBgPaletteChange(const unsigned data, const unsigned long cycleCounter) { - update(cycleCounter); - bgpData[0] = data; - setDmgPalette(bgPalette, dmgColors, data); - } - - void dmgSpPalette1Change(const unsigned data, const unsigned long cycleCounter) { - update(cycleCounter); - objpData[0] = data; - setDmgPalette(spPalette, dmgColors + 4, data); - } - - void dmgSpPalette2Change(const unsigned data, const unsigned long cycleCounter) { - update(cycleCounter); - objpData[1] = data; - setDmgPalette(spPalette + 4, dmgColors + 8, data); - } - - void cgbBgColorChange(unsigned index, const unsigned data, const unsigned long cycleCounter) { - if (bgpData[index] != data && cgbpAccessible(cycleCounter)) { - update(cycleCounter); - bgpData[index] = data; - index >>= 1; - bgPalette[index] = (*gbcToFormat)(bgpData[index << 1] | bgpData[(index << 1) + 1] << 8); - } - } - - void cgbSpColorChange(unsigned index, const unsigned data, const unsigned long cycleCounter) { - if (objpData[index] != data && cgbpAccessible(cycleCounter)) { - update(cycleCounter); - objpData[index] = data; - index >>= 1; - spPalette[index] = (*gbcToFormat)(objpData[index << 1] | objpData[(index << 1) + 1] << 8); - } - } - - unsigned cgbBgColorRead(const unsigned index, const unsigned long cycleCounter) { - return cgb & cgbpAccessible(cycleCounter) ? bgpData[index] : 0xFF; - } - - unsigned cgbSpColorRead(const unsigned index, const unsigned long cycleCounter) { - return cgb & cgbpAccessible(cycleCounter) ? objpData[index] : 0xFF; - } - - void updateScreen(unsigned long cc); - void enableChange(unsigned long cycleCounter); - void preResetCounter(unsigned long cycleCounter); - void postResetCounter(unsigned long oldCC, unsigned long cycleCounter); - void preSpeedChange(unsigned long cycleCounter); - void postSpeedChange(unsigned long cycleCounter); -// unsigned get_mode(unsigned cycleCounter) /*const*/; - bool vramAccessible(unsigned long cycleCounter); - bool oamAccessible(unsigned long cycleCounter); - void weChange(bool newValue, unsigned long cycleCounter); - void wxChange(unsigned newValue, unsigned long cycleCounter); - void wyChange(unsigned newValue, unsigned long cycleCounter); - void oamChange(unsigned long cycleCounter); - void oamChange(const unsigned char *oamram, unsigned long cycleCounter); - void scxChange(unsigned newScx, unsigned long cycleCounter); - void scyChange(unsigned newValue, unsigned long cycleCounter); - void spriteSizeChange(bool newLarge, unsigned long cycleCounter); - - void vramChange(const unsigned long cycleCounter) { - update(cycleCounter); - } - - unsigned get_stat(unsigned lycReg, unsigned long cycleCounter); - - unsigned getLyReg(const unsigned long cycleCounter) { - unsigned lyReg = 0; - - if (enabled) { - if (cycleCounter >= lyCounter.time()) - update(cycleCounter); - - lyReg = lyCounter.ly(); - - if (lyCounter.time() - cycleCounter <= 4) { - if (lyReg == 153) - lyReg = 0; - else - ++lyReg; - } else if (lyReg == 153) - lyReg = 0; - } - - return lyReg; - } - - unsigned long nextMode1IrqTime() const { - return mode1Irq.time(); - } - - void lyWrite(unsigned long cycleCounter); - void lcdstatChange(unsigned data, unsigned long cycleCounter); - void lycRegChange(unsigned data, unsigned long cycleCounter); - unsigned long nextIrqEvent() const; - unsigned getIfReg(unsigned long cycleCounter); - void setIfReg(unsigned ifReg_in, unsigned long cycleCounter); - - unsigned long nextHdmaTime(unsigned long cycleCounter); - bool isHdmaPeriod(unsigned long cycleCounter); - - unsigned long nextHdmaTimeInvalid() const { - return mode3Event.time(); - } -}; - -#endif diff --git a/src/lib/libgambatte/src/video/basic_add_event.cpp b/src/lib/libgambatte/src/video/basic_add_event.cpp deleted file mode 100644 index 4bc57a09..00000000 --- a/src/lib/libgambatte/src/video/basic_add_event.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2008 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "basic_add_event.h" -#include "../event_queue.h" - -void addEvent(event_queue &q, VideoEvent *const e, const unsigned long newTime) { - const unsigned long oldTime = e->time(); - - if (oldTime != newTime) { - e->setTime(newTime); - - if (newTime < oldTime) { - if (oldTime == VideoEvent::DISABLED_TIME) - q.push(e); - else - q.dec(e, e); - } else { - if (newTime == VideoEvent::DISABLED_TIME) - q.remove(e); - else - q.inc(e, e); - } - } -} - -void addUnconditionalEvent(event_queue &q, VideoEvent *const e, const unsigned long newTime) { - const unsigned long oldTime = e->time(); - - e->setTime(newTime); - - if (newTime < oldTime) { - if (oldTime == VideoEvent::DISABLED_TIME) - q.push(e); - else - q.dec(e, e); - } else if (oldTime != newTime) { - q.inc(e, e); - } -} - -void addFixedtimeEvent(event_queue &q, VideoEvent *const e, const unsigned long newTime) { - const unsigned long oldTime = e->time(); - - if (oldTime != newTime) { - e->setTime(newTime); - - if (oldTime == VideoEvent::DISABLED_TIME) - q.push(e); - else - q.remove(e); - } -} - -void addUnconditionalFixedtimeEvent(event_queue &q, VideoEvent *const e, const unsigned long newTime) { - if (e->time() == VideoEvent::DISABLED_TIME) { - e->setTime(newTime); - q.push(e); - } -} diff --git a/src/lib/libgambatte/src/video/basic_add_event.h b/src/lib/libgambatte/src/video/basic_add_event.h deleted file mode 100644 index 780d7191..00000000 --- a/src/lib/libgambatte/src/video/basic_add_event.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef BASIC_ADD_EVENT_H -#define BASIC_ADD_EVENT_H - -template class event_queue; - -#include "video_event.h" -#include "video_event_comparer.h" - -/*template -static inline void addEvent(T &event, const LyCounter &lyCounter, const unsigned long cycleCounter, event_queue &queue) { - if (event.time() == VideoEvent::DISABLED_TIME) { - event.schedule(lyCounter, cycleCounter); - queue.push(&event); - } -} - -template -static inline void addEvent(T &event, const unsigned data, const LyCounter &lyCounter, const unsigned long cycleCounter, event_queue &queue) { - if (event.time() == VideoEvent::DISABLED_TIME) { - event.schedule(data, lyCounter, cycleCounter); - queue.push(&event); - } -} - -template -static inline void addEvent(T &event, const unsigned data1, const unsigned data2, const LyCounter &lyCounter, const unsigned long cycleCounter, event_queue &queue) { - if (event.time() == VideoEvent::DISABLED_TIME) { - event.schedule(data1, data2, lyCounter, cycleCounter); - queue.push(&event); - } -}*/ - -void addEvent(event_queue &q, VideoEvent *e, unsigned long newTime); -void addUnconditionalEvent(event_queue &q, VideoEvent *e, unsigned long newTime); -void addFixedtimeEvent(event_queue &q, VideoEvent *e, unsigned long newTime); -void addUnconditionalFixedtimeEvent(event_queue &q, VideoEvent *e, unsigned long newTime); - -#endif diff --git a/src/lib/libgambatte/src/video/break_event.cpp b/src/lib/libgambatte/src/video/break_event.cpp deleted file mode 100644 index e6e7ffbf..00000000 --- a/src/lib/libgambatte/src/video/break_event.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "break_event.h" - -BreakEvent::BreakEvent(unsigned char &drawStartCycle_in, unsigned char &scReadOffset_in) : - VideoEvent(3), - drawStartCycle(drawStartCycle_in), - scReadOffset(scReadOffset_in) -{ - setDoubleSpeed(false); - setScxSource(0); -} - -void BreakEvent::doEvent() { - scReadOffset = baseCycle; - drawStartCycle = baseCycle + (scxSrc & 7); - - setTime(DISABLED_TIME); -} diff --git a/src/lib/libgambatte/src/video/break_event.h b/src/lib/libgambatte/src/video/break_event.h deleted file mode 100644 index 9e7dcb82..00000000 --- a/src/lib/libgambatte/src/video/break_event.h +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef BREAK_EVENT_H -#define BREAK_EVENT_H - -#include "video_event.h" -#include "ly_counter.h" -#include "basic_add_event.h" - -class BreakEvent : public VideoEvent { - unsigned char &drawStartCycle; - unsigned char &scReadOffset; - - unsigned char scxSrc; - unsigned char baseCycle; - -public: - BreakEvent(unsigned char &drawStartCycle_in, unsigned char &scReadOffset_in); - - void doEvent(); - - static unsigned long schedule(const LyCounter &lyCounter) { - return lyCounter.time(); - } - - void setDoubleSpeed(const bool dS) { - baseCycle = 90 + dS * 4; - } - - void setScxSource(const unsigned scxSrc_in) { - scxSrc = scxSrc_in; - } -}; - -static inline void addEvent(event_queue &q, BreakEvent *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, BreakEvent *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/filters/catrom2x.cpp b/src/lib/libgambatte/src/video/filters/catrom2x.cpp deleted file mode 100644 index 53a4c931..00000000 --- a/src/lib/libgambatte/src/video/filters/catrom2x.cpp +++ /dev/null @@ -1,194 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "catrom2x.h" -#include "filterinfo.h" -#include - -struct Colorsum { - Gambatte::uint_least32_t r, g, b; -}; - -static void merge_columns(Gambatte::uint_least32_t *dest, const Colorsum *sums) { - unsigned w = 160; - - while (w--) { - { - Gambatte::uint_least32_t rsum = sums[1].r; - Gambatte::uint_least32_t gsum = sums[1].g; - Gambatte::uint_least32_t bsum = sums[1].b; - - if (rsum & 0x80000000) rsum = 0; - if (gsum & 0x80000000) gsum = 0; - if (bsum & 0x80000000) bsum = 0; - - rsum <<= 12; - rsum += 0x008000; - gsum >>= 4; - gsum += 0x0080; - bsum += 0x0008; - bsum >>= 4; - - if (rsum > 0xFF0000) rsum = 0xFF0000; - if (gsum > 0x00FF00) gsum = 0x00FF00; - if (bsum > 0x0000FF) bsum = 0x0000FF; - - *dest++ = (rsum & 0xFF0000) | (gsum & 0x00FF00) | bsum; - } - - { - Gambatte::uint_least32_t rsum = sums[1].r * 9; - Gambatte::uint_least32_t gsum = sums[1].g * 9; - Gambatte::uint_least32_t bsum = sums[1].b * 9; - - rsum -= sums[0].r; - gsum -= sums[0].g; - bsum -= sums[0].b; - - rsum += sums[2].r * 9; - gsum += sums[2].g * 9; - bsum += sums[2].b * 9; - - rsum -= sums[3].r; - gsum -= sums[3].g; - bsum -= sums[3].b; - - if (rsum & 0x80000000) rsum = 0; - if (gsum & 0x80000000) gsum = 0; - if (bsum & 0x80000000) bsum = 0; - - rsum <<= 8; - rsum += 0x008000; - gsum >>= 8; - gsum += 0x000080; - bsum += 0x000080; - bsum >>= 8; - - if (rsum > 0xFF0000) rsum = 0xFF0000; - if (gsum > 0x00FF00) gsum = 0x00FF00; - if (bsum > 0x0000FF) bsum = 0x0000FF; - - *dest++ = (rsum & 0xFF0000) | (gsum & 0x00FF00) | bsum; - } - - ++sums; - } -} - -static void filter(Gambatte::uint_least32_t *dline, const unsigned pitch, const Gambatte::uint_least32_t *sline) { - Colorsum sums[163]; - - for (unsigned h = 144; h--;) { - { - const Gambatte::uint_least32_t *s = sline; - Colorsum *sum = sums; - unsigned n = 163; - - while (n--) { - unsigned long pixel = *s; - sum->r = pixel >> 12 & 0x000FF0 ; - pixel <<= 4; - sum->g = pixel & 0x0FF000; - sum->b = pixel & 0x000FF0; - - ++s; - ++sum; - } - } - - merge_columns(dline, sums); - dline += pitch; - - { - const Gambatte::uint_least32_t *s = sline; - Colorsum *sum = sums; - unsigned n = 163; - - while (n--) { - unsigned long pixel = *s; - unsigned long rsum = (pixel >> 16) * 9; - unsigned long gsum = (pixel & 0x00FF00) * 9; - unsigned long bsum = (pixel & 0x0000FF) * 9; - - pixel = s[-1*163]; - rsum -= pixel >> 16; - gsum -= pixel & 0x00FF00; - bsum -= pixel & 0x0000FF; - - pixel = s[1*163]; - rsum += (pixel >> 16) * 9; - gsum += (pixel & 0x00FF00) * 9; - bsum += (pixel & 0x0000FF) * 9; - - pixel = s[2*163]; - rsum -= pixel >> 16; - gsum -= pixel & 0x00FF00; - bsum -= pixel & 0x0000FF; - - sum->r = rsum; - sum->g = gsum; - sum->b = bsum; - - ++s; - ++sum; - } - } - - merge_columns(dline, sums); - dline += pitch; - sline += 163; - } -} - -Catrom2x::Catrom2x() { - buffer = NULL; -} - -Catrom2x::~Catrom2x() { - delete []buffer; -} - -void Catrom2x::init() { - delete []buffer; - - buffer = new Gambatte::uint_least32_t[147 * 163]; - std::memset(buffer, 0, 147ul * 163 * sizeof(Gambatte::uint_least32_t)); -} - -void Catrom2x::outit() { - delete []buffer; - buffer = NULL; -} - -const Gambatte::FilterInfo& Catrom2x::info() { - static Gambatte::FilterInfo fInfo = { "Bicubic Catmull-Rom Spline 2x", 160 * 2, 144 * 2 }; - - return fInfo; -} - -Gambatte::uint_least32_t* Catrom2x::inBuffer() { - return buffer + 164; -} - -unsigned Catrom2x::inPitch() { - return 163; -} - -void Catrom2x::filter(Gambatte::uint_least32_t *const dbuffer, const unsigned pitch) { - ::filter(dbuffer, pitch, buffer + 163); -} diff --git a/src/lib/libgambatte/src/video/filters/catrom2x.h b/src/lib/libgambatte/src/video/filters/catrom2x.h deleted file mode 100644 index df657f04..00000000 --- a/src/lib/libgambatte/src/video/filters/catrom2x.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CATROM2X_H -#define CATROM2X_H - -#include "filter.h" - -struct FilterInfo; - -class Catrom2x : public Filter { - Gambatte::uint_least32_t *buffer; - -public: - Catrom2x(); - ~Catrom2x(); - void init(); - void outit(); - const Gambatte::FilterInfo& info(); - void filter(Gambatte::uint_least32_t *dbuffer, unsigned pitch); - Gambatte::uint_least32_t* inBuffer(); - unsigned inPitch(); -}; - -#endif diff --git a/src/lib/libgambatte/src/video/filters/catrom3x.cpp b/src/lib/libgambatte/src/video/filters/catrom3x.cpp deleted file mode 100644 index 09a03f6a..00000000 --- a/src/lib/libgambatte/src/video/filters/catrom3x.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "catrom3x.h" -#include "filterinfo.h" -#include - -struct Colorsum { - Gambatte::uint_least32_t r, g, b; -}; - -static void merge_columns(Gambatte::uint_least32_t *dest, const Colorsum *sums) { - unsigned w = 160; - - while (w--) { - { - Gambatte::uint_least32_t rsum = sums[1].r; - Gambatte::uint_least32_t gsum = sums[1].g; - Gambatte::uint_least32_t bsum = sums[1].b; - - if (rsum & 0x80000000) - rsum = 0; - else if (rsum > 6869) - rsum = 0xFF0000; - else { - rsum *= 607; - rsum <<= 2; - rsum += 0x008000; - rsum &= 0xFF0000; - } - - if (gsum & 0x80000000) - gsum = 0; - else if (gsum > 1758567) - gsum = 0xFF00; - else { - gsum *= 607; - gsum >>= 14; - gsum += 0x000080; - gsum &= 0x00FF00; - } - - if (bsum & 0x80000000) - bsum = 0; - else if (bsum > 6869) - bsum = 0xFF; - else { - bsum *= 607; - bsum += 8192; - bsum >>= 14; - } - - /*rsum/=27; - rsum<<=8; - gsum/=27; - gsum<<=5; - bsum<<=4; - bsum+=27; - bsum/=54; - rsum+=0x008000; - gsum+=0x000080; - - if(rsum>0xFF0000) rsum=0xFF0000; - if(gsum>0x00FF00) gsum=0x00FF00; - if(bsum>0x0000FF) bsum=0x0000FF;*/ - - *dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum; - } - { - Gambatte::uint_least32_t rsum = sums[1].r * 21; - Gambatte::uint_least32_t gsum = sums[1].g * 21; - Gambatte::uint_least32_t bsum = sums[1].b * 21; - - rsum -= sums[0].r << 1; - gsum -= sums[0].g << 1; - bsum -= sums[0].b << 1; - - rsum += sums[2].r * 9; - gsum += sums[2].g * 9; - bsum += sums[2].b * 9; - - rsum -= sums[3].r; - gsum -= sums[3].g; - bsum -= sums[3].b; - - if (rsum & 0x80000000) - rsum = 0; - else if (rsum > 185578) - rsum = 0xFF0000; - else { - rsum *= 719; - rsum >>= 3; - rsum += 0x008000; - rsum &= 0xFF0000; - } - - if (gsum & 0x80000000) - gsum = 0; - else if (gsum > 47508223) - gsum = 0x00FF00; - else { - gsum >>= 8; - gsum *= 719; - gsum >>= 11; - gsum += 0x000080; - gsum &= 0x00FF00; - } - - if (bsum & 0x80000000) - bsum = 0; - else if (bsum > 185578) - bsum = 0x0000FF; - else { - bsum *= 719; - bsum += 0x040000; - bsum >>= 19; - } - - /*rsum/=729; - rsum<<=8; - gsum/=729; - gsum<<=5; - bsum<<=4; - bsum+=729; - bsum/=1458; - rsum+=0x008000; - gsum+=0x000080; - - if(rsum>0xFF0000) rsum=0xFF0000; - if(gsum>0x00FF00) gsum=0x00FF00; - if(bsum>0x0000FF) bsum=0x0000FF;*/ - - *dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum; - } - { - Gambatte::uint_least32_t rsum = sums[1].r * 9; - Gambatte::uint_least32_t gsum = sums[1].g * 9; - Gambatte::uint_least32_t bsum = sums[1].b * 9; - - rsum -= sums[0].r; - gsum -= sums[0].g; - bsum -= sums[0].b; - - rsum += sums[2].r * 21; - gsum += sums[2].g * 21; - bsum += sums[2].b * 21; - - rsum -= sums[3].r << 1; - gsum -= sums[3].g << 1; - bsum -= sums[3].b << 1; - - if (rsum & 0x80000000) - rsum = 0; - else if (rsum > 185578) - rsum = 0xFF0000; - else { - rsum *= 719; - rsum >>= 3; - rsum += 0x008000; - rsum &= 0xFF0000; - } - - if (gsum & 0x80000000) - gsum = 0; - else if (gsum > 47508223) - gsum = 0xFF00; - else { - gsum >>= 8; - gsum *= 719; - gsum >>= 11; - gsum += 0x000080; - gsum &= 0x00FF00; - } - - if (bsum & 0x80000000) - bsum = 0; - else if (bsum > 185578) - bsum = 0x0000FF; - else { - bsum *= 719; - bsum += 0x040000; - bsum >>= 19; - } - - /*rsum/=729; - rsum<<=8; - gsum/=729; - gsum<<=5; - bsum<<=4; - bsum+=729; - bsum/=1458; - rsum+=0x008000; - gsum+=0x000080; - - if(rsum>0xFF0000) rsum=0xFF0000; - if(gsum>0x00FF00) gsum=0x00FF00; - if(bsum>0x0000FF) bsum=0x0000FF;*/ - - *dest++ = rsum/*&0xFF0000*/ | gsum/*&0x00FF00*/ | bsum; - } - ++sums; - } -} - -static void filter(Gambatte::uint_least32_t *dline, const unsigned pitch, const Gambatte::uint_least32_t *sline) { - Colorsum sums[163]; - - for (unsigned h = 144; h--;) { - { - const Gambatte::uint_least32_t *s = sline; - Colorsum *sum = sums; - unsigned n = 163; - - while (n--) { - const unsigned long pixel = *s; - sum->r = (pixel >> 16) * 27; - sum->g = (pixel & 0x00FF00) * 27; - sum->b = (pixel & 0x0000FF) * 27; - - ++s; - ++sum; - } - } - - merge_columns(dline, sums); - dline += pitch; - - { - const Gambatte::uint_least32_t *s = sline; - Colorsum *sum = sums; - unsigned n = 163; - - while (n--) { - unsigned long pixel = *s; - unsigned long rsum = (pixel >> 16) * 21; - unsigned long gsum = (pixel & 0x00FF00) * 21; - unsigned long bsum = (pixel & 0x0000FF) * 21; - - pixel = s[-1 * 163]; - rsum -= (pixel >> 16) << 1; - pixel <<= 1; - gsum -= pixel & 0x01FE00; - bsum -= pixel & 0x0001FE; - - pixel = s[1 * 163]; - rsum += (pixel >> 16) * 9; - gsum += (pixel & 0x00FF00) * 9; - bsum += (pixel & 0x0000FF) * 9; - - pixel = s[2 * 163]; - rsum -= pixel >> 16; - gsum -= pixel & 0x00FF00; - bsum -= pixel & 0x0000FF; - - sum->r = rsum; - sum->g = gsum; - sum->b = bsum; - - ++s; - ++sum; - } - } - - merge_columns(dline, sums); - dline += pitch; - - { - const Gambatte::uint_least32_t *s = sline; - Colorsum *sum = sums; - unsigned n = 163; - - while (n--) { - unsigned long pixel = *s; - unsigned long rsum = (pixel >> 16) * 9; - unsigned long gsum = (pixel & 0x00FF00) * 9; - unsigned long bsum = (pixel & 0x0000FF) * 9; - - pixel = s[-1 * 163]; - rsum -= pixel >> 16; - gsum -= pixel & 0x00FF00; - bsum -= pixel & 0x0000FF; - - pixel = s[1 * 163]; - rsum += (pixel >> 16) * 21; - gsum += (pixel & 0x00FF00) * 21; - bsum += (pixel & 0x0000FF) * 21; - - pixel = s[2 * 163]; - rsum -= (pixel >> 16) << 1; - pixel <<= 1; - gsum -= pixel & 0x01FE00; - bsum -= pixel & 0x0001FE; - - sum->r = rsum; - sum->g = gsum; - sum->b = bsum; - - ++s; - ++sum; - } - } - - merge_columns(dline, sums); - dline += pitch; - sline += 163; - } -} - -Catrom3x::Catrom3x() { - buffer = NULL; -} - -Catrom3x::~Catrom3x() { - delete []buffer; -} - -void Catrom3x::init() { - delete []buffer; - - buffer = new Gambatte::uint_least32_t[147 * 163]; - std::memset(buffer, 0, 147ul * 163 * sizeof(Gambatte::uint_least32_t)); -} - -void Catrom3x::outit() { - delete []buffer; - buffer = NULL; -} - -const Gambatte::FilterInfo& Catrom3x::info() { - static Gambatte::FilterInfo fInfo = { "Bicubic Catmull-Rom Spline 3x", 160 * 3, 144 * 3 }; - - return fInfo; -} - -Gambatte::uint_least32_t* Catrom3x::inBuffer() { - return buffer + 164; -} - -unsigned Catrom3x::inPitch() { - return 163; -} - -void Catrom3x::filter(Gambatte::uint_least32_t *const dbuffer, const unsigned pitch) { - ::filter(dbuffer, pitch, buffer + 163); -} diff --git a/src/lib/libgambatte/src/video/filters/catrom3x.h b/src/lib/libgambatte/src/video/filters/catrom3x.h deleted file mode 100644 index 64f47827..00000000 --- a/src/lib/libgambatte/src/video/filters/catrom3x.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef CATROM3X_H -#define CATROM3X_H - -#include "filter.h" - -struct FilterInfo; - -class Catrom3x : public Filter { - Gambatte::uint_least32_t *buffer; - -public: - Catrom3x(); - ~Catrom3x(); - void init(); - void outit(); - const Gambatte::FilterInfo& info(); - void filter(Gambatte::uint_least32_t *dbuffer, unsigned pitch); - Gambatte::uint_least32_t* inBuffer(); - unsigned inPitch(); -}; - -#endif diff --git a/src/lib/libgambatte/src/video/filters/filter.h b/src/lib/libgambatte/src/video/filters/filter.h deleted file mode 100644 index 72e3bf7d..00000000 --- a/src/lib/libgambatte/src/video/filters/filter.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef FILTER_H -#define FILTER_H - -#include "int.h" - -namespace Gambatte { -struct FilterInfo; -} - -class Filter { -public: - virtual ~Filter() {} - virtual void init() {}; - virtual void outit() {}; - virtual const Gambatte::FilterInfo& info() = 0; - virtual void filter(Gambatte::uint_least32_t *dbuffer, unsigned pitch) = 0; - virtual Gambatte::uint_least32_t* inBuffer() = 0; - virtual unsigned inPitch() = 0; -}; - -#endif diff --git a/src/lib/libgambatte/src/video/filters/kreed2xsai.cpp b/src/lib/libgambatte/src/video/filters/kreed2xsai.cpp deleted file mode 100644 index 70c261b3..00000000 --- a/src/lib/libgambatte/src/video/filters/kreed2xsai.cpp +++ /dev/null @@ -1,243 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * Copyright (C) 1999 Derek Liauw Kie Fa (Kreed) * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "kreed2xsai.h" -#include "filterinfo.h" -#include - -static inline int getResult1(const unsigned long a, const unsigned long b, const unsigned long c, const unsigned long d) { - int x = 0; - int y = 0; - int r = 0; - - if (a == c) ++x; - else if (b == c) ++y; - - if (a == d) ++x; - else if (b == d) ++y; - - if (x <= 1) ++r; - - if (y <= 1) --r; - - return r; -} - -static inline int getResult2(const unsigned long a, const unsigned long b, const unsigned long c, const unsigned long d) { - int x = 0; - int y = 0; - int r = 0; - - if (a == c) ++x; - else if (b == c) ++y; - - if (a == d) ++x; - else if (b == d) ++y; - - if (x <= 1) --r; - - if (y <= 1) ++r; - - return r; -} - -static inline unsigned long interpolate(const unsigned long a, const unsigned long b) { - return (a + b - ((a ^ b) & 0x010101)) >> 1; -} - -static inline unsigned long qInterpolate(const unsigned long a, const unsigned long b, const unsigned long c, const unsigned long d) { - const unsigned long lowBits = ((a & 0x030303) + (b & 0x030303) + (c & 0x030303) + (d & 0x030303)) & 0x030303; - - return (a + b + c + d - lowBits) >> 2; -} - -static void filter(Gambatte::uint_least32_t *dstPtr, const unsigned dstPitch, - const Gambatte::uint_least32_t *srcPtr, const unsigned srcPitch, const unsigned width, unsigned height) -{ - while (height--) { - const Gambatte::uint_least32_t *bP = srcPtr; - Gambatte::uint_least32_t *dP = dstPtr; - - for (unsigned finish = width; finish--;) { - register unsigned long colorA, colorB; - unsigned long colorC, colorD, - colorE, colorF, colorG, colorH, - colorI, colorJ, colorK, colorL, - - colorM, colorN, colorO, colorP; - unsigned long product, product1, product2; - - //--------------------------------------- - // Map of the pixels: I|E F|J - // G|A B|K - // H|C D|L - // M|N O|P - colorI = *(bP - srcPitch - 1); - colorE = *(bP - srcPitch); - colorF = *(bP - srcPitch + 1); - colorJ = *(bP - srcPitch + 2); - - colorG = *(bP - 1); - colorA = *(bP); - colorB = *(bP + 1); - colorK = *(bP + 2); - - colorH = *(bP + srcPitch - 1); - colorC = *(bP + srcPitch); - colorD = *(bP + srcPitch + 1); - colorL = *(bP + srcPitch + 2); - - colorM = *(bP + srcPitch * 2 - 1); - colorN = *(bP + srcPitch * 2); - colorO = *(bP + srcPitch * 2 + 1); - colorP = *(bP + srcPitch * 2 + 2); - - if (colorA == colorD && colorB != colorC) { - if ((colorA == colorE && colorB == colorL) || - (colorA == colorC && colorA == colorF - && colorB != colorE && colorB == colorJ)) { - product = colorA; - } else { - product = interpolate(colorA, colorB); - } - - if ((colorA == colorG && colorC == colorO) || - (colorA == colorB && colorA == colorH - && colorG != colorC && colorC == colorM)) { - product1 = colorA; - } else { - product1 = interpolate(colorA, colorC); - } - product2 = colorA; - } else if (colorB == colorC && colorA != colorD) { - if ((colorB == colorF && colorA == colorH) || - (colorB == colorE && colorB == colorD - && colorA != colorF && colorA == colorI)) { - product = colorB; - } else { - product = interpolate(colorA, colorB); - } - - if ((colorC == colorH && colorA == colorF) || - (colorC == colorG && colorC == colorD - && colorA != colorH && colorA == colorI)) { - product1 = colorC; - } else { - product1 = interpolate(colorA, colorC); - } - product2 = colorB; - } else if (colorA == colorD && colorB == colorC) { - if (colorA == colorB) { - product = colorA; - product1 = colorA; - product2 = colorA; - } else { - register int r = 0; - - product1 = interpolate(colorA, colorC); - product = interpolate(colorA, colorB); - - r += getResult1(colorA, colorB, colorG, colorE); - r += getResult2(colorB, colorA, colorK, colorF); - r += getResult2(colorB, colorA, colorH, colorN); - r += getResult1(colorA, colorB, colorL, colorO); - - if (r > 0) - product2 = colorA; - else if (r < 0) - product2 = colorB; - else { - product2 = qInterpolate(colorA, colorB, colorC, colorD); - } - } - } else { - product2 = qInterpolate(colorA, colorB, colorC, colorD); - - if (colorA == colorC && colorA == colorF - && colorB != colorE && colorB == colorJ) { - product = colorA; - } else if (colorB == colorE && colorB == colorD - && colorA != colorF && colorA == colorI) { - product = colorB; - } else { - product = interpolate(colorA, colorB); - } - - if (colorA == colorB && colorA == colorH - && colorG != colorC && colorC == colorM) { - product1 = colorA; - } else if (colorC == colorG && colorC == colorD - && colorA != colorH && colorA == colorI) { - product1 = colorC; - } else { - product1 = interpolate(colorA, colorC); - } - } - *dP = colorA; - *(dP + 1) = product; - *(dP + dstPitch) = product1; - *(dP + dstPitch + 1) = product2; - - ++bP; - dP += 2; - } - - srcPtr += srcPitch; - dstPtr += dstPitch * 2; - } -} - -Kreed_2xSaI::Kreed_2xSaI() { - buffer = NULL; -} - -Kreed_2xSaI::~Kreed_2xSaI() { - delete []buffer; -} - -void Kreed_2xSaI::init() { - delete []buffer; - - buffer = new Gambatte::uint_least32_t[145 * 161]; - std::memset(buffer, 0, 145ul * 161 * sizeof(Gambatte::uint_least32_t)); -} - -void Kreed_2xSaI::outit() { - delete []buffer; - buffer = NULL; -} - -const Gambatte::FilterInfo& Kreed_2xSaI::info() { - static Gambatte::FilterInfo fInfo = { "Kreed's 2xSaI", 160 * 2, 144 * 2 }; - - return fInfo; -} - -Gambatte::uint_least32_t* Kreed_2xSaI::inBuffer() { - return buffer; -} - -unsigned Kreed_2xSaI::inPitch() { - return 161; -} - -void Kreed_2xSaI::filter(Gambatte::uint_least32_t *const dbuffer, const unsigned pitch) { - ::filter(dbuffer, pitch, buffer, 161, 160, 144); -} diff --git a/src/lib/libgambatte/src/video/filters/kreed2xsai.h b/src/lib/libgambatte/src/video/filters/kreed2xsai.h deleted file mode 100644 index f2feffc0..00000000 --- a/src/lib/libgambatte/src/video/filters/kreed2xsai.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef KREED2XSAI_H -#define KREED2XSAI_H - -#include "filter.h" - -struct FilterInfo; - -class Kreed_2xSaI : public Filter { - Gambatte::uint_least32_t *buffer; - -public: - Kreed_2xSaI(); - ~Kreed_2xSaI(); - void init(); - void outit(); - const Gambatte::FilterInfo& info(); - void filter(Gambatte::uint_least32_t *dbuffer, unsigned pitch); - Gambatte::uint_least32_t* inBuffer(); - unsigned inPitch(); -}; - -#endif diff --git a/src/lib/libgambatte/src/video/filters/maxsthq2x.cpp b/src/lib/libgambatte/src/video/filters/maxsthq2x.cpp deleted file mode 100644 index a818d62a..00000000 --- a/src/lib/libgambatte/src/video/filters/maxsthq2x.cpp +++ /dev/null @@ -1,2875 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * Copyright (C) 2003 MaxSt * - * maxst@hiend3d.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#include "maxsthq2x.h" -#include "filterinfo.h" -#include - -static /*inline*/ unsigned long Interp1(const unsigned long c1, const unsigned long c2) { - const unsigned long lowbits = ((c1 & 0x030303) * 3 + (c2 & 0x030303)) & 0x030303; - - return (c1 * 3 + c2 - lowbits) >> 2; -} - -static /*inline*/ unsigned long Interp2(const unsigned long c1, const unsigned long c2, const unsigned long c3) { - const unsigned long lowbits = ((c1 * 2 & 0x020202) + (c2 & 0x030303) + (c3 & 0x030303)) & 0x030303; - - return (c1 * 2 + c2 + c3 - lowbits) >> 2; -} - -static /*inline*/ unsigned long Interp6(const unsigned long c1, const unsigned long c2, const unsigned long c3) { - const unsigned long lowbits = ((c1 & 0x070707) * 5 + (c2 * 2 & 0x060606) + (c3 & 0x070707)) & 0x070707; - - return ((c1 * 5 + c2 * 2 + c3) - lowbits) >> 3; -} - -static /*inline*/ unsigned long Interp7(const unsigned long c1, const unsigned long c2, const unsigned long c3) { - const unsigned long lowbits = ((c1 & 0x070707) * 6 + (c2 & 0x070707) + (c3 & 0x070707)) & 0x070707; - - return ((c1 * 6 + c2 + c3) - lowbits) >> 3; -} - -static /*inline*/ unsigned long Interp9(unsigned long c1, const unsigned long c2, const unsigned long c3) { - const unsigned lowbits = ((c1 * 2 & 0x070707) + ((c2 & 0x070707) + (c3 & 0x070707)) * 3) & 0x070707; - - return (c1 * 2 + (c2 + c3) * 3 - lowbits) >> 3; -} - -static /*inline*/ unsigned long Interp10(const unsigned long c1, const unsigned long c2, const unsigned long c3) { - const unsigned lowbits = ((c1 & 0x0F0F0F) * 14 + (c2 & 0x0F0F0F) + (c3 & 0x0F0F0F)) & 0x0F0F0F; - - return (c1 * 14 + c2 + c3 - lowbits) >> 4; -} - -#define PIXEL00_0 *pOut = w[5]; -#define PIXEL00_10 *pOut = Interp1(w[5], w[1]); -#define PIXEL00_11 *pOut = Interp1(w[5], w[4]); -#define PIXEL00_12 *pOut = Interp1(w[5], w[2]); -#define PIXEL00_20 *pOut = Interp2(w[5], w[4], w[2]); -#define PIXEL00_21 *pOut = Interp2(w[5], w[1], w[2]); -#define PIXEL00_22 *pOut = Interp2(w[5], w[1], w[4]); -#define PIXEL00_60 *pOut = Interp6(w[5], w[2], w[4]); -#define PIXEL00_61 *pOut = Interp6(w[5], w[4], w[2]); -#define PIXEL00_70 *pOut = Interp7(w[5], w[4], w[2]); -#define PIXEL00_90 *pOut = Interp9(w[5], w[4], w[2]); -#define PIXEL00_100 *pOut = Interp10(w[5], w[4], w[2]); -#define PIXEL01_0 *(pOut+1) = w[5]; -#define PIXEL01_10 *(pOut+1) = Interp1(w[5], w[3]); -#define PIXEL01_11 *(pOut+1) = Interp1(w[5], w[2]); -#define PIXEL01_12 *(pOut+1) = Interp1(w[5], w[6]); -#define PIXEL01_20 *(pOut+1) = Interp2(w[5], w[2], w[6]); -#define PIXEL01_21 *(pOut+1) = Interp2(w[5], w[3], w[6]); -#define PIXEL01_22 *(pOut+1) = Interp2(w[5], w[3], w[2]); -#define PIXEL01_60 *(pOut+1) = Interp6(w[5], w[6], w[2]); -#define PIXEL01_61 *(pOut+1) = Interp6(w[5], w[2], w[6]); -#define PIXEL01_70 *(pOut+1) = Interp7(w[5], w[2], w[6]); -#define PIXEL01_90 *(pOut+1) = Interp9(w[5], w[2], w[6]); -#define PIXEL01_100 *(pOut+1) = Interp10(w[5], w[2], w[6]); -#define PIXEL10_0 *(pOut+dstPitch) = w[5]; -#define PIXEL10_10 *(pOut+dstPitch) = Interp1(w[5], w[7]); -#define PIXEL10_11 *(pOut+dstPitch) = Interp1(w[5], w[8]); -#define PIXEL10_12 *(pOut+dstPitch) = Interp1(w[5], w[4]); -#define PIXEL10_20 *(pOut+dstPitch) = Interp2(w[5], w[8], w[4]); -#define PIXEL10_21 *(pOut+dstPitch) = Interp2(w[5], w[7], w[4]); -#define PIXEL10_22 *(pOut+dstPitch) = Interp2(w[5], w[7], w[8]); -#define PIXEL10_60 *(pOut+dstPitch) = Interp6(w[5], w[4], w[8]); -#define PIXEL10_61 *(pOut+dstPitch) = Interp6(w[5], w[8], w[4]); -#define PIXEL10_70 *(pOut+dstPitch) = Interp7(w[5], w[8], w[4]); -#define PIXEL10_90 *(pOut+dstPitch) = Interp9(w[5], w[8], w[4]); -#define PIXEL10_100 *(pOut+dstPitch) = Interp10(w[5], w[8], w[4]); -#define PIXEL11_0 *(pOut+dstPitch+1) = w[5]; -#define PIXEL11_10 *(pOut+dstPitch+1) = Interp1(w[5], w[9]); -#define PIXEL11_11 *(pOut+dstPitch+1) = Interp1(w[5], w[6]); -#define PIXEL11_12 *(pOut+dstPitch+1) = Interp1(w[5], w[8]); -#define PIXEL11_20 *(pOut+dstPitch+1) = Interp2(w[5], w[6], w[8]); -#define PIXEL11_21 *(pOut+dstPitch+1) = Interp2(w[5], w[9], w[8]); -#define PIXEL11_22 *(pOut+dstPitch+1) = Interp2(w[5], w[9], w[6]); -#define PIXEL11_60 *(pOut+dstPitch+1) = Interp6(w[5], w[8], w[6]); -#define PIXEL11_61 *(pOut+dstPitch+1) = Interp6(w[5], w[6], w[8]); -#define PIXEL11_70 *(pOut+dstPitch+1) = Interp7(w[5], w[6], w[8]); -#define PIXEL11_90 *(pOut+dstPitch+1) = Interp9(w[5], w[6], w[8]); -#define PIXEL11_100 *(pOut+dstPitch+1) = Interp10(w[5], w[6], w[8]); - -static /*inline*/ bool Diff(const unsigned long w1, const unsigned long w2) { - const unsigned rdiff = (w1 >> 16) - (w2 >> 16); - const unsigned gdiff = (w1 >> 8 & 0xFF) - (w2 >> 8 & 0xFF); - const unsigned bdiff = (w1 & 0xFF) - (w2 & 0xFF); - - return rdiff + gdiff + bdiff + 0xC0U > 0xC0U * 2 || - rdiff - bdiff + 0x1CU > 0x1CU * 2 || - gdiff * 2 - rdiff - bdiff + 0x30U > 0x30U * 2; -} - -static void filter(Gambatte::uint_least32_t *pOut, const unsigned dstPitch, - const Gambatte::uint_least32_t *pIn, const unsigned Xres, const unsigned Yres) -{ - unsigned long w[10]; - - // +----+----+----+ - // | | | | - // | w1 | w2 | w3 | - // +----+----+----+ - // | | | | - // | w4 | w5 | w6 | - // +----+----+----+ - // | | | | - // | w7 | w8 | w9 | - // +----+----+----+ - - for (unsigned j = 0; j < Yres; j++) { - const unsigned prevline = j > 0 ? Xres : 0; - const unsigned nextline = j < Yres - 1 ? Xres : 0; - - for (unsigned i = 0; i < Xres; i++) { - w[2] = *(pIn - prevline); - w[5] = *(pIn); - w[8] = *(pIn + nextline); - - if (i > 0) { - w[1] = *(pIn - prevline - 1); - w[4] = *(pIn - 1); - w[7] = *(pIn + nextline - 1); - } else { - w[1] = w[2]; - w[4] = w[5]; - w[7] = w[8]; - } - - if (i < Xres - 1) { - w[3] = *(pIn - prevline + 1); - w[6] = *(pIn + 1); - w[9] = *(pIn + nextline + 1); - } else { - w[3] = w[2]; - w[6] = w[5]; - w[9] = w[8]; - } - - unsigned pattern = 0; - - { - unsigned flag = 1; - - const unsigned r1 = w[5] >> 16; - const unsigned g1 = w[5] >> 8 & 0xFF; - const unsigned b1 = w[5] & 0xFF; - - for (unsigned k = 1; k < 10; ++k) { - if (k == 5) continue; - - if (w[k] != w[5]) { - const unsigned rdiff = r1 - (w[k] >> 16); - const unsigned gdiff = g1 - (w[k] >> 8 & 0xFF); - const unsigned bdiff = b1 - (w[k] & 0xFF); - - if (rdiff + gdiff + bdiff + 0xC0U > 0xC0U * 2 || - rdiff - bdiff + 0x1CU > 0x1CU * 2 || - gdiff * 2 - rdiff - bdiff + 0x30U > 0x30U * 2) - pattern |= flag; - } - - flag <<= 1; - } - } - - switch (pattern) - { - case 0: - case 1: - case 4: - case 32: - case 128: - case 5: - case 132: - case 160: - case 33: - case 129: - case 36: - case 133: - case 164: - case 161: - case 37: - case 165: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_20 - PIXEL11_20 - break; - } - case 2: - case 34: - case 130: - case 162: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_20 - PIXEL11_20 - break; - } - case 16: - case 17: - case 48: - case 49: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_20 - PIXEL11_21 - break; - } - case 64: - case 65: - case 68: - case 69: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_21 - PIXEL11_22 - break; - } - case 8: - case 12: - case 136: - case 140: - { - PIXEL00_21 - PIXEL01_20 - PIXEL10_22 - PIXEL11_20 - break; - } - case 3: - case 35: - case 131: - case 163: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_20 - PIXEL11_20 - break; - } - case 6: - case 38: - case 134: - case 166: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_20 - PIXEL11_20 - break; - } - case 20: - case 21: - case 52: - case 53: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_20 - PIXEL11_21 - break; - } - case 144: - case 145: - case 176: - case 177: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_20 - PIXEL11_12 - break; - } - case 192: - case 193: - case 196: - case 197: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_21 - PIXEL11_11 - break; - } - case 96: - case 97: - case 100: - case 101: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_12 - PIXEL11_22 - break; - } - case 40: - case 44: - case 168: - case 172: - { - PIXEL00_21 - PIXEL01_20 - PIXEL10_11 - PIXEL11_20 - break; - } - case 9: - case 13: - case 137: - case 141: - { - PIXEL00_12 - PIXEL01_20 - PIXEL10_22 - PIXEL11_20 - break; - } - case 18: - case 50: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_20 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 80: - case 81: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_20 - } - break; - } - case 72: - case 76: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 10: - case 138: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_22 - PIXEL11_20 - break; - } - case 66: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_21 - PIXEL11_22 - break; - } - case 24: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_22 - PIXEL11_21 - break; - } - case 7: - case 39: - case 135: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_20 - PIXEL11_20 - break; - } - case 148: - case 149: - case 180: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_20 - PIXEL11_12 - break; - } - case 224: - case 228: - case 225: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_12 - PIXEL11_11 - break; - } - case 41: - case 169: - case 45: - { - PIXEL00_12 - PIXEL01_20 - PIXEL10_11 - PIXEL11_20 - break; - } - case 22: - case 54: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 208: - case 209: - { - PIXEL00_20 - PIXEL01_22 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 104: - case 108: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 11: - case 139: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_22 - PIXEL11_20 - break; - } - case 19: - case 51: - { - if (Diff(w[2], w[6])) - { - PIXEL00_11 - PIXEL01_10 - } - else - { - PIXEL00_60 - PIXEL01_90 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 146: - case 178: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - PIXEL11_12 - } - else - { - PIXEL01_90 - PIXEL11_61 - } - PIXEL10_20 - break; - } - case 84: - case 85: - { - PIXEL00_20 - if (Diff(w[6], w[8])) - { - PIXEL01_11 - PIXEL11_10 - } - else - { - PIXEL01_60 - PIXEL11_90 - } - PIXEL10_21 - break; - } - case 112: - case 113: - { - PIXEL00_20 - PIXEL01_22 - if (Diff(w[6], w[8])) - { - PIXEL10_12 - PIXEL11_10 - } - else - { - PIXEL10_61 - PIXEL11_90 - } - break; - } - case 200: - case 204: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - PIXEL11_11 - } - else - { - PIXEL10_90 - PIXEL11_60 - } - break; - } - case 73: - case 77: - { - if (Diff(w[8], w[4])) - { - PIXEL00_12 - PIXEL10_10 - } - else - { - PIXEL00_61 - PIXEL10_90 - } - PIXEL01_20 - PIXEL11_22 - break; - } - case 42: - case 170: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - PIXEL10_11 - } - else - { - PIXEL00_90 - PIXEL10_60 - } - PIXEL01_21 - PIXEL11_20 - break; - } - case 14: - case 142: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - PIXEL01_12 - } - else - { - PIXEL00_90 - PIXEL01_61 - } - PIXEL10_22 - PIXEL11_20 - break; - } - case 67: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_21 - PIXEL11_22 - break; - } - case 70: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_21 - PIXEL11_22 - break; - } - case 28: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_22 - PIXEL11_21 - break; - } - case 152: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_22 - PIXEL11_12 - break; - } - case 194: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_21 - PIXEL11_11 - break; - } - case 98: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_12 - PIXEL11_22 - break; - } - case 56: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_11 - PIXEL11_21 - break; - } - case 25: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_22 - PIXEL11_21 - break; - } - case 26: - case 31: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_22 - PIXEL11_21 - break; - } - case 82: - case 214: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 88: - case 248: - { - PIXEL00_21 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 74: - case 107: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 27: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - PIXEL10_22 - PIXEL11_21 - break; - } - case 86: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_21 - PIXEL11_10 - break; - } - case 216: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 106: - { - PIXEL00_10 - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 30: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_22 - PIXEL11_21 - break; - } - case 210: - { - PIXEL00_22 - PIXEL01_10 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 120: - { - PIXEL00_21 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 75: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_10 - PIXEL11_22 - break; - } - case 29: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_22 - PIXEL11_21 - break; - } - case 198: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_21 - PIXEL11_11 - break; - } - case 184: - { - PIXEL00_21 - PIXEL01_22 - PIXEL10_11 - PIXEL11_12 - break; - } - case 99: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_12 - PIXEL11_22 - break; - } - case 57: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_11 - PIXEL11_21 - break; - } - case 71: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_21 - PIXEL11_22 - break; - } - case 156: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_22 - PIXEL11_12 - break; - } - case 226: - { - PIXEL00_22 - PIXEL01_21 - PIXEL10_12 - PIXEL11_11 - break; - } - case 60: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_11 - PIXEL11_21 - break; - } - case 195: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_21 - PIXEL11_11 - break; - } - case 102: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_12 - PIXEL11_22 - break; - } - case 153: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_22 - PIXEL11_12 - break; - } - case 58: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 83: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 92: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 202: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_11 - break; - } - case 78: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_22 - break; - } - case 154: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_22 - PIXEL11_12 - break; - } - case 114: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 89: - { - PIXEL00_12 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 90: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 55: - case 23: - { - if (Diff(w[2], w[6])) - { - PIXEL00_11 - PIXEL01_0 - } - else - { - PIXEL00_60 - PIXEL01_90 - } - PIXEL10_20 - PIXEL11_21 - break; - } - case 182: - case 150: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - PIXEL11_12 - } - else - { - PIXEL01_90 - PIXEL11_61 - } - PIXEL10_20 - break; - } - case 213: - case 212: - { - PIXEL00_20 - if (Diff(w[6], w[8])) - { - PIXEL01_11 - PIXEL11_0 - } - else - { - PIXEL01_60 - PIXEL11_90 - } - PIXEL10_21 - break; - } - case 241: - case 240: - { - PIXEL00_20 - PIXEL01_22 - if (Diff(w[6], w[8])) - { - PIXEL10_12 - PIXEL11_0 - } - else - { - PIXEL10_61 - PIXEL11_90 - } - break; - } - case 236: - case 232: - { - PIXEL00_21 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - PIXEL11_11 - } - else - { - PIXEL10_90 - PIXEL11_60 - } - break; - } - case 109: - case 105: - { - if (Diff(w[8], w[4])) - { - PIXEL00_12 - PIXEL10_0 - } - else - { - PIXEL00_61 - PIXEL10_90 - } - PIXEL01_20 - PIXEL11_22 - break; - } - case 171: - case 43: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL10_11 - } - else - { - PIXEL00_90 - PIXEL10_60 - } - PIXEL01_21 - PIXEL11_20 - break; - } - case 143: - case 15: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL01_12 - } - else - { - PIXEL00_90 - PIXEL01_61 - } - PIXEL10_22 - PIXEL11_20 - break; - } - case 124: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 203: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - PIXEL10_10 - PIXEL11_11 - break; - } - case 62: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 211: - { - PIXEL00_11 - PIXEL01_10 - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 118: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_12 - PIXEL11_10 - break; - } - case 217: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 110: - { - PIXEL00_10 - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 155: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - PIXEL10_22 - PIXEL11_12 - break; - } - case 188: - { - PIXEL00_21 - PIXEL01_11 - PIXEL10_11 - PIXEL11_12 - break; - } - case 185: - { - PIXEL00_12 - PIXEL01_22 - PIXEL10_11 - PIXEL11_12 - break; - } - case 61: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_11 - PIXEL11_21 - break; - } - case 157: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_22 - PIXEL11_12 - break; - } - case 103: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_12 - PIXEL11_22 - break; - } - case 227: - { - PIXEL00_11 - PIXEL01_21 - PIXEL10_12 - PIXEL11_11 - break; - } - case 230: - { - PIXEL00_22 - PIXEL01_12 - PIXEL10_12 - PIXEL11_11 - break; - } - case 199: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_21 - PIXEL11_11 - break; - } - case 220: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 158: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_22 - PIXEL11_12 - break; - } - case 234: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_11 - break; - } - case 242: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 59: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 121: - { - PIXEL00_12 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 87: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 79: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_22 - break; - } - case 122: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 94: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 218: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 91: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 229: - { - PIXEL00_20 - PIXEL01_20 - PIXEL10_12 - PIXEL11_11 - break; - } - case 167: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_20 - PIXEL11_20 - break; - } - case 173: - { - PIXEL00_12 - PIXEL01_20 - PIXEL10_11 - PIXEL11_20 - break; - } - case 181: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_20 - PIXEL11_12 - break; - } - case 186: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_11 - PIXEL11_12 - break; - } - case 115: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 93: - { - PIXEL00_12 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 206: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_11 - break; - } - case 205: - case 201: - { - PIXEL00_12 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_10 - } - else - { - PIXEL10_70 - } - PIXEL11_11 - break; - } - case 174: - case 46: - { - if (Diff(w[4], w[2])) - { - PIXEL00_10 - } - else - { - PIXEL00_70 - } - PIXEL01_12 - PIXEL10_11 - PIXEL11_20 - break; - } - case 179: - case 147: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_10 - } - else - { - PIXEL01_70 - } - PIXEL10_20 - PIXEL11_12 - break; - } - case 117: - case 116: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_10 - } - else - { - PIXEL11_70 - } - break; - } - case 189: - { - PIXEL00_12 - PIXEL01_11 - PIXEL10_11 - PIXEL11_12 - break; - } - case 231: - { - PIXEL00_11 - PIXEL01_12 - PIXEL10_12 - PIXEL11_11 - break; - } - case 126: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 219: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 125: - { - if (Diff(w[8], w[4])) - { - PIXEL00_12 - PIXEL10_0 - } - else - { - PIXEL00_61 - PIXEL10_90 - } - PIXEL01_11 - PIXEL11_10 - break; - } - case 221: - { - PIXEL00_12 - if (Diff(w[6], w[8])) - { - PIXEL01_11 - PIXEL11_0 - } - else - { - PIXEL01_60 - PIXEL11_90 - } - PIXEL10_10 - break; - } - case 207: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL01_12 - } - else - { - PIXEL00_90 - PIXEL01_61 - } - PIXEL10_10 - PIXEL11_11 - break; - } - case 238: - { - PIXEL00_10 - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - PIXEL11_11 - } - else - { - PIXEL10_90 - PIXEL11_60 - } - break; - } - case 190: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - PIXEL11_12 - } - else - { - PIXEL01_90 - PIXEL11_61 - } - PIXEL10_11 - break; - } - case 187: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - PIXEL10_11 - } - else - { - PIXEL00_90 - PIXEL10_60 - } - PIXEL01_10 - PIXEL11_12 - break; - } - case 243: - { - PIXEL00_11 - PIXEL01_10 - if (Diff(w[6], w[8])) - { - PIXEL10_12 - PIXEL11_0 - } - else - { - PIXEL10_61 - PIXEL11_90 - } - break; - } - case 119: - { - if (Diff(w[2], w[6])) - { - PIXEL00_11 - PIXEL01_0 - } - else - { - PIXEL00_60 - PIXEL01_90 - } - PIXEL10_12 - PIXEL11_10 - break; - } - case 237: - case 233: - { - PIXEL00_12 - PIXEL01_20 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - PIXEL11_11 - break; - } - case 175: - case 47: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - PIXEL01_12 - PIXEL10_11 - PIXEL11_20 - break; - } - case 183: - case 151: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_20 - PIXEL11_12 - break; - } - case 245: - case 244: - { - PIXEL00_20 - PIXEL01_11 - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 250: - { - PIXEL00_10 - PIXEL01_10 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 123: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 95: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_10 - PIXEL11_10 - break; - } - case 222: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 252: - { - PIXEL00_21 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 249: - { - PIXEL00_12 - PIXEL01_22 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 235: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_21 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - PIXEL11_11 - break; - } - case 111: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_22 - break; - } - case 63: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_11 - PIXEL11_21 - break; - } - case 159: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_22 - PIXEL11_12 - break; - } - case 215: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_21 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 246: - { - PIXEL00_22 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 254: - { - PIXEL00_10 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 253: - { - PIXEL00_12 - PIXEL01_11 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 251: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - PIXEL01_10 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 239: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - PIXEL01_12 - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - PIXEL11_11 - break; - } - case 127: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_20 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_20 - } - PIXEL11_10 - break; - } - case 191: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_11 - PIXEL11_12 - break; - } - case 223: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_20 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_10 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_20 - } - break; - } - case 247: - { - PIXEL00_11 - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - PIXEL10_12 - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - case 255: - { - if (Diff(w[4], w[2])) - { - PIXEL00_0 - } - else - { - PIXEL00_100 - } - if (Diff(w[2], w[6])) - { - PIXEL01_0 - } - else - { - PIXEL01_100 - } - if (Diff(w[8], w[4])) - { - PIXEL10_0 - } - else - { - PIXEL10_100 - } - if (Diff(w[6], w[8])) - { - PIXEL11_0 - } - else - { - PIXEL11_100 - } - break; - } - } - ++pIn; - pOut += 2; - } - pOut += dstPitch * 2 - Xres * 2; - } -} - -MaxSt_Hq2x::MaxSt_Hq2x() { - buffer = NULL; -} - -MaxSt_Hq2x::~MaxSt_Hq2x() { - outit(); -} - -void MaxSt_Hq2x::init() { - delete []buffer; - buffer = new Gambatte::uint_least32_t[144 * 160]; -} - -void MaxSt_Hq2x::outit() { - delete []buffer; - buffer = NULL; -} - -const Gambatte::FilterInfo& MaxSt_Hq2x::info() { - static const Gambatte::FilterInfo fInfo = { "MaxSt's Hq2x", 160 * 2, 144 * 2 }; - return fInfo; -} - -Gambatte::uint_least32_t* MaxSt_Hq2x::inBuffer() { - return buffer; -} - -unsigned MaxSt_Hq2x::inPitch() { - return 160; -} - -void MaxSt_Hq2x::filter(Gambatte::uint_least32_t *const dbuffer, const unsigned pitch) { - ::filter(dbuffer, pitch, buffer, 160, 144); -} diff --git a/src/lib/libgambatte/src/video/filters/maxsthq2x.h b/src/lib/libgambatte/src/video/filters/maxsthq2x.h deleted file mode 100644 index ca2cf411..00000000 --- a/src/lib/libgambatte/src/video/filters/maxsthq2x.h +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef MAXSTHQ2X_H -#define MAXSTHQ2X_H - -#include "filter.h" - -struct FilterInfo; - -class MaxSt_Hq2x : public Filter { - Gambatte::uint_least32_t *buffer; - -public: - MaxSt_Hq2x(); - ~MaxSt_Hq2x(); - void init(); - void outit(); - const Gambatte::FilterInfo& info(); - void filter(Gambatte::uint_least32_t *dbuffer, unsigned pitch); - Gambatte::uint_least32_t* inBuffer(); - unsigned inPitch(); -}; - - -#endif diff --git a/src/lib/libgambatte/src/video/filters/maxsthq3x.cpp b/src/lib/libgambatte/src/video/filters/maxsthq3x.cpp deleted file mode 100644 index 996a221e..00000000 --- a/src/lib/libgambatte/src/video/filters/maxsthq3x.cpp +++ /dev/null @@ -1,3845 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * Copyright (C) 2003 MaxSt * - * maxst@hiend3d.com * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "maxsthq3x.h" -#include "filterinfo.h" -#include - -static /*inline*/ unsigned long Interp1(const unsigned long c1, const unsigned long c2) { - const unsigned long lowbits = ((c1 & 0x030303) * 3 + (c2 & 0x030303)) & 0x030303; - - return (c1 * 3 + c2 - lowbits) >> 2; -} - -static /*inline*/ unsigned long Interp2(const unsigned long c1, const unsigned long c2, const unsigned long c3) { - const unsigned long lowbits = ((c1 * 2 & 0x020202) + (c2 & 0x030303) + (c3 & 0x030303)) & 0x030303; - - return (c1 * 2 + c2 + c3 - lowbits) >> 2; -} - -static /*inline*/ unsigned long Interp3(const unsigned long c1, const unsigned long c2) { - const unsigned long lowbits = ((c1 & 0x070707) * 7 + (c2 & 0x070707)) & 0x070707; - - return (c1 * 7 + c2 - lowbits) >> 3; -} - -static /*inline*/ unsigned long Interp4(const unsigned long c1, const unsigned long c2, const unsigned long c3) { - const unsigned long lowbits = ((c1 * 2 & 0x0E0E0E) + ((c2 & 0x0F0F0F) + (c3 & 0x0F0F0F)) * 7) & 0x0F0F0F; - - return (c1 * 2 + (c2 + c3) * 7 - lowbits) >> 4; -} - -static /*inline*/ unsigned long Interp5(const unsigned long c1, const unsigned long c2) { - return (c1 + c2 - ((c1 ^ c2) & 0x010101)) >> 1; -} - -#define PIXEL00_1M *pOut = Interp1(w[5], w[1]); -#define PIXEL00_1U *pOut = Interp1(w[5], w[2]); -#define PIXEL00_1L *pOut = Interp1(w[5], w[4]); -#define PIXEL00_2 *pOut = Interp2(w[5], w[4], w[2]); -#define PIXEL00_4 *pOut = Interp4(w[5], w[4], w[2]); -#define PIXEL00_5 *pOut = Interp5(w[4], w[2]); -#define PIXEL00_C *pOut = w[5]; - -#define PIXEL01_1 *(pOut+1) = Interp1(w[5], w[2]); -#define PIXEL01_3 *(pOut+1) = Interp3(w[5], w[2]); -#define PIXEL01_6 *(pOut+1) = Interp1(w[2], w[5]); -#define PIXEL01_C *(pOut+1) = w[5]; - -#define PIXEL02_1M *(pOut+2) = Interp1(w[5], w[3]); -#define PIXEL02_1U *(pOut+2) = Interp1(w[5], w[2]); -#define PIXEL02_1R *(pOut+2) = Interp1(w[5], w[6]); -#define PIXEL02_2 *(pOut+2) = Interp2(w[5], w[2], w[6]); -#define PIXEL02_4 *(pOut+2) = Interp4(w[5], w[2], w[6]); -#define PIXEL02_5 *(pOut+2) = Interp5(w[2], w[6]); -#define PIXEL02_C *(pOut+2) = w[5]; - -#define PIXEL10_1 *(pOut+dstPitch) = Interp1(w[5], w[4]); -#define PIXEL10_3 *(pOut+dstPitch) = Interp3(w[5], w[4]); -#define PIXEL10_6 *(pOut+dstPitch) = Interp1(w[4], w[5]); -#define PIXEL10_C *(pOut+dstPitch) = w[5]; - -#define PIXEL11 *(pOut+dstPitch+1) = w[5]; - -#define PIXEL12_1 *(pOut+dstPitch+2) = Interp1(w[5], w[6]); -#define PIXEL12_3 *(pOut+dstPitch+2) = Interp3(w[5], w[6]); -#define PIXEL12_6 *(pOut+dstPitch+2) = Interp1(w[6], w[5]); -#define PIXEL12_C *(pOut+dstPitch+2) = w[5]; - -#define PIXEL20_1M *(pOut+dstPitch*2) = Interp1(w[5], w[7]); -#define PIXEL20_1D *(pOut+dstPitch*2) = Interp1(w[5], w[8]); -#define PIXEL20_1L *(pOut+dstPitch*2) = Interp1(w[5], w[4]); -#define PIXEL20_2 *(pOut+dstPitch*2) = Interp2(w[5], w[8], w[4]); -#define PIXEL20_4 *(pOut+dstPitch*2) = Interp4(w[5], w[8], w[4]); -#define PIXEL20_5 *(pOut+dstPitch*2) = Interp5(w[8], w[4]); -#define PIXEL20_C *(pOut+dstPitch*2) = w[5]; - -#define PIXEL21_1 *(pOut+dstPitch*2+1) = Interp1(w[5], w[8]); -#define PIXEL21_3 *(pOut+dstPitch*2+1) = Interp3(w[5], w[8]); -#define PIXEL21_6 *(pOut+dstPitch*2+1) = Interp1(w[8], w[5]); -#define PIXEL21_C *(pOut+dstPitch*2+1) = w[5]; - -#define PIXEL22_1M *(pOut+dstPitch*2+2) = Interp1(w[5], w[9]); -#define PIXEL22_1D *(pOut+dstPitch*2+2) = Interp1(w[5], w[8]); -#define PIXEL22_1R *(pOut+dstPitch*2+2) = Interp1(w[5], w[6]); -#define PIXEL22_2 *(pOut+dstPitch*2+2) = Interp2(w[5], w[6], w[8]); -#define PIXEL22_4 *(pOut+dstPitch*2+2) = Interp4(w[5], w[6], w[8]); -#define PIXEL22_5 *(pOut+dstPitch*2+2) = Interp5(w[6], w[8]); -#define PIXEL22_C *(pOut+dstPitch*2+2) = w[5]; - -static /*inline*/ bool Diff(const unsigned long w1, const unsigned long w2) { - const unsigned rdiff = (w1 >> 16) - (w2 >> 16); - const unsigned gdiff = (w1 >> 8 & 0xFF) - (w2 >> 8 & 0xFF); - const unsigned bdiff = (w1 & 0xFF) - (w2 & 0xFF); - - return rdiff + gdiff + bdiff + 0xC0U > 0xC0U * 2 || - rdiff - bdiff + 0x1CU > 0x1CU * 2 || - gdiff * 2 - rdiff - bdiff + 0x30U > 0x30U * 2; -} - -static void filter(Gambatte::uint_least32_t *pOut, const unsigned dstPitch, - const Gambatte::uint_least32_t *pIn, const unsigned Xres, const unsigned Yres) -{ - unsigned long w[10]; - - // +----+----+----+ - // | | | | - // | w1 | w2 | w3 | - // +----+----+----+ - // | | | | - // | w4 | w5 | w6 | - // +----+----+----+ - // | | | | - // | w7 | w8 | w9 | - // +----+----+----+ - - for (unsigned j = 0; j < Yres; j++) { - const unsigned prevline = j > 0 ? Xres : 0; - const unsigned nextline = j < Yres - 1 ? Xres : 0; - - for (unsigned i = 0; i < Xres; i++) { - w[2] = *(pIn - prevline); - w[5] = *(pIn); - w[8] = *(pIn + nextline); - - if (i > 0) { - w[1] = *(pIn - prevline - 1); - w[4] = *(pIn - 1); - w[7] = *(pIn + nextline - 1); - } else { - w[1] = w[2]; - w[4] = w[5]; - w[7] = w[8]; - } - - if (i < Xres - 1) { - w[3] = *(pIn - prevline + 1); - w[6] = *(pIn + 1); - w[9] = *(pIn + nextline + 1); - } else { - w[3] = w[2]; - w[6] = w[5]; - w[9] = w[8]; - } - - unsigned pattern = 0; - - { - unsigned flag = 1; - - const unsigned r1 = w[5] >> 16; - const unsigned g1 = w[5] >> 8 & 0xFF; - const unsigned b1 = w[5] & 0xFF; - - for (unsigned k = 1; k < 10; ++k) { - if (k == 5) continue; - - if (w[k] != w[5]) { - const unsigned rdiff = r1 - (w[k] >> 16); - const unsigned gdiff = g1 - (w[k] >> 8 & 0xFF); - const unsigned bdiff = b1 - (w[k] & 0xFF); - - if (rdiff + gdiff + bdiff + 0xC0U > 0xC0U * 2 || - rdiff - bdiff + 0x1CU > 0x1CU * 2 || - gdiff * 2 - rdiff - bdiff + 0x30U > 0x30U * 2) - pattern |= flag; - } - - flag <<= 1; - } - } - - switch (pattern) - { - case 0: - case 1: - case 4: - case 32: - case 128: - case 5: - case 132: - case 160: - case 33: - case 129: - case 36: - case 133: - case 164: - case 161: - case 37: - case 165: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_2 - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_2 - PIXEL21_1 - PIXEL22_2 - break; - } - case 2: - case 34: - case 130: - case 162: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_2 - PIXEL21_1 - PIXEL22_2 - break; - } - case 16: - case 17: - case 48: - case 49: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_2 - PIXEL21_1 - PIXEL22_1M - break; - } - case 64: - case 65: - case 68: - case 69: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_2 - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 8: - case 12: - case 136: - case 140: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_2 - PIXEL10_C - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_1 - PIXEL22_2 - break; - } - case 3: - case 35: - case 131: - case 163: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_2 - PIXEL21_1 - PIXEL22_2 - break; - } - case 6: - case 38: - case 134: - case 166: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_2 - PIXEL21_1 - PIXEL22_2 - break; - } - case 20: - case 21: - case 52: - case 53: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1U - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_2 - PIXEL21_1 - PIXEL22_1M - break; - } - case 144: - case 145: - case 176: - case 177: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_2 - PIXEL21_1 - PIXEL22_1D - break; - } - case 192: - case 193: - case 196: - case 197: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_2 - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - break; - } - case 96: - case 97: - case 100: - case 101: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_2 - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - break; - } - case 40: - case 44: - case 168: - case 172: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_2 - PIXEL10_C - PIXEL11 - PIXEL12_1 - PIXEL20_1D - PIXEL21_1 - PIXEL22_2 - break; - } - case 9: - case 13: - case 137: - case 141: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_2 - PIXEL10_C - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_1 - PIXEL22_2 - break; - } - case 18: - case 50: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_1M - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_1 - PIXEL11 - PIXEL20_2 - PIXEL21_1 - PIXEL22_1M - break; - } - case 80: - case 81: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_1M - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 72: - case 76: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_2 - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_1M - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 10: - case 138: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1M - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_1 - PIXEL22_2 - break; - } - case 66: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 24: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1M - break; - } - case 7: - case 39: - case 135: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_2 - PIXEL21_1 - PIXEL22_2 - break; - } - case 148: - case 149: - case 180: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1U - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_2 - PIXEL21_1 - PIXEL22_1D - break; - } - case 224: - case 228: - case 225: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_2 - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1R - break; - } - case 41: - case 169: - case 45: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_2 - PIXEL10_C - PIXEL11 - PIXEL12_1 - PIXEL20_1D - PIXEL21_1 - PIXEL22_2 - break; - } - case 22: - case 54: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_1 - PIXEL11 - PIXEL20_2 - PIXEL21_1 - PIXEL22_1M - break; - } - case 208: - case 209: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 104: - case 108: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_2 - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 11: - case 139: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1M - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_1 - PIXEL22_2 - break; - } - case 19: - case 51: - { - if (Diff(w[2], w[6])) - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL12_C - } - else - { - PIXEL00_2 - PIXEL01_6 - PIXEL02_5 - PIXEL12_1 - } - PIXEL10_1 - PIXEL11 - PIXEL20_2 - PIXEL21_1 - PIXEL22_1M - break; - } - case 146: - case 178: - { - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_1M - PIXEL12_C - PIXEL22_1D - } - else - { - PIXEL01_1 - PIXEL02_5 - PIXEL12_6 - PIXEL22_2 - } - PIXEL00_1M - PIXEL10_1 - PIXEL11 - PIXEL20_2 - PIXEL21_1 - break; - } - case 84: - case 85: - { - if (Diff(w[6], w[8])) - { - PIXEL02_1U - PIXEL12_C - PIXEL21_C - PIXEL22_1M - } - else - { - PIXEL02_2 - PIXEL12_6 - PIXEL21_1 - PIXEL22_5 - } - PIXEL00_2 - PIXEL01_1 - PIXEL10_1 - PIXEL11 - PIXEL20_1M - break; - } - case 112: - case 113: - { - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - } - else - { - PIXEL12_1 - PIXEL20_2 - PIXEL21_6 - PIXEL22_5 - } - PIXEL00_2 - PIXEL01_1 - PIXEL02_1M - PIXEL10_1 - PIXEL11 - break; - } - case 200: - case 204: - { - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - } - else - { - PIXEL10_1 - PIXEL20_5 - PIXEL21_6 - PIXEL22_2 - } - PIXEL00_1M - PIXEL01_1 - PIXEL02_2 - PIXEL11 - PIXEL12_1 - break; - } - case 73: - case 77: - { - if (Diff(w[8], w[4])) - { - PIXEL00_1U - PIXEL10_C - PIXEL20_1M - PIXEL21_C - } - else - { - PIXEL00_2 - PIXEL10_6 - PIXEL20_5 - PIXEL21_1 - } - PIXEL01_1 - PIXEL02_2 - PIXEL11 - PIXEL12_1 - PIXEL22_1M - break; - } - case 42: - case 170: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - PIXEL01_C - PIXEL10_C - PIXEL20_1D - } - else - { - PIXEL00_5 - PIXEL01_1 - PIXEL10_6 - PIXEL20_2 - } - PIXEL02_1M - PIXEL11 - PIXEL12_1 - PIXEL21_1 - PIXEL22_2 - break; - } - case 14: - case 142: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL10_C - } - else - { - PIXEL00_5 - PIXEL01_6 - PIXEL02_2 - PIXEL10_1 - } - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_1 - PIXEL22_2 - break; - } - case 67: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 70: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 28: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1M - break; - } - case 152: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 194: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - break; - } - case 98: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - break; - } - case 56: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 25: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1M - break; - } - case 26: - case 31: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL10_3 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL02_4 - PIXEL12_3 - } - PIXEL11 - PIXEL20_1M - PIXEL21_1 - PIXEL22_1M - break; - } - case 82: - case 214: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - } - else - { - PIXEL01_3 - PIXEL02_4 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 88: - case 248: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1M - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - } - else - { - PIXEL10_3 - PIXEL20_4 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL22_4 - } - break; - } - case 74: - case 107: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - } - else - { - PIXEL00_4 - PIXEL01_3 - } - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 27: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1M - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1M - break; - } - case 86: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_1 - PIXEL11 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 216: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 106: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 30: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_C - PIXEL11 - PIXEL20_1M - PIXEL21_1 - PIXEL22_1M - break; - } - case 210: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 120: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1M - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 75: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1M - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 29: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1M - break; - } - case 198: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - break; - } - case 184: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1D - break; - } - case 99: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - break; - } - case 57: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 71: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 156: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 226: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1R - break; - } - case 60: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 195: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - break; - } - case 102: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - break; - } - case 153: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 58: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 83: - { - PIXEL00_1L - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 92: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 202: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1R - break; - } - case 78: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1R - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1M - break; - } - case 154: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 114: - { - PIXEL00_1M - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1L - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 89: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 90: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_C - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 55: - case 23: - { - if (Diff(w[2], w[6])) - { - PIXEL00_1L - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL00_2 - PIXEL01_6 - PIXEL02_5 - PIXEL12_1 - } - PIXEL10_1 - PIXEL11 - PIXEL20_2 - PIXEL21_1 - PIXEL22_1M - break; - } - case 182: - case 150: - { - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - PIXEL22_1D - } - else - { - PIXEL01_1 - PIXEL02_5 - PIXEL12_6 - PIXEL22_2 - } - PIXEL00_1M - PIXEL10_1 - PIXEL11 - PIXEL20_2 - PIXEL21_1 - break; - } - case 213: - case 212: - { - if (Diff(w[6], w[8])) - { - PIXEL02_1U - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL02_2 - PIXEL12_6 - PIXEL21_1 - PIXEL22_5 - } - PIXEL00_2 - PIXEL01_1 - PIXEL10_1 - PIXEL11 - PIXEL20_1M - break; - } - case 241: - case 240: - { - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL20_1L - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_1 - PIXEL20_2 - PIXEL21_6 - PIXEL22_5 - } - PIXEL00_2 - PIXEL01_1 - PIXEL02_1M - PIXEL10_1 - PIXEL11 - break; - } - case 236: - case 232: - { - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - PIXEL22_1R - } - else - { - PIXEL10_1 - PIXEL20_5 - PIXEL21_6 - PIXEL22_2 - } - PIXEL00_1M - PIXEL01_1 - PIXEL02_2 - PIXEL11 - PIXEL12_1 - break; - } - case 109: - case 105: - { - if (Diff(w[8], w[4])) - { - PIXEL00_1U - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL00_2 - PIXEL10_6 - PIXEL20_5 - PIXEL21_1 - } - PIXEL01_1 - PIXEL02_2 - PIXEL11 - PIXEL12_1 - PIXEL22_1M - break; - } - case 171: - case 43: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - PIXEL20_1D - } - else - { - PIXEL00_5 - PIXEL01_1 - PIXEL10_6 - PIXEL20_2 - } - PIXEL02_1M - PIXEL11 - PIXEL12_1 - PIXEL21_1 - PIXEL22_2 - break; - } - case 143: - case 15: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL02_1R - PIXEL10_C - } - else - { - PIXEL00_5 - PIXEL01_6 - PIXEL02_2 - PIXEL10_1 - } - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_1 - PIXEL22_2 - break; - } - case 124: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 203: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1M - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - break; - } - case 62: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_C - PIXEL11 - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 211: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 118: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_1 - PIXEL11 - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - break; - } - case 217: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 110: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 155: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1M - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 188: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1D - break; - } - case 185: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1D - break; - } - case 61: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 157: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 103: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - break; - } - case 227: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1R - break; - } - case 230: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1R - break; - } - case 199: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - break; - } - case 220: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 158: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_C - PIXEL11 - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 234: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1M - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1R - break; - } - case 242: - { - PIXEL00_1M - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL20_1L - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 59: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 121: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 87: - { - PIXEL00_1L - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_1 - PIXEL11 - PIXEL20_1M - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 79: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1R - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1M - break; - } - case 122: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 94: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_C - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 218: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_C - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 91: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 229: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_2 - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1R - break; - } - case 167: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_2 - PIXEL21_1 - PIXEL22_2 - break; - } - case 173: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_2 - PIXEL10_C - PIXEL11 - PIXEL12_1 - PIXEL20_1D - PIXEL21_1 - PIXEL22_2 - break; - } - case 181: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1U - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_2 - PIXEL21_1 - PIXEL22_1D - break; - } - case 186: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1D - break; - } - case 115: - { - PIXEL00_1L - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1L - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 93: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 206: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1R - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1R - break; - } - case 205: - case 201: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_2 - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_1M - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1R - break; - } - case 174: - case 46: - { - if (Diff(w[4], w[2])) - { - PIXEL00_1M - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1R - PIXEL10_C - PIXEL11 - PIXEL12_1 - PIXEL20_1D - PIXEL21_1 - PIXEL22_2 - break; - } - case 179: - case 147: - { - PIXEL00_1L - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_1M - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_2 - PIXEL21_1 - PIXEL22_1D - break; - } - case 117: - case 116: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1U - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1L - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_1M - } - else - { - PIXEL22_2 - } - break; - } - case 189: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1D - break; - } - case 231: - { - PIXEL00_1L - PIXEL01_C - PIXEL02_1R - PIXEL10_1 - PIXEL11 - PIXEL12_1 - PIXEL20_1L - PIXEL21_C - PIXEL22_1R - break; - } - case 126: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_4 - PIXEL12_3 - } - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 219: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL01_3 - PIXEL10_3 - } - PIXEL02_1M - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 125: - { - if (Diff(w[8], w[4])) - { - PIXEL00_1U - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL00_2 - PIXEL10_6 - PIXEL20_5 - PIXEL21_1 - } - PIXEL01_1 - PIXEL02_1U - PIXEL11 - PIXEL12_C - PIXEL22_1M - break; - } - case 221: - { - if (Diff(w[6], w[8])) - { - PIXEL02_1U - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL02_2 - PIXEL12_6 - PIXEL21_1 - PIXEL22_5 - } - PIXEL00_1U - PIXEL01_1 - PIXEL10_C - PIXEL11 - PIXEL20_1M - break; - } - case 207: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL02_1R - PIXEL10_C - } - else - { - PIXEL00_5 - PIXEL01_6 - PIXEL02_2 - PIXEL10_1 - } - PIXEL11 - PIXEL12_1 - PIXEL20_1M - PIXEL21_C - PIXEL22_1R - break; - } - case 238: - { - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - PIXEL22_1R - } - else - { - PIXEL10_1 - PIXEL20_5 - PIXEL21_6 - PIXEL22_2 - } - PIXEL00_1M - PIXEL01_C - PIXEL02_1R - PIXEL11 - PIXEL12_1 - break; - } - case 190: - { - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - PIXEL22_1D - } - else - { - PIXEL01_1 - PIXEL02_5 - PIXEL12_6 - PIXEL22_2 - } - PIXEL00_1M - PIXEL10_C - PIXEL11 - PIXEL20_1D - PIXEL21_1 - break; - } - case 187: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - PIXEL20_1D - } - else - { - PIXEL00_5 - PIXEL01_1 - PIXEL10_6 - PIXEL20_2 - } - PIXEL02_1M - PIXEL11 - PIXEL12_C - PIXEL21_1 - PIXEL22_1D - break; - } - case 243: - { - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL20_1L - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_1 - PIXEL20_2 - PIXEL21_6 - PIXEL22_5 - } - PIXEL00_1L - PIXEL01_C - PIXEL02_1M - PIXEL10_1 - PIXEL11 - break; - } - case 119: - { - if (Diff(w[2], w[6])) - { - PIXEL00_1L - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL00_2 - PIXEL01_6 - PIXEL02_5 - PIXEL12_1 - } - PIXEL10_1 - PIXEL11 - PIXEL20_1L - PIXEL21_C - PIXEL22_1M - break; - } - case 237: - case 233: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_2 - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_C - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1R - break; - } - case 175: - case 47: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1R - PIXEL10_C - PIXEL11 - PIXEL12_1 - PIXEL20_1D - PIXEL21_1 - PIXEL22_2 - break; - } - case 183: - case 151: - { - PIXEL00_1L - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_2 - PIXEL21_1 - PIXEL22_1D - break; - } - case 245: - case 244: - { - PIXEL00_2 - PIXEL01_1 - PIXEL02_1U - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1L - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_C - } - else - { - PIXEL22_2 - } - break; - } - case 250: - { - PIXEL00_1M - PIXEL01_C - PIXEL02_1M - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - } - else - { - PIXEL10_3 - PIXEL20_4 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL22_4 - } - break; - } - case 123: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - } - else - { - PIXEL00_4 - PIXEL01_3 - } - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 95: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL10_3 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL02_4 - PIXEL12_3 - } - PIXEL11 - PIXEL20_1M - PIXEL21_C - PIXEL22_1M - break; - } - case 222: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - } - else - { - PIXEL01_3 - PIXEL02_4 - } - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 252: - { - PIXEL00_1M - PIXEL01_1 - PIXEL02_1U - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - } - else - { - PIXEL10_3 - PIXEL20_4 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_C - } - else - { - PIXEL22_2 - } - break; - } - case 249: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1M - PIXEL10_C - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL20_C - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL22_4 - } - break; - } - case 235: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - } - else - { - PIXEL00_4 - PIXEL01_3 - } - PIXEL02_1M - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_C - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1R - break; - } - case 111: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1R - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 63: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL02_4 - PIXEL12_3 - } - PIXEL10_C - PIXEL11 - PIXEL20_1D - PIXEL21_1 - PIXEL22_1M - break; - } - case 159: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL10_3 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - } - else - { - PIXEL02_2 - } - PIXEL11 - PIXEL12_C - PIXEL20_1M - PIXEL21_1 - PIXEL22_1D - break; - } - case 215: - { - PIXEL00_1L - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 246: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - } - else - { - PIXEL01_3 - PIXEL02_4 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1L - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_C - } - else - { - PIXEL22_2 - } - break; - } - case 254: - { - PIXEL00_1M - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - } - else - { - PIXEL01_3 - PIXEL02_4 - } - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - } - else - { - PIXEL10_3 - PIXEL20_4 - } - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL21_3 - PIXEL22_2 - } - break; - } - case 253: - { - PIXEL00_1U - PIXEL01_1 - PIXEL02_1U - PIXEL10_C - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_C - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_C - } - else - { - PIXEL22_2 - } - break; - } - case 251: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - } - else - { - PIXEL00_4 - PIXEL01_3 - } - PIXEL02_1M - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL10_C - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL10_3 - PIXEL20_2 - PIXEL21_3 - } - if (Diff(w[6], w[8])) - { - PIXEL12_C - PIXEL22_C - } - else - { - PIXEL12_3 - PIXEL22_4 - } - break; - } - case 239: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - } - else - { - PIXEL00_2 - } - PIXEL01_C - PIXEL02_1R - PIXEL10_C - PIXEL11 - PIXEL12_1 - if (Diff(w[8], w[4])) - { - PIXEL20_C - } - else - { - PIXEL20_2 - } - PIXEL21_C - PIXEL22_1R - break; - } - case 127: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL01_C - PIXEL10_C - } - else - { - PIXEL00_2 - PIXEL01_3 - PIXEL10_3 - } - if (Diff(w[2], w[6])) - { - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL02_4 - PIXEL12_3 - } - PIXEL11 - if (Diff(w[8], w[4])) - { - PIXEL20_C - PIXEL21_C - } - else - { - PIXEL20_4 - PIXEL21_3 - } - PIXEL22_1M - break; - } - case 191: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - } - else - { - PIXEL02_2 - } - PIXEL10_C - PIXEL11 - PIXEL12_C - PIXEL20_1D - PIXEL21_1 - PIXEL22_1D - break; - } - case 223: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - PIXEL10_C - } - else - { - PIXEL00_4 - PIXEL10_3 - } - if (Diff(w[2], w[6])) - { - PIXEL01_C - PIXEL02_C - PIXEL12_C - } - else - { - PIXEL01_3 - PIXEL02_2 - PIXEL12_3 - } - PIXEL11 - PIXEL20_1M - if (Diff(w[6], w[8])) - { - PIXEL21_C - PIXEL22_C - } - else - { - PIXEL21_3 - PIXEL22_4 - } - break; - } - case 247: - { - PIXEL00_1L - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - } - else - { - PIXEL02_2 - } - PIXEL10_1 - PIXEL11 - PIXEL12_C - PIXEL20_1L - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_C - } - else - { - PIXEL22_2 - } - break; - } - case 255: - { - if (Diff(w[4], w[2])) - { - PIXEL00_C - } - else - { - PIXEL00_2 - } - PIXEL01_C - if (Diff(w[2], w[6])) - { - PIXEL02_C - } - else - { - PIXEL02_2 - } - PIXEL10_C - PIXEL11 - PIXEL12_C - if (Diff(w[8], w[4])) - { - PIXEL20_C - } - else - { - PIXEL20_2 - } - PIXEL21_C - if (Diff(w[6], w[8])) - { - PIXEL22_C - } - else - { - PIXEL22_2 - } - break; - } - } - ++pIn; - pOut += 3; - } - pOut += dstPitch * 3 - Xres * 3; - } -} - -MaxSt_Hq3x::MaxSt_Hq3x() { - buffer = NULL; -} - -MaxSt_Hq3x::~MaxSt_Hq3x() { - outit(); -} - -void MaxSt_Hq3x::init() { - delete []buffer; - buffer = new Gambatte::uint_least32_t[144 * 160]; -} - -void MaxSt_Hq3x::outit() { - delete []buffer; - buffer = NULL; -} - -const Gambatte::FilterInfo& MaxSt_Hq3x::info() { - static const Gambatte::FilterInfo fInfo = { "MaxSt's Hq3x", 160 * 3, 144 * 3 }; - return fInfo; -} - -Gambatte::uint_least32_t* MaxSt_Hq3x::inBuffer() { - return buffer; -} - -unsigned MaxSt_Hq3x::inPitch() { - return 160; -} - -void MaxSt_Hq3x::filter(Gambatte::uint_least32_t *const dbuffer, const unsigned pitch) { - ::filter(dbuffer, pitch, buffer, 160, 144); -} diff --git a/src/lib/libgambatte/src/video/filters/maxsthq3x.h b/src/lib/libgambatte/src/video/filters/maxsthq3x.h deleted file mode 100644 index 9e1f51d6..00000000 --- a/src/lib/libgambatte/src/video/filters/maxsthq3x.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef MAXSTHQ3X_H -#define MAXSTHQ3X_H - -#include "filter.h" - -struct FilterInfo; - -class MaxSt_Hq3x : public Filter { - Gambatte::uint_least32_t *buffer; - -public: - MaxSt_Hq3x(); - ~MaxSt_Hq3x(); - void init(); - void outit(); - const Gambatte::FilterInfo& info(); - void filter(Gambatte::uint_least32_t *dbuffer, unsigned pitch); - Gambatte::uint_least32_t* inBuffer(); - unsigned inPitch(); -}; - -#endif diff --git a/src/lib/libgambatte/src/video/irq_event.cpp b/src/lib/libgambatte/src/video/irq_event.cpp deleted file mode 100644 index 358f1daf..00000000 --- a/src/lib/libgambatte/src/video/irq_event.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "irq_event.h" - -IrqEvent::IrqEvent(event_queue &irqEventQueue_in) : - VideoEvent(11), - irqEventQueue(irqEventQueue_in) -{ -} - -void IrqEvent::doEvent() { - irqEventQueue.top()->doEvent(); - - if (irqEventQueue.top()->time() == DISABLED_TIME) - irqEventQueue.pop(); - else - irqEventQueue.modify_root(irqEventQueue.top()); - - setTime(schedule(irqEventQueue)); -} diff --git a/src/lib/libgambatte/src/video/irq_event.h b/src/lib/libgambatte/src/video/irq_event.h deleted file mode 100644 index c8a5b991..00000000 --- a/src/lib/libgambatte/src/video/irq_event.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#ifndef VIDEO_IRQ_EVENT_H -#define VIDEO_IRQ_EVENT_H - -#include "../event_queue.h" -#include "video_event.h" -#include "video_event_comparer.h" -#include "basic_add_event.h" - -class IrqEvent : public VideoEvent { - event_queue &irqEventQueue; - -public: - IrqEvent(event_queue &irqEventQueue_in); - - void doEvent(); - - static unsigned long schedule(const event_queue &irqEventQueue) { - return irqEventQueue.top()->time(); - } - - void schedule() { - setTime(irqEventQueue.top()->time()); - } -}; - -static inline void addEvent(event_queue &q, IrqEvent *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, IrqEvent *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/ly_counter.cpp b/src/lib/libgambatte/src/video/ly_counter.cpp deleted file mode 100644 index 5d5b6d98..00000000 --- a/src/lib/libgambatte/src/video/ly_counter.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "ly_counter.h" -#include "../savestate.h" - -LyCounter::LyCounter() : VideoEvent(0) { - setDoubleSpeed(false); - reset(0, 0); -} - -void LyCounter::doEvent() { - ++ly_; - - if (ly_ == 154) - ly_ = 0; - - setTime(time() + lineTime_); -} - -unsigned long LyCounter::nextLineCycle(const unsigned lineCycle, const unsigned long cycleCounter) const { - unsigned long tmp = time() + (lineCycle << ds); - - if (tmp - cycleCounter > lineTime_) - tmp -= lineTime_; - - return tmp; -} - -unsigned long LyCounter::nextFrameCycle(const unsigned long frameCycle, const unsigned long cycleCounter) const { - unsigned long tmp = time() + (((153U - ly()) * 456U + frameCycle) << ds); - - if (tmp - cycleCounter > 70224U << ds) - tmp -= 70224U << ds; - - return tmp; -} - -void LyCounter::reset(const unsigned long videoCycles, const unsigned long lastUpdate) { - ly_ = videoCycles / 456; - setTime(lastUpdate + ((456 - (videoCycles - ly_ * 456ul)) << isDoubleSpeed())); -} - -void LyCounter::setDoubleSpeed(const bool ds_in) { - ds = ds_in; - lineTime_ = 456U << ds_in; -} diff --git a/src/lib/libgambatte/src/video/ly_counter.h b/src/lib/libgambatte/src/video/ly_counter.h deleted file mode 100644 index 2b795fb8..00000000 --- a/src/lib/libgambatte/src/video/ly_counter.h +++ /dev/null @@ -1,69 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef LY_COUNTER_H -#define LY_COUNTER_H - -class SaveState; - -#include "video_event.h" -#include "basic_add_event.h" - -class LyCounter : public VideoEvent { - unsigned short lineTime_; - unsigned char ly_; - bool ds; - -public: - LyCounter(); - - void doEvent(); - - bool isDoubleSpeed() const { - return ds; - } - - unsigned lineCycles(const unsigned long cc) const { - return 456u - ((time() - cc) >> isDoubleSpeed()); - } - - unsigned lineTime() const { - return lineTime_; - } - - unsigned ly() const { - return ly_; - } - - unsigned long nextLineCycle(unsigned lineCycle, unsigned long cycleCounter) const; - unsigned long nextFrameCycle(unsigned long frameCycle, unsigned long cycleCounter) const; - - void reset(unsigned long videoCycles, unsigned long lastUpdate); - - void setDoubleSpeed(bool ds_in); -}; - -static inline void addEvent(event_queue &q, LyCounter *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, LyCounter *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/lyc_irq.cpp b/src/lib/libgambatte/src/video/lyc_irq.cpp deleted file mode 100644 index eb81d41b..00000000 --- a/src/lib/libgambatte/src/video/lyc_irq.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "lyc_irq.h" - -LycIrq::LycIrq(unsigned char &ifReg_in) : - VideoEvent(1), - ifReg(ifReg_in) -{ - setDoubleSpeed(false); - setM2IrqEnabled(false); - setLycReg(0); - setSkip(false); -} - -void LycIrq::doEvent() { - if (!skip && (!m2IrqEnabled || lycReg_ > 143 || lycReg_ == 0)) - ifReg |= 0x2; - - skip = false; - - setTime(time() + frameTime); -} - -unsigned long LycIrq::schedule(const unsigned statReg, const unsigned lycReg, const LyCounter &lyCounter, const unsigned long cycleCounter) { - return ((statReg & 0x40) && lycReg < 154) ? lyCounter.nextFrameCycle(lycReg ? lycReg * 456 : 153 * 456 + 8, cycleCounter) : static_cast(DISABLED_TIME); -} diff --git a/src/lib/libgambatte/src/video/lyc_irq.h b/src/lib/libgambatte/src/video/lyc_irq.h deleted file mode 100644 index ed93fdda..00000000 --- a/src/lib/libgambatte/src/video/lyc_irq.h +++ /dev/null @@ -1,67 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_LYC_IRQ_H -#define VIDEO_LYC_IRQ_H - -#include "ly_counter.h" - -class LycIrq : public VideoEvent { - unsigned char &ifReg; - unsigned long frameTime; - unsigned char lycReg_; - bool m2IrqEnabled; - bool skip; - -public: - LycIrq(unsigned char &ifReg_in); - - void doEvent(); - - unsigned lycReg() const { - return lycReg_; - } - - static unsigned long schedule(unsigned statReg, unsigned lycReg, const LyCounter &lyCounter, unsigned long cycleCounter); - - void setDoubleSpeed(const bool ds) { - frameTime = 70224 << ds; - } - - void setLycReg(const unsigned lycReg_in) { - lycReg_ = lycReg_in; - } - - void setM2IrqEnabled(const bool enabled) { - m2IrqEnabled = enabled; - } - - void setSkip(const bool skip) { - this->skip = skip; - } - - bool skips() const { - return skip; - } - - bool isSkipPeriod(const unsigned long cycleCounter, const bool doubleSpeed) const { - return lycReg_ > 0 && time() - cycleCounter > 4U >> doubleSpeed && time() - cycleCounter < 9; - } -}; - -#endif diff --git a/src/lib/libgambatte/src/video/m3_extra_cycles.cpp b/src/lib/libgambatte/src/video/m3_extra_cycles.cpp deleted file mode 100644 index de4eadb7..00000000 --- a/src/lib/libgambatte/src/video/m3_extra_cycles.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "m3_extra_cycles.h" -#include "scx_reader.h" -#include "window.h" -#include "sprite_mapper.h" -#include "../insertion_sort.h" - -M3ExtraCycles::M3ExtraCycles(const SpriteMapper &spriteMapper, - const ScxReader &scxReader, - const Window &win) : - spriteMapper(spriteMapper), - scxReader(scxReader), - win(win) -{ - invalidateCache(); -} - -static const unsigned char* addLineCycles(const unsigned char *const start, const unsigned char *const end, - const unsigned maxSpx, const unsigned scwxAnd7, const unsigned char *const posbuf_plus1, unsigned char *cycles_out) { - unsigned sum = 0; - - const unsigned char *a = start; - - for (; a < end; ++a) { - const unsigned spx = posbuf_plus1[*a]; - - if (spx > maxSpx) - break; - - unsigned cycles = 6; - const unsigned posAnd7 = (scwxAnd7 + spx) & 7; - - if (posAnd7 < 5) { - cycles = 11 - posAnd7; - - for (const unsigned char *b = a; b > start;) { - const unsigned bSpx = posbuf_plus1[*--b]; - - if (spx - bSpx > 4U) - break; - - if (((scwxAnd7 + bSpx) & 7) < 4 || spx == bSpx) { - cycles = 6; - break; - } - } - } - - sum += cycles; - } - - *cycles_out += sum; - - return a; -} - -void M3ExtraCycles::updateLine(const unsigned ly) const { - const bool windowEnabled = win.enabled(ly); - - cycles[ly] = windowEnabled ? scxReader.scxAnd7() + 6 : scxReader.scxAnd7(); - - const unsigned numSprites = spriteMapper.numSprites(ly); - - if (numSprites == 0) - return; - - unsigned char sortBuf[10]; - const unsigned char *tmp = spriteMapper.sprites(ly); - - if (spriteMapper.isCgb()) { - std::memcpy(sortBuf, tmp, sizeof(sortBuf)); - insertionSort(sortBuf, sortBuf + numSprites, SpriteMapper::SpxLess(spriteMapper.posbuf())); - tmp = sortBuf; - } - - const unsigned char *const tmpend = tmp + numSprites; - const unsigned char *const posbuf_plus1 = spriteMapper.posbuf() + 1; - - if (windowEnabled) { - addLineCycles(addLineCycles(tmp, tmpend, win.wxReader.wx(), scxReader.scxAnd7(), posbuf_plus1, cycles + ly), - tmpend, 167, 7 - win.wxReader.wx(), posbuf_plus1, cycles + ly); - } else - addLineCycles(tmp, tmpend, 167, scxReader.scxAnd7(), posbuf_plus1, cycles + ly); -} diff --git a/src/lib/libgambatte/src/video/m3_extra_cycles.h b/src/lib/libgambatte/src/video/m3_extra_cycles.h deleted file mode 100644 index 8a7f1470..00000000 --- a/src/lib/libgambatte/src/video/m3_extra_cycles.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_M3_EXTRA_CYCLES_H -#define VIDEO_M3_EXTRA_CYCLES_H - -class ScxReader; -class Window; -class SpriteMapper; - -#include - -class M3ExtraCycles { - enum { CYCLES_INVALID = 0xFF }; - - mutable unsigned char cycles[144]; - - const SpriteMapper &spriteMapper; - const ScxReader &scxReader; - const Window &win; - - void updateLine(unsigned ly) const; - -public: - M3ExtraCycles(const SpriteMapper &spriteMapper, - const ScxReader &scxReader_in, - const Window &win); - - void invalidateCache() { - std::memset(cycles, CYCLES_INVALID, sizeof(cycles)); - } - - unsigned operator()(const unsigned ly) const { - if (cycles[ly] == CYCLES_INVALID) - updateLine(ly); - - return cycles[ly]; - } -}; - -#endif diff --git a/src/lib/libgambatte/src/video/mode0_irq.cpp b/src/lib/libgambatte/src/video/mode0_irq.cpp deleted file mode 100644 index 041d3db1..00000000 --- a/src/lib/libgambatte/src/video/mode0_irq.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * -***************************************************************************/ -#include "mode0_irq.h" - -#include "ly_counter.h" -#include "lyc_irq.h" -#include "m3_extra_cycles.h" - -Mode0Irq::Mode0Irq(const LyCounter &lyCounter_in, const LycIrq &lycIrq_in, - const M3ExtraCycles &m3ExtraCycles_in, unsigned char &ifReg_in) : - VideoEvent(0), - lyCounter(lyCounter_in), - lycIrq(lycIrq_in), - m3ExtraCycles(m3ExtraCycles_in), - ifReg(ifReg_in) -{ -} - -static unsigned baseCycle(const bool ds) { - return 80 + 169 + ds * 3 + 1 - ds; -} - -void Mode0Irq::doEvent() { - if (lycIrq.time() == DISABLED_TIME || lyCounter.ly() != lycIrq.lycReg()) - ifReg |= 2; - - unsigned long nextTime = lyCounter.time(); - unsigned nextLy = lyCounter.ly() + 1; - - if (nextLy == 144) { - nextLy = 0; - nextTime += lyCounter.lineTime() * 10; - } - - nextTime += (baseCycle(lyCounter.isDoubleSpeed()) + m3ExtraCycles(nextLy)) << lyCounter.isDoubleSpeed(); - - setTime(nextTime); -} - -void Mode0Irq::mode3CyclesChange() { - unsigned long nextTime = lyCounter.time() - lyCounter.lineTime(); - unsigned nextLy = lyCounter.ly(); - - if (time() > lyCounter.time()) { - nextTime += lyCounter.lineTime(); - ++nextLy; - - if (nextLy > 143) { - nextTime += lyCounter.lineTime() * (154 - nextLy); - nextLy = 0; - } - } - - nextTime += (baseCycle(lyCounter.isDoubleSpeed()) + m3ExtraCycles(nextLy)) << lyCounter.isDoubleSpeed(); - - setTime(nextTime); -} - -unsigned long Mode0Irq::schedule(const unsigned statReg, const M3ExtraCycles &m3ExtraCycles, const LyCounter &lyCounter, const unsigned long cycleCounter) { - if (!(statReg & 0x08)) - return DISABLED_TIME; - - unsigned line = lyCounter.ly(); - int next = static_cast(baseCycle(lyCounter.isDoubleSpeed())) - static_cast(lyCounter.lineCycles(cycleCounter)); - - if (line < 144 && next + static_cast(m3ExtraCycles(line)) <= 0) { - next += 456; - ++line; - } - - if (line > 143) { - next += (154 - line) * 456; - line = 0; - } - - next += m3ExtraCycles(line); - - return cycleCounter + (static_cast(next) << lyCounter.isDoubleSpeed()); -} diff --git a/src/lib/libgambatte/src/video/mode0_irq.h b/src/lib/libgambatte/src/video/mode0_irq.h deleted file mode 100644 index bc5f1540..00000000 --- a/src/lib/libgambatte/src/video/mode0_irq.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_MODE0_IRQ_H -#define VIDEO_MODE0_IRQ_H - -class LycIrq; -class M3ExtraCycles; - -#include "ly_counter.h" - -class Mode0Irq : public VideoEvent { - const LyCounter &lyCounter; - const LycIrq &lycIrq; - const M3ExtraCycles &m3ExtraCycles; - unsigned char &ifReg; - -public: - Mode0Irq(const LyCounter &lyCounter_in, const LycIrq &lycIrq_in, - const M3ExtraCycles &m3ExtraCycles_in, unsigned char &ifReg_in); - - void doEvent(); - void mode3CyclesChange(); - static unsigned long schedule(unsigned statReg, const M3ExtraCycles &m3ExtraCycles, const LyCounter &lyCounter, unsigned long cycleCounter); -}; - -#endif diff --git a/src/lib/libgambatte/src/video/mode1_irq.cpp b/src/lib/libgambatte/src/video/mode1_irq.cpp deleted file mode 100644 index ddafe25c..00000000 --- a/src/lib/libgambatte/src/video/mode1_irq.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "mode1_irq.h" - -Mode1Irq::Mode1Irq(unsigned char &ifReg_in) : - VideoEvent(0), - ifReg(ifReg_in) -{ - setDoubleSpeed(false); - setM1StatIrqEnabled(false); -} - -void Mode1Irq::doEvent() { - ifReg |= flags; - - setTime(time() + frameTime); -} diff --git a/src/lib/libgambatte/src/video/mode1_irq.h b/src/lib/libgambatte/src/video/mode1_irq.h deleted file mode 100644 index f4e6270f..00000000 --- a/src/lib/libgambatte/src/video/mode1_irq.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_MODE1_IRQ_H -#define VIDEO_MODE1_IRQ_H - -#include "ly_counter.h" -#include "basic_add_event.h" - -class Mode1Irq : public VideoEvent { - unsigned char &ifReg; - unsigned long frameTime; - unsigned char flags; - -public: - Mode1Irq(unsigned char &ifReg_in); - - void doEvent(); - - static unsigned long schedule(const LyCounter &lyCounter, unsigned long cycleCounter) { - return lyCounter.nextFrameCycle(144 * 456, cycleCounter); - } - - void setDoubleSpeed(const bool ds) { - frameTime = 70224 << ds; - } - - void setM1StatIrqEnabled(const bool enabled) { - flags = (enabled * 2) | 1; - } -}; - -static inline void addEvent(event_queue &q, Mode1Irq *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, Mode1Irq *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/mode2_irq.cpp b/src/lib/libgambatte/src/video/mode2_irq.cpp deleted file mode 100644 index b1a419ea..00000000 --- a/src/lib/libgambatte/src/video/mode2_irq.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "mode2_irq.h" - -#include "ly_counter.h" -#include "lyc_irq.h" - -Mode2Irq::Mode2Irq(const LyCounter &lyCounter_in, const LycIrq &lycIrq_in, - unsigned char &ifReg_in) : - VideoEvent(0), - lyCounter(lyCounter_in), - lycIrq(lycIrq_in), - ifReg(ifReg_in) -{ -} - -void Mode2Irq::doEvent() { - const unsigned ly = lyCounter.time() - time() < 8 ? (lyCounter.ly() == 153 ? 0 : lyCounter.ly() + 1) : lyCounter.ly(); - - if (lycIrq.time() == DISABLED_TIME || (lycIrq.lycReg() != 0 && ly != (lycIrq.lycReg() + 1U)) || (lycIrq.lycReg() == 0 && ly > 1)) - ifReg |= 2; - - setTime(time() + lyCounter.lineTime()); - - if (ly == 0) - setTime(time() - 4); - else if (ly == 143) - setTime(time() + lyCounter.lineTime() * 10 + 4); -} - -unsigned long Mode2Irq::schedule(const unsigned statReg, const LyCounter &lyCounter, const unsigned long cycleCounter) { - if ((statReg & 0x28) != 0x20) - return DISABLED_TIME; - - unsigned next = lyCounter.time() - cycleCounter; - - if (lyCounter.ly() >= 143 || (lyCounter.ly() == 142 && next <= 4)) { - next += (153u - lyCounter.ly()) * lyCounter.lineTime(); - } else { - if (next <= 4) - next += lyCounter.lineTime(); - - next -= 4; - } - - return cycleCounter + next; -} diff --git a/src/lib/libgambatte/src/video/mode2_irq.h b/src/lib/libgambatte/src/video/mode2_irq.h deleted file mode 100644 index 2ea86055..00000000 --- a/src/lib/libgambatte/src/video/mode2_irq.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_MODE2_IRQ_H -#define VIDEO_MODE2_IRQ_H - -class LycIrq; - -#include "ly_counter.h" -#include "basic_add_event.h" - -class Mode2Irq : public VideoEvent { - const LyCounter &lyCounter; - const LycIrq &lycIrq; - unsigned char &ifReg; - -public: - Mode2Irq(const LyCounter &lyCounter_in, const LycIrq &lycIrq_in, - unsigned char &ifReg_in); - - void doEvent(); - static unsigned long schedule(unsigned statReg, const LyCounter &lyCounter, unsigned long cycleCounter); -}; - -#endif diff --git a/src/lib/libgambatte/src/video/mode3_event.cpp b/src/lib/libgambatte/src/video/mode3_event.cpp deleted file mode 100644 index 84502315..00000000 --- a/src/lib/libgambatte/src/video/mode3_event.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "mode3_event.h" -#include "mode0_irq.h" -#include "irq_event.h" - -Mode3Event::Mode3Event(event_queue &m3EventQueue_in, - event_queue &vEventQueue_in, - Mode0Irq &mode0Irq_in, IrqEvent &irqEvent_in) : - VideoEvent(1), - m3EventQueue(m3EventQueue_in), - vEventQueue(vEventQueue_in), - mode0Irq(mode0Irq_in), - irqEvent(irqEvent_in) -{ -} - -void Mode3Event::doEvent() { - m3EventQueue.top()->doEvent(); - - if (m3EventQueue.top()->time() == DISABLED_TIME) - m3EventQueue.pop(); - else - m3EventQueue.modify_root(m3EventQueue.top()); - - if (mode0Irq.time() != DISABLED_TIME) { - const unsigned long oldTime = mode0Irq.time(); - mode0Irq.mode3CyclesChange(); - - if (mode0Irq.time() != oldTime) { - // position in irqEventQueue should remain the same. - // The same may be possible for vEventQueue, with some precautions. - if (irqEvent.time() == oldTime) { - irqEvent.schedule(); - - if (mode0Irq.time() > oldTime) - vEventQueue.inc(&irqEvent, &irqEvent); - else - vEventQueue.dec(&irqEvent, &irqEvent); - } - - } - } - - setTime(schedule(m3EventQueue)); -} diff --git a/src/lib/libgambatte/src/video/mode3_event.h b/src/lib/libgambatte/src/video/mode3_event.h deleted file mode 100644 index 7f9aedc6..00000000 --- a/src/lib/libgambatte/src/video/mode3_event.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef MODE3_EVENT_H -#define MODE3_EVENT_H - -class Mode0Irq; -class IrqEvent; - -#include "video_event.h" -#include "video_event_comparer.h" -#include "../event_queue.h" - -class Mode3Event : public VideoEvent { - event_queue &m3EventQueue; - event_queue &vEventQueue; - Mode0Irq &mode0Irq; - IrqEvent &irqEvent; - -public: - Mode3Event(event_queue &m3EventQueue_in, - event_queue &vEventQueue_in, - Mode0Irq &mode0Irq_in, IrqEvent &irqEvent_in); - - void doEvent(); - - static unsigned long schedule(const event_queue &m3EventQueue) { - return m3EventQueue.empty() ? static_cast(DISABLED_TIME) : m3EventQueue.top()->time(); - } -}; - -#endif diff --git a/src/lib/libgambatte/src/video/sc_reader.cpp b/src/lib/libgambatte/src/video/sc_reader.cpp deleted file mode 100644 index fff2f66c..00000000 --- a/src/lib/libgambatte/src/video/sc_reader.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "sc_reader.h" - -#include "../event_queue.h" -#include "../savestate.h" - -ScReader::ScReader() : VideoEvent(2) { - setDoubleSpeed(false); - setScxSource(0); - setScySource(0); - scx_[1] = scx_[0] = scxSrc; - scy_[1] = scy_[0] = scySrc; -} - -void ScReader::doEvent() { - scy_[0] = scy_[1]; - scy_[1] = scySrc; - scx_[0] = scx_[1]; - scx_[1] = scxSrc; - - if ((scy_[0] ^ scy_[1]) | (scx_[0] ^ scx_[1])) - setTime(time() + incCycles); - else - setTime(DISABLED_TIME); - -} - -void ScReader::saveState(SaveState &state) const { - state.ppu.scx[0] = scx_[0]; - state.ppu.scx[1] = scx_[1]; - state.ppu.scy[0] = scy_[0]; - state.ppu.scy[1] = scy_[1]; -} - -void ScReader::loadState(const SaveState &state) { - scx_[0] = state.ppu.scx[0]; - scx_[1] = state.ppu.scx[1]; - scy_[0] = state.ppu.scy[0]; - scy_[1] = state.ppu.scy[1]; -} - -void ScReader::setDoubleSpeed(const bool dS_in) { - dS = dS_in; - incCycles = 8u << dS_in; -} diff --git a/src/lib/libgambatte/src/video/sc_reader.h b/src/lib/libgambatte/src/video/sc_reader.h deleted file mode 100644 index 0d7ef7d1..00000000 --- a/src/lib/libgambatte/src/video/sc_reader.h +++ /dev/null @@ -1,77 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SC_READER_H -#define SC_READER_H - -class SaveState; -template class event_queue; - -#include "video_event.h" -#include "video_event_comparer.h" -#include "basic_add_event.h" - -class ScReader : public VideoEvent { - unsigned char scx_[2]; - unsigned char scy_[2]; - - unsigned char scxSrc; - unsigned char scySrc; - unsigned char incCycles; - bool dS; - -public: - ScReader(); - - void doEvent(); - - unsigned scx() const { - return /*(*/scx_[0]/* & ~0x7) | (scxSrc & 0x7)*/; - } - - unsigned scy() const { - return scy_[0]; - } - - static unsigned long schedule(const unsigned long lastUpdate, const unsigned long videoCycles, const unsigned scReadOffset, const bool dS) { - return lastUpdate + ((8u - ((videoCycles - scReadOffset) & 7)) << dS); - } - - void setDoubleSpeed(bool dS_in); - - void setScxSource(const unsigned scxSrc_in) { - scxSrc = scxSrc_in; - } - - void setScySource(const unsigned scySrc_in) { - scySrc = scySrc_in; - } - - void saveState(SaveState &state) const; - void loadState(const SaveState &state); -}; - -static inline void addEvent(event_queue &q, ScReader *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, ScReader *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/scx_reader.cpp b/src/lib/libgambatte/src/video/scx_reader.cpp deleted file mode 100644 index 6baa97f9..00000000 --- a/src/lib/libgambatte/src/video/scx_reader.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "scx_reader.h" - -#include "../event_queue.h" -#include "m3_extra_cycles.h" -#include "../savestate.h" - -ScxReader::ScxReader(event_queue &m3EventQueue_in, -// VideoEvent &wyReader3_in, - VideoEvent &wxReader_in, - VideoEvent &weEnableChecker_in, - VideoEvent &weDisableChecker_in, - M3ExtraCycles &m3ExtraCycles) : - VideoEvent(1), - m3EventQueue(m3EventQueue_in), -// wyReader3(wyReader3_in), - wxReader(wxReader_in), - weEnableChecker(weEnableChecker_in), - weDisableChecker(weDisableChecker_in), - m3ExtraCycles(m3ExtraCycles) -{ - setDoubleSpeed(false); - setSource(0); - scxAnd7_ = src; -} - -static void rescheduleEvent(event_queue &m3EventQueue, VideoEvent& event, const unsigned long diff) { - if (event.time() != VideoEvent::DISABLED_TIME) { - event.setTime(event.time() + diff); - (diff & 0x10) ? m3EventQueue.dec(&event, &event) : m3EventQueue.inc(&event, &event); - } -} - -void ScxReader::doEvent() { - const unsigned long diff = (static_cast(src) - static_cast(scxAnd7_)) << dS; - scxAnd7_ = src; - -// rescheduleEvent(m3EventQueue, wyReader3, diff); - rescheduleEvent(m3EventQueue, wxReader, diff); - rescheduleEvent(m3EventQueue, weEnableChecker, diff); - rescheduleEvent(m3EventQueue, weDisableChecker, diff); - - m3ExtraCycles.invalidateCache(); - - setTime(DISABLED_TIME); -} - -void ScxReader::saveState(SaveState &state) const { - state.ppu.scxAnd7 = scxAnd7_; -} - -void ScxReader::loadState(const SaveState &state) { - scxAnd7_ = state.ppu.scxAnd7; -} diff --git a/src/lib/libgambatte/src/video/scx_reader.h b/src/lib/libgambatte/src/video/scx_reader.h deleted file mode 100644 index f92f8b2b..00000000 --- a/src/lib/libgambatte/src/video/scx_reader.h +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SCX_READER_H -#define SCX_READER_H - -template class event_queue; -class M3ExtraCycles; -class SaveState; - -#include "video_event.h" -#include "video_event_comparer.h" -#include "ly_counter.h" -#include "basic_add_event.h" - -class ScxReader : public VideoEvent { - event_queue &m3EventQueue; -// VideoEvent &wyReader3; - VideoEvent &wxReader; - VideoEvent &weEnableChecker; - VideoEvent &weDisableChecker; - M3ExtraCycles &m3ExtraCycles; - - unsigned char scxAnd7_; - unsigned char src; - bool dS; - -public: - ScxReader(event_queue &m3EventQueue_in, -// VideoEvent &wyReader3_in, - VideoEvent &wxReader_in, - VideoEvent &weEnableChecker_in, - VideoEvent &weDisableChecker_in, - M3ExtraCycles &m3ExtraCycles); - - void doEvent(); - - unsigned getSource() const { - return src; - } - - static unsigned long schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) { - return lyCounter.nextLineCycle(82 + lyCounter.isDoubleSpeed() * 3, cycleCounter); - } - - unsigned scxAnd7() const { - return scxAnd7_; - } - - void setDoubleSpeed(const bool dS_in) { - dS = dS_in; - } - - void setSource(const unsigned scxSrc) { - src = scxSrc & 7; - } - - void saveState(SaveState &state) const; - void loadState(const SaveState &state); -}; - -static inline void addEvent(event_queue &q, ScxReader *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, ScxReader *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/sprite_mapper.cpp b/src/lib/libgambatte/src/video/sprite_mapper.cpp deleted file mode 100644 index f1e9cd97..00000000 --- a/src/lib/libgambatte/src/video/sprite_mapper.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre AamÃ¥s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "sprite_mapper.h" -#include "m3_extra_cycles.h" -#include "../insertion_sort.h" -#include - -#include - -SpriteMapper::OamReader::OamReader(const LyCounter &lyCounter, const unsigned char *oamram) -: lyCounter(lyCounter), oamram(oamram) { - reset(oamram); -} - -void SpriteMapper::OamReader::reset(const unsigned char *const oamram) { - this->oamram = oamram; - setLargeSpritesSrc(false); - lu = 0; - lastChange = 0xFF; - std::fill_n(szbuf, 40, largeSpritesSrc); - - unsigned pos = 0; - unsigned distance = 80; - - while (distance--) { - buf[pos] = oamram[((pos * 2) & ~3) | (pos & 1)]; - ++pos; - } -} - -static unsigned toPosCycles(const unsigned long cc, const LyCounter &lyCounter) { - unsigned lc = lyCounter.lineCycles(cc) + 4 - lyCounter.isDoubleSpeed() * 3u; - - if (lc >= 456) - lc -= 456; - - return lc >> 1; -} - -void SpriteMapper::OamReader::update(const unsigned long cc) { - if (cc > lu) { - if (changed()) { - const unsigned lulc = toPosCycles(lu, lyCounter); - - unsigned pos = std::min(lulc, 40u); - unsigned distance = 40; - - if ((cc - lu) >> lyCounter.isDoubleSpeed() < 456) { - const unsigned cclc = toPosCycles(cc, lyCounter); - - distance = std::min(cclc, 40u) - pos + (cclc < lulc ? 40 : 0); - } - - { - const unsigned targetDistance = lastChange - pos + (lastChange <= pos ? 40 : 0); - - if (targetDistance <= distance) { - distance = targetDistance; - lastChange = 0xFF; - } - } - - while (distance--) { - if (pos >= 40) - pos = 0; - - szbuf[pos] = largeSpritesSrc; - buf[pos * 2] = oamram[pos * 4]; - buf[pos * 2 + 1] = oamram[pos * 4 + 1]; - - ++pos; - } - } - - lu = cc; - } -} - -void SpriteMapper::OamReader::change(const unsigned long cc) { - update(cc); - lastChange = std::min(toPosCycles(lu, lyCounter), 40u); -} - -void SpriteMapper::OamReader::setStatePtrs(SaveState &state) { - state.ppu.oamReaderBuf.set(buf, sizeof buf); - state.ppu.oamReaderSzbuf.set(szbuf, sizeof(szbuf) / sizeof(bool)); -} - -void SpriteMapper::OamReader::enableDisplay(const unsigned long cc) { - std::memset(buf, 0x00, sizeof(buf)); - std::fill(szbuf, szbuf + 40, false); - lu = cc + 160; - lastChange = 40; -} - -bool SpriteMapper::OamReader::oamAccessible(const unsigned long cycleCounter, const M3ExtraCycles &m3ExtraCycles) const { - unsigned ly = lyCounter.ly(); - unsigned lc = lyCounter.lineCycles(cycleCounter) + 4 - lyCounter.isDoubleSpeed() * 3u; - - if (lc >= 456) { - lc -= 456; - ++ly; - } - - return cycleCounter < lu || ly >= 144 || lc >= 80 + 173 + m3ExtraCycles(ly); -} - -SpriteMapper::SpriteMapper(M3ExtraCycles &m3ExtraCycles, - const LyCounter &lyCounter, - const unsigned char *const oamram) : - VideoEvent(2), - m3ExtraCycles(m3ExtraCycles), - oamReader(lyCounter, oamram), - cgb(false) -{ - clearMap(); -} - -void SpriteMapper::reset(const unsigned char *const oamram, const bool cgb_in) { - oamReader.reset(oamram); - cgb = cgb_in; - clearMap(); -} - -void SpriteMapper::clearMap() { - std::memset(num, cgb ? 0 : NEED_SORTING_MASK, sizeof(num)); -} - -void SpriteMapper::mapSprites() { - clearMap(); - - for (unsigned i = 0x00; i < 0x50; i += 2) { - const unsigned spriteHeight = 8u << largeSprites(i >> 1); - const unsigned bottom_pos = posbuf()[i] - (17u - spriteHeight); - - if (bottom_pos >= 143 + spriteHeight) - continue; - - unsigned char *map = spritemap; - unsigned char *n = num; - - if (bottom_pos >= spriteHeight) { - const unsigned startly = bottom_pos + 1 - spriteHeight; - n += startly; - map += startly * 10; - } - - unsigned char *const end = num + (bottom_pos >= 143 ? 143 : bottom_pos); - - do { - if ((*n & ~NEED_SORTING_MASK) < 10) - map[(*n)++ & ~NEED_SORTING_MASK] = i; - - map += 10; - ++n; - } while (n <= end); - } - - m3ExtraCycles.invalidateCache(); -} - -void SpriteMapper::sortLine(const unsigned ly) const { - num[ly] &= ~NEED_SORTING_MASK; - insertionSort(spritemap + ly * 10, spritemap + ly * 10 + num[ly], SpxLess(posbuf())); -} - -void SpriteMapper::doEvent() { - oamReader.update(time()); - mapSprites(); - setTime(oamReader.changed() ? time() + oamReader.lyCounter.lineTime() : static_cast(DISABLED_TIME)); -} diff --git a/src/lib/libgambatte/src/video/sprite_mapper.h b/src/lib/libgambatte/src/video/sprite_mapper.h deleted file mode 100644 index 25b8090b..00000000 --- a/src/lib/libgambatte/src/video/sprite_mapper.h +++ /dev/null @@ -1,148 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef SPRITE_MAPPER_H -#define SPRITE_MAPPER_H - -#include "video_event.h" -//#include "video_event_comparer.h" -#include "ly_counter.h" -#include "basic_add_event.h" -#include "../savestate.h" - -class M3ExtraCycles; -class SaveState; - -class SpriteMapper : public VideoEvent { - class OamReader { - unsigned char buf[80]; - bool szbuf[40]; - - public: - const LyCounter &lyCounter; - - private: - const unsigned char *oamram; - unsigned long lu; - unsigned char lastChange; - bool largeSpritesSrc; - - public: - OamReader(const LyCounter &lyCounter, const unsigned char *oamram); - void reset(const unsigned char *oamram); - void change(unsigned long cc); - void change(const unsigned char *oamram, unsigned long cc) { change(cc); this->oamram = oamram; } - bool changed() const { return lastChange != 0xFF; } - bool largeSprites(unsigned spNr) const { return szbuf[spNr]; } - const unsigned char *oam() const { return oamram; } - void resetCycleCounter(const unsigned long oldCc, const unsigned long newCc) { lu = lu + newCc - oldCc; } - void setLargeSpritesSrc(const bool src) { largeSpritesSrc = src; } - void update(unsigned long cc); - const unsigned char *spritePosBuf() const { return buf; } - void setStatePtrs(SaveState &state); - void enableDisplay(unsigned long cc); - void saveState(SaveState &state) const { state.ppu.enableDisplayM0Time = lu; } - void loadState(const SaveState &state) { lu = state.ppu.enableDisplayM0Time; } - void resetVideoState() { change(lu); } - bool oamAccessible(unsigned long cycleCounter, const M3ExtraCycles &m3ExtraCycles) const; - bool inactivePeriodAfterDisplayEnable(const unsigned long cc) const { return cc < lu; } - }; - - enum { NEED_SORTING_MASK = 0x80 }; - -public: - class SpxLess { - const unsigned char *const posbuf_plus1; - - public: - SpxLess(const unsigned char *const posbuf) : posbuf_plus1(posbuf + 1) {} - - bool operator()(const unsigned char l, const unsigned char r) const { - return posbuf_plus1[l] < posbuf_plus1[r]; - } - }; - -private: - mutable unsigned char spritemap[144*10]; - mutable unsigned char num[144]; - - M3ExtraCycles &m3ExtraCycles; - OamReader oamReader; - - bool cgb; - - void clearMap(); - void mapSprites(); - void sortLine(unsigned ly) const; - -public: - SpriteMapper(M3ExtraCycles &m3ExtraCycles, - const LyCounter &lyCounter, - const unsigned char *oamram_in); - void reset(const unsigned char *oamram, bool cgb_in); - void doEvent(); - bool isCgb() const { return cgb; } - bool largeSprites(unsigned spNr) const { return oamReader.largeSprites(spNr); } - unsigned numSprites(const unsigned ly) const { return num[ly] & ~NEED_SORTING_MASK; } - void oamChange(const unsigned long cc) { oamReader.change(cc); } - void oamChange(const unsigned char *oamram, const unsigned long cc) { oamReader.change(oamram, cc); } - const unsigned char *oamram() const { return oamReader.oam(); } - const unsigned char *posbuf() const { return oamReader.spritePosBuf(); } - void preCounterChange(const unsigned long cc) { oamReader.update(cc); } - - void resetCycleCounter(const unsigned long oldCc, const unsigned long newCc) { - oamReader.resetCycleCounter(oldCc, newCc); - } - - static unsigned long schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) { - return lyCounter.nextLineCycle(80, cycleCounter); - } - - void setLargeSpritesSource(const bool src) { oamReader.setLargeSpritesSrc(src); } - - const unsigned char* sprites(const unsigned ly) const { - if (num[ly] & NEED_SORTING_MASK) - sortLine(ly); - - return spritemap + ly * 10; - } - - void setStatePtrs(SaveState &state) { oamReader.setStatePtrs(state); } - void enableDisplay(unsigned long cc) { oamReader.enableDisplay(cc); } - void saveState(SaveState &state) const { oamReader.saveState(state); } - void loadState(const SaveState &state) { oamReader.loadState(state); } - void resetVideoState() { oamReader.resetVideoState(); } - - bool oamAccessible(unsigned long cycleCounter) const { - return oamReader.oamAccessible(cycleCounter, m3ExtraCycles); - } - - bool inactivePeriodAfterDisplayEnable(const unsigned long cc) const { - return oamReader.inactivePeriodAfterDisplayEnable(cc); - } -}; - -static inline void addEvent(event_queue &q, SpriteMapper *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, SpriteMapper *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/video_event.h b/src/lib/libgambatte/src/video/video_event.h deleted file mode 100644 index fb64d5b2..00000000 --- a/src/lib/libgambatte/src/video/video_event.h +++ /dev/null @@ -1,50 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_EVENT_H -#define VIDEO_EVENT_H - -class VideoEvent { - unsigned long time_; - const unsigned char priority_; - -public: - enum { DISABLED_TIME = 0xFFFFFFFFu }; - - VideoEvent(const unsigned priority_in) : - time_(DISABLED_TIME), - priority_(priority_in) - {} - - virtual ~VideoEvent() {} - virtual void doEvent() = 0; - - unsigned priority() const { - return priority_; - } - - unsigned long time() const { - return time_; - } - - void setTime(const unsigned long time_in) { - time_ = time_in; - } -}; - -#endif diff --git a/src/lib/libgambatte/src/video/video_event_comparer.h b/src/lib/libgambatte/src/video/video_event_comparer.h deleted file mode 100644 index 4eb25969..00000000 --- a/src/lib/libgambatte/src/video/video_event_comparer.h +++ /dev/null @@ -1,31 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef VIDEO_EVENT_COMPARER_H -#define VIDEO_EVENT_COMPARER_H - -#include "video_event.h" - -class VideoEventComparer { -public: - bool less(const VideoEvent *const a, const VideoEvent *const b) const { - return a->time() < b->time() || (a->time() == b->time() && a->priority() < b->priority()); - } -}; - -#endif diff --git a/src/lib/libgambatte/src/video/we.cpp b/src/lib/libgambatte/src/video/we.cpp deleted file mode 100644 index d5e66c47..00000000 --- a/src/lib/libgambatte/src/video/we.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "we.h" -#include "../savestate.h" - -We::WeEnableChecker::WeEnableChecker(We &we) : - VideoEvent(8), - we(we) -{} - -void We::WeEnableChecker::doEvent() { - we.set(we.src_); - - setTime(DISABLED_TIME); -} - -We::WeDisableChecker::WeDisableChecker(We &we) : - VideoEvent(9), - we(we) -{} - -void We::WeDisableChecker::doEvent() { - we.set(we.we_ & we.src_); - - setTime(DISABLED_TIME); -} - -We::We(M3ExtraCycles &m3ExtraCycles) : - m3ExtraCycles_(m3ExtraCycles), - enableChecker_(*this), - disableChecker_(*this) -{ - setSource(false); - we_ = src_; -} - -void We::saveState(SaveState &state) const { - state.ppu.lcdc = (state.ppu.lcdc & ~0x20) | we_ << 5; -} - -void We::loadState(const SaveState &state) { - we_ = state.ppu.lcdc >> 5 & 1; -} diff --git a/src/lib/libgambatte/src/video/we.h b/src/lib/libgambatte/src/video/we.h deleted file mode 100644 index d800ca11..00000000 --- a/src/lib/libgambatte/src/video/we.h +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef WE_H -#define WE_H - -class SaveState; - -#include "video_event.h" -#include "ly_counter.h" -#include "m3_extra_cycles.h" -#include "basic_add_event.h" - -class We { -public: - class WeEnableChecker : public VideoEvent { - We &we; - - public: - WeEnableChecker(We &we); - - void doEvent(); - - static unsigned long schedule(const unsigned scxAnd7, const unsigned wx, const LyCounter &lyCounter, const unsigned long cycleCounter) { - return lyCounter.nextLineCycle(scxAnd7 + 82 + wx + lyCounter.isDoubleSpeed() * 3, cycleCounter); - } - }; - - class WeDisableChecker : public VideoEvent { - We &we; - - public: - WeDisableChecker(We &we); - - void doEvent(); - - static unsigned long schedule(const unsigned scxAnd7, const unsigned wx, const LyCounter &lyCounter, const unsigned long cycleCounter) { - return lyCounter.nextLineCycle(scxAnd7 + 88 + wx + lyCounter.isDoubleSpeed() * 3, cycleCounter); - } - }; - - friend class WeEnableChecker; - friend class WeDisableChecker; - -private: - M3ExtraCycles &m3ExtraCycles_; - WeEnableChecker enableChecker_; - WeDisableChecker disableChecker_; - - bool we_; - bool src_; - - void set(const bool value) { - if (we_ != value) - m3ExtraCycles_.invalidateCache(); - - we_ = value; - } - -public: - We(M3ExtraCycles &m3ExtraCycles); - - WeDisableChecker& disableChecker() { - return disableChecker_; - } - - WeEnableChecker& enableChecker() { - return enableChecker_; - } - - bool getSource() const { - return src_; - } - - void setSource(const bool src) { - src_ = src; - } - - bool value() const { - return we_; - } - - void saveState(SaveState &state) const; - void loadState(const SaveState &state); -}; - -static inline void addEvent(event_queue &q, We::WeEnableChecker *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, We::WeEnableChecker *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -static inline void addEvent(event_queue &q, We::WeDisableChecker *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, We::WeDisableChecker *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/we_master_checker.cpp b/src/lib/libgambatte/src/video/we_master_checker.cpp deleted file mode 100644 index bff81585..00000000 --- a/src/lib/libgambatte/src/video/we_master_checker.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "we_master_checker.h" - -#include "event_queue.h" -#include "wy.h" -#include "basic_add_event.h" -#include "../savestate.h" - -WeMasterChecker::WeMasterChecker(event_queue &m3EventQueue_in, - Wy &wy_in, - const LyCounter &lyCounter_in, - M3ExtraCycles &m3ExtraCycles) : - VideoEvent(10), - m3EventQueue(m3EventQueue_in), - wy(wy_in), - lyCounter(lyCounter_in), - m3ExtraCycles(m3ExtraCycles) -{ - weMaster_ = false; -} - -void WeMasterChecker::doEvent() { -// if (wy.value() >= lyCounter.ly()) { - if (!weMaster_ /*&& src */&& wy.value() == lyCounter.ly()) { - wy.weirdAssWeMasterEnableOnWyLineCase(); - addEvent(m3EventQueue, &wy.reader4(), Wy::WyReader4::schedule(lyCounter, time())); - } - - set(true); -// } - - setTime(time() + (70224U << lyCounter.isDoubleSpeed())); -} - -void WeMasterChecker::saveState(SaveState &state) const { - state.ppu.weMaster = weMaster_; -} - -void WeMasterChecker::loadState(const SaveState &state) { - weMaster_ = state.ppu.weMaster; -} diff --git a/src/lib/libgambatte/src/video/we_master_checker.h b/src/lib/libgambatte/src/video/we_master_checker.h deleted file mode 100644 index cf1f1209..00000000 --- a/src/lib/libgambatte/src/video/we_master_checker.h +++ /dev/null @@ -1,73 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef WE_MASTER_CHECKER_H -#define WE_MASTER_CHECKER_H - -template class event_queue; -class Wy; -class SaveState; - -#include "video_event.h" -#include "video_event_comparer.h" -#include "ly_counter.h" -#include "m3_extra_cycles.h" - -class WeMasterChecker : public VideoEvent { - event_queue &m3EventQueue; - Wy &wy; - const LyCounter &lyCounter; - M3ExtraCycles &m3ExtraCycles; - - bool weMaster_; - - void set(const bool value) { - if (weMaster_ != value) - m3ExtraCycles.invalidateCache(); - - weMaster_ = value; - } - -public: - WeMasterChecker(event_queue &m3EventQueue_in, - Wy &wy_in, - const LyCounter &lyCounter_in, - M3ExtraCycles &m3ExtraCycles); - - void doEvent(); - - static unsigned long schedule(const unsigned wySrc, const bool weSrc, const LyCounter &lyCounter, const unsigned long cycleCounter) { - if (weSrc && wySrc < 143) - return lyCounter.nextFrameCycle(wySrc * 456ul + 448 + lyCounter.isDoubleSpeed() * 4, cycleCounter); - else - return DISABLED_TIME; - } - - void unset() { - set(false); - } - - bool weMaster() const { - return weMaster_; - } - - void saveState(SaveState &state) const; - void loadState(const SaveState &state); -}; - -#endif diff --git a/src/lib/libgambatte/src/video/window.h b/src/lib/libgambatte/src/video/window.h deleted file mode 100644 index 790d612c..00000000 --- a/src/lib/libgambatte/src/video/window.h +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef WINDOW_H -#define WINDOW_H - -#include "we.h" -#include "we_master_checker.h" -#include "wy.h" -#include "wx_reader.h" - -struct Window { - We we; - WeMasterChecker weMasterChecker; - Wy wyReg; - WxReader wxReader; - - Window(event_queue &m3EventQueue, - const LyCounter &lyCounter, - M3ExtraCycles &m3ExtraCycles) : - we(m3ExtraCycles), - weMasterChecker(m3EventQueue, wyReg, lyCounter, m3ExtraCycles), - wyReg(lyCounter, weMasterChecker, m3ExtraCycles), - wxReader(m3EventQueue, we.enableChecker(), we.disableChecker(), m3ExtraCycles) - {} - - bool enabled(const unsigned ly) const { - return we.value() && wxReader.wx() < 0xA7 && ly >= wyReg.value() && (weMasterChecker.weMaster() || ly == wyReg.value()); - } -}; - -#endif /*WINDOW_H*/ diff --git a/src/lib/libgambatte/src/video/wx_reader.cpp b/src/lib/libgambatte/src/video/wx_reader.cpp deleted file mode 100644 index 80a6b640..00000000 --- a/src/lib/libgambatte/src/video/wx_reader.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aam�s * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "wx_reader.h" - -#include "../event_queue.h" -#include "m3_extra_cycles.h" -#include "../savestate.h" - -WxReader::WxReader(event_queue &m3EventQueue, - VideoEvent &weEnableChecker, - VideoEvent &weDisableChecker, - M3ExtraCycles &m3ExtraCycles) : -VideoEvent(7), -m3EventQueue(m3EventQueue), -weEnableChecker(weEnableChecker), -weDisableChecker(weDisableChecker), -m3ExtraCycles(m3ExtraCycles) -{ - setDoubleSpeed(false); - setSource(0); - wx_ = src_; -} - -static void rescheduleEvent(event_queue &m3EventQueue, VideoEvent& event, const unsigned long diff) { - if (event.time() != VideoEvent::DISABLED_TIME) { - event.setTime(event.time() + diff); - (diff & 0x200) ? m3EventQueue.dec(&event, &event) : m3EventQueue.inc(&event, &event); - } -} - -void WxReader::doEvent() { - const unsigned long diff = (static_cast(src_) - static_cast(wx_)) << dS; - wx_ = src_; - - rescheduleEvent(m3EventQueue, weEnableChecker, diff); - rescheduleEvent(m3EventQueue, weDisableChecker, diff); - - m3ExtraCycles.invalidateCache(); - - setTime(DISABLED_TIME); -} - -void WxReader::saveState(SaveState &state) const { - state.ppu.wx = wx_; -} - -void WxReader::loadState(const SaveState &state) { - wx_ = state.ppu.wx; -} diff --git a/src/lib/libgambatte/src/video/wx_reader.h b/src/lib/libgambatte/src/video/wx_reader.h deleted file mode 100644 index 1681f8a4..00000000 --- a/src/lib/libgambatte/src/video/wx_reader.h +++ /dev/null @@ -1,83 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef WX_READER_H -#define WX_READER_H - -template class event_queue; -class M3ExtraCycles; -class SaveState; - -#include "video_event.h" -#include "video_event_comparer.h" -#include "ly_counter.h" -#include "basic_add_event.h" -#include - -class WxReader : public VideoEvent { - event_queue &m3EventQueue; - VideoEvent &weEnableChecker; - VideoEvent &weDisableChecker; - M3ExtraCycles &m3ExtraCycles; - - unsigned char wx_; - unsigned char src_; - bool dS; - -public: - WxReader(event_queue &m3EventQueue_in, - VideoEvent &weEnableChecker_in, - VideoEvent &weDisableChecker_in, - M3ExtraCycles &m3ExtraCycles); - - void doEvent(); - - unsigned getSource() const { - return src_; - } - - unsigned wx() const { - return wx_; - } - - void setDoubleSpeed(const bool dS_in) { - dS = dS_in; - } - - void setSource(const unsigned src) { - src_ = src; - } - - static unsigned long schedule(const unsigned scxAnd7, const LyCounter &lyCounter, const WxReader &wxReader, const unsigned long cycleCounter) { - return lyCounter.nextLineCycle(scxAnd7 + 82 + lyCounter.isDoubleSpeed() * 3 + std::min(wxReader.getSource(), wxReader.wx()), cycleCounter); - //setTime(lyCounter.nextLineCycle(scxAnd7 + 89 + lyCounter.isDoubleSpeed() * 3, cycleCounter)); - } - - void saveState(SaveState &state) const; - void loadState(const SaveState &state); -}; - -static inline void addEvent(event_queue &q, WxReader *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, WxReader *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/libgambatte/src/video/wy.cpp b/src/lib/libgambatte/src/video/wy.cpp deleted file mode 100644 index 64a5f725..00000000 --- a/src/lib/libgambatte/src/video/wy.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#include "wy.h" - -#include "we_master_checker.h" -#include "scx_reader.h" -#include "../event_queue.h" -#include "../savestate.h" - -Wy::WyReader1::WyReader1(Wy &wy, const WeMasterChecker &weMasterChecker) : - VideoEvent(3), - wy(wy), - weMasterChecker(weMasterChecker) -{} - -void Wy::WyReader1::doEvent() { - if (wy.src_ >= wy.lyCounter.ly() && /*wy >= lyCounter.ly()*/ !weMasterChecker.weMaster()) - wy.set(wy.src_); - - setTime(DISABLED_TIME); -} - -Wy::WyReader2::WyReader2(Wy &wy) : - VideoEvent(4), - wy(wy) -{} - -void Wy::WyReader2::doEvent() { - if (wy.wy_ == wy.lyCounter.ly() + 1 - wy.lyCounter.isDoubleSpeed() && wy.src_ > wy.wy_) - wy.set(wy.src_); - - setTime(DISABLED_TIME); -} - -Wy::WyReader3::WyReader3(Wy &wy) : - VideoEvent(5), - wy(wy) -{} - -void Wy::WyReader3::doEvent() { - if (wy.src_ == wy.lyCounter.ly() && wy.wy_ > wy.lyCounter.ly()) - wy.set(wy.src_); - - setTime(DISABLED_TIME); -} - -unsigned long Wy::WyReader3::schedule(const unsigned wxSrc, const ScxReader &scxReader, const LyCounter &lyCounter, const unsigned long cycleCounter) { - const unsigned curLineCycle = 456 - ((lyCounter.time() - cycleCounter) >> lyCounter.isDoubleSpeed()); - const unsigned baseTime = 78 + lyCounter.isDoubleSpeed() * 6 + wxSrc; - - if (curLineCycle >= 82U + lyCounter.isDoubleSpeed() * 3) { - if (baseTime + scxReader.scxAnd7() > curLineCycle) - return lyCounter.time() + ((baseTime + scxReader.scxAnd7()) << lyCounter.isDoubleSpeed()) - lyCounter.lineTime(); - else - return lyCounter.time() + ((baseTime + scxReader.getSource()) << lyCounter.isDoubleSpeed()); - } else - return lyCounter.nextLineCycle(baseTime + scxReader.getSource(), cycleCounter); -} - -Wy::WyReader4::WyReader4(Wy &wy) : - VideoEvent(6), - wy(wy) -{} - -void Wy::WyReader4::doEvent() { - wy.set(wy.src_); - - setTime(DISABLED_TIME); -} - -Wy::Wy(const LyCounter &lyCounter, const WeMasterChecker &weMasterChecker, M3ExtraCycles &m3ExtraCycles) : - lyCounter(lyCounter), - m3ExtraCycles(m3ExtraCycles), - reader1_(*this, weMasterChecker), - reader2_(*this), - reader3_(*this), - reader4_(*this) -{ - setSource(0); - wy_ = src_; -} - -void Wy::saveState(SaveState &state) const { - state.ppu.wy = wy_; -} - -void Wy::loadState(const SaveState &state) { - wy_ = state.ppu.wy; -} diff --git a/src/lib/libgambatte/src/video/wy.h b/src/lib/libgambatte/src/video/wy.h deleted file mode 100644 index 2a1033f9..00000000 --- a/src/lib/libgambatte/src/video/wy.h +++ /dev/null @@ -1,187 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2007 by Sindre Aamås * - * aamas@stud.ntnu.no * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License version 2 as * - * published by the Free Software Foundation. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License version 2 for more details. * - * * - * You should have received a copy of the GNU General Public License * - * version 2 along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef WY_H -#define WY_H - -class WeMasterChecker; -class ScxReader; -template class event_queue; -class SaveState; - -#include "video_event.h" -#include "video_event_comparer.h" -#include "ly_counter.h" -#include "m3_extra_cycles.h" -#include "basic_add_event.h" - -class Wy { -public: - class WyReader1 : public VideoEvent { - Wy &wy; - const WeMasterChecker &weMasterChecker; - - public: - WyReader1(Wy &wy, const WeMasterChecker &weMasterChecker); - - void doEvent(); - - static unsigned long schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) { - return lyCounter.nextLineCycle(448 + lyCounter.isDoubleSpeed() * 4, cycleCounter); - } - }; - - class WyReader2 : public VideoEvent { - Wy &wy; - - public: - WyReader2(Wy &wy); - - void doEvent(); - - static unsigned long schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) { - return lyCounter.isDoubleSpeed() ? lyCounter.time() : lyCounter.nextLineCycle(452, cycleCounter); - } - }; - - class WyReader3 : public VideoEvent { - Wy &wy; - - public: - WyReader3(Wy &wy); - - void doEvent(); - static unsigned long schedule(unsigned wxSrc, const ScxReader &scxReader, const LyCounter &lyCounter, unsigned long cycleCounter); - - //void schedule(const unsigned scxAnd7, const LyCounter &lyCounter, const unsigned cycleCounter) { - // setTime(lyCounter.nextLineCycle(scxAnd7 + 85 + lyCounter.isDoubleSpeed() * 6, cycleCounter)); - //} - }; - - class WyReader4 : public VideoEvent { - Wy &wy; - - public: - WyReader4(Wy &wy); - - void doEvent(); - - static unsigned long schedule(const LyCounter &lyCounter, const unsigned long cycleCounter) { - return lyCounter.nextFrameCycle(lyCounter.isDoubleSpeed() * 4, cycleCounter); - } - }; - - friend class WyReader1; - friend class WyReader2; - friend class WyReader3; - friend class WyReader4; - -private: - const LyCounter &lyCounter; - M3ExtraCycles &m3ExtraCycles; - WyReader1 reader1_; - WyReader2 reader2_; - WyReader3 reader3_; - WyReader4 reader4_; - - unsigned char wy_; - unsigned char src_; - - void set(const unsigned char value) { - if (wy_ != value) - m3ExtraCycles.invalidateCache(); - - wy_ = value; - } - -public: - Wy(const LyCounter &lyCounter, const WeMasterChecker &weMasterChecker, M3ExtraCycles &m3ExtraCycles); - - WyReader1& reader1() { - return reader1_; - } - - WyReader2& reader2() { - return reader2_; - } - - WyReader3& reader3() { - return reader3_; - } - - WyReader4& reader4() { - return reader4_; - } - - unsigned getSource() const { - return src_; - } - - void setSource(const unsigned src) { - src_ = src; - } - - //void setValue(const unsigned val) { - // wy_ = val; - //} - - unsigned value() const { - return wy_; - } - - void weirdAssWeMasterEnableOnWyLineCase() { - set(wy_ + 1); - } - - void saveState(SaveState &state) const; - void loadState(const SaveState &state); -}; - -static inline void addEvent(event_queue &q, Wy::WyReader1 *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, Wy::WyReader1 *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -static inline void addEvent(event_queue &q, Wy::WyReader2 *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, Wy::WyReader2 *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -static inline void addEvent(event_queue &q, Wy::WyReader3 *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, Wy::WyReader3 *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -static inline void addEvent(event_queue &q, Wy::WyReader4 *const e, const unsigned long newTime) { - addUnconditionalEvent(q, e, newTime); -} - -static inline void addFixedtimeEvent(event_queue &q, Wy::WyReader4 *const e, const unsigned long newTime) { - addUnconditionalFixedtimeEvent(q, e, newTime); -} - -#endif diff --git a/src/lib/reader/filereader.cpp b/src/lib/libreader/filereader.cpp similarity index 65% rename from src/lib/reader/filereader.cpp rename to src/lib/libreader/filereader.cpp index 71913bfe..c5d13780 100644 --- a/src/lib/reader/filereader.cpp +++ b/src/lib/libreader/filereader.cpp @@ -1,9 +1,8 @@ #ifdef READER_CPP - #include "filereader.hpp" unsigned FileReader::size() { - return fp->size(); + return fp.size(); } //This function will allocate memory even if open() fails. @@ -15,38 +14,36 @@ uint8_t* FileReader::read(unsigned length) { if(length == 0) { //read the entire file into RAM - data = new(zeromemory) uint8_t[fp->size()]; - if(fp->open()) fp->read(data, fp->size()); - } else if(length > fp->size()) { + data = new(zeromemory) uint8_t[fp.size()]; + if(fp.open()) fp.read(data, fp.size()); + } else if(length > fp.size()) { //read the entire file into RAM, pad the rest with 0x00s data = new(zeromemory) uint8_t[length]; - if(fp->open()) fp->read(data, fp->size()); + if(fp.open()) fp.read(data, fp.size()); } else { //filesize >= length //read only what was requested data = new(zeromemory) uint8_t[length]; - if(fp->open()) fp->read(data, length); + if(fp.open()) fp.read(data, length); } return data; } bool FileReader::ready() { - return fp->open(); + return fp.open(); } FileReader::FileReader(const char *fn) { - fp = new file; - if(!fp->open(fn, file::mode_read)) return; + if(!fp.open(fn, file::mode_read)) return; - if(fp->size() == 0) { + if(fp.size() == 0) { //empty file - fp->close(); + fp.close(); } } FileReader::~FileReader() { - if(fp->open()) fp->close(); - delete fp; + if(fp.open()) fp.close(); } -#endif +#endif //ifdef READER_CPP diff --git a/src/lib/reader/filereader.hpp b/src/lib/libreader/filereader.hpp similarity index 73% rename from src/lib/reader/filereader.hpp rename to src/lib/libreader/filereader.hpp index e3bc17b3..c48819c1 100644 --- a/src/lib/reader/filereader.hpp +++ b/src/lib/libreader/filereader.hpp @@ -1,7 +1,3 @@ -namespace nall { - class file; -} - class FileReader : public Reader { public: unsigned size(); @@ -12,5 +8,5 @@ public: ~FileReader(); private: - nall::file *fp; + file fp; }; diff --git a/src/lib/reader/gzreader.cpp b/src/lib/libreader/gzreader.cpp similarity index 99% rename from src/lib/reader/gzreader.cpp rename to src/lib/libreader/gzreader.cpp index 3bed61d4..28e4e497 100644 --- a/src/lib/reader/gzreader.cpp +++ b/src/lib/libreader/gzreader.cpp @@ -1,5 +1,4 @@ #ifdef READER_CPP - #include "gzreader.hpp" unsigned GZReader::size() { diff --git a/src/lib/reader/gzreader.hpp b/src/lib/libreader/gzreader.hpp similarity index 100% rename from src/lib/reader/gzreader.hpp rename to src/lib/libreader/gzreader.hpp diff --git a/src/lib/reader/jmareader.cpp b/src/lib/libreader/jmareader.cpp similarity index 99% rename from src/lib/reader/jmareader.cpp rename to src/lib/libreader/jmareader.cpp index 44f72215..be65068c 100644 --- a/src/lib/reader/jmareader.cpp +++ b/src/lib/libreader/jmareader.cpp @@ -1,5 +1,4 @@ #ifdef READER_CPP - #include "jmareader.hpp" unsigned JMAReader::size() { diff --git a/src/lib/reader/jmareader.hpp b/src/lib/libreader/jmareader.hpp similarity index 100% rename from src/lib/reader/jmareader.hpp rename to src/lib/libreader/jmareader.hpp diff --git a/src/lib/reader/reader.cpp b/src/lib/libreader/libreader.cpp similarity index 94% rename from src/lib/reader/reader.cpp rename to src/lib/libreader/libreader.cpp index 035c7129..1d674222 100644 --- a/src/lib/reader/reader.cpp +++ b/src/lib/libreader/libreader.cpp @@ -1,7 +1,6 @@ -#include <../base.hpp> +#include "libreader.hpp" #define READER_CPP -#include "reader.hpp" #include "filereader.cpp" #if defined(GZIP_SUPPORT) diff --git a/src/lib/reader/reader.hpp b/src/lib/libreader/libreader.hpp similarity index 50% rename from src/lib/reader/reader.hpp rename to src/lib/libreader/libreader.hpp index 1dd19448..77540ce8 100644 --- a/src/lib/reader/reader.hpp +++ b/src/lib/libreader/libreader.hpp @@ -1,3 +1,9 @@ +#include +#include +#include +#include +using namespace nall; + class Reader { public: enum Type { @@ -11,5 +17,5 @@ public: static Type detect(const char *fn, bool inspectheader); virtual unsigned size() = 0; virtual uint8_t* read(unsigned length = 0) = 0; - virtual bool ready() { return true; } //can only call read() when ready() returns true + virtual bool ready() { return true; } //can only call read() when ready() returns true }; diff --git a/src/lib/reader/zipreader.cpp b/src/lib/libreader/zipreader.cpp similarity index 99% rename from src/lib/reader/zipreader.cpp rename to src/lib/libreader/zipreader.cpp index ea35dbd1..9484398b 100644 --- a/src/lib/reader/zipreader.cpp +++ b/src/lib/libreader/zipreader.cpp @@ -1,5 +1,4 @@ #ifdef READER_CPP - #include "zipreader.hpp" unsigned ZipReader::size() { diff --git a/src/lib/reader/zipreader.hpp b/src/lib/libreader/zipreader.hpp similarity index 100% rename from src/lib/reader/zipreader.hpp rename to src/lib/libreader/zipreader.hpp diff --git a/src/lib/nall/Makefile.string b/src/lib/nall/Makefile similarity index 62% rename from src/lib/nall/Makefile.string rename to src/lib/nall/Makefile index 0de1db25..82dc00a5 100644 --- a/src/lib/nall/Makefile.string +++ b/src/lib/nall/Makefile @@ -1,4 +1,4 @@ -# Makefile.string +# Makefile # author: byuu # license: public domain @@ -7,9 +7,49 @@ [0-9] = 0 1 2 3 4 5 6 7 8 9 [markup] = ` ~ ! @ \# $$ % ^ & * ( ) - _ = + [ { ] } \ | ; : ' " , < . > / ? [all] = $([A-Z]) $([a-z]) $([0-9]) $([markup]) -[space] := +[space] := [space] += +##### +# platform detection +##### + +ifeq ($(platform),) + uname := $(shell uname -a) + ifeq ($(uname),) + platform := win + delete = del $(subst /,\,$1) + else ifneq ($(findstring Darwin,$(uname)),) + platform := osx + delete = rm -f $1 + else + platform := x + delete = rm -f $1 + endif +endif + +ifeq ($(compiler),) + compiler := gcc +endif + +ifeq ($(prefix),) + prefix := /usr/local +endif + +##### +# function rwildcard(directory, pattern) +##### +rwildcard = \ + $(strip \ + $(filter $(if $2,$2,%), \ + $(foreach f, \ + $(wildcard $1*), \ + $(eval t = $(call rwildcard,$f/)) \ + $(if $t,$t,$f) \ + ) \ + ) \ + ) + ##### # function strtr(source, from, to) ##### @@ -61,3 +101,9 @@ streq = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),,1) # function strne(source) ##### strne = $(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),1,) + +##### +# function ifhas(needle, haystack, true, false) +##### +ifhas = $(if $(findstring $1,$2),$3,$4) + diff --git a/src/lib/nall/datasource.hpp b/src/lib/nall/datasource.hpp deleted file mode 100644 index f7529de0..00000000 --- a/src/lib/nall/datasource.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef NALL_DATASOURCE_HPP -#define NALL_DATASOURCE_HPP - -#include -#include -#include -#include - -namespace nall { - struct datasource : public property { - enum source_t { disk, memory }; - - property_t source; - property_t name; - property_t data; - property_t size; - - datasource(const char *name_) { - set(source, disk); - set(name, strdup(name_)); - set(data, (uint8_t*)0); - set(size, file::size(name_)); - } - - datasource(uint8_t *data_, unsigned size_) { - set(source, memory); - set(name, (char*)0); - set(data, data_); - set(size, size_); - } - - ~datasource() { - if(name()) free(name()); - } - }; -} - -#endif diff --git a/src/lib/nall/dl.hpp b/src/lib/nall/dl.hpp new file mode 100644 index 00000000..13cd69eb --- /dev/null +++ b/src/lib/nall/dl.hpp @@ -0,0 +1,81 @@ +#ifndef NALL_DL_HPP +#define NALL_DL_HPP + +//dynamic linking support + +#include +#include +#include +#include + +#if defined(PLATFORM_X) + #include +#elif defined(PLATFORM_WIN) + #include + #include +#endif + +namespace nall { + struct library : noncopyable { + bool open(const char*); + void* sym(const char*); + void close(); + + library() : handle(0) {} + ~library() { close(); } + + private: + uintptr_t handle; + }; + + #if defined(PLATFORM_X) + inline bool library::open(const char *name) { + if(handle) close(); + char *t = new char[strlen(name) + 8]; + strcpy(t, "lib"); + strcat(t, name); + strcat(t, ".so"); + handle = (uintptr_t)dlopen(t, RTLD_LAZY); + delete[] t; + return handle; + } + + inline void* library::sym(const char *name) { + if(!handle) return 0; + return dlsym((void*)handle, name); + } + + inline void library::close() { + if(!handle) return; + dlclose((void*)handle); + handle = 0; + } + #elif defined(PLATFORM_WIN) + inline bool library::open(const char *name) { + if(handle) close(); + char *t = new char[strlen(name) + 8]; + strcpy(t, name); + strcat(t, ".dll"); + handle = (uintptr_t)LoadLibraryW(utf16_t(t)); + delete[] t; + return handle; + } + + inline void* library::sym(const char *name) { + if(!handle) return 0; + return (void*)GetProcAddress((HMODULE)handle, name); + } + + inline void library::close() { + if(!handle) return; + FreeLibrary((HMODULE)handle); + handle = 0; + } + #else + inline bool library::open(const char*) { return false; } + inline void* library::sym(const char*) { return 0; } + inline void library::close() {} + #endif +}; + +#endif diff --git a/src/lib/nall/function.hpp b/src/lib/nall/function.hpp index 9e90cb1d..dfd66ee3 100644 --- a/src/lib/nall/function.hpp +++ b/src/lib/nall/function.hpp @@ -133,7 +133,12 @@ namespace nall { R operator()(PL) const { return data.fn_call(data cat(CL)); } operator bool() const { return data.fn_call; } - function() { data.fn_call = 0; } + function() { data.fn_call = 0; } + + function(void *fn) { + data.fn_call = &fn_call_global; + data.fn_global = (R (*)(PL))fn; + } function(R (*fn)(PL)) { data.fn_call = &fn_call_global; @@ -155,8 +160,9 @@ namespace nall { assert(sizeof data.fn_member >= sizeof fn); data.object = obj; } - - function &operator=(const function &source) { memcpy(&data, &source.data, sizeof(data_t)); return *this; } + + 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)); } }; diff --git a/src/lib/nall/platform.hpp b/src/lib/nall/platform.hpp index 1cc74bea..3fe3c7a0 100644 --- a/src/lib/nall/platform.hpp +++ b/src/lib/nall/platform.hpp @@ -74,3 +74,4 @@ #endif #endif + diff --git a/src/memory/memory.cpp b/src/memory/memory.cpp index b198ae0b..326efe92 100644 --- a/src/memory/memory.cpp +++ b/src/memory/memory.cpp @@ -109,3 +109,4 @@ void Bus::map( } }; + diff --git a/src/memory/memory.hpp b/src/memory/memory.hpp index 5e33df03..7d58e154 100644 --- a/src/memory/memory.hpp +++ b/src/memory/memory.hpp @@ -20,39 +20,51 @@ struct UnmappedMMIO : MMIO { }; struct StaticRAM : Memory { - uint8* handle() { return data; } - unsigned size() const { return datasize; } + uint8* data() { return data_; } + unsigned size() const { return size_; } - inline uint8 read(unsigned addr) { return data[addr]; } - inline void write(unsigned addr, uint8 n) { data[addr] = n; } - inline uint8& operator[](unsigned addr) { return data[addr]; } - inline const uint8& operator[](unsigned addr) const { return data[addr]; } + inline uint8 read(unsigned addr) { return data_[addr]; } + inline void write(unsigned addr, uint8 n) { data_[addr] = n; } + inline uint8& operator[](unsigned addr) { return data_[addr]; } + inline const uint8& operator[](unsigned addr) const { return data_[addr]; } - StaticRAM(unsigned n) : datasize(n) { data = new uint8[datasize]; } - ~StaticRAM() { delete[] data; } + StaticRAM(unsigned n) : size_(n) { data_ = new uint8[size_]; } + ~StaticRAM() { delete[] data_; } private: - uint8 *data; - unsigned datasize; + uint8 *data_; + unsigned size_; }; -struct MappedRAM : Memory { - void map(uint8 *source, unsigned length) { data = source; datasize = length > 0 ? length : -1U; } - void write_protect(bool status) { write_protection = status; } - uint8* handle() { return data; } - unsigned size() const { return datasize; } - void reset() { delete[] data; data = 0; datasize = -1U; write_protection = false; } +struct MappedRAM : Memory { + void reset() { + if(data_) { + delete[] data_; + data_ = 0; + } + size_ = -1U; + write_protect_ = false; + } - inline uint8 read(unsigned addr) { return data[addr]; } - inline void write(unsigned addr, uint8 n) { if(!write_protection) data[addr] = n; } - inline const uint8& operator[](unsigned addr) const { return data[addr]; } + void map(uint8 *source, unsigned length) { + reset(); + data_ = source; + size_ = data_ && length > 0 ? length : -1U; + } - MappedRAM() : data(0), datasize(0), write_protection(false) {} + void write_protect(bool status) { write_protect_ = status; } + uint8* data() { return data_; } + unsigned size() const { return size_; } + + inline uint8 read(unsigned addr) { return data_[addr]; } + inline void write(unsigned addr, uint8 n) { if(!write_protect_) data_[addr] = n; } + inline const uint8 operator[](unsigned addr) const { return data_[addr]; } + MappedRAM() : data_(0), size_(-1U), write_protect_(false) {} private: - uint8 *data; - unsigned datasize; - bool write_protection; + uint8 *data_; + unsigned size_; + bool write_protect_; }; struct MMIOAccess : Memory { diff --git a/src/memory/smemory/smemory.cpp b/src/memory/smemory/smemory.cpp index 8f8c005b..871700a0 100644 --- a/src/memory/smemory/smemory.cpp +++ b/src/memory/smemory/smemory.cpp @@ -44,3 +44,4 @@ sBus::~sBus() { } }; + diff --git a/src/ppu/bppu/bppu.cpp b/src/ppu/bppu/bppu.cpp index 2f075854..673b0a66 100644 --- a/src/ppu/bppu/bppu.cpp +++ b/src/ppu/bppu/bppu.cpp @@ -1,48 +1,46 @@ #include <../base.hpp> - -#define BPPU_CPP + +#define BPPU_CPP namespace SNES { #include "bppu_mmio.cpp" #include "bppu_render.cpp" void bPPU::enter() { - loop: - //H = 0 (initialize) - scanline(); - if(ivcounter() == 0) frame(); - add_clocks(10); + while(true) { + //H = 0 (initialize) + scanline(); + if(ivcounter() == 0) frame(); + add_clocks(10); - //H = 10 (OAM address reset) - if(ivcounter() == (!overscan() ? 225 : 240)) { - if(regs.display_disabled == false) { - regs.oam_addr = regs.oam_baseaddr << 1; - regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; + //H = 10 (OAM address reset) + if(ivcounter() == (!overscan() ? 225 : 240)) { + if(regs.display_disabled == false) { + regs.oam_addr = regs.oam_baseaddr << 1; + regs.oam_firstsprite = (regs.oam_priority == false) ? 0 : (regs.oam_addr >> 2) & 127; + } } + add_clocks(502); + + //H = 512 (render) + render_scanline(); + add_clocks(640); + + //H = 1152 (cache OBSEL) + cache.oam_basesize = regs.oam_basesize; + cache.oam_nameselect = regs.oam_nameselect; + cache.oam_tdaddr = regs.oam_tdaddr; + add_clocks(ilineclocks() - 1152); //seek to start of next scanline } - add_clocks(502); - - //H = 512 (render) - render_scanline(); - add_clocks(640); - - //H = 1152 (cache OBSEL) - cache.oam_basesize = regs.oam_basesize; - cache.oam_nameselect = regs.oam_nameselect; - cache.oam_tdaddr = regs.oam_tdaddr; - add_clocks(ilineclocks() - 1152); //seek to start of next scanline - - goto loop; } -void bPPU::add_clocks(unsigned clocks) { +void bPPU::add_clocks(unsigned clocks) { tock(clocks); scheduler.addclocks_ppu(clocks); - scheduler.sync_ppucpu(); + scheduler.sync_ppucpu(); } void bPPU::scanline() { - system.scanline(); line = ivcounter(); if(line == 0) { @@ -347,5 +345,5 @@ bPPU::bPPU() { bPPU::~bPPU() { free_tiledata_cache(); } - -}; +}; + diff --git a/src/ppu/bppu/bppu_mmio.cpp b/src/ppu/bppu/bppu_mmio.cpp index d4df9afe..092b9fce 100644 --- a/src/ppu/bppu/bppu_mmio.cpp +++ b/src/ppu/bppu/bppu_mmio.cpp @@ -333,17 +333,17 @@ void bPPU::mmio_w2115(uint8 value) { regs.vram_incmode = !!(value & 0x80); regs.vram_mapping = (value >> 2) & 3; switch(value & 3) { - case 0: regs.vram_incsize = 1; break; - case 1: regs.vram_incsize = 32; break; - case 2: regs.vram_incsize = 128; break; - case 3: regs.vram_incsize = 128; break; + case 0: regs.vram_incsize = 1; break; + case 1: regs.vram_incsize = 32; break; + case 2: regs.vram_incsize = 128; break; + case 3: regs.vram_incsize = 128; break; } } //VMADDL void bPPU::mmio_w2116(uint8 value) { regs.vram_addr = (regs.vram_addr & 0xff00) | value; -uint16 addr = get_vram_address(); + uint16 addr = get_vram_address(); regs.vram_readbuffer = vram_mmio_read(addr + 0); regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8; } @@ -351,7 +351,7 @@ uint16 addr = get_vram_address(); //VMADDH void bPPU::mmio_w2117(uint8 value) { regs.vram_addr = (value << 8) | (regs.vram_addr & 0x00ff); -uint16 addr = get_vram_address(); + uint16 addr = get_vram_address(); regs.vram_readbuffer = vram_mmio_read(addr + 0); regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8; } @@ -759,21 +759,20 @@ uint8 bPPU::mmio_read(unsigned addr) { case 0x2128: case 0x2129: case 0x212a: return regs.ppu1_mdr; - case 0x2134: return mmio_r2134(); //MPYL - case 0x2135: return mmio_r2135(); //MPYM - case 0x2136: return mmio_r2136(); //MPYH - case 0x2137: return mmio_r2137(); //SLHV - case 0x2138: return mmio_r2138(); //OAMDATAREAD - case 0x2139: return mmio_r2139(); //VMDATALREAD - case 0x213a: return mmio_r213a(); //VMDATAHREAD - case 0x213b: return mmio_r213b(); //CGDATAREAD - case 0x213c: return mmio_r213c(); //OPHCT - case 0x213d: return mmio_r213d(); //OPVCT - case 0x213e: return mmio_r213e(); //STAT77 - case 0x213f: return mmio_r213f(); //STAT78 + case 0x2134: return mmio_r2134(); //MPYL + case 0x2135: return mmio_r2135(); //MPYM + case 0x2136: return mmio_r2136(); //MPYH + case 0x2137: return mmio_r2137(); //SLHV + case 0x2138: return mmio_r2138(); //OAMDATAREAD + case 0x2139: return mmio_r2139(); //VMDATALREAD + case 0x213a: return mmio_r213a(); //VMDATAHREAD + case 0x213b: return mmio_r213b(); //CGDATAREAD + case 0x213c: return mmio_r213c(); //OPHCT + case 0x213d: return mmio_r213d(); //OPVCT + case 0x213e: return mmio_r213e(); //STAT77 + case 0x213f: return mmio_r213f(); //STAT78 } - //return 0x00; return cpu.regs.mdr; } @@ -781,59 +780,60 @@ void bPPU::mmio_write(unsigned addr, uint8 data) { scheduler.sync_cpuppu(); switch(addr & 0xffff) { - case 0x2100: mmio_w2100(data); return; //INIDISP - case 0x2101: mmio_w2101(data); return; //OBSEL - case 0x2102: mmio_w2102(data); return; //OAMADDL - case 0x2103: mmio_w2103(data); return; //OAMADDH - case 0x2104: mmio_w2104(data); return; //OAMDATA - case 0x2105: mmio_w2105(data); return; //BGMODE - case 0x2106: mmio_w2106(data); return; //MOSAIC - case 0x2107: mmio_w2107(data); return; //BG1SC - case 0x2108: mmio_w2108(data); return; //BG2SC - case 0x2109: mmio_w2109(data); return; //BG3SC - case 0x210a: mmio_w210a(data); return; //BG4SC - case 0x210b: mmio_w210b(data); return; //BG12NBA - case 0x210c: mmio_w210c(data); return; //BG34NBA - case 0x210d: mmio_w210d(data); return; //BG1HOFS - case 0x210e: mmio_w210e(data); return; //BG1VOFS - case 0x210f: mmio_w210f(data); return; //BG2HOFS - case 0x2110: mmio_w2110(data); return; //BG2VOFS - case 0x2111: mmio_w2111(data); return; //BG3HOFS - case 0x2112: mmio_w2112(data); return; //BG3VOFS - case 0x2113: mmio_w2113(data); return; //BG4HOFS - case 0x2114: mmio_w2114(data); return; //BG4VOFS - case 0x2115: mmio_w2115(data); return; //VMAIN - case 0x2116: mmio_w2116(data); return; //VMADDL - case 0x2117: mmio_w2117(data); return; //VMADDH - case 0x2118: mmio_w2118(data); return; //VMDATAL - case 0x2119: mmio_w2119(data); return; //VMDATAH - case 0x211a: mmio_w211a(data); return; //M7SEL - case 0x211b: mmio_w211b(data); return; //M7A - case 0x211c: mmio_w211c(data); return; //M7B - case 0x211d: mmio_w211d(data); return; //M7C - case 0x211e: mmio_w211e(data); return; //M7D - case 0x211f: mmio_w211f(data); return; //M7X - case 0x2120: mmio_w2120(data); return; //M7Y - case 0x2121: mmio_w2121(data); return; //CGADD - case 0x2122: mmio_w2122(data); return; //CGDATA - case 0x2123: mmio_w2123(data); return; //W12SEL - case 0x2124: mmio_w2124(data); return; //W34SEL - case 0x2125: mmio_w2125(data); return; //WOBJSEL - case 0x2126: mmio_w2126(data); return; //WH0 - case 0x2127: mmio_w2127(data); return; //WH1 - case 0x2128: mmio_w2128(data); return; //WH2 - case 0x2129: mmio_w2129(data); return; //WH3 - case 0x212a: mmio_w212a(data); return; //WBGLOG - case 0x212b: mmio_w212b(data); return; //WOBJLOG - case 0x212c: mmio_w212c(data); return; //TM - case 0x212d: mmio_w212d(data); return; //TS - case 0x212e: mmio_w212e(data); return; //TMW - case 0x212f: mmio_w212f(data); return; //TSW - case 0x2130: mmio_w2130(data); return; //CGWSEL - case 0x2131: mmio_w2131(data); return; //CGADDSUB - case 0x2132: mmio_w2132(data); return; //COLDATA - case 0x2133: mmio_w2133(data); return; //SETINI + case 0x2100: return mmio_w2100(data); //INIDISP + case 0x2101: return mmio_w2101(data); //OBSEL + case 0x2102: return mmio_w2102(data); //OAMADDL + case 0x2103: return mmio_w2103(data); //OAMADDH + case 0x2104: return mmio_w2104(data); //OAMDATA + case 0x2105: return mmio_w2105(data); //BGMODE + case 0x2106: return mmio_w2106(data); //MOSAIC + case 0x2107: return mmio_w2107(data); //BG1SC + case 0x2108: return mmio_w2108(data); //BG2SC + case 0x2109: return mmio_w2109(data); //BG3SC + case 0x210a: return mmio_w210a(data); //BG4SC + case 0x210b: return mmio_w210b(data); //BG12NBA + case 0x210c: return mmio_w210c(data); //BG34NBA + case 0x210d: return mmio_w210d(data); //BG1HOFS + case 0x210e: return mmio_w210e(data); //BG1VOFS + case 0x210f: return mmio_w210f(data); //BG2HOFS + case 0x2110: return mmio_w2110(data); //BG2VOFS + case 0x2111: return mmio_w2111(data); //BG3HOFS + case 0x2112: return mmio_w2112(data); //BG3VOFS + case 0x2113: return mmio_w2113(data); //BG4HOFS + case 0x2114: return mmio_w2114(data); //BG4VOFS + case 0x2115: return mmio_w2115(data); //VMAIN + case 0x2116: return mmio_w2116(data); //VMADDL + case 0x2117: return mmio_w2117(data); //VMADDH + case 0x2118: return mmio_w2118(data); //VMDATAL + case 0x2119: return mmio_w2119(data); //VMDATAH + case 0x211a: return mmio_w211a(data); //M7SEL + case 0x211b: return mmio_w211b(data); //M7A + case 0x211c: return mmio_w211c(data); //M7B + case 0x211d: return mmio_w211d(data); //M7C + case 0x211e: return mmio_w211e(data); //M7D + case 0x211f: return mmio_w211f(data); //M7X + case 0x2120: return mmio_w2120(data); //M7Y + case 0x2121: return mmio_w2121(data); //CGADD + case 0x2122: return mmio_w2122(data); //CGDATA + case 0x2123: return mmio_w2123(data); //W12SEL + case 0x2124: return mmio_w2124(data); //W34SEL + case 0x2125: return mmio_w2125(data); //WOBJSEL + case 0x2126: return mmio_w2126(data); //WH0 + case 0x2127: return mmio_w2127(data); //WH1 + case 0x2128: return mmio_w2128(data); //WH2 + case 0x2129: return mmio_w2129(data); //WH3 + case 0x212a: return mmio_w212a(data); //WBGLOG + case 0x212b: return mmio_w212b(data); //WOBJLOG + case 0x212c: return mmio_w212c(data); //TM + case 0x212d: return mmio_w212d(data); //TS + case 0x212e: return mmio_w212e(data); //TMW + case 0x212f: return mmio_w212f(data); //TSW + case 0x2130: return mmio_w2130(data); //CGWSEL + case 0x2131: return mmio_w2131(data); //CGADDSUB + case 0x2132: return mmio_w2132(data); //COLDATA + case 0x2133: return mmio_w2133(data); //SETINI } } -#endif //ifdef BPPU_CPP +#endif + diff --git a/src/ppu/bppu/bppu_render_oam.cpp b/src/ppu/bppu/bppu_render_oam.cpp index f0da95cb..f3468892 100644 --- a/src/ppu/bppu/bppu_render_oam.cpp +++ b/src/ppu/bppu/bppu_render_oam.cpp @@ -1,8 +1,8 @@ #ifdef BPPU_CPP void bPPU::build_sprite_list() { - uint8 *tableA = memory::oam.handle(); - uint8 *tableB = memory::oam.handle() + 512; + uint8 *tableA = memory::oam.data(); + uint8 *tableB = memory::oam.data() + 512; for(unsigned i = 0; i < 128; i++) { unsigned x = !!(*tableB & (1 << ((i & 3) << 1))); //0x01, 0x04, 0x10, 0x40 diff --git a/src/ppu/counter.cpp b/src/ppu/counter.cpp index 5a9f2140..9eaf3493 100644 --- a/src/ppu/counter.cpp +++ b/src/ppu/counter.cpp @@ -15,20 +15,20 @@ void PPUcounter::scanline() { cpu.scanline(); } //dot 327 range = { 1310, 1312, 1314 } uint16 PPUcounter::hdot() const { - if(region() == 0 && interlace() == false && status.vcounter == 240 && status.field == 1) { - return (status.hcounter >> 2); + if(region() == 0 && interlace() == false && vcounter() == 240 && field() == 1) { + return (hcounter() >> 2); } else { - return (status.hcounter - ((status.hcounter > 1292) << 1) - ((status.hcounter > 1310) << 1)) >> 2; + return (hcounter() - ((hcounter() > 1292) << 1) - ((hcounter() > 1310) << 1)) >> 2; } } uint16 PPUcounter::lineclocks() const { - if(region() == 0 && interlace() == false && vcounter() == 240 && status.field == 1) return 1360; + if(region() == 0 && interlace() == false && vcounter() == 240 && field() == 1) return 1360; return 1364; } uint16 PPUcounter::ilineclocks() const { - if(region() == 0 && interlace() == false && ivcounter() == 240 && status.field == 1) return 1360; + if(region() == 0 && interlace() == false && ivcounter() == 240 && ifield() == 1) return 1360; return 1364; } diff --git a/src/ppu/counter.hpp b/src/ppu/counter.hpp index 515f64ee..2ab8d036 100644 --- a/src/ppu/counter.hpp +++ b/src/ppu/counter.hpp @@ -1,9 +1,7 @@ class PPUcounter { public: alwaysinline void tick() { - history.ppudiff += 2; status.hcounter += 2; - if(status.hcounter >= 1360 && status.hcounter == lineclocks()) { status.hcounter = 0; status.vcounter++; @@ -17,7 +15,6 @@ public: status.vcounter = 0; status.field = !status.field; } - scanline(); } @@ -25,6 +22,7 @@ public: history.field [history.index] = status.field; history.vcounter[history.index] = status.vcounter; history.hcounter[history.index] = status.hcounter; + history.ppudiff += 2; } alwaysinline void tock(unsigned clocks) { @@ -67,7 +65,7 @@ private: uint16 vcounter[2048]; uint16 hcounter[2048]; - unsigned index; - signed ppudiff; + int32 index; + int32 ppudiff; } history; }; diff --git a/src/ppu/ppu.cpp b/src/ppu/ppu.cpp index 6526f481..73677f59 100644 --- a/src/ppu/ppu.cpp +++ b/src/ppu/ppu.cpp @@ -1,6 +1,6 @@ #include <../base.hpp> - -#define PPU_CPP + +#define PPU_CPP namespace SNES { #include "counter.cpp" @@ -47,5 +47,5 @@ PPU::PPU() { PPU::~PPU() { delete[] output; } - -}; +}; + diff --git a/src/smp/core/bpp.sh b/src/smp/core/bpp.sh index 684413a9..25208596 100644 --- a/src/smp/core/bpp.sh +++ b/src/smp/core/bpp.sh @@ -1,3 +1,4 @@ clear bpp opcode_functions.cpp opcode_functions.bpp bpp opcode_headers.hpp opcode_headers.bpp + diff --git a/src/smp/core/core.cpp b/src/smp/core/core.cpp index 6709748f..e710263f 100644 --- a/src/smp/core/core.cpp +++ b/src/smp/core/core.cpp @@ -1,15 +1,16 @@ -#include <../base.hpp> - -#define SMPCORE_CPP +#include <../base.hpp> + +#define SMPCORE_CPP namespace SNES { -#include "opcode_algorithms.cpp" -#include "opcode_functions.cpp" -#include "opcode_table.cpp" +#include "opcode_algorithms.cpp" +#include "opcode_functions.cpp" +#include "opcode_table.cpp" #include "disasm/disasm.cpp" - -SMPcore::SMPcore() { - initialize_opcode_table(); -} - -}; + +SMPcore::SMPcore() { + initialize_opcode_table(); +} + +}; + diff --git a/src/smp/core/core.hpp b/src/smp/core/core.hpp index a3108e43..9865fd80 100644 --- a/src/smp/core/core.hpp +++ b/src/smp/core/core.hpp @@ -1,15 +1,15 @@ -class SMPcore { -public: - #include "registers.hpp" - #include "memory.hpp" - #include "opcode_headers.hpp" - #include "disasm/disasm.hpp" - - regs_t regs; - uint16 dp, sp, rd, wr, bit, ya; - - virtual void op_io() = 0; - virtual uint8_t op_read(uint16_t addr) = 0; +class SMPcore { +public: + #include "registers.hpp" + #include "memory.hpp" + #include "opcode_headers.hpp" + #include "disasm/disasm.hpp" + + regs_t regs; + uint16 dp, sp, rd, wr, bit, ya; + + virtual void op_io() = 0; + virtual uint8_t op_read(uint16_t addr) = 0; virtual void op_write(uint16_t addr, uint8_t data) = 0; uint8 op_adc (uint8 x, uint8 y); @@ -27,9 +27,10 @@ public: uint8 op_lsr (uint8 x); uint8 op_rol (uint8 x); uint8 op_ror (uint8 x); - - void (SMPcore::*opcode_table[256])(); - void initialize_opcode_table(); - - SMPcore(); -}; + + void (SMPcore::*opcode_table[256])(); + void initialize_opcode_table(); + + SMPcore(); +}; + diff --git a/src/smp/core/disasm/disasm.cpp b/src/smp/core/disasm/disasm.cpp index 94eae4e2..3cab4ff9 100644 --- a/src/smp/core/disasm/disasm.cpp +++ b/src/smp/core/disasm/disasm.cpp @@ -1,5 +1,5 @@ #ifdef SMPCORE_CPP - + uint16 SMPcore::__relb(int8 offset, int op_len) { uint16 pc = regs.pc + op_len; return pc + offset; @@ -12,8 +12,8 @@ void SMPcore::disassemble_opcode(char *output) { s = output; sprintf(s, "..%.4x ", regs.pc); - - //todo: this needs to access IPLROM at $ffc0+, when enabled + + //TODO: read from IPLROM when applicable op = memory::apuram[(uint16_t)(regs.pc + 0)]; op0 = memory::apuram[(uint16_t)(regs.pc + 1)]; op1 = memory::apuram[(uint16_t)(regs.pc + 2)]; @@ -301,4 +301,5 @@ void SMPcore::disassemble_opcode(char *output) { strcat(s, t); } -#endif +#endif + diff --git a/src/smp/core/disasm/disasm.hpp b/src/smp/core/disasm/disasm.hpp index 7309f444..7c97b2fe 100644 --- a/src/smp/core/disasm/disasm.hpp +++ b/src/smp/core/disasm/disasm.hpp @@ -1,2 +1,3 @@ - void disassemble_opcode(char *output); - inline uint16 __relb(int8 offset, int op_len); +void disassemble_opcode(char *output); +inline uint16 __relb(int8 offset, int op_len); + diff --git a/src/smp/core/memory.hpp b/src/smp/core/memory.hpp index 57825700..1d4b9c18 100644 --- a/src/smp/core/memory.hpp +++ b/src/smp/core/memory.hpp @@ -1,27 +1,28 @@ -alwaysinline uint8 op_readpc() { - return op_read(regs.pc++); +alwaysinline uint8_t op_readpc() { + return op_read(regs.pc++); +} + +alwaysinline uint8_t op_readstack() { + return op_read(0x0100 | ++regs.sp); +} + +alwaysinline void op_writestack(uint8_t data) { + op_write(0x0100 | regs.sp--, data); +} + +alwaysinline uint8_t op_readaddr(uint16_t addr) { + return op_read(addr); +} + +alwaysinline void op_writeaddr(uint16_t addr, uint8_t data) { + op_write(addr, data); +} + +alwaysinline uint8_t op_readdp(uint8_t addr) { + return op_read(((unsigned)regs.p.p << 8) + addr); +} + +alwaysinline void op_writedp(uint8_t addr, uint8_t data) { + op_write(((unsigned)regs.p.p << 8) + addr, data); } -alwaysinline uint8 op_readstack() { - return op_read(0x0100 | ++regs.sp); -} - -alwaysinline void op_writestack(uint8 data) { - op_write(0x0100 | regs.sp--, data); -} - -alwaysinline uint8 op_readaddr(uint16 addr) { - return op_read(addr); -} - -alwaysinline void op_writeaddr(uint16 addr, uint8 data) { - op_write(addr, data); -} - -alwaysinline uint8 op_readdp(uint8 addr) { - return op_read((unsigned(regs.p.p) << 8) + addr); -} - -alwaysinline void op_writedp(uint8 addr, uint8 data) { - op_write((unsigned(regs.p.p) << 8) + addr, data); -} diff --git a/src/smp/core/opcode_algorithms.cpp b/src/smp/core/opcode_algorithms.cpp index b7e0b095..f4938eb4 100644 --- a/src/smp/core/opcode_algorithms.cpp +++ b/src/smp/core/opcode_algorithms.cpp @@ -123,4 +123,5 @@ uint8 SMPcore::op_ror(uint8 x) { return x; } -#endif +#endif + diff --git a/src/smp/core/opcode_functions.bpp b/src/smp/core/opcode_functions.bpp index be0a633c..fe0e3811 100644 --- a/src/smp/core/opcode_functions.bpp +++ b/src/smp/core/opcode_functions.bpp @@ -2,10 +2,11 @@ @global class SMPcore -@include "opcode_move.bpp" +@include "opcode_mov.bpp" @include "opcode_pc.bpp" @include "opcode_read.bpp" @include "opcode_rmw.bpp" @include "opcode_misc.bpp" @include "opcode_list.bpp" + diff --git a/src/smp/core/opcode_functions.cpp b/src/smp/core/opcode_functions.cpp index 9c1b6706..7719d8d0 100644 --- a/src/smp/core/opcode_functions.cpp +++ b/src/smp/core/opcode_functions.cpp @@ -77,9 +77,14 @@ -//=============== -//opcode_move.bpp -//=============== + + + + + +//============== +//opcode_mov.bpp +//============== void SMPcore::op_mov_a_x() { op_io(); @@ -140,7 +145,6 @@ regs.p.z = (regs.y == 0); } - void SMPcore::op_mov_a_ix() { op_io(); regs.a = op_readdp(regs.x); @@ -400,7 +404,6 @@ op_writeaddr(dp, regs.a); } - void SMPcore::op_movw_ya_dp() { sp = op_readpc(); regs.a = op_readdp(sp + 0); @@ -417,14 +420,13 @@ op_writedp(dp + 1, regs.y); } - void SMPcore::op_mov1_c_bit() { sp = op_readpc() << 0; sp |= op_readpc() << 8; bit = sp >> 13; sp &= 0x1fff; rd = op_readaddr(sp); - regs.p.c = !!(rd & (1 << bit)); + regs.p.c = (rd & (1 << bit)); } void SMPcore::op_mov1_bit_c() { @@ -433,8 +435,7 @@ bit = dp >> 13; dp &= 0x1fff; rd = op_readaddr(dp); - if(regs.p.c) rd |= (1 << bit); - else rd &= ~(1 << bit); + (regs.p.c) ? rd |= (1 << bit) : rd &= ~(1 << bit); op_io(); op_writeaddr(dp, rd); } @@ -714,7 +715,7 @@ if(regs.a == sp) return; op_io(); op_io(); - regs.pc += (int8_t)rd; + regs.pc += (int8_t)rd; } void SMPcore::op_dbnz_dp() { @@ -1235,7 +1236,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.x); + rd = op_readaddr(dp + regs.x); regs.a = op_adc(regs.a, rd); } @@ -1243,7 +1244,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.y); + rd = op_readaddr(dp + regs.y); regs.a = op_adc(regs.a, rd); } @@ -1251,7 +1252,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.x); + rd = op_readaddr(dp + regs.x); regs.a = op_and(regs.a, rd); } @@ -1259,7 +1260,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.y); + rd = op_readaddr(dp + regs.y); regs.a = op_and(regs.a, rd); } @@ -1267,7 +1268,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.x); + rd = op_readaddr(dp + regs.x); regs.a = op_cmp(regs.a, rd); } @@ -1275,7 +1276,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.y); + rd = op_readaddr(dp + regs.y); regs.a = op_cmp(regs.a, rd); } @@ -1283,7 +1284,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.x); + rd = op_readaddr(dp + regs.x); regs.a = op_eor(regs.a, rd); } @@ -1291,7 +1292,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.y); + rd = op_readaddr(dp + regs.y); regs.a = op_eor(regs.a, rd); } @@ -1299,7 +1300,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.x); + rd = op_readaddr(dp + regs.x); regs.a = op_or(regs.a, rd); } @@ -1307,7 +1308,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.y); + rd = op_readaddr(dp + regs.y); regs.a = op_or(regs.a, rd); } @@ -1315,7 +1316,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.x); + rd = op_readaddr(dp + regs.x); regs.a = op_sbc(regs.a, rd); } @@ -1323,7 +1324,7 @@ dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.y); + rd = op_readaddr(dp + regs.y); regs.a = op_sbc(regs.a, rd); } @@ -1443,7 +1444,7 @@ rd = op_readdp(regs.y); wr = op_readdp(regs.x); wr = op_adc(wr, rd); - true ? op_writedp(regs.x, wr) : op_io(); + 1 ? op_writedp(regs.x, wr) : op_io(); } void SMPcore::op_and_ix_iy() { @@ -1451,7 +1452,7 @@ rd = op_readdp(regs.y); wr = op_readdp(regs.x); wr = op_and(wr, rd); - true ? op_writedp(regs.x, wr) : op_io(); + 1 ? op_writedp(regs.x, wr) : op_io(); } void SMPcore::op_cmp_ix_iy() { @@ -1459,7 +1460,7 @@ rd = op_readdp(regs.y); wr = op_readdp(regs.x); wr = op_cmp(wr, rd); - false ? op_writedp(regs.x, wr) : op_io(); + 0 ? op_writedp(regs.x, wr) : op_io(); } void SMPcore::op_eor_ix_iy() { @@ -1467,7 +1468,7 @@ rd = op_readdp(regs.y); wr = op_readdp(regs.x); wr = op_eor(wr, rd); - true ? op_writedp(regs.x, wr) : op_io(); + 1 ? op_writedp(regs.x, wr) : op_io(); } void SMPcore::op_or_ix_iy() { @@ -1475,7 +1476,7 @@ rd = op_readdp(regs.y); wr = op_readdp(regs.x); wr = op_or(wr, rd); - true ? op_writedp(regs.x, wr) : op_io(); + 1 ? op_writedp(regs.x, wr) : op_io(); } void SMPcore::op_sbc_ix_iy() { @@ -1483,7 +1484,7 @@ rd = op_readdp(regs.y); wr = op_readdp(regs.x); wr = op_sbc(wr, rd); - true ? op_writedp(regs.x, wr) : op_io(); + 1 ? op_writedp(regs.x, wr) : op_io(); } @@ -1493,7 +1494,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_adc(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_and_dp_dp() { @@ -1502,7 +1503,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_and(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_cmp_dp_dp() { @@ -1511,7 +1512,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_cmp(wr, rd); - false ? op_writedp(dp, wr) : op_io(); + 0 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_eor_dp_dp() { @@ -1520,7 +1521,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_eor(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_or_dp_dp() { @@ -1529,7 +1530,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_or(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_sbc_dp_dp() { @@ -1538,7 +1539,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_sbc(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } @@ -1547,7 +1548,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_adc(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_and_dp_const() { @@ -1555,7 +1556,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_and(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_cmp_dp_const() { @@ -1563,7 +1564,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_cmp(wr, rd); - false ? op_writedp(dp, wr) : op_io(); + 0 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_eor_dp_const() { @@ -1571,7 +1572,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_eor(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_or_dp_const() { @@ -1579,7 +1580,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_or(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } void SMPcore::op_sbc_dp_const() { @@ -1587,7 +1588,7 @@ dp = op_readpc(); wr = op_readdp(dp); wr = op_sbc(wr, rd); - true ? op_writedp(dp, wr) : op_io(); + 1 ? op_writedp(dp, wr) : op_io(); } @@ -1649,7 +1650,7 @@ bit = dp >> 13; dp &= 0x1fff; rd = op_readaddr(dp); - rd ^= (1 << bit); + rd ^= 1 << bit; op_writeaddr(dp, rd); } @@ -1893,7 +1894,7 @@ void SMPcore::op_incw_dp() { dp = op_readpc(); - rd = op_readdp(dp); + rd = op_readdp(dp) << 0; rd ++; op_writedp(dp++, rd); rd += op_readdp(dp) << 8; @@ -1904,7 +1905,7 @@ void SMPcore::op_decw_dp() { dp = op_readpc(); - rd = op_readdp(dp); + rd = op_readdp(dp) << 0; rd --; op_writedp(dp++, rd); rd += op_readdp(dp) << 8; @@ -1923,15 +1924,17 @@ } void SMPcore::op_sleep() { - op_io(); - op_io(); - regs.pc--; + while(true) { + op_io(); + op_io(); + } } void SMPcore::op_stop() { - op_io(); - op_io(); - regs.pc--; + while(true) { + op_io(); + op_io(); + } } void SMPcore::op_xcn() { @@ -1954,7 +1957,7 @@ if(regs.p.h || (regs.a & 15) > 0x09) { regs.a += 0x06; } - regs.p.n = (regs.a & 0x80); + regs.p.n = !!(regs.a & 0x80); regs.p.z = (regs.a == 0); } @@ -1968,7 +1971,7 @@ if(!regs.p.h || (regs.a & 15) > 0x09) { regs.a -= 0x06; } - regs.p.n = (regs.a & 0x80); + regs.p.n = !!(regs.a & 0x80); regs.p.z = (regs.a == 0); } @@ -1998,13 +2001,13 @@ regs.p.v=regs.p.h=0; } + void SMPcore::op_notc() { op_io(); op_io(); regs.p.c = !regs.p.c; } - void SMPcore::op_ei() { op_io(); op_io(); @@ -2194,7 +2197,7 @@ regs.a = ya; regs.y = ya >> 8; //result is set based on y (high-byte) only - regs.p.n = (regs.y & 0x80); + regs.p.n = !!(regs.y & 0x80); regs.p.z = (regs.y == 0); } @@ -2212,8 +2215,8 @@ op_io(); ya = regs.ya; //overflow set if quotient >= 256 - regs.p.v = (regs.y >= regs.x); - regs.p.h = ((regs.y & 15) >= (regs.x & 15)); + regs.p.v = !!(regs.y >= regs.x); + regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); if(regs.y < (regs.x << 1)) { //if quotient is <= 511 (will fit into 9-bit result) regs.a = ya / regs.x; @@ -2225,9 +2228,11 @@ regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); } //result is set based on a (quotient) only - regs.p.n = (regs.a & 0x80); + regs.p.n = !!(regs.a & 0x80); regs.p.z = (regs.a == 0); } + + diff --git a/src/smp/core/opcode_headers.bpp b/src/smp/core/opcode_headers.bpp index 1ae3f5ec..e212d2f9 100644 --- a/src/smp/core/opcode_headers.bpp +++ b/src/smp/core/opcode_headers.bpp @@ -1,96 +1,96 @@ -//=============== -//opcode_move.bpp -//=============== +//============== +//opcode_mov.bpp +//============== -@macro op_move_reg(rd, rs) -void op_mov_{rd}_{rs}(); +@macro op_mov_reg(d, s) +void op_mov_{d}_{s}(); @endmacro -@macro op_move_sp_x() +@macro op_mov_sp_x() void op_mov_sp_x(); @endmacro -@macro op_move_const(r) +@macro op_mov_reg_const(r) void op_mov_{r}_const(); @endmacro -@macro op_move_a_ix() +@macro op_mov_a_ix() void op_mov_a_ix(); @endmacro -@macro op_move_a_ixinc() +@macro op_mov_a_ixinc() void op_mov_a_ixinc(); @endmacro -@macro op_move_dp(r) +@macro op_mov_reg_dp(r) void op_mov_{r}_dp(); @endmacro -@macro op_move_dpi(rd, rs) -void op_mov_{rd}_dp{rs}(); +@macro op_mov_reg_dpi(r, i) +void op_mov_{r}_dp{i}(); @endmacro -@macro op_move_addr(r) +@macro op_mov_reg_addr(r) void op_mov_{r}_addr(); @endmacro -@macro op_move_addri(r) -void op_mov_a_addr{r}(); +@macro op_mov_a_addri(i) +void op_mov_a_addr{i}(); @endmacro -@macro op_move_a_idpx() +@macro op_mov_a_idpx() void op_mov_a_idpx(); @endmacro -@macro op_move_a_idpy() +@macro op_mov_a_idpy() void op_mov_a_idpy(); @endmacro -@macro op_move_dp_dp() +@macro op_mov_dp_dp() void op_mov_dp_dp(); @endmacro -@macro op_move_dp_const() +@macro op_mov_dp_const() void op_mov_dp_const(); @endmacro -@macro op_move_ix_a() +@macro op_mov_ix_a() void op_mov_ix_a(); @endmacro -@macro op_move_ixinc_a() +@macro op_mov_ixinc_a() void op_mov_ixinc_a(); @endmacro -@macro op_move_dp_reg(r) +@macro op_mov_dp_reg(r) void op_mov_dp_{r}(); @endmacro -@macro op_move_dpi_reg(ri, rs) -void op_mov_dp{ri}_{rs}(); +@macro op_mov_dpi_reg(r, i) +void op_mov_dp{i}_{r}(); @endmacro -@macro op_move_addr_reg(r) +@macro op_mov_addr_reg(r) void op_mov_addr_{r}(); @endmacro -@macro op_move_addri_reg(r) -void op_mov_addr{r}_a(); +@macro op_mov_addri_a(i) +void op_mov_addr{i}_a(); @endmacro -@macro op_move_idpx_a() +@macro op_mov_idpx_a() void op_mov_idpx_a(); @endmacro -@macro op_move_idpy_a() +@macro op_mov_idpy_a() void op_mov_idpy_a(); @endmacro -@macro op_move_ya_dp() +@macro op_movw_ya_dp() void op_movw_ya_dp(); @endmacro -@macro op_move_dp_ya() +@macro op_movw_dp_ya() void op_movw_dp_ya(); @endmacro @@ -166,47 +166,47 @@ void op_reti(); //opcode_read.bpp //=============== -@macro op_read_const(name, r) +@macro op_read_reg_const(name, r) void op_{name}_{r}_const(); @endmacro -@macro op_read_ix(name) +@macro op_read_a_ix(name) void op_{name}_a_ix(); @endmacro -@macro op_read_dp(name, r) +@macro op_read_reg_dp(name, r) void op_{name}_{r}_dp(); @endmacro -@macro op_read_dpx(name) +@macro op_read_a_dpx(name) void op_{name}_a_dpx(); @endmacro -@macro op_read_addr(name, r) +@macro op_read_reg_addr(name, r) void op_{name}_{r}_addr(); @endmacro -@macro op_read_addrn(name, r) -void op_{name}_a_addr{r}(); +@macro op_read_a_addri(name, i) +void op_{name}_a_addr{i}(); @endmacro -@macro op_read_idpx(name) +@macro op_read_a_idpx(name) void op_{name}_a_idpx(); @endmacro -@macro op_read_idpy(name) +@macro op_read_a_idpy(name) void op_{name}_a_idpy(); @endmacro -@macro op_rmw_ix_iy(name, write) +@macro op_read_ix_iy(name, write) void op_{name}_ix_iy(); @endmacro -@macro op_rmw_dp_dp(name, write) +@macro op_read_dp_dp(name, write) void op_{name}_dp_dp(); @endmacro -@macro op_rmw_dp_const(name, write) +@macro op_read_dp_const(name, write) void op_{name}_dp_const(); @endmacro @@ -238,27 +238,27 @@ void op_or1_{name}(); //opcode_rmw.bpp //============== -@macro op_rmw_immediate(name, r) +@macro op_adjust_reg(name, r) void op_{name}_{r}(); @endmacro -@macro op_rmw_dp(name) +@macro op_adjust_dp(name) void op_{name}_dp(); @endmacro -@macro op_rmw_dpx(name) +@macro op_adjust_dpx(name) void op_{name}_dpx(); @endmacro -@macro op_rmw_addr(name) +@macro op_adjust_addr(name) void op_{name}_addr(); @endmacro -@macro op_rmw_taddr(name, op) +@macro op_tadjust_addr(name, op) void op_{name}_addr_a(); @endmacro -@macro op_rmw_adjust(name, op) +@macro op_adjustw_dp(name, op) void op_{name}_dp(); @endmacro @@ -270,7 +270,7 @@ void op_{name}_dp(); void op_nop(); @endmacro -@macro op_stall(name) +@macro op_wait(name) void op_{name}(); @endmacro @@ -286,7 +286,7 @@ void op_daa(); void op_das(); @endmacro -@macro op_flagadjust(name, op) +@macro op_setbit(name, op) void op_{name}(); @endmacro @@ -294,11 +294,11 @@ void op_{name}(); void op_notc(); @endmacro -@macro op_seti(name, state) +@macro op_seti(name, bit) void op_{name}(); @endmacro -@macro op_bit_dp(name, op) +@macro op_setbit_dp(name, op) void op_{name}_dp(); @endmacro @@ -321,3 +321,4 @@ void op_div_ya_x(); // @include "opcode_list.bpp" + diff --git a/src/smp/core/opcode_headers.hpp b/src/smp/core/opcode_headers.hpp index ddc93cbc..5a119375 100644 --- a/src/smp/core/opcode_headers.hpp +++ b/src/smp/core/opcode_headers.hpp @@ -1,6 +1,6 @@ -//=============== -//opcode_move.bpp -//=============== +//============== +//opcode_mov.bpp +//============== @@ -95,9 +95,9 @@ // -//=============== -//opcode_move.bpp -//=============== +//============== +//opcode_mov.bpp +//============== void op_mov_a_x(); @@ -118,7 +118,6 @@ void op_mov_x_const(); void op_mov_y_const(); - void op_mov_a_ix(); void op_mov_a_ixinc(); @@ -193,12 +192,10 @@ void op_mov_idpx_a(); void op_mov_idpy_a(); - void op_movw_ya_dp(); void op_movw_dp_ya(); - void op_mov1_c_bit(); void op_mov1_bit_c(); @@ -609,8 +606,8 @@ void op_setp(); void op_clrv(); -void op_notc(); +void op_notc(); void op_ei(); @@ -674,3 +671,5 @@ void op_div_ya_x(); + + diff --git a/src/smp/core/opcode_list.bpp b/src/smp/core/opcode_list.bpp index 93119cbe..6b592e4a 100644 --- a/src/smp/core/opcode_list.bpp +++ b/src/smp/core/opcode_list.bpp @@ -1,64 +1,61 @@ -//=============== -//opcode_move.bpp -//=============== +//============== +//opcode_mov.bpp +//============== -@op_move_reg(a, x) -@op_move_reg(a, y) -@op_move_reg(x, a) -@op_move_reg(y, a) -@op_move_reg(x, sp) -@op_move_sp_x() +@op_mov_reg(a, x) +@op_mov_reg(a, y) +@op_mov_reg(x, a) +@op_mov_reg(y, a) +@op_mov_reg(x, sp) +@op_mov_sp_x() -@op_move_const(a) -@op_move_const(x) -@op_move_const(y) +@op_mov_reg_const(a) +@op_mov_reg_const(x) +@op_mov_reg_const(y) +@op_mov_a_ix() +@op_mov_a_ixinc() -@op_move_a_ix() -@op_move_a_ixinc() +@op_mov_reg_dp(a) +@op_mov_reg_dp(x) +@op_mov_reg_dp(y) -@op_move_dp(a) -@op_move_dp(x) -@op_move_dp(y) +@op_mov_reg_dpi(a, x) +@op_mov_reg_dpi(x, y) +@op_mov_reg_dpi(y, x) -@op_move_dpi(a, x) -@op_move_dpi(x, y) -@op_move_dpi(y, x) +@op_mov_reg_addr(a) +@op_mov_reg_addr(x) +@op_mov_reg_addr(y) -@op_move_addr(a) -@op_move_addr(x) -@op_move_addr(y) +@op_mov_a_addri(x) +@op_mov_a_addri(y) -@op_move_addri(x) -@op_move_addri(y) +@op_mov_a_idpx() +@op_mov_a_idpy() +@op_mov_dp_dp() +@op_mov_dp_const() +@op_mov_ix_a() +@op_mov_ixinc_a() -@op_move_a_idpx() -@op_move_a_idpy() -@op_move_dp_dp() -@op_move_dp_const() -@op_move_ix_a() -@op_move_ixinc_a() +@op_mov_dp_reg(a) +@op_mov_dp_reg(x) +@op_mov_dp_reg(y) -@op_move_dp_reg(a) -@op_move_dp_reg(x) -@op_move_dp_reg(y) +@op_mov_dpi_reg(a, x) +@op_mov_dpi_reg(x, y) +@op_mov_dpi_reg(y, x) -@op_move_dpi_reg(x, a) -@op_move_dpi_reg(y, x) -@op_move_dpi_reg(x, y) +@op_mov_addr_reg(a) +@op_mov_addr_reg(x) +@op_mov_addr_reg(y) -@op_move_addr_reg(a) -@op_move_addr_reg(x) -@op_move_addr_reg(y) - -@op_move_addri_reg(x) -@op_move_addri_reg(y) - -@op_move_idpx_a() -@op_move_idpy_a() - -@op_move_ya_dp() -@op_move_dp_ya() +@op_mov_addri_a(x) +@op_mov_addri_a(y) +@op_mov_idpx_a() +@op_mov_idpy_a() +@op_movw_ya_dp() +@op_movw_dp_ya() @op_mov1_c_bit() @op_mov1_bit_c() @@ -127,185 +124,185 @@ //opcode_read.bpp //=============== -@op_read_const(adc, a) -@op_read_const(and, a) -@op_read_const(cmp, a) -@op_read_const(cmp, x) -@op_read_const(cmp, y) -@op_read_const(eor, a) -@op_read_const(or, a) -@op_read_const(sbc, a) +@op_read_reg_const(adc, a) +@op_read_reg_const(and, a) +@op_read_reg_const(cmp, a) +@op_read_reg_const(cmp, x) +@op_read_reg_const(cmp, y) +@op_read_reg_const(eor, a) +@op_read_reg_const(or, a) +@op_read_reg_const(sbc, a) -@op_read_ix(adc) -@op_read_ix(and) -@op_read_ix(cmp) -@op_read_ix(eor) -@op_read_ix(or) -@op_read_ix(sbc) +@op_read_a_ix(adc) +@op_read_a_ix(and) +@op_read_a_ix(cmp) +@op_read_a_ix(eor) +@op_read_a_ix(or) +@op_read_a_ix(sbc) -@op_read_dp(adc, a) -@op_read_dp(and, a) -@op_read_dp(cmp, a) -@op_read_dp(cmp, x) -@op_read_dp(cmp, y) -@op_read_dp(eor, a) -@op_read_dp(or, a) -@op_read_dp(sbc, a) +@op_read_reg_dp(adc, a) +@op_read_reg_dp(and, a) +@op_read_reg_dp(cmp, a) +@op_read_reg_dp(cmp, x) +@op_read_reg_dp(cmp, y) +@op_read_reg_dp(eor, a) +@op_read_reg_dp(or, a) +@op_read_reg_dp(sbc, a) -@op_read_dpx(adc) -@op_read_dpx(and) -@op_read_dpx(cmp) -@op_read_dpx(eor) -@op_read_dpx(or) -@op_read_dpx(sbc) +@op_read_a_dpx(adc) +@op_read_a_dpx(and) +@op_read_a_dpx(cmp) +@op_read_a_dpx(eor) +@op_read_a_dpx(or) +@op_read_a_dpx(sbc) -@op_read_addr(adc, a) -@op_read_addr(and, a) -@op_read_addr(cmp, a) -@op_read_addr(cmp, x) -@op_read_addr(cmp, y) -@op_read_addr(eor, a) -@op_read_addr(or, a) -@op_read_addr(sbc, a) +@op_read_reg_addr(adc, a) +@op_read_reg_addr(and, a) +@op_read_reg_addr(cmp, a) +@op_read_reg_addr(cmp, x) +@op_read_reg_addr(cmp, y) +@op_read_reg_addr(eor, a) +@op_read_reg_addr(or, a) +@op_read_reg_addr(sbc, a) -@op_read_addrn(adc, x) -@op_read_addrn(adc, y) -@op_read_addrn(and, x) -@op_read_addrn(and, y) -@op_read_addrn(cmp, x) -@op_read_addrn(cmp, y) -@op_read_addrn(eor, x) -@op_read_addrn(eor, y) -@op_read_addrn(or, x) -@op_read_addrn(or, y) -@op_read_addrn(sbc, x) -@op_read_addrn(sbc, y) +@op_read_a_addri(adc, x) +@op_read_a_addri(adc, y) +@op_read_a_addri(and, x) +@op_read_a_addri(and, y) +@op_read_a_addri(cmp, x) +@op_read_a_addri(cmp, y) +@op_read_a_addri(eor, x) +@op_read_a_addri(eor, y) +@op_read_a_addri(or, x) +@op_read_a_addri(or, y) +@op_read_a_addri(sbc, x) +@op_read_a_addri(sbc, y) -@op_read_idpx(adc) -@op_read_idpx(and) -@op_read_idpx(cmp) -@op_read_idpx(eor) -@op_read_idpx(or) -@op_read_idpx(sbc) +@op_read_a_idpx(adc) +@op_read_a_idpx(and) +@op_read_a_idpx(cmp) +@op_read_a_idpx(eor) +@op_read_a_idpx(or) +@op_read_a_idpx(sbc) -@op_read_idpy(adc) -@op_read_idpy(and) -@op_read_idpy(cmp) -@op_read_idpy(eor) -@op_read_idpy(or) -@op_read_idpy(sbc) +@op_read_a_idpy(adc) +@op_read_a_idpy(and) +@op_read_a_idpy(cmp) +@op_read_a_idpy(eor) +@op_read_a_idpy(or) +@op_read_a_idpy(sbc) -@op_rmw_ix_iy(adc, true) -@op_rmw_ix_iy(and, true) -@op_rmw_ix_iy(cmp, false) -@op_rmw_ix_iy(eor, true) -@op_rmw_ix_iy(or, true) -@op_rmw_ix_iy(sbc, true) +@op_read_ix_iy(adc, 1) +@op_read_ix_iy(and, 1) +@op_read_ix_iy(cmp, 0) +@op_read_ix_iy(eor, 1) +@op_read_ix_iy(or, 1) +@op_read_ix_iy(sbc, 1) -@op_rmw_dp_dp(adc, true) -@op_rmw_dp_dp(and, true) -@op_rmw_dp_dp(cmp, false) -@op_rmw_dp_dp(eor, true) -@op_rmw_dp_dp(or, true) -@op_rmw_dp_dp(sbc, true) +@op_read_dp_dp(adc, 1) +@op_read_dp_dp(and, 1) +@op_read_dp_dp(cmp, 0) +@op_read_dp_dp(eor, 1) +@op_read_dp_dp(or, 1) +@op_read_dp_dp(sbc, 1) -@op_rmw_dp_const(adc, true) -@op_rmw_dp_const(and, true) -@op_rmw_dp_const(cmp, false) -@op_rmw_dp_const(eor, true) -@op_rmw_dp_const(or, true) -@op_rmw_dp_const(sbc, true) +@op_read_dp_const(adc, 1) +@op_read_dp_const(and, 1) +@op_read_dp_const(cmp, 0) +@op_read_dp_const(eor, 1) +@op_read_dp_const(or, 1) +@op_read_dp_const(sbc, 1) @op_read_ya_dp(addw) @op_read_ya_dp(subw) @op_cmpw_ya_dp() -@op_and1(bit, !!) -@op_and1(notbit, !) +@op_and1(bit, !!) +@op_and1(notbit, !) @op_eor1() @op_not1() -@op_or1(bit, !!) -@op_or1(notbit, !) +@op_or1(bit, !!) +@op_or1(notbit, !) //============== //opcode_rmw.bpp //============== -@op_rmw_immediate(inc, a) -@op_rmw_immediate(inc, x) -@op_rmw_immediate(inc, y) -@op_rmw_immediate(dec, a) -@op_rmw_immediate(dec, x) -@op_rmw_immediate(dec, y) -@op_rmw_immediate(asl, a) -@op_rmw_immediate(lsr, a) -@op_rmw_immediate(rol, a) -@op_rmw_immediate(ror, a) +@op_adjust_reg(inc, a) +@op_adjust_reg(inc, x) +@op_adjust_reg(inc, y) +@op_adjust_reg(dec, a) +@op_adjust_reg(dec, x) +@op_adjust_reg(dec, y) +@op_adjust_reg(asl, a) +@op_adjust_reg(lsr, a) +@op_adjust_reg(rol, a) +@op_adjust_reg(ror, a) -@op_rmw_dp(inc) -@op_rmw_dp(dec) -@op_rmw_dp(asl) -@op_rmw_dp(lsr) -@op_rmw_dp(rol) -@op_rmw_dp(ror) +@op_adjust_dp(inc) +@op_adjust_dp(dec) +@op_adjust_dp(asl) +@op_adjust_dp(lsr) +@op_adjust_dp(rol) +@op_adjust_dp(ror) -@op_rmw_dpx(inc) -@op_rmw_dpx(dec) -@op_rmw_dpx(asl) -@op_rmw_dpx(lsr) -@op_rmw_dpx(rol) -@op_rmw_dpx(ror) +@op_adjust_dpx(inc) +@op_adjust_dpx(dec) +@op_adjust_dpx(asl) +@op_adjust_dpx(lsr) +@op_adjust_dpx(rol) +@op_adjust_dpx(ror) -@op_rmw_addr(inc) -@op_rmw_addr(dec) -@op_rmw_addr(asl) -@op_rmw_addr(lsr) -@op_rmw_addr(rol) -@op_rmw_addr(ror) +@op_adjust_addr(inc) +@op_adjust_addr(dec) +@op_adjust_addr(asl) +@op_adjust_addr(lsr) +@op_adjust_addr(rol) +@op_adjust_addr(ror) -@op_rmw_taddr(tset, |) -@op_rmw_taddr(tclr, &~) +@op_tadjust_addr(tset, |) +@op_tadjust_addr(tclr, &~) -@op_rmw_adjust(incw, ++) -@op_rmw_adjust(decw, --) +@op_adjustw_dp(incw, ++) +@op_adjustw_dp(decw, --) //=============== //opcode_misc.bpp //=============== @op_nop() -@op_stall(sleep) -@op_stall(stop) +@op_wait(sleep) +@op_wait(stop) @op_xcn() @op_daa() @op_das() -@op_flagadjust(clrc, regs.p.c = 0) -@op_flagadjust(clrp, regs.p.p = 0) -@op_flagadjust(setc, regs.p.c = 1) -@op_flagadjust(setp, regs.p.p = 1) -@op_flagadjust(clrv, regs.p.v = regs.p.h = 0) -@op_notc() +@op_setbit(clrc, regs.p.c = 0) +@op_setbit(clrp, regs.p.p = 0) +@op_setbit(setc, regs.p.c = 1) +@op_setbit(setp, regs.p.p = 1) +@op_setbit(clrv, regs.p.v = regs.p.h = 0) +@op_notc() @op_seti(ei, 1) @op_seti(di, 0) -@op_bit_dp(set0, |= 0x01) -@op_bit_dp(clr0, &= ~0x01) -@op_bit_dp(set1, |= 0x02) -@op_bit_dp(clr1, &= ~0x02) -@op_bit_dp(set2, |= 0x04) -@op_bit_dp(clr2, &= ~0x04) -@op_bit_dp(set3, |= 0x08) -@op_bit_dp(clr3, &= ~0x08) -@op_bit_dp(set4, |= 0x10) -@op_bit_dp(clr4, &= ~0x10) -@op_bit_dp(set5, |= 0x20) -@op_bit_dp(clr5, &= ~0x20) -@op_bit_dp(set6, |= 0x40) -@op_bit_dp(clr6, &= ~0x40) -@op_bit_dp(set7, |= 0x80) -@op_bit_dp(clr7, &= ~0x80) +@op_setbit_dp(set0, |= 0x01) +@op_setbit_dp(clr0, &= ~0x01) +@op_setbit_dp(set1, |= 0x02) +@op_setbit_dp(clr1, &= ~0x02) +@op_setbit_dp(set2, |= 0x04) +@op_setbit_dp(clr2, &= ~0x04) +@op_setbit_dp(set3, |= 0x08) +@op_setbit_dp(clr3, &= ~0x08) +@op_setbit_dp(set4, |= 0x10) +@op_setbit_dp(clr4, &= ~0x10) +@op_setbit_dp(set5, |= 0x20) +@op_setbit_dp(clr5, &= ~0x20) +@op_setbit_dp(set6, |= 0x40) +@op_setbit_dp(clr6, &= ~0x40) +@op_setbit_dp(set7, |= 0x80) +@op_setbit_dp(clr7, &= ~0x80) @op_push(a) @op_push(x) @@ -319,3 +316,4 @@ @op_mul_ya() @op_div_ya_x() + diff --git a/src/smp/core/opcode_misc.bpp b/src/smp/core/opcode_misc.bpp index e0f123b3..1f5074d9 100644 --- a/src/smp/core/opcode_misc.bpp +++ b/src/smp/core/opcode_misc.bpp @@ -4,11 +4,12 @@ } @endmacro -@macro op_stall(name) +@macro op_wait(name) void {class}::op_{name}() { - op_io(); - op_io(); - regs.pc--; + while(true) { + op_io(); + op_io(); + } } @endmacro @@ -35,7 +36,7 @@ if(regs.p.h || (regs.a & 15) > 0x09) { regs.a += 0x06; } - regs.p.n = (regs.a & 0x80); + regs.p.n = !!(regs.a & 0x80); regs.p.z = (regs.a == 0); } @endmacro @@ -51,12 +52,12 @@ if(!regs.p.h || (regs.a & 15) > 0x09) { regs.a -= 0x06; } - regs.p.n = (regs.a & 0x80); + regs.p.n = !!(regs.a & 0x80); regs.p.z = (regs.a == 0); } @endmacro -@macro op_flagadjust(name, op) +@macro op_setbit(name, op) void {class}::op_{name}() { op_io(); {op}; @@ -71,15 +72,15 @@ } @endmacro -@macro op_seti(name, state) +@macro op_seti(name, bit) void {class}::op_{name}() { op_io(); op_io(); - regs.p.i = {state}; + regs.p.i = {bit}; } @endmacro -@macro op_bit_dp(name, op) +@macro op_setbit_dp(name, op) void {class}::op_{name}_dp() { dp = op_readpc(); rd = op_readdp(dp); @@ -118,7 +119,7 @@ regs.a = ya; regs.y = ya >> 8; //result is set based on y (high-byte) only - regs.p.n = (regs.y & 0x80); + regs.p.n = !!(regs.y & 0x80); regs.p.z = (regs.y == 0); } @endmacro @@ -138,8 +139,8 @@ op_io(); ya = regs.ya; //overflow set if quotient >= 256 - regs.p.v = (regs.y >= regs.x); - regs.p.h = ((regs.y & 15) >= (regs.x & 15)); + regs.p.v = !!(regs.y >= regs.x); + regs.p.h = !!((regs.y & 15) >= (regs.x & 15)); if(regs.y < (regs.x << 1)) { //if quotient is <= 511 (will fit into 9-bit result) regs.a = ya / regs.x; @@ -151,7 +152,8 @@ regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x); } //result is set based on a (quotient) only - regs.p.n = (regs.a & 0x80); + regs.p.n = !!(regs.a & 0x80); regs.p.z = (regs.a == 0); } @endmacro + diff --git a/src/smp/core/opcode_move.bpp b/src/smp/core/opcode_mov.bpp similarity index 76% rename from src/smp/core/opcode_move.bpp rename to src/smp/core/opcode_mov.bpp index 5b81b29d..b643f9e3 100644 --- a/src/smp/core/opcode_move.bpp +++ b/src/smp/core/opcode_mov.bpp @@ -1,20 +1,20 @@ -@macro op_move_reg(rd, rs) - void {class}::op_mov_{rd}_{rs}() { +@macro op_mov_reg(d, s) + void {class}::op_mov_{d}_{s}() { op_io(); - regs.{rd} = regs.{rs}; - regs.p.n = (regs.{rd} & 0x80); - regs.p.z = (regs.{rd} == 0); + regs.{d} = regs.{s}; + regs.p.n = (regs.{d} & 0x80); + regs.p.z = (regs.{d} == 0); } @endmacro -@macro op_move_sp_x() +@macro op_mov_sp_x() void {class}::op_mov_sp_x() { op_io(); regs.sp = regs.x; } @endmacro -@macro op_move_const(r) +@macro op_mov_reg_const(r) void {class}::op_mov_{r}_const() { regs.{r} = op_readpc(); regs.p.n = (regs.{r} & 0x80); @@ -22,7 +22,7 @@ } @endmacro -@macro op_move_a_ix() +@macro op_mov_a_ix() void {class}::op_mov_a_ix() { op_io(); regs.a = op_readdp(regs.x); @@ -31,7 +31,7 @@ } @endmacro -@macro op_move_a_ixinc() +@macro op_mov_a_ixinc() void {class}::op_mov_a_ixinc() { op_io(); regs.a = op_readdp(regs.x++); @@ -41,7 +41,7 @@ } @endmacro -@macro op_move_dp(r) +@macro op_mov_reg_dp(r) void {class}::op_mov_{r}_dp() { sp = op_readpc(); regs.{r} = op_readdp(sp); @@ -50,17 +50,17 @@ } @endmacro -@macro op_move_dpi(rd, rs) - void {class}::op_mov_{rd}_dp{rs}() { +@macro op_mov_reg_dpi(r, i) + void {class}::op_mov_{r}_dp{i}() { sp = op_readpc(); op_io(); - regs.{rd} = op_readdp(sp + regs.{rs}); - regs.p.n = (regs.{rd} & 0x80); - regs.p.z = (regs.{rd} == 0); + regs.{r} = op_readdp(sp + regs.{i}); + regs.p.n = (regs.{r} & 0x80); + regs.p.z = (regs.{r} == 0); } @endmacro -@macro op_move_addr(r) +@macro op_mov_reg_addr(r) void {class}::op_mov_{r}_addr() { sp = op_readpc() << 0; sp |= op_readpc() << 8; @@ -70,18 +70,18 @@ } @endmacro -@macro op_move_addri(r) - void {class}::op_mov_a_addr{r}() { +@macro op_mov_a_addri(i) + void {class}::op_mov_a_addr{i}() { sp = op_readpc() << 0; sp |= op_readpc() << 8; op_io(); - regs.a = op_readaddr(sp + regs.{r}); + regs.a = op_readaddr(sp + regs.{i}); regs.p.n = (regs.a & 0x80); regs.p.z = (regs.a == 0); } @endmacro -@macro op_move_a_idpx() +@macro op_mov_a_idpx() void {class}::op_mov_a_idpx() { dp = op_readpc() + regs.x; op_io(); @@ -93,7 +93,7 @@ } @endmacro -@macro op_move_a_idpy() +@macro op_mov_a_idpy() void {class}::op_mov_a_idpy() { dp = op_readpc(); op_io(); @@ -105,7 +105,7 @@ } @endmacro -@macro op_move_dp_dp() +@macro op_mov_dp_dp() void {class}::op_mov_dp_dp() { sp = op_readpc(); rd = op_readdp(sp); @@ -114,7 +114,7 @@ } @endmacro -@macro op_move_dp_const() +@macro op_mov_dp_const() void {class}::op_mov_dp_const() { rd = op_readpc(); dp = op_readpc(); @@ -123,7 +123,7 @@ } @endmacro -@macro op_move_ix_a() +@macro op_mov_ix_a() void {class}::op_mov_ix_a() { op_io(); op_readdp(regs.x); @@ -131,7 +131,7 @@ } @endmacro -@macro op_move_ixinc_a() +@macro op_mov_ixinc_a() void {class}::op_mov_ixinc_a() { op_io(); op_io(); @@ -139,7 +139,7 @@ } @endmacro -@macro op_move_dp_reg(r) +@macro op_mov_dp_reg(r) void {class}::op_mov_dp_{r}() { dp = op_readpc(); op_readdp(dp); @@ -147,17 +147,17 @@ } @endmacro -@macro op_move_dpi_reg(ri, rs) - void {class}::op_mov_dp{ri}_{rs}() { +@macro op_mov_dpi_reg(r, i) + void {class}::op_mov_dp{i}_{r}() { dp = op_readpc(); op_io(); - dp += regs.{ri}; + dp += regs.{i}; op_readdp(dp); - op_writedp(dp, regs.{rs}); + op_writedp(dp, regs.{r}); } @endmacro -@macro op_move_addr_reg(r) +@macro op_mov_addr_reg(r) void {class}::op_mov_addr_{r}() { dp = op_readpc() << 0; dp |= op_readpc() << 8; @@ -166,18 +166,18 @@ } @endmacro -@macro op_move_addri_reg(r) - void {class}::op_mov_addr{r}_a() { +@macro op_mov_addri_a(i) + void {class}::op_mov_addr{i}_a() { dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - dp += regs.{r}; + dp += regs.{i}; op_readaddr(dp); op_writeaddr(dp, regs.a); } @endmacro -@macro op_move_idpx_a() +@macro op_mov_idpx_a() void {class}::op_mov_idpx_a() { sp = op_readpc(); op_io(); @@ -189,7 +189,7 @@ } @endmacro -@macro op_move_idpy_a() +@macro op_mov_idpy_a() void {class}::op_mov_idpy_a() { sp = op_readpc(); dp = op_readdp(sp + 0) << 0; @@ -201,7 +201,7 @@ } @endmacro -@macro op_move_ya_dp() +@macro op_movw_ya_dp() void {class}::op_movw_ya_dp() { sp = op_readpc(); regs.a = op_readdp(sp + 0); @@ -212,7 +212,7 @@ } @endmacro -@macro op_move_dp_ya() +@macro op_movw_dp_ya() void {class}::op_movw_dp_ya() { dp = op_readpc(); op_readdp(dp); @@ -228,7 +228,7 @@ bit = sp >> 13; sp &= 0x1fff; rd = op_readaddr(sp); - regs.p.c = !!(rd & (1 << bit)); + regs.p.c = (rd & (1 << bit)); } @endmacro @@ -239,9 +239,9 @@ bit = dp >> 13; dp &= 0x1fff; rd = op_readaddr(dp); - if(regs.p.c) rd |= (1 << bit); - else rd &= ~(1 << bit); + (regs.p.c) ? rd |= (1 << bit) : rd &= ~(1 << bit); op_io(); op_writeaddr(dp, rd); } @endmacro + diff --git a/src/smp/core/opcode_pc.bpp b/src/smp/core/opcode_pc.bpp index 12339029..8f9ecdd7 100644 --- a/src/smp/core/opcode_pc.bpp +++ b/src/smp/core/opcode_pc.bpp @@ -44,7 +44,7 @@ if(regs.a == sp) return; op_io(); op_io(); - regs.pc += (int8_t)rd; + regs.pc += (int8_t)rd; } @endmacro @@ -167,3 +167,4 @@ regs.pc = rd; } @endmacro + diff --git a/src/smp/core/opcode_read.bpp b/src/smp/core/opcode_read.bpp index 5cb45b1f..1a5057d9 100644 --- a/src/smp/core/opcode_read.bpp +++ b/src/smp/core/opcode_read.bpp @@ -1,11 +1,11 @@ -@macro op_read_const(name, r) +@macro op_read_reg_const(name, r) void {class}::op_{name}_{r}_const() { rd = op_readpc(); regs.{r} = op_{name}(regs.{r}, rd); } @endmacro -@macro op_read_ix(name) +@macro op_read_a_ix(name) void {class}::op_{name}_a_ix() { op_io(); rd = op_readdp(regs.x); @@ -13,7 +13,7 @@ } @endmacro -@macro op_read_dp(name, r) +@macro op_read_reg_dp(name, r) void {class}::op_{name}_{r}_dp() { dp = op_readpc(); rd = op_readdp(dp); @@ -21,7 +21,7 @@ } @endmacro -@macro op_read_dpx(name) +@macro op_read_a_dpx(name) void {class}::op_{name}_a_dpx() { dp = op_readpc(); op_io(); @@ -30,7 +30,7 @@ } @endmacro -@macro op_read_addr(name, r) +@macro op_read_reg_addr(name, r) void {class}::op_{name}_{r}_addr() { dp = op_readpc() << 0; dp |= op_readpc() << 8; @@ -39,17 +39,17 @@ } @endmacro -@macro op_read_addrn(name, r) - void {class}::op_{name}_a_addr{r}() { +@macro op_read_a_addri(name, i) + void {class}::op_{name}_a_addr{i}() { dp = op_readpc() << 0; dp |= op_readpc() << 8; op_io(); - rd = op_readaddr(dp + regs.{r}); + rd = op_readaddr(dp + regs.{i}); regs.a = op_{name}(regs.a, rd); } @endmacro -@macro op_read_idpx(name) +@macro op_read_a_idpx(name) void {class}::op_{name}_a_idpx() { dp = op_readpc() + regs.x; op_io(); @@ -60,7 +60,7 @@ } @endmacro -@macro op_read_idpy(name) +@macro op_read_a_idpy(name) void {class}::op_{name}_a_idpy() { dp = op_readpc(); op_io(); @@ -71,7 +71,7 @@ } @endmacro -@macro op_rmw_ix_iy(name, write) +@macro op_read_ix_iy(name, write) void {class}::op_{name}_ix_iy() { op_io(); rd = op_readdp(regs.y); @@ -81,7 +81,7 @@ } @endmacro -@macro op_rmw_dp_dp(name, write) +@macro op_read_dp_dp(name, write) void {class}::op_{name}_dp_dp() { sp = op_readpc(); rd = op_readdp(sp); @@ -92,7 +92,7 @@ } @endmacro -@macro op_rmw_dp_const(name, write) +@macro op_read_dp_const(name, write) void {class}::op_{name}_dp_const() { rd = op_readpc(); dp = op_readpc(); @@ -151,7 +151,7 @@ bit = dp >> 13; dp &= 0x1fff; rd = op_readaddr(dp); - rd ^= (1 << bit); + rd ^= 1 << bit; op_writeaddr(dp, rd); } @endmacro @@ -167,3 +167,4 @@ regs.p.c = regs.p.c | {op}(rd & (1 << bit)); } @endmacro + diff --git a/src/smp/core/opcode_rmw.bpp b/src/smp/core/opcode_rmw.bpp index f771608e..bac5700f 100644 --- a/src/smp/core/opcode_rmw.bpp +++ b/src/smp/core/opcode_rmw.bpp @@ -1,11 +1,11 @@ -@macro op_rmw_immediate(name, r) +@macro op_adjust_reg(name, r) void {class}::op_{name}_{r}() { op_io(); regs.{r} = op_{name}(regs.{r}); } @endmacro -@macro op_rmw_dp(name) +@macro op_adjust_dp(name) void {class}::op_{name}_dp() { dp = op_readpc(); rd = op_readdp(dp); @@ -14,7 +14,7 @@ } @endmacro -@macro op_rmw_dpx(name) +@macro op_adjust_dpx(name) void {class}::op_{name}_dpx() { dp = op_readpc(); op_io(); @@ -24,7 +24,7 @@ } @endmacro -@macro op_rmw_addr(name) +@macro op_adjust_addr(name) void {class}::op_{name}_addr() { dp = op_readpc() << 0; dp |= op_readpc() << 8; @@ -34,7 +34,7 @@ } @endmacro -@macro op_rmw_taddr(name, op) +@macro op_tadjust_addr(name, op) void {class}::op_{name}_addr_a() { dp = op_readpc() << 0; dp |= op_readpc() << 8; @@ -46,10 +46,10 @@ } @endmacro -@macro op_rmw_adjust(name, op) +@macro op_adjustw_dp(name, op) void {class}::op_{name}_dp() { dp = op_readpc(); - rd = op_readdp(dp); + rd = op_readdp(dp) << 0; rd {op}; op_writedp(dp++, rd); rd += op_readdp(dp) << 8; @@ -58,3 +58,4 @@ regs.p.z = (rd == 0); } @endmacro + diff --git a/src/smp/core/opcode_table.cpp b/src/smp/core/opcode_table.cpp index 48dfa0cf..c8964e73 100644 --- a/src/smp/core/opcode_table.cpp +++ b/src/smp/core/opcode_table.cpp @@ -1,5 +1,7 @@ +#ifdef SMPCORE_CPP + void SMPcore::initialize_opcode_table() { - #define op(id, name) opcode_table[id] = &SMPcore::op_ ## name; + #define op(id, name) opcode_table[id] = &sSMP::op_ ## name; op(0x00, nop) op(0x01, tcall_0) op(0x02, set0_dp) op(0x03, bbs0) op(0x04, or_a_dp) op(0x05, or_a_addr) op(0x06, or_a_ix) op(0x07, or_a_idpx) @@ -68,3 +70,6 @@ void SMPcore::initialize_opcode_table() { #undef op } + +#endif + diff --git a/src/smp/core/ssmpgen.cpp b/src/smp/core/ssmpgen.cpp new file mode 100644 index 00000000..b6a67db2 --- /dev/null +++ b/src/smp/core/ssmpgen.cpp @@ -0,0 +1,12 @@ +#define CLASS_NAME "sSMP" +#include + +int main() { + generate("op_mov.cpp", "op_mov.b"); + generate("op_pc.cpp", "op_pc.b"); + generate("op_read.cpp", "op_read.b"); + generate("op_rmw.cpp", "op_rmw.b"); + generate("op_misc.cpp", "op_misc.b"); + + return 0; +} diff --git a/src/smp/smp.cpp b/src/smp/smp.cpp index 66f9fcc5..66960a32 100644 --- a/src/smp/smp.cpp +++ b/src/smp/smp.cpp @@ -1,8 +1,8 @@ -#include <../base.hpp> - -#define SMP_CPP -namespace SNES { - +#include <../base.hpp> + +#define SMP_CPP +namespace SNES { + //this is the IPLROM for the S-SMP coprocessor. //the S-SMP does not allow writing to the IPLROM. //all writes are instead mapped to the extended @@ -43,5 +43,5 @@ const uint8_t SMP::iplrom[64] = { /*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x) /*fffe*/ 0xc0, 0xff //reset vector location ($ffc0) }; - -}; +}; + diff --git a/src/smp/smp.hpp b/src/smp/smp.hpp index ac98bf05..e472ef6e 100644 --- a/src/smp/smp.hpp +++ b/src/smp/smp.hpp @@ -1,9 +1,11 @@ class SMP { public: virtual void enter() = 0; + static const uint8_t iplrom[64]; virtual uint8 ram_read(uint16 addr) = 0; - virtual void ram_write(uint16 addr, uint8 value) = 0; + virtual void ram_write(uint16 addr, uint8 value) = 0; + //$f4-$f7 virtual uint8 port_read(uint8 port) = 0; virtual void port_write(uint8 port, uint8 value) = 0; @@ -11,8 +13,6 @@ public: virtual void power() = 0; virtual void reset() = 0; - static const uint8_t iplrom[64]; - SMP() {} virtual ~SMP() {} }; diff --git a/src/smp/ssmp/memory/memory.cpp b/src/smp/ssmp/memory/memory.cpp index 279177d1..e3594bd9 100644 --- a/src/smp/ssmp/memory/memory.cpp +++ b/src/smp/ssmp/memory/memory.cpp @@ -223,4 +223,5 @@ void sSMP::op_write(uint16 addr, uint8 data) { tick_timers(); } -#endif +#endif + diff --git a/src/smp/ssmp/memory/memory.hpp b/src/smp/ssmp/memory/memory.hpp index 4dfdccc1..79141b6f 100644 --- a/src/smp/ssmp/memory/memory.hpp +++ b/src/smp/ssmp/memory/memory.hpp @@ -10,3 +10,4 @@ void op_io(); uint8 op_read(uint16 addr); void op_write(uint16 addr, uint8 data); + diff --git a/src/smp/ssmp/ssmp.cpp b/src/smp/ssmp/ssmp.cpp index 265ae013..1a49cd99 100644 --- a/src/smp/ssmp/ssmp.cpp +++ b/src/smp/ssmp/ssmp.cpp @@ -1,19 +1,19 @@ #include <../base.hpp> - -#define SSMP_CPP + +#define SSMP_CPP namespace SNES { #include "memory/memory.cpp" -#include "timing/timing.cpp" - +#include "timing/timing.cpp" + void sSMP::enter() { - unsigned counter = 0; - while(true) { tracer.trace_smpop(); //traces SMP opcode (only if tracer is enabled) + (this->*opcode_table[op_readpc()])(); //forcefully sync S-CPU and S-SMP, in case chips are not communicating + static unsigned counter = 0; if(++counter >= 128) { counter = 0; scheduler.sync_smpcpu(); @@ -77,10 +77,11 @@ void sSMP::reset() { t2.stage3_ticks = 0; } -sSMP::sSMP() { +sSMP::sSMP() { + initialize_opcode_table(); } sSMP::~sSMP() { } - -}; +}; + diff --git a/src/system/audio/audio.cpp b/src/system/audio/audio.cpp index c0922b15..45e6aeb5 100644 --- a/src/system/audio/audio.cpp +++ b/src/system/audio/audio.cpp @@ -1,111 +1,13 @@ -#ifdef SNES_CPP +#ifdef SYSTEM_CPP -//====================== -//System::AudioResampler -//====================== - -double System::AudioResampler::hermite(double mu1, double a, double b, double c, double d) { - const double tension = 0.0; //-1 = low, 0 = normal, 1 = high - const double bias = 0.0; //-1 = left, 0 = even, 1 = right - double mu2, mu3, m0, m1, a0, a1, a2, a3; - - mu2 = mu1 * mu1; - mu3 = mu2 * mu1; - - m0 = (b - a) * (1 + bias) * (1 - tension) / 2; - m0 += (c - b) * (1 - bias) * (1 - tension) / 2; - m1 = (c - b) * (1 + bias) * (1 - tension) / 2; - m1 += (d - c) * (1 - bias) * (1 - tension) / 2; - - a0 = +2 * mu3 - 3 * mu2 + 1; - a1 = mu3 - 2 * mu2 + mu1; - a2 = mu3 - mu2; - a3 = -2 * mu3 + 3 * mu2; - - return (a0 * b) + (a1 * m0) + (a2 * m1) + (a3 * c); -} - -void System::AudioResampler::sample(uint16_t lsamp, uint16_t rsamp) { - lhist[0] = lhist[1]; - lhist[1] = lhist[2]; - lhist[2] = lhist[3]; - lhist[3] = lsamp; - - rhist[0] = rhist[1]; - rhist[1] = rhist[2]; - rhist[2] = rhist[3]; - rhist[3] = rsamp; - - while(fraction <= 1.0) { - unsigned p = bufferwr++; - lbuffer[p] = sclamp<16>(hermite(fraction, lhist[0], lhist[1], lhist[2], lhist[3])); - rbuffer[p] = sclamp<16>(hermite(fraction, rhist[0], rhist[1], rhist[2], rhist[3])); - bufferlength++; - fraction += step; - } - - fraction -= 1.0; -} - -void System::AudioResampler::reset(unsigned ifreq_, unsigned ofreq_) { - ifreq = ifreq_; - ofreq = ofreq_; - - fraction = 0; - step = (double)ifreq / (double)ofreq; - - bufferlength = 0; - bufferrd = 0; - bufferwr = 0; - - for(unsigned i = 0; i < 4; i++) lhist[i] = 0, rhist[i] = 0; -} - -//============= -//System::Audio -//============= - -//DSP represents S-DSP core sample generation -//COP represents cartridge co-processor sample generation - -//DSP frequency is typically ~32040hz -//must be valid, as SNES always generates audio -void System::Audio::set_dsp_frequency(unsigned freq) { - dsp_frequency = freq; - resample.reset(cop_frequency, dsp_frequency); -} - -//COP frequency can be any value -//a value of zero indicates the cartridge connector sample pins are not used, -//ergo setting to zero will disable mixing between DSP and COP samples -void System::Audio::set_cop_frequency(unsigned freq) { - cop_frequency = freq; - resample.reset(cop_frequency, dsp_frequency); -} - -//TODO: no actual mixing done yet. -//only the Super Gameboy uses this feature thus far; where it is -//possible to stop the SGB completely via disable flag. -//need a way to prevent buffer stalling when this occurs. - -void System::Audio::dsp_sample(uint16 l_sample, uint16 r_sample) { - if(cop_frequency != 0) return; +Audio audio; +void Audio::sample(uint16 l_sample, uint16 r_sample) { system.interface->audio_sample(l_sample, r_sample); -} - -void System::Audio::cop_sample(uint16 l_sample, uint16 r_sample) { - if(cop_frequency == 0) return; - - resample.sample(l_sample, r_sample); - while(resample.bufferlength) { - unsigned p = resample.bufferrd++; - system.interface->audio_sample(resample.lbuffer[p], resample.rbuffer[p]); - resample.bufferlength--; - } } -void System::Audio::init() { +void Audio::init() { } -#endif +#endif + diff --git a/src/system/audio/audio.hpp b/src/system/audio/audio.hpp index 51654cb9..45acaf4f 100644 --- a/src/system/audio/audio.hpp +++ b/src/system/audio/audio.hpp @@ -1,36 +1,8 @@ -class AudioResampler { -public: - //output ofreq samples per input of ifreq samples - unsigned ifreq; //input frequency - unsigned ofreq; //output frequency - - //intrinsic ring buffer: indices wrap around buffer size automatically - uint16_t lbuffer[256]; - uint16_t rbuffer[256]; - uint8_t bufferlength; - uint8_t bufferrd, bufferwr; - - double fraction, step; - int16_t lhist[4], rhist[4]; - double hermite(double mu, double a, double b, double c, double d); - - void sample(uint16_t lsamp, uint16_t rsamp); - void reset(unsigned ifreq, unsigned ofreq); -}; - class Audio { public: - void set_dsp_frequency(unsigned); - void set_cop_frequency(unsigned); - - void dsp_sample(uint16 l_sample, uint16 r_sample); - void cop_sample(uint16 l_sample, uint16 r_sample); + void sample(uint16 l_sample, uint16 r_sample); void init(); +}; - friend class System; +extern Audio audio; -private: - AudioResampler resample; - unsigned dsp_frequency; - unsigned cop_frequency; -} audio; diff --git a/src/system/config/config.cpp b/src/system/config/config.cpp index 59276db4..ca906024 100644 --- a/src/system/config/config.cpp +++ b/src/system/config/config.cpp @@ -1,6 +1,10 @@ -Config::Config() { - controller_port1 = System::Input::DeviceJoypad; - controller_port2 = System::Input::DeviceJoypad; +#ifdef SYSTEM_CPP + +Configuration config; + +Configuration::Configuration() { + controller_port1 = Input::DeviceJoypad; + controller_port2 = Input::DeviceJoypad; expansion_port = System::ExpansionBSX; region = System::Autodetect; @@ -17,3 +21,6 @@ Config::Config() { ppu1.version = 1; ppu2.version = 3; } + +#endif + diff --git a/src/system/config/config.hpp b/src/system/config/config.hpp index 2ead9bb5..8688a432 100644 --- a/src/system/config/config.hpp +++ b/src/system/config/config.hpp @@ -1,32 +1,33 @@ -struct Config { - unsigned controller_port1; - unsigned controller_port2; - unsigned expansion_port; +struct Configuration { + unsigned controller_port1; + unsigned controller_port2; + unsigned expansion_port; unsigned region; - - struct CPU { - unsigned version; - unsigned ntsc_clock_rate; - unsigned pal_clock_rate; - unsigned alu_mul_delay; - unsigned alu_div_delay; - unsigned wram_init_value; - } cpu; - - struct SMP { - unsigned ntsc_clock_rate; - unsigned pal_clock_rate; - } smp; - - struct PPU1 { - unsigned version; - } ppu1; - - struct PPU2 { - unsigned version; + + struct CPU { + unsigned version; + unsigned ntsc_clock_rate; + unsigned pal_clock_rate; + unsigned alu_mul_delay; + unsigned alu_div_delay; + unsigned wram_init_value; + } cpu; + + struct SMP { + unsigned ntsc_clock_rate; + unsigned pal_clock_rate; + } smp; + + struct PPU1 { + unsigned version; + } ppu1; + + struct PPU2 { + unsigned version; } ppu2; - Config(); + Configuration(); }; -extern Config config; +extern Configuration config; + diff --git a/src/system/input/input.cpp b/src/system/input/input.cpp index df3c095b..7535efd4 100644 --- a/src/system/input/input.cpp +++ b/src/system/input/input.cpp @@ -1,6 +1,8 @@ -#ifdef SNES_CPP +#ifdef SYSTEM_CPP + +Input input; -uint8 System::Input::port_read(bool portnumber) { +uint8 Input::port_read(bool portnumber) { port_t &p = port[portnumber]; switch(p.device) { @@ -230,7 +232,7 @@ uint8 System::Input::port_read(bool portnumber) { } //scan all input; update cursor positions if needed -void System::Input::update() { +void Input::update() { system.interface->input_poll(); port_t &p = port[1]; @@ -271,10 +273,21 @@ void System::Input::update() { latchy = (p.device == DeviceJustifiers ? p.justifier.y2 : -1); } } break; + } + + if(latchy < 0 || latchy >= (ppu.overscan() ? 240 : 225) || latchx < 0 || latchx >= 256) { + //cursor is offscreen, set to invalid position so counters are not latched + latchx = ~0; + latchy = ~0; + } else { + //cursor is onscreen + latchx += 40; //offset trigger position to simulate hardware latching delay + latchx <<= 2; //dot -> clock conversion + latchx += 2; //align trigger on half-dot ala interrupts (speed optimization for sCPU::add_clocks) } } -void System::Input::port_set_device(bool portnumber, unsigned device) { +void Input::port_set_device(bool portnumber, unsigned device) { port_t &p = port[portnumber]; p.device = device; @@ -326,7 +339,7 @@ void System::Input::port_set_device(bool portnumber, unsigned device) { } } -void System::Input::poll() { +void Input::poll() { port[0].counter0 = 0; port[0].counter1 = 0; port[1].counter0 = 0; @@ -335,7 +348,8 @@ void System::Input::poll() { port[1].justifier.active = !port[1].justifier.active; } -void System::Input::init() { +void Input::init() { } -#endif +#endif + diff --git a/src/system/input/input.hpp b/src/system/input/input.hpp index f866c83e..357fb8c2 100644 --- a/src/system/input/input.hpp +++ b/src/system/input/input.hpp @@ -67,12 +67,8 @@ public: //latchx, latchy are updated during update() (once per frame) alwaysinline void tick() { //only test if Super Scope or Justifier is connected - if(iobit) { - if(ppu.vcounter() == latchy //test Y cursor position - && ppu.hcounter() == latchx << 2 //test X cursor position (cycles == pixels << 2) - && latchy < (ppu.overscan() ? 240 : 225) //verify Y is not offscreen - && latchx < 256 //verify X is not offscreen - ) ppu.latch_counters(); + if(iobit && ppu.vcounter() == latchy && ppu.hcounter() == latchx) { + ppu.latch_counters(); } } @@ -111,4 +107,8 @@ private: } port[2]; friend class System; -} input; + friend class Video; +}; + +extern Input input; + diff --git a/src/system/interface/interface.hpp b/src/system/interface/interface.hpp index 6e37568a..21a069e3 100644 --- a/src/system/interface/interface.hpp +++ b/src/system/interface/interface.hpp @@ -1,12 +1,8 @@ -//interfaces SNES core with platform-specific functionality (video, audio, input, ...) - class Interface { public: virtual void video_refresh(uint16_t *data, unsigned pitch, unsigned *line, unsigned width, unsigned height) {} virtual void audio_sample(uint16_t l_sample, uint16_t r_sample) {} virtual void input_poll() {} virtual int16_t input_poll(unsigned deviceid, unsigned id) { return 0; } - - virtual void init() {} - virtual void term() {} }; + diff --git a/src/system/scheduler/scheduler.cpp b/src/system/scheduler/scheduler.cpp index 66398cfb..cb808b3d 100644 --- a/src/system/scheduler/scheduler.cpp +++ b/src/system/scheduler/scheduler.cpp @@ -1,4 +1,4 @@ -#ifdef SNES_CPP +#ifdef SYSTEM_CPP Scheduler scheduler; @@ -60,3 +60,4 @@ Scheduler::Scheduler() { } #endif + diff --git a/src/system/system.cpp b/src/system/system.cpp index 82f2548f..4820e44d 100644 --- a/src/system/system.cpp +++ b/src/system/system.cpp @@ -1,34 +1,15 @@ #include <../base.hpp> -#define SNES_CPP +#define SYSTEM_CPP namespace SNES { -System system; -Config config; - +System system; BUSCORE bus; CPUCORE cpu; SMPCORE smp; DSPCORE dsp; PPUCORE ppu; -SuperGameboy sgb; -SA1 sa1; -SA1Bus sa1bus; -BSXBase bsxbase; -BSXCart bsxcart; -BSXFlash bsxflash; -SRTC srtc; -SDD1 sdd1; -SPC7110 spc7110; -Cx4 cx4; -DSP1 dsp1; -DSP2 dsp2; -DSP3 dsp3; -DSP4 dsp4; -OBC1 obc1; -ST010 st010; - #include "scheduler/scheduler.cpp" #include "tracer/tracer.cpp" #include "config/config.cpp" @@ -38,10 +19,9 @@ ST010 st010; #include "input/input.cpp" void System::coprocessor_enter() { - if(cartridge.mode() == Cartridge::ModeSuperGameboy) sgb.enter(); + if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.enter(); if(cartridge.has_sa1()) sa1.enter(); - //no active co-processor while(true) { scheduler.addclocks_cop(64 * 1024 * 1024); scheduler.sync_copcpu(); @@ -57,6 +37,7 @@ void System::runtoframe() { void System::init(Interface *interface_) { interface = interface_; + assert(interface != 0); sgb.init(); sa1.init(); @@ -77,11 +58,9 @@ void System::init(Interface *interface_) { video.init(); audio.init(); input.init(); - interface->init(); } void System::term() { - interface->term(); } void System::power() { @@ -93,9 +72,6 @@ void System::power() { } scheduler.init(); - unsigned freq = (snes_region == NTSC ? config.smp.ntsc_clock_rate : config.smp.pal_clock_rate); - audio.set_dsp_frequency(freq / 768); - audio.set_cop_frequency(0); //disable bus audio by default ppu.PPUcounter::reset(); cpu.power(); @@ -105,9 +81,9 @@ void System::power() { bus.power(); if(expansion() == ExpansionBSX) bsxbase.power(); + if(memory::bsxflash.data()) bsxflash.power(); if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.power(); - if(cartridge.bsx_flash_loaded()) bsxflash.power(); - if(cartridge.mode() == Cartridge::ModeSuperGameboy) sgb.power(); + if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.power(); if(cartridge.has_sa1()) sa1.power(); if(cartridge.has_srtc()) srtc.power(); @@ -129,9 +105,9 @@ void System::power() { for(unsigned i = 0x4300; i <= 0x437f; i++) memory::mmio.map(i, cpu); if(expansion() == ExpansionBSX) bsxbase.enable(); + if(memory::bsxflash.data()) bsxflash.enable(); if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.enable(); - if(cartridge.bsx_flash_loaded()) bsxflash.enable(); - if(cartridge.mode() == Cartridge::ModeSuperGameboy) sgb.enable(); + if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.enable(); if(cartridge.has_sa1()) sa1.enable(); if(cartridge.has_srtc()) srtc.enable(); @@ -153,9 +129,6 @@ void System::power() { void System::reset() { scheduler.init(); - unsigned freq = (snes_region == NTSC ? config.smp.ntsc_clock_rate : config.smp.pal_clock_rate); - audio.set_dsp_frequency(freq / 768); - audio.set_cop_frequency(0); //disable bus audio by default ppu.PPUcounter::reset(); cpu.reset(); @@ -165,9 +138,9 @@ void System::reset() { bus.reset(); if(expansion() == ExpansionBSX) bsxbase.reset(); + if(memory::bsxflash.data()) bsxflash.reset(); if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.reset(); - if(cartridge.bsx_flash_loaded()) bsxflash.reset(); - if(cartridge.mode() == Cartridge::ModeSuperGameboy) sgb.reset(); + if(cartridge.mode() == Cartridge::ModeSuperGameBoy) sgb.reset(); if(cartridge.has_sa1()) sa1.reset(); if(cartridge.has_srtc()) srtc.reset(); @@ -208,7 +181,8 @@ System::ExpansionPortDevice System::expansion() const { return (System::ExpansionPortDevice)snes_expansion; } -System::System() : snes_region(NTSC), snes_expansion(ExpansionNone) { +System::System() : interface(0), snes_region(NTSC), snes_expansion(ExpansionNone) { } }; + diff --git a/src/system/system.hpp b/src/system/system.hpp index 58b2c382..ebb2e778 100644 --- a/src/system/system.hpp +++ b/src/system/system.hpp @@ -1,9 +1,11 @@ +#include "config/config.hpp" #include "interface/interface.hpp" #include "scheduler/scheduler.hpp" #include "tracer/tracer.hpp" -#include "config/config.hpp" -class VideoFilter; +#include "video/video.hpp" +#include "audio/audio.hpp" +#include "input/input.hpp" class System { public: @@ -26,21 +28,21 @@ public: virtual void scanline(); //return *active* region / expansion port device information - //config settings are cached upon power-on + //settings cached upon power-on Region region() const; ExpansionPortDevice expansion() const; - #include "video/video.hpp" - #include "audio/audio.hpp" - #include "input/input.hpp" - System(); virtual ~System() {} -private: +private: Interface *interface; unsigned snes_region; - unsigned snes_expansion; + unsigned snes_expansion; + + friend class Video; + friend class Audio; + friend class Input; }; extern System system; diff --git a/src/system/tracer/tracer.cpp b/src/system/tracer/tracer.cpp index f6b57482..66dea595 100644 --- a/src/system/tracer/tracer.cpp +++ b/src/system/tracer/tracer.cpp @@ -1,4 +1,4 @@ -#ifdef SNES_CPP +#ifdef SYSTEM_CPP Tracer tracer; @@ -89,4 +89,5 @@ Tracer::Tracer() { Tracer::~Tracer() { } -#endif //ifdef SNES_CPP +#endif + diff --git a/src/system/video/video.cpp b/src/system/video/video.cpp index f3f3a7a4..38286cdf 100644 --- a/src/system/video/video.cpp +++ b/src/system/video/video.cpp @@ -1,6 +1,8 @@ -#ifdef SNES_CPP +#ifdef SYSTEM_CPP -const uint8_t System::Video::cursor[15 * 15] = { +Video video; + +const uint8_t Video::cursor[15 * 15] = { 0,0,0,0,0,0,1,1,1,0,0,0,0,0,0, 0,0,0,0,1,1,2,2,2,1,1,0,0,0,0, 0,0,0,1,2,2,1,2,1,2,2,1,0,0,0, @@ -18,7 +20,7 @@ const uint8_t System::Video::cursor[15 * 15] = { 0,0,0,0,0,0,1,1,1,0,0,0,0,0,0, }; -void System::Video::draw_cursor(uint16_t color, int x, int y) { +void Video::draw_cursor(uint16_t color, int x, int y) { for(int cy = 0; cy < 15; cy++) { int vy = y + cy - 7; if(vy <= 0 || vy >= 240) continue; //do not draw offscreen @@ -44,14 +46,14 @@ void System::Video::draw_cursor(uint16_t color, int x, int y) { } } -void System::Video::update() { +void Video::update() { uint16_t *data = (uint16_t*)ppu.output; unsigned width, height; - switch(system.input.port[1].device) { - case System::Input::DeviceSuperScope: draw_cursor(0x001f, system.input.port[1].superscope.x, system.input.port[1].superscope.y); break; - case System::Input::DeviceJustifiers: draw_cursor(0x02e0, system.input.port[1].justifier.x2, system.input.port[1].justifier.y2); //fallthrough - case System::Input::DeviceJustifier: draw_cursor(0x001f, system.input.port[1].justifier.x1, system.input.port[1].justifier.y1); break; + switch(input.port[1].device) { + case Input::DeviceSuperScope: draw_cursor(0x001f, input.port[1].superscope.x, input.port[1].superscope.y); break; + case Input::DeviceJustifiers: draw_cursor(0x02e0, input.port[1].justifier.x2, input.port[1].justifier.y2); //fallthrough + case Input::DeviceJustifier: draw_cursor(0x001f, input.port[1].justifier.x1, input.port[1].justifier.y1); break; } unsigned yoffset = 1; //scanline 0 is always black, skip this line for video output @@ -76,7 +78,7 @@ void System::Video::update() { frame_interlace = false; } -void System::Video::scanline() { +void Video::scanline() { unsigned y = ppu.vcounter(); if(y >= 240) return; @@ -88,11 +90,11 @@ void System::Video::scanline() { frame_interlace |= ppu.interlace(); } -void System::Video::set_mode(Mode mode_) { +void Video::set_mode(Mode mode_) { mode = mode_; } -void System::Video::init() { +void Video::init() { for(unsigned i = 0; i < 240; i++) pline_width[i] = 256; for(unsigned i = 0; i < 480; i++) iline_width[i] = 256; frame_hires = false; @@ -101,3 +103,4 @@ void System::Video::init() { } #endif + diff --git a/src/system/video/video.hpp b/src/system/video/video.hpp index 1118b9fa..b8d44f8b 100644 --- a/src/system/video/video.hpp +++ b/src/system/video/video.hpp @@ -22,4 +22,7 @@ private: void draw_cursor(uint16_t color, int x, int y); friend class System; -} video; +}; + +extern Video video; + diff --git a/src/ui_qt/Makefile b/src/ui_qt/Makefile index 03ca0253..7ea341f2 100644 --- a/src/ui_qt/Makefile +++ b/src/ui_qt/Makefile @@ -1,79 +1,58 @@ -############################## -### platform configuration ### -############################## - objects := main $(if $(call streq,$(platform),win),resource) $(objects) - -moc = moc -rcc = rcc - -ifeq ($(platform),x) # X11 - link += $(call mklib,Xtst) - link += `pkg-config --libs QtCore QtGui` - qtflags = `pkg-config --cflags QtCore QtGui` -else ifeq ($(platform),win) # Windows - qtdir = c:/qt450 - - link += $(call mklibpath,$(qtdir)/lib) - link += $(call mklibpath,$(qtdir)/plugins/imageformats) - - link += $(call mklib,mingw32) - link += $(call mklib,qtmain) - link += $(call mklib,QtGui) - link += $(call mklib,comdlg32) - link += $(call mklib,oleaut32) - link += $(call mklib,imm32) - link += $(call mklib,winmm) - link += $(call mklib,winspool) - link += $(call mklib,msimg32) - link += $(call mklib,QtCore) - link += $(call mklib,ole32) - link += $(call mklib,advapi32) - link += $(call mklib,ws2_32) - link += $(call mklib,uuid) - link += $(call mklib,gdi32) - - # optional image-file support: - # link += $(call mklib,qjpeg) - # link += $(call mklib,qmng) - - qtflags = $(call mkincpath,$(qtdir)/include) - qtflags += $(call mkincpath,$(qtdir)/include/QtCore) - qtflags += $(call mkincpath,$(qtdir)/include/QtGui) + +ifeq ($(moc),) +moc := moc +endif + +ifeq ($(rcc),) +rcc := rcc endif -moc_objects = \ - $(ui)/base/main.moc \ - $(ui)/base/loader.moc \ - $(ui)/base/htmlviewer.moc \ - $(ui)/base/about.moc \ - $(ui)/settings/settings.moc \ - $(ui)/settings/video.moc \ - $(ui)/settings/audio.moc \ - $(ui)/settings/input.moc \ - $(ui)/settings/paths.moc \ - $(ui)/settings/cheateditor.moc \ - $(ui)/settings/advanced.moc \ - $(ui)/settings/utility/inputcapture.moc \ - $(ui)/settings/utility/codeeditor.moc \ +ifeq ($(platform),x) + qtflags = `pkg-config --cflags QtCore QtGui` + link += `pkg-config --libs QtCore QtGui` +else ifeq ($(platform),win) + ifeq ($(qtpath),) + # find Qt install directory from PATH environment variable + qtpath := $(foreach path,$(subst ;, ,$(PATH)),$(if $(wildcard $(path)/$(moc).exe),$(path))) + qtpath := $(strip $(qtpath)) + qtpath := $(subst \,/,$(qtpath)) + qtpath := $(patsubst %/bin,%,$(qtpath)) + endif + + qtflags := -I$(qtpath)/include + qtflags += -I$(qtpath)/include/QtCore + qtflags += -I$(qtpath)/include/QtGui + + link += -L$(qtpath)/lib + link += -L$(qtpath)/plugins/imageformats + + link += -lmingw32 -lqtmain -lQtGui -lcomdlg32 -loleaut32 -limm32 -lwinmm + link += -lwinspool -lmsimg32 -lQtCore -lole32 -ladvapi32 -lws2_32 -luuid -lgdi32 + + # optional image-file support: + # link += -lqjpeg -lqmng +endif + +moc_headers := $(call rwildcard,$(ui)/,%.mh) +moc_objects := $(patsubst %.mh,%.moc,$(moc_headers)) ############# ### rules ### ############# -%.moc: $<; $(moc) $(patsubst %.moc,%.hpp,$@) -o $@ -$(foreach object,$(moc_objects),$(eval $(object): $(patsubst %.moc,%.hpp,$(object)))) +# automatically run moc on all .mh (.MocHeader) files +%.moc: $<; $(moc) -f $< -o $@ +$(foreach f,$(moc_objects),$(eval $f: $(patsubst %.moc,%.mh,$f))) -obj/main.$(obj): $(ui)/main.cpp \ -$(ui)/* $(ui)/cartridge/* $(ui)/input/* $(ui)/utility/* $(ui)/base/* $(ui)/settings/* $(ui)/settings/utility/* \ -data/* +obj/main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/) $(call compile,$(qtflags)) $(ui)/resource/resource.rcc: $(ui)/resource/resource.qrc data/* $(rcc) $(ui)/resource/resource.qrc -o $(ui)/resource/resource.rcc -obj/resource.$(obj): $(ui)/resource/resource.rc - windres $(ui)/resource/resource.rc obj/resource.$(obj) +obj/resource.o: $(ui)/resource/resource.rc + windres $(ui)/resource/resource.rc obj/resource.o ############### ### targets ### @@ -81,5 +60,5 @@ obj/resource.$(obj): $(ui)/resource/resource.rc ui_build: $(ui)/resource/resource.rcc $(moc_objects); ui_clean: - -$(foreach object,$(moc_objects),@$(call delete,$(object))) + -$(foreach f,$(moc_objects),@$(call delete,$f)) -@$(call delete,$(ui)/resource/resource.rcc) diff --git a/src/ui_qt/base/about.hpp b/src/ui_qt/base/about.mh similarity index 100% rename from src/ui_qt/base/about.hpp rename to src/ui_qt/base/about.mh diff --git a/src/ui_qt/base/htmlviewer.hpp b/src/ui_qt/base/htmlviewer.mh similarity index 100% rename from src/ui_qt/base/htmlviewer.hpp rename to src/ui_qt/base/htmlviewer.mh diff --git a/src/ui_qt/base/loader.cpp b/src/ui_qt/base/loader.cpp index e0b6679c..e19720b1 100644 --- a/src/ui_qt/base/loader.cpp +++ b/src/ui_qt/base/loader.cpp @@ -46,10 +46,6 @@ void LoaderWindow::setup() { slot2Clear = new QPushButton("Clear"); grid->addWidget(slot2Clear, 2, 3); - - bypassSuperGameboy = new QCheckBox("Bypass Super Gameboy BIOS"); - bypassSuperGameboy->setEnabled(false); - grid->addWidget(bypassSuperGameboy, 3, 0, 1, 3); } grid->setSpacing(Style::WidgetSpacing); layout->addLayout(grid); @@ -90,7 +86,6 @@ void LoaderWindow::loadBsxSlottedCartridge(const char *filebase, const char *fil baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show(); slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show(); slot2Label->hide(), slot2File->hide(), slot2Browse->hide(), slot2Clear->hide(); - bypassSuperGameboy->hide(); slot1Label->setText("Slot cartridge:"); @@ -107,7 +102,6 @@ void LoaderWindow::loadBsxCartridge(const char *fileBase, const char *fileSlot1) baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show(); slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show(); slot2Label->hide(), slot2File->hide(), slot2Browse->hide(), slot2Clear->hide(); - bypassSuperGameboy->hide(); slot1Label->setText("Slot cartridge:"); @@ -124,7 +118,6 @@ void LoaderWindow::loadSufamiTurboCartridge(const char *fileBase, const char *fi baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show(); slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show(); slot2Label->show(), slot2File->show(), slot2Browse->show(), slot2Clear->show(); - bypassSuperGameboy->hide(); slot1Label->setText("Slot A cartridge:"); slot2Label->setText("Slot B cartridge:"); @@ -136,23 +129,22 @@ void LoaderWindow::loadSufamiTurboCartridge(const char *fileBase, const char *fi syncUi(); mode = SNES::Cartridge::ModeSufamiTurbo; showWindow("Load Sufami Turbo Cartridge"); -} - -void LoaderWindow::loadSuperGameboyCartridge(const char *fileBase, const char *fileSlot1) { - window->hide(); - baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show(); - slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show(); - slot2Label->hide(), slot2File->hide(), slot2Browse->hide(), slot2Clear->hide(); - bypassSuperGameboy->show(); - - slot1Label->setText("Gameboy cartridge:"); - - baseFile->setText(fileBase); - slot1File->setText(fileSlot1); - - syncUi(); - mode = SNES::Cartridge::ModeSuperGameboy; - showWindow("Load Super Gameboy Cartridge"); +} + +void LoaderWindow::loadSuperGameBoyCartridge(const char *fileBase, const char *fileSlot1) { + window->hide(); + baseLabel->show(), baseFile->show(), baseBrowse->show(), baseClear->show(); + slot1Label->show(), slot1File->show(), slot1Browse->show(), slot1Clear->show(); + slot2Label->hide(), slot2File->hide(), slot2Browse->hide(), slot2Clear->hide(); + + slot1Label->setText("Game Boy cartridge:"); + + baseFile->setText(fileBase); + slot1File->setText(fileSlot1); + + syncUi(); + mode = SNES::Cartridge::ModeSuperGameBoy; + showWindow("Load Super Game Boy Cartridge"); } void LoaderWindow::showWindow(const char *title) { @@ -162,7 +154,7 @@ void LoaderWindow::showWindow(const char *title) { } void LoaderWindow::selectBaseCartridge() { - string filename = utility.selectCartridge(Utility::SnesCartridge); + string filename = utility.selectCartridge(); if(filename.length() > 0) baseFile->setText(utf8() << filename); syncUi(); } @@ -173,12 +165,7 @@ void LoaderWindow::clearBaseCartridge() { } void LoaderWindow::selectSlot1Cartridge() { - string filename; - if(mode == SNES::Cartridge::ModeSuperGameboy) { - filename = utility.selectCartridge(Utility::GameboyCartridge); - } else { - filename = utility.selectCartridge(Utility::SnesCartridge); - } + string filename = utility.selectCartridge(); if(filename.length() > 0) slot1File->setText(utf8() << filename); syncUi(); } @@ -189,7 +176,7 @@ void LoaderWindow::clearSlot1Cartridge() { } void LoaderWindow::selectSlot2Cartridge() { - string filename = utility.selectCartridge(Utility::SnesCartridge); + string filename = utility.selectCartridge(); if(filename.length() > 0) slot2File->setText(utf8() << filename); syncUi(); } @@ -207,22 +194,22 @@ void LoaderWindow::onLoad() { switch(mode) { case SNES::Cartridge::ModeBsxSlotted: { - cartridge.loadBsxSlotted(base, slot1); + utility.loadCartridgeBsxSlotted(base, slot1); } break; case SNES::Cartridge::ModeBsx: { config.path.bsx = base; - cartridge.loadBsx(base, slot1); + utility.loadCartridgeBsx(base, slot1); } break; case SNES::Cartridge::ModeSufamiTurbo: { config.path.st = base; - cartridge.loadSufamiTurbo(base, slot1, slot2); - } break; - - case SNES::Cartridge::ModeSuperGameboy: { - config.path.sgb = base; - cartridge.loadSuperGameboy(base, slot1); + utility.loadCartridgeSufamiTurbo(base, slot1, slot2); + } break; + + case SNES::Cartridge::ModeSuperGameBoy: { + config.path.sgb = base; + utility.loadCartridgeSuperGameBoy(base, slot1); } break; } } diff --git a/src/ui_qt/base/loader.hpp b/src/ui_qt/base/loader.mh similarity index 88% rename from src/ui_qt/base/loader.hpp rename to src/ui_qt/base/loader.mh index 621ba9d5..d4dd52e2 100644 --- a/src/ui_qt/base/loader.hpp +++ b/src/ui_qt/base/loader.mh @@ -17,7 +17,6 @@ public: QLineEdit *slot2File; QPushButton *slot2Browse; QPushButton *slot2Clear; - QCheckBox *bypassSuperGameboy; QHBoxLayout *controls; QPushButton *load; QPushButton *cancel; @@ -27,8 +26,8 @@ public: void syncUi(); void loadBsxSlottedCartridge(const char*, const char*); void loadBsxCartridge(const char*, const char*); - void loadSufamiTurboCartridge(const char*, const char*, const char*); - void loadSuperGameboyCartridge(const char*, const char*); + void loadSufamiTurboCartridge(const char*, const char*, const char*); + void loadSuperGameBoyCartridge(const char*, const char*); public slots: void selectBaseCartridge(); diff --git a/src/ui_qt/base/main.cpp b/src/ui_qt/base/main.cpp index 71136d83..8e60bfd3 100644 --- a/src/ui_qt/base/main.cpp +++ b/src/ui_qt/base/main.cpp @@ -200,17 +200,17 @@ void MainWindow::syncUi() { system_power_off->setChecked(application.power == false); system_reset->setEnabled(SNES::cartridge.loaded() && application.power); - system_port1_none->setChecked (SNES::config.controller_port1 == SNES::System::Input::DeviceNone); - system_port1_joypad->setChecked (SNES::config.controller_port1 == SNES::System::Input::DeviceJoypad); - system_port1_multitap->setChecked (SNES::config.controller_port1 == SNES::System::Input::DeviceMultitap); - system_port1_mouse->setChecked (SNES::config.controller_port1 == SNES::System::Input::DeviceMouse); - system_port2_none->setChecked (SNES::config.controller_port2 == SNES::System::Input::DeviceNone); - system_port2_joypad->setChecked (SNES::config.controller_port2 == SNES::System::Input::DeviceJoypad); - system_port2_multitap->setChecked (SNES::config.controller_port2 == SNES::System::Input::DeviceMultitap); - system_port2_mouse->setChecked (SNES::config.controller_port2 == SNES::System::Input::DeviceMouse); - system_port2_superscope->setChecked(SNES::config.controller_port2 == SNES::System::Input::DeviceSuperScope); - system_port2_justifier->setChecked (SNES::config.controller_port2 == SNES::System::Input::DeviceJustifier); - system_port2_justifiers->setChecked(SNES::config.controller_port2 == SNES::System::Input::DeviceJustifiers); + system_port1_none->setChecked (SNES::config.controller_port1 == SNES::Input::DeviceNone); + system_port1_joypad->setChecked (SNES::config.controller_port1 == SNES::Input::DeviceJoypad); + system_port1_multitap->setChecked (SNES::config.controller_port1 == SNES::Input::DeviceMultitap); + system_port1_mouse->setChecked (SNES::config.controller_port1 == SNES::Input::DeviceMouse); + system_port2_none->setChecked (SNES::config.controller_port2 == SNES::Input::DeviceNone); + system_port2_joypad->setChecked (SNES::config.controller_port2 == SNES::Input::DeviceJoypad); + system_port2_multitap->setChecked (SNES::config.controller_port2 == SNES::Input::DeviceMultitap); + system_port2_mouse->setChecked (SNES::config.controller_port2 == SNES::Input::DeviceMouse); + system_port2_superscope->setChecked(SNES::config.controller_port2 == SNES::Input::DeviceSuperScope); + system_port2_justifier->setChecked (SNES::config.controller_port2 == SNES::Input::DeviceJustifier); + system_port2_justifiers->setChecked(SNES::config.controller_port2 == SNES::Input::DeviceJustifiers); settings_videoMode_1x->setChecked (config.video.context->multiplier == 1); settings_videoMode_2x->setChecked (config.video.context->multiplier == 2); @@ -244,7 +244,7 @@ void MainWindow::syncUi() { } void MainWindow::loadCartridge() { - string filename = utility.selectCartridge(Utility::AnyCartridge); + string filename = utility.selectCartridge(); if(filename.length() > 0) utility.loadCartridge(filename); } @@ -252,17 +252,17 @@ void MainWindow::powerOn() { utility.modifySystemState(Utility::PowerOn); } void MainWindow::powerOff() { utility.modifySystemState(Utility::PowerOff); } void MainWindow::reset() { utility.modifySystemState(Utility::Reset); } -void MainWindow::setPort1None() { SNES::config.controller_port1 = SNES::System::Input::DeviceNone; utility.updateControllers(); syncUi(); } -void MainWindow::setPort1Joypad() { SNES::config.controller_port1 = SNES::System::Input::DeviceJoypad; utility.updateControllers(); syncUi(); } -void MainWindow::setPort1Multitap() { SNES::config.controller_port1 = SNES::System::Input::DeviceMultitap; utility.updateControllers(); syncUi(); } -void MainWindow::setPort1Mouse() { SNES::config.controller_port1 = SNES::System::Input::DeviceMouse; utility.updateControllers(); syncUi(); } -void MainWindow::setPort2None() { SNES::config.controller_port2 = SNES::System::Input::DeviceNone; utility.updateControllers(); syncUi(); } -void MainWindow::setPort2Joypad() { SNES::config.controller_port2 = SNES::System::Input::DeviceJoypad; utility.updateControllers(); syncUi(); } -void MainWindow::setPort2Multitap() { SNES::config.controller_port2 = SNES::System::Input::DeviceMultitap; utility.updateControllers(); syncUi(); } -void MainWindow::setPort2Mouse() { SNES::config.controller_port2 = SNES::System::Input::DeviceMouse; utility.updateControllers(); syncUi(); } -void MainWindow::setPort2SuperScope() { SNES::config.controller_port2 = SNES::System::Input::DeviceSuperScope; utility.updateControllers(); syncUi(); } -void MainWindow::setPort2Justifier() { SNES::config.controller_port2 = SNES::System::Input::DeviceJustifier; utility.updateControllers(); syncUi(); } -void MainWindow::setPort2Justifiers() { SNES::config.controller_port2 = SNES::System::Input::DeviceJustifiers; utility.updateControllers(); syncUi(); } +void MainWindow::setPort1None() { SNES::config.controller_port1 = SNES::Input::DeviceNone; utility.updateControllers(); syncUi(); } +void MainWindow::setPort1Joypad() { SNES::config.controller_port1 = SNES::Input::DeviceJoypad; utility.updateControllers(); syncUi(); } +void MainWindow::setPort1Multitap() { SNES::config.controller_port1 = SNES::Input::DeviceMultitap; utility.updateControllers(); syncUi(); } +void MainWindow::setPort1Mouse() { SNES::config.controller_port1 = SNES::Input::DeviceMouse; utility.updateControllers(); syncUi(); } +void MainWindow::setPort2None() { SNES::config.controller_port2 = SNES::Input::DeviceNone; utility.updateControllers(); syncUi(); } +void MainWindow::setPort2Joypad() { SNES::config.controller_port2 = SNES::Input::DeviceJoypad; utility.updateControllers(); syncUi(); } +void MainWindow::setPort2Multitap() { SNES::config.controller_port2 = SNES::Input::DeviceMultitap; utility.updateControllers(); syncUi(); } +void MainWindow::setPort2Mouse() { SNES::config.controller_port2 = SNES::Input::DeviceMouse; utility.updateControllers(); syncUi(); } +void MainWindow::setPort2SuperScope() { SNES::config.controller_port2 = SNES::Input::DeviceSuperScope; utility.updateControllers(); syncUi(); } +void MainWindow::setPort2Justifier() { SNES::config.controller_port2 = SNES::Input::DeviceJustifier; utility.updateControllers(); syncUi(); } +void MainWindow::setPort2Justifiers() { SNES::config.controller_port2 = SNES::Input::DeviceJustifiers; utility.updateControllers(); syncUi(); } void MainWindow::quit() { application.terminate = true; diff --git a/src/ui_qt/base/main.hpp b/src/ui_qt/base/main.mh similarity index 100% rename from src/ui_qt/base/main.hpp rename to src/ui_qt/base/main.mh diff --git a/src/ui_qt/cartridge/cartridge.cpp b/src/ui_qt/cartridge/cartridge.cpp deleted file mode 100644 index da90fb9a..00000000 --- a/src/ui_qt/cartridge/cartridge.cpp +++ /dev/null @@ -1,341 +0,0 @@ -bool Cartridge::loadNormal(const char *base) { - uint8_t *data; - unsigned size; - if(!loadFile(base, data, size, true)) return false; - unload(); - mode = SNES::Cartridge::ModeNormal; - cartName = base; - - if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512); - SNES::cartridge.load_normal(data, size); - delete[] data; - - loadMemory(SNES::memory::cartram, cartName, ".srm"); - loadMemory(SNES::memory::cartrtc, cartName, ".rtc"); - loadCheats(cartName); - - name = basename(cartName); - utility.modifySystemState(Utility::LoadCartridge); - return true; -} - -bool Cartridge::loadBsxSlotted(const char *base, const char *slot) { - uint8_t *data; - unsigned size; - if(!loadFile(base, data, size, true)) return false; - unload(); - mode = SNES::Cartridge::ModeBsxSlotted; - cartName = base; - slotName[0] = slot; - - uint8_t *slotData; - unsigned slotSize; - loadFile(slot, slotData, slotSize, true); - - if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512); - SNES::cartridge.load_bsx_slotted(data, size, slotData, slotSize); - delete[] data; - if(slotData) delete[] slotData; - - loadMemory(SNES::memory::cartram, cartName, ".srm"); - loadCheats(cartName); - - name = basename(cartName); - if(slotName[0] != "") name << " + " << basename(slotName[0]); - utility.modifySystemState(Utility::LoadCartridge); - return true; -} - -bool Cartridge::loadBsx(const char *base, const char *slot) { - uint8_t *data; - unsigned size; - if(!loadFile(base, data, size, true)) return false; - unload(); - mode = SNES::Cartridge::ModeBsx; - cartName = base; - slotName[0] = slot; - - uint8_t *slotData; - unsigned slotSize; - loadFile(slot, slotData, slotSize, true); - - if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512); - SNES::cartridge.load_bsx(data, size, slotData, slotSize); - delete[] data; - if(slotData) delete[] slotData; - - loadMemory(SNES::bsxcart.sram, cartName, ".srm"); - loadMemory(SNES::bsxcart.psram, cartName, ".psr"); - loadCheats(cartName); - - if(slotName[0] != "") name = basename(slotName[0]); - else name = basename(cartName); - utility.modifySystemState(Utility::LoadCartridge); - return true; -} - -bool Cartridge::loadSufamiTurbo(const char *base, const char *slotA, const char *slotB) { - uint8_t *data; - unsigned size; - if(!loadFile(base, data, size, true)) return false; - unload(); - mode = SNES::Cartridge::ModeSufamiTurbo; - cartName = base; - slotName[0] = slotA; - slotName[1] = slotB; - - uint8_t *slotData[2]; - unsigned slotSize[2]; - loadFile(slotA, slotData[0], slotSize[0], true); - loadFile(slotB, slotData[1], slotSize[1], true); - - if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512); - SNES::cartridge.load_sufami_turbo(data, size, slotData[0], slotSize[0], slotData[1], slotSize[1]); - delete[] data; - if(slotData[0]) delete[] slotData[0]; - if(slotData[1]) delete[] slotData[1]; - - loadMemory(SNES::memory::stAram, slotName[0], ".srm"); - loadMemory(SNES::memory::stBram, slotName[1], ".srm"); - loadCheats(cartName); - - if(slotName[0] != "" && slotName[1] != "") name = string() << basename(slotName[0]) << " + " << basename(slotName[1]); - else if(slotName[0] != "") name = basename(slotName[0]); - else if(slotName[1] != "") name = basename(slotName[1]); - else name = basename(cartName); - utility.modifySystemState(Utility::LoadCartridge); - return true; -} - -bool Cartridge::loadSuperGameboy(const char *base, const char *slot) { - uint8_t *data; - unsigned size; - if(!loadFile(base, data, size, true)) return false; - unload(); - mode = SNES::Cartridge::ModeSuperGameboy; - cartName = base; - slotName[0] = slot; - - uint8_t *slotData; - unsigned slotSize; - loadFile(slot, slotData, slotSize, true); - - if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512); - SNES::cartridge.load_super_gameboy(data, size, slotData, slotSize); - delete[] data; - - loadMemory(SNES::memory::dmgram, slotName[0], ".sav"); - loadMemory(SNES::memory::dmgrtc, slotName[0], ".rtc"); - loadCheats(cartName); - - if(slotName[0] != "") name = basename(slotName[0]); - else name = basename(cartName); - utility.modifySystemState(Utility::LoadCartridge); - return true; -} - -void Cartridge::unload() { - switch(mode) { - case SNES::Cartridge::ModeNormal: - case SNES::Cartridge::ModeBsxSlotted: { - saveMemory(SNES::memory::cartram, cartName, ".srm"); - saveMemory(SNES::memory::cartrtc, cartName, ".rtc"); - } break; - - case SNES::Cartridge::ModeBsx: { - saveMemory(SNES::bsxcart.sram, cartName, ".srm"); - saveMemory(SNES::bsxcart.psram, cartName, ".psr"); - } break; - - case SNES::Cartridge::ModeSufamiTurbo: { - saveMemory(SNES::memory::stAram, slotName[0], ".srm"); - saveMemory(SNES::memory::stBram, slotName[1], ".srm"); - } break; - - case SNES::Cartridge::ModeSuperGameboy: { - SNES::sgb.unload(); - saveMemory(SNES::memory::dmgram, slotName[0], ".sav"); - saveMemory(SNES::memory::dmgrtc, slotName[0], ".rtc"); - } break; - }; - - saveCheats(cartName); - utility.modifySystemState(Utility::UnloadCartridge); -} - -void Cartridge::loadCheats(const char *filename) { - string name; - name << (config.path.cheat != "" ? config.path.cheat : basepath(filename)); - name << basename(filename); - name << ".cht"; - if(file::exists(name)) SNES::cheat.load(name); -} - -void Cartridge::saveCheats(const char *filename) { - string name; - name << (config.path.cheat != "" ? config.path.cheat : basepath(filename)); - name << basename(filename); - name << ".cht"; - if(file::exists(name) || SNES::cheat.count() > 0) SNES::cheat.save(name); -} - -// - -void Cartridge::loadMemory(SNES::MappedRAM &memory, const char *filename, const char *extension) { - if(*filename && memory.size() > 0 && memory.size() != -1U) { - string name; - name << (config.path.save != "" ? config.path.save : basepath(filename)); - name << basename(filename); - name << extension; - - uint8_t *data; - unsigned size; - if(loadFile(name, data, size, false)) { - memcpy(memory.handle(), data, min(memory.size(), size)); - delete[] data; - } - } -} - -void Cartridge::saveMemory(SNES::MappedRAM &memory, const char *filename, const char *extension) { - if(*filename && memory.size() > 0 && memory.size() != -1U) { - string name; - name << (config.path.save != "" ? config.path.save : basepath(filename)); - name << basename(filename); - name << extension; - - file fp; - if(fp.open(name, file::mode_write)) { - fp.write(memory.handle(), memory.size()); - fp.close(); - } - } -} - -bool Cartridge::loadFile(const char *name, uint8_t *&data, unsigned &size, bool compression) { - data = 0; - size = 0; - - switch(Reader::detect(name, config.file.autodetect_type)) { - case Reader::Normal: { - FileReader fp(name); - if(!fp.ready()) return false; - size = fp.size(); - data = fp.read(); - } break; - - #ifdef GZIP_SUPPORT - case Reader::GZIP: { - GZReader fp(name); - if(!fp.ready()) return false; - size = fp.size(); - data = fp.read(); - } break; - - case Reader::ZIP: { - ZipReader fp(name); - if(!fp.ready()) return false; - size = fp.size(); - data = fp.read(); - } break; - #endif - - #ifdef JMA_SUPPORT - case Reader::JMA: { - try { - JMAReader fp(fp); - size = fp.size(); - data = fp.read(); - } catch(JMA::jma_errors jma_error) { - return false; - } - } break; - #endif - - default: return false; - } - - return true; -} - -SNES::Cartridge::Type Cartridge::detectImageType(const char *filename) { - uint8_t *data; - unsigned size; - if(!loadFile(filename, data, size, true)) return SNES::Cartridge::TypeUnknown; - - if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512); - SNES::Cartridge::Type type = SNES::cartridge.detect_image_type(data, size); - delete[] data; - return type; -} - -// - -//ensure file path is absolute (eg resolve relative paths) -string Cartridge::filepath(const char *filename, const char *pathname) { - //if no pathname, return filename as-is - string file(filename); - file.replace("\\", "/"); - - string path = (!pathname || !*pathname) ? (const char*)config.path.current : pathname; - //ensure path ends with trailing '/' - path.replace("\\", "/"); - if(!strend(path, "/")) path.append("/"); - - //replace relative path with absolute path - if(strbegin(path, "./")) { - ltrim(path, "./"); - path = string() << config.path.base << path; - } - - //remove folder part of filename - lstring part; - part.split("/", file); - return path << part[part.size() - 1]; -} - -//remove directory information and file extension ("/foo/bar.ext" -> "bar") -string Cartridge::basename(const char *filename) { - string name(filename); - - //remove extension - for(signed i = strlen(name) - 1; i >= 0; i--) { - if(name[i] == '.') { - name[i] = 0; - break; - } - } - - //remove directory information - for(signed i = strlen(name) - 1; i >= 0; i--) { - if(name[i] == '/' || name[i] == '\\') { - i++; - char *output = name(); - while(true) { - *output++ = name[i]; - if(!name[i]) break; - i++; - } - break; - } - } - - return name; -} - -//remove filename and return path only ("/foo/bar.ext" -> "/foo/") -string Cartridge::basepath(const char *filename) { - string path(filename); - path.replace("\\", "/"); - - //remove filename - for(signed i = strlen(path) - 1; i >= 0; i--) { - if(path[i] == '/') { - path[i] = 0; - break; - } - } - - if(!strend(path, "/")) path.append("/"); - return path; -} diff --git a/src/ui_qt/cartridge/cartridge.hpp b/src/ui_qt/cartridge/cartridge.hpp deleted file mode 100644 index f69436b8..00000000 --- a/src/ui_qt/cartridge/cartridge.hpp +++ /dev/null @@ -1,25 +0,0 @@ -class Cartridge { -public: - SNES::Cartridge::Mode mode; - string name; - string cartName, slotName[2]; - - SNES::Cartridge::Type detectImageType(const char *filename); - bool loadNormal(const char *base); - bool loadBsxSlotted(const char *base, const char *slot); - bool loadBsx(const char *base, const char *slot); - bool loadSufamiTurbo(const char *base, const char *slotA, const char *slotB); - bool loadSuperGameboy(const char *base, const char *slot); - void unload(); - - static string filepath(const char*, const char*); - static string basename(const char*); - static string basepath(const char*); - -private: - bool loadFile(const char *name, uint8_t *&data, unsigned &size, bool compression); - void loadMemory(SNES::MappedRAM&, const char*, const char*); - void saveMemory(SNES::MappedRAM&, const char*, const char*); - void loadCheats(const char *filename); - void saveCheats(const char *filename); -} cartridge; diff --git a/src/ui_qt/config.cpp b/src/ui_qt/config.cpp index c6fb5b37..7afb2592 100644 --- a/src/ui_qt/config.cpp +++ b/src/ui_qt/config.cpp @@ -1,11 +1,11 @@ class Configuration : public configuration { -public: +public: struct System { string video, audio, input; bool crashedOnLastRun; unsigned speed; - } system; - + } system; + struct File { bool autodetect_type; bool bypass_patch_crc32; @@ -13,7 +13,7 @@ public: struct Path { string base; //binary path - string user; //user profile path + string user; //user profile path (bsnes.cfg, ...) string current; //current working directory (path to currently loaded cartridge) string rom, save, patch, cheat, data; string bsx, st, sgb; @@ -83,10 +83,10 @@ public: //external //======== - attach(SNES::config.controller_port1 = SNES::System::Input::DeviceJoypad, "snes.controllerPort1"); - attach(SNES::config.controller_port2 = SNES::System::Input::DeviceJoypad, "snes.controllerPort2"); - attach(SNES::config.expansion_port = SNES::System::ExpansionBSX, "snes.expansionPort"); - attach(SNES::config.region = SNES::System::Autodetect, "snes.region"); + attach(SNES::config.controller_port1 = SNES::Input::DeviceJoypad, "snes.controllerPort1"); + attach(SNES::config.controller_port2 = SNES::Input::DeviceJoypad, "snes.controllerPort2"); + attach(SNES::config.expansion_port = SNES::System::ExpansionBSX, "snes.expansionPort"); + attach(SNES::config.region = SNES::System::Autodetect, "snes.region"); attach(SNES::config.cpu.version = 2, "cpu.version", "Valid version(s) are: 1, 2"); attach(SNES::config.cpu.ntsc_clock_rate = 21477272, "cpu.ntscClockRate"); @@ -105,18 +105,15 @@ public: //internal //======== - attach(system.video = "", "driver.video"); - attach(system.audio = "", "driver.audio"); - attach(system.input = "", "driver.input"); - attach(system.crashedOnLastRun = false, "emulator.crashedOnLastRun"); - attach(system.speed = 2, "emulator.speed"); - + attach(system.video = "", "system.video"); + attach(system.audio = "", "system.audio"); + attach(system.input = "", "system.input"); + attach(system.crashedOnLastRun = false, "system.crashedOnLastRun"); + attach(system.speed = 2, "system.speed"); + attach(file.autodetect_type = false, "file.autodetectType"); attach(file.bypass_patch_crc32 = false, "file.bypassPatchCrc32"); - path.base = ""; - path.user = ""; - path.current = ""; attach(path.rom = "", "path.rom"); attach(path.save = "", "path.save"); attach(path.patch = "", "path.patch"); @@ -124,7 +121,7 @@ public: attach(path.data = "", "path.data"); attach(path.bsx = "", "path.bsx"); attach(path.st = "", "path.st"); - attach(path.sgb = "", "path.sgb"); + attach(path.sgb = "", "path.sgb"); video.context = &video.windowed; attach(video.isFullscreen = false, "video.isFullscreen"); diff --git a/src/ui_qt/input/device.cpp b/src/ui_qt/input/device.cpp index 6722ce4f..6b41ba1b 100644 --- a/src/ui_qt/input/device.cpp +++ b/src/ui_qt/input/device.cpp @@ -2,7 +2,7 @@ //InputDevice //=========== -InputDevice::InputDevice(SNES::System::Input::DeviceID i, bool p, const char *n) : InputGroup(n), id(i), port(p) { +InputDevice::InputDevice(SNES::Input::DeviceID i, bool p, const char *n) : InputGroup(n), id(i), port(p) { } //====== @@ -13,29 +13,29 @@ int16_t Joypad::state(unsigned index) const { if(config.input.allowInvalidInput == false) { //SNES D-pads have central pivot point, making up+down or left+right combinations impossible. //some software programs rely on this, and will crash if these combinations are allowed. - if(index == SNES::System::Input::JoypadDown && up.state ) return 0; - if(index == SNES::System::Input::JoypadRight && left.state) return 0; + if(index == SNES::Input::JoypadDown && up.state ) return 0; + if(index == SNES::Input::JoypadRight && left.state) return 0; } switch(index) { - case SNES::System::Input::JoypadUp: return up.state; - case SNES::System::Input::JoypadDown: return down.state; - case SNES::System::Input::JoypadLeft: return left.state; - case SNES::System::Input::JoypadRight: return right.state; - case SNES::System::Input::JoypadA: return a.state; - case SNES::System::Input::JoypadB: return b.state; - case SNES::System::Input::JoypadX: return x.state; - case SNES::System::Input::JoypadY: return y.state; - case SNES::System::Input::JoypadL: return l.state; - case SNES::System::Input::JoypadR: return r.state; - case SNES::System::Input::JoypadSelect: return select.state; - case SNES::System::Input::JoypadStart: return start.state; + case SNES::Input::JoypadUp: return up.state; + case SNES::Input::JoypadDown: return down.state; + case SNES::Input::JoypadLeft: return left.state; + case SNES::Input::JoypadRight: return right.state; + case SNES::Input::JoypadA: return a.state; + case SNES::Input::JoypadB: return b.state; + case SNES::Input::JoypadX: return x.state; + case SNES::Input::JoypadY: return y.state; + case SNES::Input::JoypadL: return l.state; + case SNES::Input::JoypadR: return r.state; + case SNES::Input::JoypadSelect: return select.state; + case SNES::Input::JoypadStart: return start.state; } return 0; } -Joypad::Joypad(SNES::System::Input::DeviceID id, bool port, const char *name, +Joypad::Joypad(SNES::Input::DeviceID id, bool port, const char *name, string &up_t, string &down_t, string &left_t, string &right_t, string &a_t, string &b_t, string &x_t, string &y_t, string &l_t, string &r_t, string &select_t, string &start_t ) : @@ -62,16 +62,16 @@ start (InputObject::Button, "Start", start_t) { int16_t Mouse::state(unsigned index) const { switch(index) { - case SNES::System::Input::MouseX: return x.state; - case SNES::System::Input::MouseY: return y.state; - case SNES::System::Input::MouseLeft: return left.state; - case SNES::System::Input::MouseRight: return right.state; + case SNES::Input::MouseX: return x.state; + case SNES::Input::MouseY: return y.state; + case SNES::Input::MouseLeft: return left.state; + case SNES::Input::MouseRight: return right.state; } return 0; } -Mouse::Mouse(SNES::System::Input::DeviceID id, bool port, const char *name, +Mouse::Mouse(SNES::Input::DeviceID id, bool port, const char *name, string &x_t, string &y_t, string &left_t, string &right_t ) : InputDevice(id, port, name), @@ -88,18 +88,18 @@ right(InputObject::Button, "Right button", right_t) { int16_t SuperScope::state(unsigned index) const { switch(index) { - case SNES::System::Input::SuperScopeX: return x.state; - case SNES::System::Input::SuperScopeY: return y.state; - case SNES::System::Input::SuperScopeTrigger: return trigger.state; - case SNES::System::Input::SuperScopeCursor: return cursor.state; - case SNES::System::Input::SuperScopeTurbo: return turbo.state; - case SNES::System::Input::SuperScopePause: return pause.state; + case SNES::Input::SuperScopeX: return x.state; + case SNES::Input::SuperScopeY: return y.state; + case SNES::Input::SuperScopeTrigger: return trigger.state; + case SNES::Input::SuperScopeCursor: return cursor.state; + case SNES::Input::SuperScopeTurbo: return turbo.state; + case SNES::Input::SuperScopePause: return pause.state; } return 0; } -SuperScope::SuperScope(SNES::System::Input::DeviceID id, bool port, const char *name, +SuperScope::SuperScope(SNES::Input::DeviceID id, bool port, const char *name, string &x_t, string &y_t, string &trigger_t, string &cursor_t, string &turbo_t, string &pause_t ) : InputDevice(id, port, name), @@ -118,16 +118,16 @@ pause (InputObject::Button, "Pause", pause_t) { int16_t Justifier::state(unsigned index) const { switch(index) { - case SNES::System::Input::JustifierX: return x.state; - case SNES::System::Input::JustifierY: return y.state; - case SNES::System::Input::JustifierTrigger: return trigger.state; - case SNES::System::Input::JustifierStart: return start.state; + case SNES::Input::JustifierX: return x.state; + case SNES::Input::JustifierY: return y.state; + case SNES::Input::JustifierTrigger: return trigger.state; + case SNES::Input::JustifierStart: return start.state; } return 0; } -Justifier::Justifier(SNES::System::Input::DeviceID id, bool port, const char *name, +Justifier::Justifier(SNES::Input::DeviceID id, bool port, const char *name, string &x_t, string &y_t, string &trigger_t, string &start_t ) : InputDevice(id, port, name), @@ -158,7 +158,7 @@ void InputDevicePool::poll(const int16_t *table) { for(unsigned i = 0; i < list.size(); i++) list[i]->poll(table); } -InputDevice* InputDevicePool::find(SNES::System::Input::DeviceID id) { +InputDevice* InputDevicePool::find(SNES::Input::DeviceID id) { for(unsigned i = 0; i < list.size(); i++) { if(list[i]->id == id) return list[i]; } @@ -171,72 +171,72 @@ InputDevicePool::InputDevicePool() : list(*this) { // -Joypad joypad1(SNES::System::Input::DeviceIDJoypad1, InputDevice::Port1, "Joypad", +Joypad joypad1(SNES::Input::DeviceIDJoypad1, InputDevice::Port1, "Joypad", config.input.joypad1.up, config.input.joypad1.down, config.input.joypad1.left, config.input.joypad1.right, config.input.joypad1.a, config.input.joypad1.b, config.input.joypad1.x, config.input.joypad1.y, config.input.joypad1.l, config.input.joypad1.r, config.input.joypad1.select, config.input.joypad1.start); -Joypad joypad2(SNES::System::Input::DeviceIDJoypad2, InputDevice::Port2, "Joypad", +Joypad joypad2(SNES::Input::DeviceIDJoypad2, InputDevice::Port2, "Joypad", config.input.joypad2.up, config.input.joypad2.down, config.input.joypad2.left, config.input.joypad2.right, config.input.joypad2.a, config.input.joypad2.b, config.input.joypad2.x, config.input.joypad2.y, config.input.joypad2.l, config.input.joypad2.r, config.input.joypad2.select, config.input.joypad2.start); -Joypad multitap1a(SNES::System::Input::DeviceIDMultitap1A, InputDevice::Port1, "Multitap - Port 1", +Joypad multitap1a(SNES::Input::DeviceIDMultitap1A, InputDevice::Port1, "Multitap - Port 1", config.input.multitap1a.up, config.input.multitap1a.down, config.input.multitap1a.left, config.input.multitap1a.right, config.input.multitap1a.a, config.input.multitap1a.b, config.input.multitap1a.x, config.input.multitap1a.y, config.input.multitap1a.l, config.input.multitap1a.r, config.input.multitap1a.select, config.input.multitap1a.start); -Joypad multitap1b(SNES::System::Input::DeviceIDMultitap1B, InputDevice::Port1, "Multitap - Port 2", +Joypad multitap1b(SNES::Input::DeviceIDMultitap1B, InputDevice::Port1, "Multitap - Port 2", config.input.multitap1b.up, config.input.multitap1b.down, config.input.multitap1b.left, config.input.multitap1b.right, config.input.multitap1b.a, config.input.multitap1b.b, config.input.multitap1b.x, config.input.multitap1b.y, config.input.multitap1b.l, config.input.multitap1b.r, config.input.multitap1b.select, config.input.multitap1b.start); -Joypad multitap1c(SNES::System::Input::DeviceIDMultitap1C, InputDevice::Port1, "Multitap - Port 3", +Joypad multitap1c(SNES::Input::DeviceIDMultitap1C, InputDevice::Port1, "Multitap - Port 3", config.input.multitap1c.up, config.input.multitap1c.down, config.input.multitap1c.left, config.input.multitap1c.right, config.input.multitap1c.a, config.input.multitap1c.b, config.input.multitap1c.x, config.input.multitap1c.y, config.input.multitap1c.l, config.input.multitap1c.r, config.input.multitap1c.select, config.input.multitap1c.start); -Joypad multitap1d(SNES::System::Input::DeviceIDMultitap1D, InputDevice::Port1, "Multitap - Port 4", +Joypad multitap1d(SNES::Input::DeviceIDMultitap1D, InputDevice::Port1, "Multitap - Port 4", config.input.multitap1d.up, config.input.multitap1d.down, config.input.multitap1d.left, config.input.multitap1d.right, config.input.multitap1d.a, config.input.multitap1d.b, config.input.multitap1d.x, config.input.multitap1d.y, config.input.multitap1d.l, config.input.multitap1d.r, config.input.multitap1d.select, config.input.multitap1d.start); -Joypad multitap2a(SNES::System::Input::DeviceIDMultitap2A, InputDevice::Port2, "Multitap - Port 1", +Joypad multitap2a(SNES::Input::DeviceIDMultitap2A, InputDevice::Port2, "Multitap - Port 1", config.input.multitap2a.up, config.input.multitap2a.down, config.input.multitap2a.left, config.input.multitap2a.right, config.input.multitap2a.a, config.input.multitap2a.b, config.input.multitap2a.x, config.input.multitap2a.y, config.input.multitap2a.l, config.input.multitap2a.r, config.input.multitap2a.select, config.input.multitap2a.start); -Joypad multitap2b(SNES::System::Input::DeviceIDMultitap2B, InputDevice::Port2, "Multitap - Port 2", +Joypad multitap2b(SNES::Input::DeviceIDMultitap2B, InputDevice::Port2, "Multitap - Port 2", config.input.multitap2b.up, config.input.multitap2b.down, config.input.multitap2b.left, config.input.multitap2b.right, config.input.multitap2b.a, config.input.multitap2b.b, config.input.multitap2b.x, config.input.multitap2b.y, config.input.multitap2b.l, config.input.multitap2b.r, config.input.multitap2b.select, config.input.multitap2b.start); -Joypad multitap2c(SNES::System::Input::DeviceIDMultitap2C, InputDevice::Port2, "Multitap - Port 3", +Joypad multitap2c(SNES::Input::DeviceIDMultitap2C, InputDevice::Port2, "Multitap - Port 3", config.input.multitap2c.up, config.input.multitap2c.down, config.input.multitap2c.left, config.input.multitap2c.right, config.input.multitap2c.a, config.input.multitap2c.b, config.input.multitap2c.x, config.input.multitap2c.y, config.input.multitap2c.l, config.input.multitap2c.r, config.input.multitap2c.select, config.input.multitap2c.start); -Joypad multitap2d(SNES::System::Input::DeviceIDMultitap2D, InputDevice::Port2, "Multitap - Port 4", +Joypad multitap2d(SNES::Input::DeviceIDMultitap2D, InputDevice::Port2, "Multitap - Port 4", config.input.multitap2d.up, config.input.multitap2d.down, config.input.multitap2d.left, config.input.multitap2d.right, config.input.multitap2d.a, config.input.multitap2d.b, config.input.multitap2d.x, config.input.multitap2d.y, config.input.multitap2d.l, config.input.multitap2d.r, config.input.multitap2d.select, config.input.multitap2d.start); -Mouse mouse1(SNES::System::Input::DeviceIDMouse1, InputDevice::Port1, "Mouse", +Mouse mouse1(SNES::Input::DeviceIDMouse1, InputDevice::Port1, "Mouse", config.input.mouse1.x, config.input.mouse1.y, config.input.mouse1.left, config.input.mouse1.right); -Mouse mouse2(SNES::System::Input::DeviceIDMouse2, InputDevice::Port2, "Mouse", +Mouse mouse2(SNES::Input::DeviceIDMouse2, InputDevice::Port2, "Mouse", config.input.mouse2.x, config.input.mouse2.y, config.input.mouse2.left, config.input.mouse2.right); -SuperScope superscope(SNES::System::Input::DeviceIDSuperScope, InputDevice::Port2, "Super Scope", +SuperScope superscope(SNES::Input::DeviceIDSuperScope, InputDevice::Port2, "Super Scope", config.input.superscope.x, config.input.superscope.y, config.input.superscope.trigger, config.input.superscope.cursor, config.input.superscope.turbo, config.input.superscope.pause); -Justifier justifier1(SNES::System::Input::DeviceIDJustifier1, InputDevice::Port2, "Justifier 1", +Justifier justifier1(SNES::Input::DeviceIDJustifier1, InputDevice::Port2, "Justifier 1", config.input.justifier1.x, config.input.justifier1.y, config.input.justifier1.trigger, config.input.justifier1.start); -Justifier justifier2(SNES::System::Input::DeviceIDJustifier2, InputDevice::Port2, "Justifier 2", +Justifier justifier2(SNES::Input::DeviceIDJustifier2, InputDevice::Port2, "Justifier 2", config.input.justifier2.x, config.input.justifier2.y, config.input.justifier2.trigger, config.input.justifier2.start); diff --git a/src/ui_qt/input/device.hpp b/src/ui_qt/input/device.hpp index 9918c3d2..5ac95f74 100644 --- a/src/ui_qt/input/device.hpp +++ b/src/ui_qt/input/device.hpp @@ -1,16 +1,16 @@ struct InputDevice : InputGroup { - SNES::System::Input::DeviceID id; + SNES::Input::DeviceID id; enum Port { Port1, Port2 }; const bool port; - InputDevice(SNES::System::Input::DeviceID i, bool p, const char *n); + InputDevice(SNES::Input::DeviceID i, bool p, const char *n); }; struct Joypad : InputDevice { InputObject up, down, left, right, a, b, x, y, l, r, select, start; int16_t state(unsigned index) const; - Joypad(SNES::System::Input::DeviceID id, bool port, const char *name, + Joypad(SNES::Input::DeviceID id, bool port, const char *name, string&, string&, string&, string&, string&, string&, string&, string&, string&, string&, string&, string&); }; @@ -19,7 +19,7 @@ struct Mouse : InputDevice { InputObject x, y, left, right; int16_t state(unsigned index) const; - Mouse(SNES::System::Input::DeviceID id, bool port, const char *name, + Mouse(SNES::Input::DeviceID id, bool port, const char *name, string&, string&, string&, string&); }; @@ -27,7 +27,7 @@ struct SuperScope : InputDevice { InputObject x, y, trigger, cursor, turbo, pause; int16_t state(unsigned index) const; - SuperScope(SNES::System::Input::DeviceID id, bool port, const char *name, + SuperScope(SNES::Input::DeviceID id, bool port, const char *name, string&, string&, string&, string&, string&, string&); }; @@ -35,7 +35,7 @@ struct Justifier : InputDevice { InputObject x, y, trigger, start; int16_t state(unsigned index) const; - Justifier(SNES::System::Input::DeviceID id, bool port, const char *name, + Justifier(SNES::Input::DeviceID id, bool port, const char *name, string&, string&, string&, string&); }; @@ -44,7 +44,7 @@ struct InputDevicePool : public array { void bind(); void clear(); void poll(const int16_t *table); - InputDevice* find(SNES::System::Input::DeviceID id); + InputDevice* find(SNES::Input::DeviceID id); InputDevicePool(); private: diff --git a/src/ui_qt/input/input.cpp b/src/ui_qt/input/input.cpp index 02848704..f958685c 100644 --- a/src/ui_qt/input/input.cpp +++ b/src/ui_qt/input/input.cpp @@ -103,7 +103,7 @@ int16_t InputManager::lastState(uint16_t code) const { } int16_t InputManager::getStatus(unsigned deviceid, unsigned id) const { - InputDevice *device = inputPool.find((SNES::System::Input::DeviceID)deviceid); + InputDevice *device = inputPool.find((SNES::Input::DeviceID)deviceid); if(device) return device->state(id); return 0; } diff --git a/src/ui_qt/interface.cpp b/src/ui_qt/interface.cpp index df1f73c1..cc2ee82b 100644 --- a/src/ui_qt/interface.cpp +++ b/src/ui_qt/interface.cpp @@ -1,5 +1,5 @@ -class Interface : public SNES::Interface { -public: +class Interface : public SNES::Interface { +public: void video_refresh(uint16_t *data, unsigned pitch, unsigned *line, unsigned width, unsigned height) { uint32_t *output; unsigned outpitch; @@ -23,4 +23,5 @@ public: int16_t input_poll(unsigned deviceid, unsigned id) { return inputManager.getStatus(deviceid, id); } -} interface; +} interface; + diff --git a/src/ui_qt/main.cpp b/src/ui_qt/main.cpp index 141c64d9..ad9cb4a1 100644 --- a/src/ui_qt/main.cpp +++ b/src/ui_qt/main.cpp @@ -13,7 +13,6 @@ public: #include "interface.cpp" #include "ui.cpp" -#include "cartridge/cartridge.cpp" #include "input/input.cpp" #include "utility/utility.cpp" @@ -134,12 +133,27 @@ int Application::main(int argc, char **argv) { SNES::system.runtoframe(); } else { usleep(20 * 1000); + } + + clock_t currentTime = clock(); + autosaveTime += currentTime - clockTime; + screensaverTime += currentTime - clockTime; + clockTime = currentTime; + + if(autosaveTime >= CLOCKS_PER_SEC * 60) { + //auto-save RAM once per minute in case of emulator crash + autosaveTime = 0; + utility.saveMemory(); + } + + if(screensaverTime >= CLOCKS_PER_SEC * 30) { + //supress screen saver every 30 seconds so it will not trigger during gameplay + screensaverTime = 0; + supressScreenSaver(); } - - supressScreenSaver(); } - - cartridge.unload(); + + utility.unloadCartridge(); config.save(configFilename); return 0; } @@ -152,7 +166,11 @@ Application::Application() { terminate = false; power = false; pause = false; - autopause = false; + autopause = false; + + clockTime = clock(); + autosaveTime = 0; + screensaverTime = 0; } Application::~Application() { diff --git a/src/ui_qt/main.hpp b/src/ui_qt/main.hpp index b559645a..ba64fac8 100644 --- a/src/ui_qt/main.hpp +++ b/src/ui_qt/main.hpp @@ -9,31 +9,29 @@ //Q_IMPORT_PLUGIN(QJpegPlugin) //Q_IMPORT_PLUGIN(QMngPlugin) -#include -#include - -#if defined(GZIP_SUPPORT) - #include - #include -#endif - -#if defined(JMA_SUPPORT) - #include -#endif - #include <../base.hpp> #include -#include #include using namespace nall; #include -using namespace ruby; +using namespace ruby; + +#include +#include + +#if defined(GZIP_SUPPORT) + #include + #include +#endif + +#if defined(JMA_SUPPORT) + #include +#endif #include -#include "cartridge/cartridge.hpp" #include "input/input.hpp" #include "utility/utility.hpp" @@ -50,7 +48,11 @@ public: bool terminate; //set to true to terminate main() loop and exit emulator bool power; bool pause; - bool autopause; + bool autopause; + + clock_t clockTime; + clock_t autosaveTime; + clock_t screensaverTime; string configFilename; string styleSheetFilename; diff --git a/src/ui_qt/platform.cpp b/src/ui_qt/platform.cpp index d3abb4e0..a7e9c537 100644 --- a/src/ui_qt/platform.cpp +++ b/src/ui_qt/platform.cpp @@ -53,12 +53,22 @@ void supressScreenSaver() { //handled by event filter above } -#else +#else #define None XNone #define Window XWindow - #include + #include #undef None - #undef Window + #undef Window + + struct LibXtst : public library { + function XTestFakeKeyEvent; + + LibXtst() { + if(open("Xtst")) { + XTestFakeKeyEvent = sym("XTestFakeKeyEvent"); + } + } + } libXtst; //POSIX-compatible (Linux, BSD, etc.) char* userpath(char *path) { @@ -77,12 +87,8 @@ void initargs(int &argc, char **&argv) { } - void supressScreenSaver() { - static clock_t delta_x = 0, delta_y = 0; - - delta_y = clock(); - if(delta_y - delta_x < CLOCKS_PER_SEC * 20) return; - delta_x = delta_y; + void supressScreenSaver() { + if(!libXtst.XTestFakeKeyEvent) return; //XSetScreenSaver(timeout = 0) does not work //XResetScreenSaver() does not work @@ -91,9 +97,9 @@ //XSendEvent(KeyPressMask) does not work //use XTest extension to send fake keypress every ~20 seconds. //keycode of 255 does not map to any actual key, - //but it will block screensaver and power management. + //but it will block screensaver and power management. Display *display = XOpenDisplay(0); - XTestFakeKeyEvent(display, 255, True, 0); - XTestFakeKeyEvent(display, 255, False, 0); + libXtst.XTestFakeKeyEvent(display, 255, True, 0); + libXtst.XTestFakeKeyEvent(display, 255, False, 0); } #endif diff --git a/src/ui_qt/settings/advanced.hpp b/src/ui_qt/settings/advanced.mh similarity index 100% rename from src/ui_qt/settings/advanced.hpp rename to src/ui_qt/settings/advanced.mh diff --git a/src/ui_qt/settings/audio.hpp b/src/ui_qt/settings/audio.mh similarity index 100% rename from src/ui_qt/settings/audio.hpp rename to src/ui_qt/settings/audio.mh diff --git a/src/ui_qt/settings/cheateditor.hpp b/src/ui_qt/settings/cheateditor.mh similarity index 100% rename from src/ui_qt/settings/cheateditor.hpp rename to src/ui_qt/settings/cheateditor.mh diff --git a/src/ui_qt/settings/input.hpp b/src/ui_qt/settings/input.mh similarity index 100% rename from src/ui_qt/settings/input.hpp rename to src/ui_qt/settings/input.mh diff --git a/src/ui_qt/settings/paths.cpp b/src/ui_qt/settings/paths.cpp index e8da48fd..2faebadb 100644 --- a/src/ui_qt/settings/paths.cpp +++ b/src/ui_qt/settings/paths.cpp @@ -137,8 +137,7 @@ void PathSettingsWindow::syncUi() { void PathSettingsWindow::selectGamePath() { string path = utility.selectFolder("Default Game Path"); if(path.length() > 0) { - config.path.rom = strtr(path, "\\", "/"); - if(!strend(config.path.rom, "/")) config.path.rom << "/"; + config.path.rom = path; syncUi(); } } @@ -151,8 +150,7 @@ void PathSettingsWindow::defaultGamePath() { void PathSettingsWindow::selectSavePath() { string path = utility.selectFolder("Default Save RAM Path"); if(path.length() > 0) { - config.path.save = strtr(path, "\\", "/"); - if(!strend(config.path.save, "/")) config.path.save << "/"; + config.path.save = path; syncUi(); } } @@ -165,8 +163,7 @@ void PathSettingsWindow::defaultSavePath() { void PathSettingsWindow::selectPatchPath() { string path = utility.selectFolder("Default UPS Patch Path"); if(path.length() > 0) { - config.path.patch = strtr(path, "\\", "/"); - if(!strend(config.path.patch, "/")) config.path.patch << "/"; + config.path.patch = path; syncUi(); } } @@ -179,8 +176,7 @@ void PathSettingsWindow::defaultPatchPath() { void PathSettingsWindow::selectCheatPath() { string path = utility.selectFolder("Default Cheat File Path"); if(path.length() > 0) { - config.path.cheat = strtr(path, "\\", "/"); - if(!strend(config.path.cheat, "/")) config.path.cheat << "/"; + config.path.cheat = path; syncUi(); } } @@ -193,8 +189,7 @@ void PathSettingsWindow::defaultCheatPath() { void PathSettingsWindow::selectDataPath() { string path = utility.selectFolder("Default Export Data Path"); if(path.length() > 0) { - config.path.data = strtr(path, "\\", "/"); - if(!strend(config.path.data, "/")) config.path.data << "/"; + config.path.data = path; syncUi(); } } diff --git a/src/ui_qt/settings/paths.hpp b/src/ui_qt/settings/paths.mh similarity index 100% rename from src/ui_qt/settings/paths.hpp rename to src/ui_qt/settings/paths.mh diff --git a/src/ui_qt/settings/settings.hpp b/src/ui_qt/settings/settings.mh similarity index 100% rename from src/ui_qt/settings/settings.hpp rename to src/ui_qt/settings/settings.mh diff --git a/src/ui_qt/settings/utility/codeeditor.hpp b/src/ui_qt/settings/utility/codeeditor.mh similarity index 100% rename from src/ui_qt/settings/utility/codeeditor.hpp rename to src/ui_qt/settings/utility/codeeditor.mh diff --git a/src/ui_qt/settings/utility/inputcapture.hpp b/src/ui_qt/settings/utility/inputcapture.mh similarity index 100% rename from src/ui_qt/settings/utility/inputcapture.hpp rename to src/ui_qt/settings/utility/inputcapture.mh diff --git a/src/ui_qt/settings/video.hpp b/src/ui_qt/settings/video.mh similarity index 100% rename from src/ui_qt/settings/video.hpp rename to src/ui_qt/settings/video.mh diff --git a/src/ui_qt/utility/cartridge.cpp b/src/ui_qt/utility/cartridge.cpp index 06f6884e..1100fac9 100644 --- a/src/ui_qt/utility/cartridge.cpp +++ b/src/ui_qt/utility/cartridge.cpp @@ -1,59 +1,163 @@ -string Utility::selectCartridge(unsigned cartridgeType) { - string match; - - if(cartridgeType == AnyCartridge) { - match = "All cartridges (*.sfc *.smc *.swc *.fig *.bs *.st *.gb *.gbc #GZIP #JMA);;" - "SNES cartridges (*.sfc *.smc *.swc *.fig *.bs *.st #GZIP #JMA);;" - "Gameboy cartridges (*.gb *.gbc #GZIP #JMA);;"; - } else if(cartridgeType == SnesCartridge) { - match = "SNES cartridges (*.sfc *.smc *.swc *.fig *.bs *.st #GZIP #JMA);;"; - } else if(cartridgeType == GameboyCartridge) { - match = "Gameboy cartridges (*.gb *.gbc #GZIP #JMA);;"; - } else return ""; - - #if defined(GZIP_SUPPORT) - match.replace(" #GZIP", " *.zip *.gz"); - #else - match.replace(" #GZIP", ""); - #endif - - #if defined(JMA_SUPPORT) - match.replace(" #JMA", " *.jma"); - #else - match.replace( "#JMA", ""); - #endif - - match << "All files (*)"; - +string Utility::selectCartridge() { audio.clear(); - QString filename = QFileDialog::getOpenFileName(0, "Load Cartridge", - utf8() << (config.path.rom != "" ? config.path.rom : config.path.current), - utf8() << match - ); - return string() << filename.toUtf8().constData(); + QString filename = QFileDialog::getOpenFileName(0, + "Load Cartridge", + utf8() << (config.path.rom != "" ? config.path.rom : config.path.current), + "SNES images (*.smc *.sfc *.swc *.fig *.bs *.st" + #if defined(GZIP_SUPPORT) + " *.zip *.gz" + #endif + #if defined(JMA_SUPPORT) + " *.jma" + #endif + ");;" + "All files (*)" + ); + + string name = filename.toUtf8().constData(); + if(strlen(name) > 0) config.path.current = basepath(name); + return name; } string Utility::selectFolder(const char *title) { audio.clear(); QString pathname = QFileDialog::getExistingDirectory(0, title, utf8() << config.path.current, - QFileDialog::ShowDirsOnly); - return string() << pathname.toUtf8().constData(); + QFileDialog::ShowDirsOnly); + string path = pathname.toUtf8().constData(); + strtr(path, "\\", "/"); + if(strend(path, "/") == false) path << "/"; + return path; } -void Utility::loadCartridge(const char *filename) { - switch(cartridge.detectImageType(filename)) { - case SNES::Cartridge::TypeNormal: cartridge.loadNormal(filename); break; +void Utility::loadCartridge(const char *filename) { + SNES::MappedRAM memory; + if(loadCartridge(filename, memory) == false) return; + SNES::Cartridge::Type type = SNES::cartridge.detect_image_type(memory.data(), memory.size()); + memory.reset(); + + switch(type) { + case SNES::Cartridge::TypeNormal: loadCartridgeNormal(filename); break; case SNES::Cartridge::TypeBsxSlotted: winLoader->loadBsxSlottedCartridge(filename, ""); break; case SNES::Cartridge::TypeBsxBios: winLoader->loadBsxCartridge(filename, ""); break; case SNES::Cartridge::TypeBsx: winLoader->loadBsxCartridge(config.path.bsx, filename); break; case SNES::Cartridge::TypeSufamiTurboBios: winLoader->loadSufamiTurboCartridge(filename, "", ""); break; - case SNES::Cartridge::TypeSufamiTurbo: winLoader->loadSufamiTurboCartridge(config.path.st, filename, ""); break; - case SNES::Cartridge::TypeSuperGameboyBios: winLoader->loadSuperGameboyCartridge(filename, ""); break; - case SNES::Cartridge::TypeGameboy: winLoader->loadSuperGameboyCartridge(config.path.sgb, filename); break; + case SNES::Cartridge::TypeSufamiTurbo: winLoader->loadSufamiTurboCartridge(config.path.st, filename, ""); break; + case SNES::Cartridge::TypeSuperGameBoyBios: winLoader->loadSuperGameBoyCartridge(filename, ""); break; + case SNES::Cartridge::TypeGameBoy: winLoader->loadSuperGameBoyCartridge(config.path.sgb, filename); break; } } +bool Utility::loadCartridgeNormal(const char *base) { + unloadCartridge(); + if(loadCartridge(cartridge.baseName = base, SNES::memory::cartrom) == false) return false; + SNES::cartridge.load(SNES::Cartridge::ModeNormal); + + loadMemory(cartridge.baseName, ".srm", SNES::memory::cartram); + loadMemory(cartridge.baseName, ".rtc", SNES::memory::cartrtc); + + cartridge.name = basename(base); + + modifySystemState(LoadCartridge); + return true; +} + +bool Utility::loadCartridgeBsxSlotted(const char *base, const char *slot) { + unloadCartridge(); + if(loadCartridge(cartridge.baseName = base, SNES::memory::cartrom) == false) return false; + loadCartridge(cartridge.slotAName = slot, SNES::memory::bsxflash); + SNES::cartridge.load(SNES::Cartridge::ModeBsxSlotted); + + loadMemory(cartridge.baseName, ".srm", SNES::memory::cartram); + loadMemory(cartridge.baseName, ".rtc", SNES::memory::cartrtc); + + cartridge.name = basename(base); + if(*slot) cartridge.name << " + " << basename(slot); + + modifySystemState(LoadCartridge); + return true; +} + +bool Utility::loadCartridgeBsx(const char *base, const char *slot) { + unloadCartridge(); + if(loadCartridge(cartridge.baseName = base, SNES::memory::cartrom) == false) return false; + loadCartridge(cartridge.slotAName = slot, SNES::memory::bsxflash); + SNES::cartridge.load(SNES::Cartridge::ModeBsx); + + loadMemory(cartridge.baseName, ".srm", SNES::memory::bsxram ); + loadMemory(cartridge.baseName, ".psr", SNES::memory::bsxpram); + + cartridge.name = (*slot ? basename(slot) : basename(base)); + + modifySystemState(LoadCartridge); + return true; +} + +bool Utility::loadCartridgeSufamiTurbo(const char *base, const char *slotA, const char *slotB) { + unloadCartridge(); + if(loadCartridge(cartridge.baseName = base, SNES::memory::cartrom) == false) return false; + loadCartridge(cartridge.slotAName = slotA, SNES::memory::stArom); + loadCartridge(cartridge.slotBName = slotB, SNES::memory::stBrom); + SNES::cartridge.load(SNES::Cartridge::ModeSufamiTurbo); + + loadMemory(cartridge.slotAName, ".srm", SNES::memory::stAram); + loadMemory(cartridge.slotBName, ".srm", SNES::memory::stBram); + + if(!*slotA && !*slotB) cartridge.name = basename(base); + else if(!*slotB) cartridge.name = basename(slotA); + else if(!*slotA) cartridge.name = basename(slotB); + else cartridge.name = string() << basename(slotA) << " + " << basename(slotB); + + modifySystemState(LoadCartridge); + return true; +} + +bool Utility::loadCartridgeSuperGameBoy(const char *base, const char *slot) { + unloadCartridge(); + if(loadCartridge(cartridge.baseName = base, SNES::memory::cartrom) == false) return false; + loadCartridge(cartridge.slotAName = slot, SNES::memory::gbrom); + SNES::cartridge.load(SNES::Cartridge::ModeSuperGameBoy); + + loadMemory(cartridge.slotAName, ".sav", SNES::memory::gbram); + + cartridge.name = (*slot ? basename(slot) : basename(base)); + + modifySystemState(LoadCartridge); + return true; +} + +void Utility::saveMemory() { + if(SNES::cartridge.loaded() == false) return; + + switch(SNES::cartridge.mode()) { + case SNES::Cartridge::ModeNormal: + case SNES::Cartridge::ModeBsxSlotted: { + saveMemory(cartridge.baseName, ".srm", SNES::memory::cartram); + saveMemory(cartridge.baseName, ".rtc", SNES::memory::cartrtc); + } break; + + case SNES::Cartridge::ModeBsx: { + saveMemory(cartridge.baseName, ".srm", SNES::memory::bsxram ); + saveMemory(cartridge.baseName, ".psr", SNES::memory::bsxpram); + } break; + + case SNES::Cartridge::ModeSufamiTurbo: { + saveMemory(cartridge.slotAName, ".srm", SNES::memory::stAram); + saveMemory(cartridge.slotBName, ".srm", SNES::memory::stBram); + } break; + + case SNES::Cartridge::ModeSuperGameBoy: { + saveMemory(cartridge.slotAName, ".sav", SNES::memory::gbram); + } break; + } +} + +void Utility::unloadCartridge() { + if(SNES::cartridge.loaded() == false) return; + saveMemory(); + modifySystemState(UnloadCartridge); +} + void Utility::modifySystemState(system_state_t state) { video.clear(); audio.clear(); @@ -61,8 +165,8 @@ void Utility::modifySystemState(system_state_t state) { switch(state) { case LoadCartridge: { //must call cartridge.load_cart_...() before calling modifySystemState(LoadCartridge) - if(SNES::cartridge.loaded() == false) break; - config.path.current = Cartridge::basepath(cartridge.cartName); + if(SNES::cartridge.loaded() == false) break; + loadCheats(); application.power = true; application.pause = false; @@ -73,7 +177,7 @@ void Utility::modifySystemState(system_state_t state) { if(SNES::cartridge.has_superfx()) chip = "SuperFX"; else if(SNES::cartridge.has_st011()) chip = "ST011"; else if(SNES::cartridge.has_st018()) chip = "ST018"; - else if(SNES::cartridge.has_dsp3()) chip = "DSP-3"; //unplayable (only partially supported) + else if(SNES::cartridge.has_dsp3()) chip = "DSP-3"; //unplayable; only partially supported if(chip != "") { QMessageBox::warning(winMain->window, "Warning", utf8() << "

Warning:
Unsupported " << chip << " chip detected. " @@ -82,12 +186,14 @@ void Utility::modifySystemState(system_state_t state) { showMessage(utf8() << "Loaded " << cartridge.name - << (SNES::cartridge.patched() ? ", and applied UPS patch." : ".")); + << (false ? ", and applied UPS patch." : ".")); winMain->window->setWindowTitle(utf8() << BSNES_TITLE << " - " << cartridge.name); } break; case UnloadCartridge: { - if(SNES::cartridge.loaded() == false) break; //no cart to unload? + if(SNES::cartridge.loaded() == false) break; //no cart to unload? + saveCheats(); + SNES::cartridge.unload(); application.power = false; @@ -141,3 +247,182 @@ void Utility::modifySystemState(system_state_t state) { winCheatEditor->reloadList(); winCheatEditor->syncUi(); } +// + +bool Utility::loadCartridge(const char *filename, SNES::MappedRAM &memory) { + if(file::exists(filename) == false) return false; + Reader::Type filetype = Reader::detect(filename, config.file.autodetect_type); + + uint8_t *data; + unsigned size; + + switch(filetype) { default: + case Reader::Normal: { + FileReader fp(filename); + if(!fp.ready()) return false; + size = fp.size(); + data = fp.read(); + } break; + + #ifdef GZIP_SUPPORT + case Reader::GZIP: { + GZReader fp(filename); + if(!fp.ready()) return false; + size = fp.size(); + data = fp.read(); + } break; + + case Reader::ZIP: { + ZipReader fp(filename); + if(!fp.ready()) return false; + size = fp.size(); + data = fp.read(); + } break; + #endif + + #ifdef JMA_SUPPORT + case Reader::JMA: { + try { + JMAReader fp(filename); + size = fp.size(); + data = fp.read(); + } catch(JMA::jma_errors) { + return false; + } + } break; + #endif + } + + if((size & 0x7fff) == 512) memmove(data, data + 512, size -= 512); + memory.map(data, size); + return true; +} + +bool Utility::loadMemory(const char *filename, const char *extension, SNES::MappedRAM &memory) { + if(memory.size() == 0 || memory.size() == -1U) return false; + + string name; + name << filepath(basename(filename), config.path.save); + name << extension; + + file fp; + if(fp.open(name, file::mode_read) == false) return false; + + unsigned size; + uint8_t *data = new uint8_t[size = fp.size()]; + fp.read(data, size); + fp.close(); + + memcpy(memory.data(), data, min(size, memory.size())); + return true; +} + +bool Utility::saveMemory(const char *filename, const char *extension, SNES::MappedRAM &memory) { + if(memory.size() == 0 || memory.size() == -1U) return false; + + string name; + name << filepath(basename(filename), config.path.save); + name << extension; + + file fp; + if(fp.open(name, file::mode_write) == false) return false; + + fp.write(memory.data(), memory.size()); + fp.close(); + return true; +} + +void Utility::loadCheats() { + string name, data; + name << filepath(basename(cartridge.baseName), config.path.cheat); + name << ".cht"; + + SNES::cheat.clear(); + if(data.readfile(name)) SNES::cheat.load(data); +} + +void Utility::saveCheats() { + string name; + name << filepath(basename(cartridge.baseName), config.path.cheat); + name << ".cht"; + + file fp; + if(SNES::cheat.count() > 0 || file::exists(name)) { + if(fp.open(name, file::mode_write)) { + fp.print(SNES::cheat.save()); + fp.close(); + } + } +} + +// + +//ensure file path is absolute (eg resolve relative paths) +string Utility::filepath(const char *filename, const char *pathname) { + //if no pathname, return filename as-is + string file(filename); + file.replace("\\", "/"); + + string path = (!pathname || !*pathname) ? (const char*)config.path.current : pathname; + //ensure path ends with trailing '/' + path.replace("\\", "/"); + if(!strend(path, "/")) path.append("/"); + + //replace relative path with absolute path + if(strbegin(path, "./")) { + ltrim(path, "./"); + path = string() << config.path.base << path; + } + + //remove folder part of filename + lstring part; + part.split("/", file); + return path << part[part.size() - 1]; +} + +//remove directory information and file extension ("/foo/bar.ext" -> "bar") +string Utility::basename(const char *filename) { + string name(filename); + + //remove extension + for(signed i = strlen(name) - 1; i >= 0; i--) { + if(name[i] == '.') { + name[i] = 0; + break; + } + } + + //remove directory information + for(signed i = strlen(name) - 1; i >= 0; i--) { + if(name[i] == '/' || name[i] == '\\') { + i++; + char *output = name(); + while(true) { + *output++ = name[i]; + if(!name[i]) break; + i++; + } + break; + } + } + + return name; +} + +//remove filename and return path only ("/foo/bar.ext" -> "/foo/") +string Utility::basepath(const char *filename) { + string path(filename); + path.replace("\\", "/"); + + //remove filename + for(signed i = strlen(path) - 1; i >= 0; i--) { + if(path[i] == '/') { + path[i] = 0; + break; + } + } + + if(!strend(path, "/")) path.append("/"); + return path; +} + diff --git a/src/ui_qt/utility/utility.cpp b/src/ui_qt/utility/utility.cpp index 7ff7bfe8..8f30ed03 100644 --- a/src/ui_qt/utility/utility.cpp +++ b/src/ui_qt/utility/utility.cpp @@ -51,7 +51,7 @@ void Utility::inputEvent(uint16_t code) { bool resizeWindow = false; if(isButtonDown(code, inputUiGeneral.loadCartridge)) { - string filename = selectCartridge(AnyCartridge); + string filename = selectCartridge(); if(filename.length() > 0) loadCartridge(filename); } @@ -146,11 +146,11 @@ void Utility::updateSystemState() { void Utility::acquireMouse() { if(SNES::cartridge.loaded()) { - if(SNES::config.controller_port1 == SNES::System::Input::DeviceMouse - || SNES::config.controller_port2 == SNES::System::Input::DeviceMouse - || SNES::config.controller_port2 == SNES::System::Input::DeviceSuperScope - || SNES::config.controller_port2 == SNES::System::Input::DeviceJustifier - || SNES::config.controller_port2 == SNES::System::Input::DeviceJustifiers + if(SNES::config.controller_port1 == SNES::Input::DeviceMouse + || SNES::config.controller_port2 == SNES::Input::DeviceMouse + || SNES::config.controller_port2 == SNES::Input::DeviceSuperScope + || SNES::config.controller_port2 == SNES::Input::DeviceJustifier + || SNES::config.controller_port2 == SNES::Input::DeviceJustifiers ) input.acquire(); } } @@ -166,9 +166,9 @@ void Utility::updateAvSync() { void Utility::updateVideoMode() { if(config.video.context->region == 0) { - SNES::system.video.set_mode(SNES::System::Video::ModeNTSC); + SNES::video.set_mode(SNES::Video::ModeNTSC); } else { - SNES::system.video.set_mode(SNES::System::Video::ModePAL); + SNES::video.set_mode(SNES::Video::ModePAL); } } @@ -214,6 +214,6 @@ void Utility::updateEmulationSpeed() { } void Utility::updateControllers() { - SNES::system.input.port_set_device(0, SNES::config.controller_port1); - SNES::system.input.port_set_device(1, SNES::config.controller_port2); + SNES::input.port_set_device(0, SNES::config.controller_port1); + SNES::input.port_set_device(1, SNES::config.controller_port2); } diff --git a/src/ui_qt/utility/utility.hpp b/src/ui_qt/utility/utility.hpp index e3a57283..f08d746b 100644 --- a/src/ui_qt/utility/utility.hpp +++ b/src/ui_qt/utility/utility.hpp @@ -17,18 +17,33 @@ public: void updateControllers(); //cartridge.cpp - enum CartridgeType { - AnyCartridge = 1 << 0, - SnesCartridge = 1 << 1, - GameboyCartridge = 1 << 2, - }; - string selectCartridge(unsigned cartridgeType); + struct Cartridge { + string name, baseName, slotAName, slotBName; + } cartridge; + + string selectCartridge(); string selectFolder(const char *title); void loadCartridge(const char*); + bool loadCartridgeNormal(const char*); + bool loadCartridgeBsxSlotted(const char*, const char*); + bool loadCartridgeBsx(const char*, const char*); + bool loadCartridgeSufamiTurbo(const char*, const char *, const char*); + bool loadCartridgeSuperGameBoy(const char*, const char*); + void saveMemory(); void unloadCartridge(); enum system_state_t { LoadCartridge, UnloadCartridge, PowerOn, PowerOff, PowerCycle, Reset }; - void modifySystemState(system_state_t state); + void modifySystemState(system_state_t state); + + bool loadCartridge(const char*, SNES::MappedRAM&); + bool loadMemory(const char*, const char*, SNES::MappedRAM&); + bool saveMemory(const char*, const char*, SNES::MappedRAM&); + void loadCheats(); + void saveCheats(); + + string filepath(const char *filename, const char *pathname); + string basename(const char *filename); + string basepath(const char *filename); //window.cpp void showCentered(QWidget *window);

NameLicenseAuthor(s)
gambatte Gameboy emulatorGPL 2Sindre Aamas
Cx4 emulatoranomie, Kris Bleakley, Nach, zsKnight
DSP-1 emulatorAndreas Naive, John Weidman, Kris Bleakley, neviksti
DSP-2 emulatorKris Bleakley