├── COPYING ├── Makefile.bittboy ├── Makefile.funkeys ├── Makefile.pocketgo ├── README ├── README.md ├── build_funkeys_opk.sh ├── build_gcw0.sh ├── build_retrofw_ipk.sh ├── build_retrofw_opk.sh ├── clean.sh ├── common.mk ├── common ├── adaptivesleep.cpp ├── adaptivesleep.h ├── array.h ├── defined_ptr.h ├── rateest.cpp ├── rateest.h ├── resample │ ├── resampler.h │ ├── resamplerinfo.h │ └── src │ │ ├── blackmansinc.h │ │ ├── chainresampler.cpp │ │ ├── chainresampler.h │ │ ├── cic2.h │ │ ├── cic3.h │ │ ├── cic4.h │ │ ├── hammingsinc.h │ │ ├── i0.cpp │ │ ├── i0.h │ │ ├── kaiser50sinc.cpp │ │ ├── kaiser50sinc.h │ │ ├── kaiser70sinc.cpp │ │ ├── kaiser70sinc.h │ │ ├── linint.h │ │ ├── makesinckernel.cpp │ │ ├── makesinckernel.h │ │ ├── polyphasefir.h │ │ ├── rectsinc.h │ │ ├── resamplerinfo.cpp │ │ ├── rshift16_round.h │ │ ├── subresampler.h │ │ ├── u48div.cpp │ │ ├── u48div.h │ │ └── upsampler.h ├── ringbuffer.h ├── scoped_ptr.h ├── skipsched.cpp ├── skipsched.h ├── transfer_ptr.h ├── uncopyable.h ├── usec.h └── videolink │ ├── rgb32conv.cpp │ ├── rgb32conv.h │ ├── vfilterinfo.cpp │ ├── vfilterinfo.h │ └── videolink.h ├── dist ├── funkeys │ └── default.funkey-s.desktop ├── gambatte_dmg.png ├── gambatte_dms.png ├── gambatte_gbc.png ├── gcw0 │ └── default.gcw0.desktop ├── manual.txt └── retrofw │ ├── control │ ├── default.retrofw.desktop │ ├── gambatte.lnk │ ├── gb.gambatte.lnk │ ├── gb.retrofw.desktop │ ├── gbc.gambatte.lnk │ └── gbc.retrofw.desktop ├── gambatte_sdl ├── SConstruct ├── SFont.c ├── SFont.h ├── builddate.h ├── defaultborders.h ├── libmenu.cpp ├── libmenu.h ├── menu.cpp ├── menu.h ├── menusounds.h ├── scaler.c ├── scaler.h ├── sfont_gameboy.h └── src │ ├── audiosink.cpp │ ├── audiosink.h │ ├── blitterwrapper.cpp │ ├── blitterwrapper.h │ ├── gambatte_sdl.cpp │ ├── parser.cpp │ ├── parser.h │ ├── scalebuffer.h │ ├── sdlblitter.cpp │ ├── sdlblitter.h │ ├── str_to_sdlkey.cpp │ ├── str_to_sdlkey.h │ └── usec.cpp └── libgambatte ├── SConstruct ├── include ├── gambatte.h ├── gbint.h ├── inputgetter.h ├── loadres.h └── pakinfo.h └── src ├── bitmap_font.cpp ├── bitmap_font.h ├── bootloader.cpp ├── bootloader.h ├── counterdef.h ├── cpu.cpp ├── cpu.h ├── file ├── file.cpp ├── file.h ├── file_zip.cpp ├── stdfile.h └── unzip │ ├── crypt.h │ ├── ioapi.c │ ├── ioapi.h │ ├── unzip.c │ └── unzip.h ├── gambatte.cpp ├── initstate.cpp ├── initstate.h ├── insertion_sort.h ├── interrupter.cpp ├── interrupter.h ├── interruptrequester.cpp ├── interruptrequester.h ├── loadres.cpp ├── mem ├── cartridge.cpp ├── cartridge.h ├── memptrs.cpp ├── memptrs.h ├── pakinfo.cpp ├── pakinfo_internal.h ├── rtc.cpp └── rtc.h ├── memory.cpp ├── memory.h ├── minkeeper.h ├── osd_element.h ├── savestate.h ├── sound.cpp ├── sound.h ├── sound ├── channel1.cpp ├── channel1.h ├── channel2.cpp ├── channel2.h ├── channel3.cpp ├── channel3.h ├── channel4.cpp ├── channel4.h ├── duty_unit.cpp ├── duty_unit.h ├── envelope_unit.cpp ├── envelope_unit.h ├── length_counter.cpp ├── length_counter.h ├── master_disabler.h ├── sound_unit.h └── static_output_tester.h ├── state_osd_elements.cpp ├── state_osd_elements.h ├── statesaver.cpp ├── statesaver.h ├── tima.cpp ├── tima.h ├── video.cpp ├── video.h └── video ├── lcddef.h ├── ly_counter.cpp ├── ly_counter.h ├── lyc_irq.cpp ├── lyc_irq.h ├── m0_irq.h ├── next_m0_time.cpp ├── next_m0_time.h ├── ppu.cpp ├── ppu.h ├── sprite_mapper.cpp └── sprite_mapper.h /Makefile.bittboy: -------------------------------------------------------------------------------- 1 | CHAINPREFIX=/opt/buildroot-bittboy/output/host 2 | CROSS_COMPILE=$(CHAINPREFIX)/bin/arm-miyoo-linux-musleabi- 3 | 4 | CC = $(CROSS_COMPILE)gcc 5 | CXX = $(CROSS_COMPILE)g++ 6 | SYSROOT := $(CHAINPREFIX)/arm-miyoo-linux-musleabi/sysroot 7 | SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) 8 | 9 | OUTPUTNAME = gambatte-dms-bittboy 10 | 11 | DEFINES = -DHAVE_STDINT_H -DVERSION_BITTBOY 12 | INCLUDES = -Isrc/gambatte_sdl -Ilibgambatte -Icommon -Iinclude -Ilibgambatte/include -Ilibgambatte/src $(SDL_CFLAGS) 13 | OPT_FLAGS = -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto 14 | EXTRA_LDFLAGS = -lasound -lmikmod -lmodplug -Wl,--as-needed -Wl,--gc-sections -flto -s 15 | 16 | include common.mk 17 | -------------------------------------------------------------------------------- /Makefile.funkeys: -------------------------------------------------------------------------------- 1 | CHAINPREFIX=/opt/FunKey-sdk-2.0.0 2 | CROSS_COMPILE=$(CHAINPREFIX)/bin/arm-funkey-linux-musleabihf- 3 | 4 | CC = $(CROSS_COMPILE)gcc 5 | CXX = $(CROSS_COMPILE)g++ 6 | SYSROOT := $(CHAINPREFIX)/arm-funkey-linux-musleabihf/sysroot 7 | SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) 8 | 9 | OUTPUTNAME = gambatte-dms.funkeys 10 | 11 | DEFINES = -DHAVE_STDINT_H -DVERSION_FUNKEYS -DROM_BROWSER 12 | INCLUDES = -Isrc/gambatte_sdl -Ilibgambatte -Icommon -Iinclude -Ilibgambatte/include -Ilibgambatte/src $(SDL_CFLAGS) 13 | OPT_FLAGS = -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto 14 | EXTRA_LDFLAGS = -lasound -lmikmod -Wl,--as-needed -Wl,--gc-sections -flto -s 15 | 16 | CFLAGS = $(DEFINES) $(INCLUDES) $(OPT_FLAGS) -std=gnu11 17 | CXXFLAGS = $(DEFINES) $(INCLUDES) $(OPT_FLAGS) -std=gnu++11 18 | LDFLAGS = -Wl,--start-group -lSDL -lSDL_image -lpng -ljpeg -lSDL_mixer -logg -lvorbisidec -lmikmod -lm -pthread -lz -lstdc++ $(EXTRA_LDFLAGS) -Wl,--end-group 19 | 20 | # Redream (main engine) 21 | OBJS = \ 22 | libgambatte/src/bitmap_font.o \ 23 | libgambatte/src/bootloader.o \ 24 | libgambatte/src/cpu.o \ 25 | libgambatte/src/gambatte.o \ 26 | libgambatte/src/initstate.o \ 27 | libgambatte/src/interrupter.o \ 28 | libgambatte/src/interruptrequester.o \ 29 | libgambatte/src/loadres.o \ 30 | libgambatte/src/memory.o \ 31 | libgambatte/src/sound.o \ 32 | libgambatte/src/state_osd_elements.o \ 33 | libgambatte/src/statesaver.o \ 34 | libgambatte/src/tima.o \ 35 | libgambatte/src/video.o \ 36 | libgambatte/src/mem/cartridge.o \ 37 | libgambatte/src/mem/memptrs.o \ 38 | libgambatte/src/mem/pakinfo.o \ 39 | libgambatte/src/mem/rtc.o \ 40 | libgambatte/src/sound/channel1.o \ 41 | libgambatte/src/sound/channel2.o \ 42 | libgambatte/src/sound/channel3.o \ 43 | libgambatte/src/sound/channel4.o \ 44 | libgambatte/src/sound/duty_unit.o \ 45 | libgambatte/src/sound/envelope_unit.o \ 46 | libgambatte/src/sound/length_counter.o \ 47 | libgambatte/src/video/ly_counter.o \ 48 | libgambatte/src/video/lyc_irq.o \ 49 | libgambatte/src/video/next_m0_time.o \ 50 | libgambatte/src/video/ppu.o \ 51 | libgambatte/src/video/sprite_mapper.o 52 | 53 | ifeq ($(NOZIP), YES) 54 | OBJS += libgambatte/src/file/file.o 55 | else 56 | OBJS += libgambatte/src/file/file_zip.o libgambatte/src/file/unzip/ioapi.o libgambatte/src/file/unzip/unzip.o 57 | endif 58 | 59 | OBJS += gambatte_sdl/src/audiosink.o \ 60 | gambatte_sdl/src/blitterwrapper.o \ 61 | gambatte_sdl/src/parser.o \ 62 | gambatte_sdl/src/sdlblitter.o \ 63 | gambatte_sdl/src/str_to_sdlkey.o \ 64 | gambatte_sdl/src/usec.o \ 65 | gambatte_sdl/src/gambatte_sdl.o \ 66 | gambatte_sdl/SFont.o \ 67 | gambatte_sdl/menu.o \ 68 | gambatte_sdl/libmenu.o \ 69 | gambatte_sdl/scaler.o \ 70 | common/adaptivesleep.o \ 71 | common/resample/src/chainresampler.o \ 72 | common/resample/src/i0.o \ 73 | common/resample/src/kaiser50sinc.o \ 74 | common/resample/src/kaiser70sinc.o \ 75 | common/resample/src/makesinckernel.o \ 76 | common/resample/src/resamplerinfo.o \ 77 | common/resample/src/u48div.o \ 78 | common/rateest.o \ 79 | common/skipsched.o \ 80 | common/videolink/rgb32conv.o \ 81 | common/videolink/vfilterinfo.o 82 | 83 | .c.o: 84 | $(CC) $(CFLAGS) -c -o $@ $< 85 | 86 | .cpp.o: 87 | $(CXX) $(CXXFLAGS) -c -o $@ $< 88 | 89 | all: executable 90 | 91 | gambatte_sdl/menu.o: builddate 92 | 93 | builddate: 94 | echo "#define BUILDDATE \"$$(date +'%Y%m%d-%H%M%S')"\" > ./gambatte_sdl/builddate.h 95 | 96 | executable: $(OBJS) 97 | $(CC) -o $(OUTPUTNAME) $(OBJS) $(CFLAGS) $(LDFLAGS) 98 | 99 | clean: 100 | rm $(OBJS) $(OUTPUTNAME) 101 | -------------------------------------------------------------------------------- /Makefile.pocketgo: -------------------------------------------------------------------------------- 1 | CHAINPREFIX=/opt/buildroot-bittboy/output/host 2 | CROSS_COMPILE=$(CHAINPREFIX)/bin/arm-miyoo-linux-musleabi- 3 | 4 | CC = $(CROSS_COMPILE)gcc 5 | CXX = $(CROSS_COMPILE)g++ 6 | SYSROOT := $(CHAINPREFIX)/arm-miyoo-linux-musleabi/sysroot 7 | SDL_CFLAGS := $(shell $(SYSROOT)/usr/bin/sdl-config --cflags) 8 | 9 | OUTPUTNAME = gambatte-dms-pocketgo 10 | 11 | DEFINES = -DHAVE_STDINT_H -DVERSION_POCKETGO 12 | INCLUDES = -Isrc/gambatte_sdl -Ilibgambatte -Icommon -Iinclude -Ilibgambatte/include -Ilibgambatte/src $(SDL_CFLAGS) 13 | OPT_FLAGS = -Ofast -fdata-sections -fdata-sections -fno-common -fno-PIC -flto 14 | EXTRA_LDFLAGS = -lasound -lmikmod -lmodplug -Wl,--as-needed -Wl,--gc-sections -flto -s 15 | 16 | include common.mk 17 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bardeci/gambatte-dms/41453c497e3802a16acba8bd7f500e4d3b412ae4/README -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Gambatte-DMS** 2 | 3 | Gameboy emulator for handheld devices, using a modified Gambatte core (based on r572). 4 | 5 | Working on the following systems: 6 | - GCW Zero / RG-350 / RG350M / PocketGo2 / PlayGo / MiyooMax / GKD350H and other OpenDingux devices 7 | - RS-97 / RS-97 Plus / RS-97 Pro / RetroGame Plus / RetroGame Pro / LDK Vertical / LDK Landscape/ RG-300 and other RetroFW devices 8 | - New Bittboy / PocketGo / MiYoo / Powkiddy Q90 9 | - FunKey S / Q36 Mini / RG Nano 10 | -------------------------------------------------------------------------------- /build_funkeys_opk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BDAT=$(date +"%Y%m%d-%H%M%S") 4 | echo '#define BUILDDATE "'$BDAT'"' >./gambatte_sdl/builddate.h 5 | 6 | make -f Makefile.funkeys 7 | BDAT=$(date +"%Y%m%d") 8 | rm -f gambatte-dms-funkey-s-r572u4-$BDAT.opk 9 | mksquashfs ./dist/funkeys/default.funkey-s.desktop gambatte-dms.funkeys ./dist/gambatte_dms.png ./dist/manual.txt gambatte-dms-funkey-s-r572u4-$BDAT.opk -all-root -no-xattrs -noappend -no-exports 10 | make -f Makefile.funkeys clean 11 | -------------------------------------------------------------------------------- /build_gcw0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BDAT=$(date +"%Y%m%d-%H%M%S") 4 | echo '#define BUILDDATE "'$BDAT'"' >./gambatte_sdl/builddate.h 5 | 6 | echo "cd libgambatte && scons" 7 | (cd libgambatte && scons -Q target=gcw0) || exit 8 | echo "cd gambatte_sdl && scons" 9 | (cd gambatte_sdl && scons -Q target=gcw0) 10 | mv gambatte_sdl/gambatte_sdl gambatte_sdl/gambatte-dms.gcw0 11 | 12 | echo "cd gambatte_sdl && scons -c" 13 | (cd gambatte_sdl && scons -c) 14 | echo "cd libgambatte && scons -c" 15 | (cd libgambatte && scons -c) 16 | echo "rm -f *gambatte*/config.log" 17 | rm -f *gambatte*/config.log 18 | echo "rm -rf *gambatte*/.scon*" 19 | rm -rf *gambatte*/.scon* 20 | find . -type f -iname \*.o -delete 21 | find . -type f -iname gambatte_sdl -delete 22 | 23 | rm -f gambatte-dms-gcw0-r572u4-$BDAT.opk 24 | mksquashfs ./dist/gcw0/default.gcw0.desktop ./gambatte_sdl/gambatte-dms.gcw0 ./dist/gambatte_dms.png ./dist/manual.txt gambatte-dms-gcw0-r572u4-$BDAT.opk -all-root -no-xattrs -noappend -no-exports 25 | 26 | find . -type f -iname gambatte-dms.gcw0 -delete 27 | -------------------------------------------------------------------------------- /build_retrofw_ipk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BDAT=$(date +"%Y%m%d-%H%M%S") 4 | echo '#define BUILDDATE "'$BDAT'"' >./gambatte_sdl/builddate.h 5 | 6 | echo "cd libgambatte && scons" 7 | (cd libgambatte && scons -Q target=retrofw) || exit 8 | echo "cd gambatte_sdl && scons" 9 | (cd gambatte_sdl && scons -Q target=retrofw) 10 | 11 | rm -rf /tmp/.gambatte-ipk/ && mkdir -p /tmp/.gambatte-ipk/root/home/retrofw/emus/gambatte /tmp/.gambatte-ipk/root/home/retrofw/apps/gmenu2x/sections/emulators /tmp/.gambatte-ipk/root/home/retrofw/apps/gmenu2x/sections/emulators.systems 12 | cp dist/manual.txt dist/gambatte_dms.png dist/gambatte_dmg.png dist/gambatte_gbc.png /tmp/.gambatte-ipk/root/home/retrofw/emus/gambatte 13 | cp gambatte_sdl/gambatte_sdl /tmp/.gambatte-ipk/root/home/retrofw/emus/gambatte/gambatte-dms.dge 14 | cp dist/retrofw/gambatte.lnk /tmp/.gambatte-ipk/root/home/retrofw/apps/gmenu2x/sections/emulators 15 | cp dist/retrofw/gb.gambatte.lnk dist/retrofw/gbc.gambatte.lnk /tmp/.gambatte-ipk/root/home/retrofw/apps/gmenu2x/sections/emulators.systems 16 | sed "s/^Version:.*/Version: `date +%Y%m%d`/" dist/retrofw/control > /tmp/.gambatte-ipk/control 17 | tar --owner=0 --group=0 -czvf /tmp/.gambatte-ipk/control.tar.gz -C /tmp/.gambatte-ipk/ control 18 | tar --owner=0 --group=0 -czvf /tmp/.gambatte-ipk/data.tar.gz -C /tmp/.gambatte-ipk/root/ . 19 | echo 2.0 > /tmp/.gambatte-ipk/debian-binary 20 | ar r gambatte-dms-retrofw-r572u4-$BDAT.ipk /tmp/.gambatte-ipk/control.tar.gz /tmp/.gambatte-ipk/data.tar.gz /tmp/.gambatte-ipk/debian-binary 21 | 22 | echo "cd gambatte_sdl && scons -c" 23 | (cd gambatte_sdl && scons -c) 24 | echo "cd libgambatte && scons -c" 25 | (cd libgambatte && scons -c) 26 | echo "rm -f *gambatte*/config.log" 27 | rm -f *gambatte*/config.log 28 | echo "rm -rf *gambatte*/.scon*" 29 | rm -rf *gambatte*/.scon* 30 | find . -type f -iname \*.o -delete 31 | find . -type f -iname gambatte_sdl -delete 32 | -------------------------------------------------------------------------------- /build_retrofw_opk.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | BDAT=$(date +"%Y%m%d-%H%M%S") 4 | echo '#define BUILDDATE "'$BDAT'"' >./gambatte_sdl/builddate.h 5 | 6 | echo "cd libgambatte && scons" 7 | (cd libgambatte && scons -Q target=retrofw) || exit 8 | echo "cd gambatte_sdl && scons" 9 | (cd gambatte_sdl && scons -Q target=retrofw) 10 | mv gambatte_sdl/gambatte_sdl gambatte_sdl/gambatte-dms.retrofw 11 | 12 | echo "cd gambatte_sdl && scons -c" 13 | (cd gambatte_sdl && scons -c) 14 | echo "cd libgambatte && scons -c" 15 | (cd libgambatte && scons -c) 16 | echo "rm -f *gambatte*/config.log" 17 | rm -f *gambatte*/config.log 18 | echo "rm -rf *gambatte*/.scon*" 19 | rm -rf *gambatte*/.scon* 20 | find . -type f -iname \*.o -delete 21 | find . -type f -iname gambatte_sdl -delete 22 | 23 | rm -f gambatte-dms-retrofw-r572u4-$BDAT.opk 24 | mksquashfs ./dist/retrofw/default.retrofw.desktop ./dist/retrofw/gb.retrofw.desktop ./dist/retrofw/gbc.retrofw.desktop ./gambatte_sdl/gambatte-dms.retrofw ./dist/gambatte_dms.png ./dist/gambatte_dmg.png ./dist/gambatte_gbc.png ./dist/manual.txt gambatte-dms-retrofw-r572u4-$BDAT.opk -all-root -no-xattrs -noappend -no-exports 25 | 26 | find . -type f -iname gambatte-dms.retrofw -delete 27 | -------------------------------------------------------------------------------- /clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo "cd gambatte_sdl && scons -c" 4 | (cd gambatte_sdl && scons -c) 5 | 6 | echo "cd libgambatte && scons -c" 7 | (cd libgambatte && scons -c) 8 | 9 | echo "rm -f *gambatte*/config.log" 10 | rm -f *gambatte*/config.log 11 | 12 | echo "rm -rf *gambatte*/.scon*" 13 | rm -rf *gambatte*/.scon* 14 | 15 | find . -type f -iname \*.o -delete 16 | 17 | find . -type f -iname gambatte_sdl -delete 18 | -------------------------------------------------------------------------------- /common.mk: -------------------------------------------------------------------------------- 1 | 2 | CFLAGS = $(DEFINES) $(INCLUDES) $(OPT_FLAGS) -std=gnu11 3 | CXXFLAGS = $(DEFINES) $(INCLUDES) $(OPT_FLAGS) -std=gnu++11 4 | LDFLAGS = -Wl,--start-group -lSDL -lSDL_image -lpng -ljpeg -lSDL_mixer -logg -lvorbisidec -lmikmod -lmodplug -lm -pthread -lz -lstdc++ $(EXTRA_LDFLAGS) -Wl,--end-group 5 | 6 | # Redream (main engine) 7 | OBJS = \ 8 | libgambatte/src/bitmap_font.o \ 9 | libgambatte/src/bootloader.o \ 10 | libgambatte/src/cpu.o \ 11 | libgambatte/src/gambatte.o \ 12 | libgambatte/src/initstate.o \ 13 | libgambatte/src/interrupter.o \ 14 | libgambatte/src/interruptrequester.o \ 15 | libgambatte/src/loadres.o \ 16 | libgambatte/src/memory.o \ 17 | libgambatte/src/sound.o \ 18 | libgambatte/src/state_osd_elements.o \ 19 | libgambatte/src/statesaver.o \ 20 | libgambatte/src/tima.o \ 21 | libgambatte/src/video.o \ 22 | libgambatte/src/mem/cartridge.o \ 23 | libgambatte/src/mem/memptrs.o \ 24 | libgambatte/src/mem/pakinfo.o \ 25 | libgambatte/src/mem/rtc.o \ 26 | libgambatte/src/sound/channel1.o \ 27 | libgambatte/src/sound/channel2.o \ 28 | libgambatte/src/sound/channel3.o \ 29 | libgambatte/src/sound/channel4.o \ 30 | libgambatte/src/sound/duty_unit.o \ 31 | libgambatte/src/sound/envelope_unit.o \ 32 | libgambatte/src/sound/length_counter.o \ 33 | libgambatte/src/video/ly_counter.o \ 34 | libgambatte/src/video/lyc_irq.o \ 35 | libgambatte/src/video/next_m0_time.o \ 36 | libgambatte/src/video/ppu.o \ 37 | libgambatte/src/video/sprite_mapper.o 38 | 39 | ifeq ($(NOZIP), YES) 40 | OBJS += libgambatte/src/file/file.o 41 | else 42 | OBJS += libgambatte/src/file/file_zip.o libgambatte/src/file/unzip/ioapi.o libgambatte/src/file/unzip/unzip.o 43 | endif 44 | 45 | OBJS += gambatte_sdl/src/audiosink.o \ 46 | gambatte_sdl/src/blitterwrapper.o \ 47 | gambatte_sdl/src/parser.o \ 48 | gambatte_sdl/src/sdlblitter.o \ 49 | gambatte_sdl/src/str_to_sdlkey.o \ 50 | gambatte_sdl/src/usec.o \ 51 | gambatte_sdl/src/gambatte_sdl.o \ 52 | gambatte_sdl/SFont.o \ 53 | gambatte_sdl/menu.o \ 54 | gambatte_sdl/libmenu.o \ 55 | gambatte_sdl/scaler.o \ 56 | common/adaptivesleep.o \ 57 | common/resample/src/chainresampler.o \ 58 | common/resample/src/i0.o \ 59 | common/resample/src/kaiser50sinc.o \ 60 | common/resample/src/kaiser70sinc.o \ 61 | common/resample/src/makesinckernel.o \ 62 | common/resample/src/resamplerinfo.o \ 63 | common/resample/src/u48div.o \ 64 | common/rateest.o \ 65 | common/skipsched.o \ 66 | common/videolink/rgb32conv.o \ 67 | common/videolink/vfilterinfo.o 68 | 69 | .c.o: 70 | $(CC) $(CFLAGS) -c -o $@ $< 71 | 72 | .cpp.o: 73 | $(CXX) $(CXXFLAGS) -c -o $@ $< 74 | 75 | all: executable 76 | 77 | gambatte_sdl/menu.o: builddate 78 | 79 | builddate: 80 | echo "#define BUILDDATE \"$$(date +'%Y%m%d-%H%M%S')"\" > ./gambatte_sdl/builddate.h 81 | 82 | executable: $(OBJS) 83 | $(CC) -o $(OUTPUTNAME) $(OBJS) $(CFLAGS) $(LDFLAGS) 84 | 85 | clean: 86 | rm $(OBJS) $(OUTPUTNAME) 87 | -------------------------------------------------------------------------------- /common/adaptivesleep.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "adaptivesleep.h" 20 | 21 | static usec_t absdiff(usec_t a, usec_t b) { return a < b ? b - a : a - b; } 22 | 23 | usec_t AdaptiveSleep::sleepUntil(usec_t base, usec_t inc) { 24 | usec_t now = getusecs(); 25 | usec_t diff = now - base; 26 | if (diff >= inc) 27 | return diff - inc; 28 | 29 | diff = inc - diff; 30 | if (diff > oversleep_ + oversleepVar_) { 31 | diff -= oversleep_ + oversleepVar_; 32 | usecsleep(diff); 33 | usec_t const sleepTarget = now + diff; 34 | now = getusecs(); 35 | 36 | usec_t curOversleep = now - sleepTarget; 37 | if (curOversleep > usec_t(-1) / 2) 38 | curOversleep = 0; 39 | 40 | oversleepVar_ = (oversleepVar_ * 15 + absdiff(curOversleep, oversleep_) + 8) >> 4; 41 | oversleep_ = (oversleep_ * 15 + curOversleep + 8) >> 4; 42 | noSleep_ = 60; 43 | } else if (--noSleep_ == 0) { 44 | noSleep_ = 60; 45 | oversleep_ = oversleepVar_ = 0; 46 | } 47 | 48 | while (now - base < inc) 49 | now = getusecs(); 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /common/adaptivesleep.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef ADAPTIVE_SLEEP_H 20 | #define ADAPTIVE_SLEEP_H 21 | 22 | #include "usec.h" 23 | 24 | class AdaptiveSleep { 25 | public: 26 | AdaptiveSleep() : oversleep_(0), oversleepVar_(0), noSleep_(60) {} 27 | usec_t sleepUntil(usec_t base, usec_t inc); 28 | 29 | private: 30 | usec_t oversleep_; 31 | usec_t oversleepVar_; 32 | unsigned noSleep_; 33 | }; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /common/array.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef ARRAY_H 20 | #define ARRAY_H 21 | 22 | #include "defined_ptr.h" 23 | #include "uncopyable.h" 24 | #include 25 | 26 | template 27 | class SimpleArray : Uncopyable { 28 | public: 29 | explicit SimpleArray(std::size_t size = 0) : a_(size ? new T[size] : 0) {} 30 | ~SimpleArray() { delete[] defined_ptr(a_); } 31 | void reset(std::size_t size = 0) { delete[] defined_ptr(a_); a_ = size ? new T[size] : 0; } 32 | T * get() const { return a_; } 33 | operator T *() const { return a_; } 34 | 35 | private: 36 | T *a_; 37 | }; 38 | 39 | template 40 | class Array { 41 | public: 42 | explicit Array(std::size_t size = 0) : a_(size), size_(size) {} 43 | void reset(std::size_t size = 0) { a_.reset(size); size_ = size; } 44 | std::size_t size() const { return size_; } 45 | T * get() const { return a_; } 46 | operator T *() const { return a_; } 47 | 48 | private: 49 | SimpleArray a_; 50 | std::size_t size_; 51 | }; 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /common/defined_ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef DEFINED_PTR_H 2 | #define DEFINED_PTR_H 3 | 4 | template 5 | inline T * defined_ptr(T *t) { 6 | typedef char type_is_defined[sizeof *t ? 1 : -1]; 7 | (void) sizeof(type_is_defined); 8 | return t; 9 | } 10 | 11 | template 12 | inline void defined_delete(T *t) { delete defined_ptr(t); } 13 | 14 | struct defined_deleter { template static void del(T *p) { defined_delete(p); } }; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /common/rateest.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "rateest.h" 20 | #include 21 | 22 | void RateEst::SumQueue::push(std::ptrdiff_t const samples, usec_t const usecs) { 23 | q_.push_back(std::make_pair(samples, usecs)); 24 | samples_ += samples; 25 | usecs_ += usecs; 26 | } 27 | 28 | void RateEst::SumQueue::pop() { 29 | std::pair const &f = q_.front(); 30 | samples_ -= f.first; 31 | usecs_ -= f.second; 32 | q_.pop_front(); 33 | } 34 | 35 | static usec_t sampleUsecs(std::ptrdiff_t samples, long rate) { 36 | return usec_t((samples * 1000000.0f) / (rate ? rate : 1) + 0.5f); 37 | } 38 | 39 | static long limit(long est, long const reference) { 40 | if (est > reference + (reference >> 6)) 41 | est = reference + (reference >> 6); 42 | else if (est < reference - (reference >> 6)) 43 | est = reference - (reference >> 6); 44 | 45 | return est; 46 | } 47 | 48 | RateEst::RateEst(long const nominalSampleRate, std::size_t const maxValidFeedPeriodSamples) 49 | : srate_(nominalSampleRate * est_scale) 50 | , reference_(srate_) 51 | , maxPeriod_(sampleUsecs(maxValidFeedPeriodSamples, nominalSampleRate)) 52 | , last_(0) 53 | , t_(6000) 54 | , s_(nominalSampleRate * 6) 55 | , st_(s_ * t_) 56 | , t2_(t_ * t_) 57 | { 58 | } 59 | 60 | void RateEst::feed(std::ptrdiff_t samplesIn, usec_t const now) { 61 | usec_t usecsIn = now - last_; 62 | 63 | if (last_ && usecsIn < maxPeriod_) { 64 | sumq_.push(samplesIn, usecsIn); 65 | 66 | while ((usecsIn = sumq_.usecs()) > 100000) { 67 | samplesIn = sumq_.samples(); 68 | sumq_.pop(); 69 | 70 | long const srateIn = long(samplesIn * (1000000.0f * est_scale) / usecsIn); 71 | if (std::abs(srateIn - reference_) < reference_ >> 1) { 72 | s_ += samplesIn - sumq_.samples() ; 73 | t_ += ( usecsIn - sumq_.usecs() ) * 0.001; 74 | st_ += s_ * t_; 75 | t2_ += t_ * t_; 76 | 77 | long est = long(st_ * (1000.0 * est_scale) / t2_ + 0.5); 78 | srate_ = limit((srate_ * 31 + est + 16) >> 5, reference_); 79 | 80 | if (t_ > 8000) { 81 | s_ *= 3.0 / 4; 82 | t_ *= 3.0 / 4; 83 | st_ *= 9.0 / 16; 84 | t2_ *= 9.0 / 16; 85 | } 86 | } 87 | } 88 | } 89 | 90 | last_ = now; 91 | } 92 | -------------------------------------------------------------------------------- /common/rateest.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef RATEEST_H 20 | #define RATEEST_H 21 | 22 | #include "usec.h" 23 | #include 24 | #include 25 | #include 26 | 27 | class RateEst { 28 | public: 29 | RateEst() { *this = RateEst(0, 0); } 30 | RateEst(long nominalSampleRate, std::size_t maxValidFeedPeriodSamples); 31 | void resetLastFeedTimeStamp() { last_ = 0; } 32 | void feed(std::ptrdiff_t samples, usec_t usecsNow = getusecs()); 33 | long result() const { return (srate_ + est_scale / 2) >> est_lshift; } 34 | 35 | private: 36 | class SumQueue { 37 | public: 38 | SumQueue() : samples_(0), usecs_(0) {} 39 | std::ptrdiff_t samples() const { return samples_; } 40 | usec_t usecs() const { return usecs_; } 41 | void push(std::ptrdiff_t samples, usec_t usecs); 42 | void pop(); 43 | 44 | private: 45 | std::deque< std::pair > q_; 46 | std::ptrdiff_t samples_; 47 | usec_t usecs_; 48 | }; 49 | 50 | enum { est_lshift = 5 }; 51 | enum { est_scale = 1 << est_lshift }; 52 | 53 | SumQueue sumq_; 54 | long srate_; 55 | long reference_; 56 | usec_t maxPeriod_; 57 | usec_t last_; 58 | double t_, s_, st_, t2_; 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /common/resample/resamplerinfo.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef RESAMPLER_INFO_H 20 | #define RESAMPLER_INFO_H 21 | 22 | #include 23 | 24 | class Resampler; 25 | 26 | /** 27 | * Used for creating instances of resamplers, and getting information on 28 | * available resamplers. 29 | */ 30 | struct ResamplerInfo { 31 | /** Number of interleaved channels per audio sample (frame) */ 32 | enum { channels = 2 }; 33 | 34 | /** Short character string description of the resampler. */ 35 | char const *desc; 36 | 37 | /** 38 | * Points to a function that can be used to create an instance of the resampler. 39 | * 40 | * @param inRate The input sampling rate. 41 | * @param outRate The desired output sampling rate. 42 | * @param periodSize The maximum number of input samples to resample at a time/The 43 | * maximal inlen passed to Resampler::resample. 44 | * @return Pointer to the created instance on the free store. 45 | */ 46 | Resampler * (*create)(long inRate, long outRate, std::size_t periodSize); 47 | 48 | /** Returns the number of ResamplerInfos that can be gotten with get(). */ 49 | static std::size_t num() { return num_; } 50 | 51 | /** Returns ResamplerInfo number n. Where n is less than num(). */ 52 | static ResamplerInfo const & get(std::size_t n) { return resamplers_[n]; } 53 | 54 | private: 55 | static ResamplerInfo const resamplers_[]; 56 | static std::size_t const num_; 57 | }; 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /common/resample/src/blackmansinc.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef BLACKMANSINC_H 20 | #define BLACKMANSINC_H 21 | 22 | #include "array.h" 23 | #include "cic4.h" 24 | #include "makesinckernel.h" 25 | #include "polyphasefir.h" 26 | #include "subresampler.h" 27 | #include 28 | #include 29 | #include 30 | 31 | template 32 | class BlackmanSinc : public SubResampler { 33 | public: 34 | enum { MUL = phases }; 35 | typedef Cic4 Cic; 36 | static float cicLimit() { return 4.7f; } 37 | 38 | class RollOff { 39 | public: 40 | unsigned const taps; 41 | float const fc; 42 | 43 | RollOff(float rollOffStart, float rollOffWidth) 44 | : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) 45 | { 46 | } 47 | 48 | private: 49 | static unsigned toTaps(float rollOffWidth) { 50 | float widthTimesTaps = 4.5f; 51 | return std::max(unsigned(std::ceil(widthTimesTaps / rollOffWidth)), 4u); 52 | } 53 | 54 | static float toFc(float rollOffStart, int taps) { 55 | float startToFcDeltaTimesTaps = 1.69f; 56 | return startToFcDeltaTimesTaps / taps + rollOffStart; 57 | } 58 | }; 59 | 60 | BlackmanSinc(unsigned div, unsigned phaseLen, double fc) 61 | : kernel_(phaseLen * phases) 62 | , polyfir_(kernel_, phaseLen, div) 63 | { 64 | makeSincKernel(kernel_, phases, phaseLen, fc, blackmanWin, 1.0); 65 | } 66 | 67 | BlackmanSinc(unsigned div, RollOff ro, double gain) 68 | : kernel_(ro.taps * phases) 69 | , polyfir_(kernel_, ro.taps, div) 70 | { 71 | makeSincKernel(kernel_, phases, ro.taps, ro.fc, blackmanWin, gain); 72 | } 73 | 74 | virtual std::size_t resample(short *out, short const *in, std::size_t inlen) { 75 | return polyfir_.filter(out, in, inlen); 76 | } 77 | 78 | virtual void adjustDiv(unsigned div) { polyfir_.adjustDiv(div); } 79 | virtual unsigned mul() const { return MUL; } 80 | virtual unsigned div() const { return polyfir_.div(); } 81 | 82 | private: 83 | Array const kernel_; 84 | PolyphaseFir polyfir_; 85 | 86 | static double blackmanWin(long i, long M) { 87 | double pi = 3.14159265358979323846; 88 | return 0.42 - 0.5 * std::cos(2 * pi * i / M) 89 | + 0.08 * std::cos(4 * pi * i / M); 90 | } 91 | }; 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /common/resample/src/hammingsinc.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef HAMMINGSINC_H 20 | #define HAMMINGSINC_H 21 | 22 | #include "array.h" 23 | #include "cic3.h" 24 | #include "makesinckernel.h" 25 | #include "polyphasefir.h" 26 | #include "subresampler.h" 27 | #include 28 | #include 29 | #include 30 | 31 | template 32 | class HammingSinc : public SubResampler { 33 | public: 34 | enum { MUL = phases }; 35 | typedef Cic3 Cic; 36 | static float cicLimit() { return 4.2f; } 37 | 38 | class RollOff { 39 | public: 40 | unsigned const taps; 41 | float const fc; 42 | 43 | RollOff(float rollOffStart, float rollOffWidth) 44 | : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) 45 | { 46 | } 47 | 48 | private: 49 | static unsigned toTaps(float rollOffWidth) { 50 | float widthTimesTaps = 3.0f; 51 | return std::max(unsigned(std::ceil(widthTimesTaps / rollOffWidth)), 4u); 52 | } 53 | 54 | static float toFc(float rollOffStart, int taps) { 55 | float startToFcDeltaTimesTaps = 1.27f; 56 | return startToFcDeltaTimesTaps / taps + rollOffStart; 57 | } 58 | }; 59 | 60 | HammingSinc(unsigned div, unsigned phaseLen, double fc) 61 | : kernel_(phaseLen * phases) 62 | , polyfir_(kernel_, phaseLen, div) 63 | { 64 | makeSincKernel(kernel_, phases, phaseLen, fc, hammingWin, 1.0); 65 | } 66 | 67 | HammingSinc(unsigned div, RollOff ro, double gain) 68 | : kernel_(ro.taps * phases) 69 | , polyfir_(kernel_, ro.taps, div) 70 | { 71 | makeSincKernel(kernel_, phases, ro.taps, ro.fc, hammingWin, gain); 72 | } 73 | 74 | virtual std::size_t resample(short *out, short const *in, std::size_t inlen) { 75 | return polyfir_.filter(out, in, inlen); 76 | } 77 | 78 | virtual void adjustDiv(unsigned div) { polyfir_.adjustDiv(div); } 79 | virtual unsigned mul() const { return MUL; } 80 | virtual unsigned div() const { return polyfir_.div(); } 81 | 82 | private: 83 | Array const kernel_; 84 | PolyphaseFir polyfir_; 85 | 86 | static double hammingWin(long i, long M) { 87 | double pi = 3.14159265358979323846; 88 | return 0.53836 - 0.46164 * std::cos(2 * pi * i / M); 89 | } 90 | }; 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /common/resample/src/i0.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "i0.h" 20 | 21 | double i0(double x) { 22 | double sum = 1.0; 23 | double xpm_dmfac = 1.0; 24 | double m = 1.0; 25 | 26 | x = 0.25 * x * x; 27 | 28 | for (int n = 16; n--;) { 29 | xpm_dmfac *= x / (m * m); 30 | sum += xpm_dmfac; 31 | m += 1.0; 32 | } 33 | 34 | return sum; 35 | } 36 | -------------------------------------------------------------------------------- /common/resample/src/i0.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef I0_H 20 | #define I0_H 21 | 22 | double i0(double x); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /common/resample/src/kaiser50sinc.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008-2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "kaiser50sinc.h" 20 | #include "i0.h" 21 | #include 22 | 23 | double kaiser50SincWin(long const n, long const M) { 24 | double const beta = 4.62; 25 | static double const i0beta_rec = 1.0 / i0(beta); 26 | 27 | double x = static_cast(n * 2) / M - 1.0; 28 | x = x * x; 29 | x = beta * std::sqrt(1.0 - x); 30 | 31 | return i0(x) * i0beta_rec; 32 | } 33 | -------------------------------------------------------------------------------- /common/resample/src/kaiser50sinc.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008-2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef KAISER50SINC_H 20 | #define KAISER50SINC_H 21 | 22 | #include "array.h" 23 | #include "cic3.h" 24 | #include "makesinckernel.h" 25 | #include "polyphasefir.h" 26 | #include "subresampler.h" 27 | #include 28 | #include 29 | #include 30 | 31 | double kaiser50SincWin(long n, long M); 32 | 33 | template 34 | class Kaiser50Sinc : public SubResampler { 35 | public: 36 | enum { MUL = phases }; 37 | typedef Cic3 Cic; 38 | static float cicLimit() { return 4.2f; } 39 | 40 | class RollOff { 41 | public: 42 | unsigned const taps; 43 | float const fc; 44 | 45 | RollOff(float rollOffStart, float rollOffWidth) 46 | : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) 47 | { 48 | } 49 | 50 | private: 51 | static unsigned toTaps(float rollOffWidth) { 52 | float widthTimesTaps = 2.715f; 53 | return std::max(unsigned(std::ceil(widthTimesTaps / rollOffWidth)), 4u); 54 | } 55 | 56 | static float toFc(float rollOffStart, int taps) { 57 | float startToFcDeltaTimesTaps = 1.2f; 58 | return startToFcDeltaTimesTaps / taps + rollOffStart; 59 | } 60 | }; 61 | 62 | Kaiser50Sinc(unsigned div, unsigned phaseLen, double fc) 63 | : kernel_(phaseLen * phases) 64 | , polyfir_(kernel_, phaseLen, div) 65 | { 66 | makeSincKernel(kernel_, phases, phaseLen, fc, kaiser50SincWin, 1.0); 67 | } 68 | 69 | Kaiser50Sinc(unsigned div, RollOff ro, double gain) 70 | : kernel_(ro.taps * phases) 71 | , polyfir_(kernel_, ro.taps, div) 72 | { 73 | makeSincKernel(kernel_, phases, ro.taps, ro.fc, kaiser50SincWin, gain); 74 | } 75 | 76 | virtual std::size_t resample(short *out, short const *in, std::size_t inlen) { 77 | return polyfir_.filter(out, in, inlen); 78 | } 79 | 80 | virtual void adjustDiv(unsigned div) { polyfir_.adjustDiv(div); } 81 | virtual unsigned mul() const { return MUL; } 82 | virtual unsigned div() const { return polyfir_.div(); } 83 | 84 | private: 85 | Array const kernel_; 86 | PolyphaseFir polyfir_; 87 | }; 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /common/resample/src/kaiser70sinc.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008-2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "kaiser70sinc.h" 20 | #include "i0.h" 21 | #include 22 | 23 | double kaiser70SincWin(long const n, long const M) { 24 | double const beta = 6.9; 25 | static double const i0beta_rec = 1.0 / i0(beta); 26 | 27 | double x = static_cast(n * 2) / M - 1.0; 28 | x = x * x; 29 | x = beta * std::sqrt(1.0 - x); 30 | 31 | return i0(x) * i0beta_rec; 32 | } 33 | -------------------------------------------------------------------------------- /common/resample/src/kaiser70sinc.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008-2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef KAISER70SINC_H 20 | #define KAISER70SINC_H 21 | 22 | #include "array.h" 23 | #include "cic4.h" 24 | #include "makesinckernel.h" 25 | #include "polyphasefir.h" 26 | #include "subresampler.h" 27 | #include 28 | #include 29 | #include 30 | 31 | double kaiser70SincWin(long n, long M); 32 | 33 | template 34 | class Kaiser70Sinc : public SubResampler { 35 | public: 36 | enum { MUL = phases }; 37 | typedef Cic4 Cic; 38 | static float cicLimit() { return 4.7f; } 39 | 40 | class RollOff { 41 | public: 42 | unsigned const taps; 43 | float const fc; 44 | 45 | RollOff(float rollOffStart, float rollOffWidth) 46 | : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) 47 | { 48 | } 49 | 50 | private: 51 | static unsigned toTaps(float rollOffWidth) { 52 | float widthTimesTaps = 3.75f; 53 | return std::max(unsigned(std::ceil(widthTimesTaps / rollOffWidth)), 4u); 54 | } 55 | 56 | static float toFc(float rollOffStart, int taps) { 57 | float startToFcDeltaTimesTaps = 1.5f; 58 | return startToFcDeltaTimesTaps / taps + rollOffStart; 59 | } 60 | }; 61 | 62 | Kaiser70Sinc(unsigned div, unsigned phaseLen, double fc) 63 | : kernel_(phaseLen * phases) 64 | , polyfir_(kernel_, phaseLen, div) 65 | { 66 | makeSincKernel(kernel_, phases, phaseLen, fc, kaiser70SincWin, 1.0); 67 | } 68 | 69 | Kaiser70Sinc(unsigned div, RollOff ro, double gain) 70 | : kernel_(ro.taps * phases) 71 | , polyfir_(kernel_, ro.taps, div) 72 | { 73 | makeSincKernel(kernel_, phases, ro.taps, ro.fc, kaiser70SincWin, gain); 74 | } 75 | 76 | virtual std::size_t resample(short *out, short const *in, std::size_t inlen) { 77 | return polyfir_.filter(out, in, inlen); 78 | } 79 | 80 | virtual void adjustDiv(unsigned div) { polyfir_.adjustDiv(div); } 81 | virtual unsigned mul() const { return MUL; } 82 | virtual unsigned div() const { return polyfir_.div(); } 83 | 84 | private: 85 | Array const kernel_; 86 | PolyphaseFir polyfir_; 87 | }; 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /common/resample/src/makesinckernel.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef MAKE_SINC_KERNEL_H 20 | #define MAKE_SINC_KERNEL_H 21 | 22 | void makeSincKernel(short *kernel, int phases, int phaseLen, 23 | double fc, double (*win)(long m, long M), double gain); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /common/resample/src/rectsinc.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef RECTSINC_H 20 | #define RECTSINC_H 21 | 22 | #include "array.h" 23 | #include "cic2.h" 24 | #include "makesinckernel.h" 25 | #include "polyphasefir.h" 26 | #include "subresampler.h" 27 | #include 28 | #include 29 | #include 30 | 31 | template 32 | class RectSinc : public SubResampler { 33 | public: 34 | enum { MUL = phases }; 35 | typedef Cic2 Cic; 36 | static float cicLimit() { return 2.0f; } 37 | 38 | class RollOff { 39 | public: 40 | unsigned const taps; 41 | float const fc; 42 | 43 | RollOff(float rollOffStart, float rollOffWidth) 44 | : taps(toTaps(rollOffWidth)), fc(toFc(rollOffStart, taps)) 45 | { 46 | } 47 | 48 | private: 49 | static unsigned toTaps(float rollOffWidth) { 50 | float widthTimesTaps = 0.9f; 51 | return std::max(unsigned(std::ceil(widthTimesTaps / rollOffWidth)), 4u); 52 | } 53 | 54 | static float toFc(float rollOffStart, int taps) { 55 | float startToFcDeltaTimesTaps = 0.43f; 56 | return startToFcDeltaTimesTaps / taps + rollOffStart; 57 | } 58 | }; 59 | 60 | RectSinc(unsigned div, unsigned phaseLen, double fc) 61 | : kernel_(phaseLen * phases) 62 | , polyfir_(kernel_, phaseLen, div) 63 | { 64 | makeSincKernel(kernel_, phases, phaseLen, fc, rectWin, 1.0); 65 | } 66 | 67 | RectSinc(unsigned div, RollOff ro, double gain) 68 | : kernel_(ro.taps * phases) 69 | , polyfir_(kernel_, ro.taps, div) 70 | { 71 | makeSincKernel(kernel_, phases, ro.taps, ro.fc, rectWin, gain); 72 | } 73 | 74 | virtual std::size_t resample(short *out, short const *in, std::size_t inlen) { 75 | return polyfir_.filter(out, in, inlen); 76 | } 77 | 78 | virtual void adjustDiv(unsigned div) { polyfir_.adjustDiv(div); } 79 | virtual unsigned mul() const { return MUL; } 80 | virtual unsigned div() const { return polyfir_.div(); } 81 | 82 | private: 83 | Array const kernel_; 84 | PolyphaseFir polyfir_; 85 | 86 | static double rectWin(long /*i*/, long /*M*/) { return 1; } 87 | }; 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /common/resample/src/resamplerinfo.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "../resamplerinfo.h" 20 | #include "chainresampler.h" 21 | #include "kaiser50sinc.h" 22 | #include "kaiser70sinc.h" 23 | // #include "hammingsinc.h" 24 | // #include "blackmansinc.h" 25 | #include "rectsinc.h" 26 | #include "linint.h" 27 | 28 | static Resampler * createLinint(long inRate, long outRate, std::size_t ) { 29 | return new Linint(inRate, outRate); 30 | } 31 | 32 | ResamplerInfo const ResamplerInfo::resamplers_[] = { 33 | { "Fast", createLinint }, 34 | { "High quality (polyphase FIR)", ChainResampler::create }, 35 | // { "Hamming windowed sinc (~50 dB SNR)", ChainResampler::create }, 36 | // { "Blackman windowed sinc (~70 dB SNR)", ChainResampler::create }, 37 | { "Very high quality (polyphase FIR)", ChainResampler::create }, 38 | { "Highest quality (polyphase FIR)", ChainResampler::create }, 39 | }; 40 | 41 | std::size_t const ResamplerInfo::num_ = 42 | sizeof ResamplerInfo::resamplers_ / sizeof *ResamplerInfo::resamplers_; 43 | -------------------------------------------------------------------------------- /common/resample/src/rshift16_round.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef RSHIFT16_ROUND_H 20 | #define RSHIFT16_ROUND_H 21 | 22 | // negative shift is not defined in c++98 23 | #ifdef NO_NEGATIVE_SHIFT 24 | inline long rshift16_round(long const l) { 25 | return l < 0 ? -((-l + 0x8000) >> 16) : (l + 0x8000) >> 16; 26 | } 27 | #else 28 | inline long rshift16_round(long l) { 29 | return (l + 0x8000) >> 16; 30 | } 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /common/resample/src/subresampler.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef SUBRESAMPLER_H 20 | #define SUBRESAMPLER_H 21 | 22 | #include 23 | 24 | class SubResampler { 25 | public: 26 | virtual ~SubResampler() {} 27 | virtual std::size_t resample(short *out, short const *in, std::size_t inlen) = 0; 28 | virtual unsigned mul() const = 0; 29 | virtual unsigned div() const = 0; 30 | virtual void adjustDiv(unsigned /*div*/) {} 31 | }; 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /common/resample/src/u48div.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "u48div.h" 20 | #include 21 | 22 | unsigned long u48div(unsigned long num1, unsigned num2, unsigned long const den) { 23 | unsigned long res = 0; 24 | unsigned s = 16; 25 | 26 | do { 27 | if (num1 < 0x10000) { 28 | num1 <<= s; 29 | num1 |= num2 & ((1 << s) - 1); 30 | s = 0; 31 | } else { 32 | if (num1 < 0x1000000) { 33 | unsigned const maxs = std::min(s, 8u); 34 | num1 <<= maxs; 35 | num1 |= (num2 >> (s - maxs)) & ((1 << maxs) - 1); 36 | s -= maxs; 37 | } 38 | if (num1 < 0x10000000) { 39 | unsigned const maxs = std::min(s, 4u); 40 | num1 <<= maxs; 41 | num1 |= (num2 >> (s - maxs)) & ((1 << maxs) - 1); 42 | s -= maxs; 43 | } 44 | 45 | while (num1 < den && s) { 46 | num1 <<= 1; // if this overflows we're screwed 47 | num1 |= num2 >> (s - 1) & 1; 48 | s -= 1; 49 | } 50 | } 51 | 52 | res += (num1 / den) << s; 53 | num1 = (num1 % den); 54 | } while (s); 55 | 56 | return res; 57 | } 58 | -------------------------------------------------------------------------------- /common/resample/src/u48div.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef U48DIV_H 20 | #define U48DIV_H 21 | 22 | unsigned long u48div(unsigned long numeratorLow, unsigned numeratorHigh, unsigned long denominator); 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /common/resample/src/upsampler.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef UPSAMPLER_H 20 | #define UPSAMPLER_H 21 | 22 | #include "subresampler.h" 23 | #include 24 | 25 | template 26 | class Upsampler : public SubResampler { 27 | public: 28 | explicit Upsampler(unsigned mul) : mul_(mul) {} 29 | virtual std::size_t resample(short *out, short const *in, std::size_t inlen); 30 | virtual unsigned mul() const { return mul_; } 31 | virtual unsigned div() const { return 1; } 32 | 33 | private: 34 | unsigned mul_; 35 | }; 36 | 37 | template 38 | std::size_t Upsampler::resample(short *out, short const *in, std::size_t const inlen) { 39 | unsigned const mul = mul_; 40 | if (std::size_t n = inlen) { 41 | std::memset(out, 0, inlen * mul * channels * sizeof *out); 42 | 43 | do { 44 | std::memcpy(out, in, channels * sizeof *out); 45 | in += channels; 46 | out += mul * channels; 47 | } while (--n); 48 | } 49 | 50 | return inlen * mul; 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /common/ringbuffer.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef RINGBUFFER_H 20 | #define RINGBUFFER_H 21 | 22 | #include "array.h" 23 | #include 24 | #include 25 | #include 26 | 27 | template 28 | class RingBuffer { 29 | public: 30 | explicit RingBuffer(std::size_t size = 0) 31 | : endpos_(0), rpos_(0), wpos_(0) 32 | { 33 | reset(size); 34 | } 35 | 36 | void reset(std::size_t size); 37 | 38 | void clear() { 39 | wpos_ = rpos_ = 0; 40 | } 41 | 42 | void fill(T value); 43 | void read(T *out, std::size_t num); 44 | void write(T const *in, std::size_t num); 45 | 46 | std::size_t avail() const { 47 | return (wpos_ < rpos_ ? 0 : endpos_) + rpos_ - wpos_ - 1; 48 | } 49 | 50 | std::size_t used() const { 51 | return (wpos_ < rpos_ ? endpos_ : 0) + wpos_ - rpos_; 52 | } 53 | 54 | std::size_t size() const { 55 | return endpos_ - 1; 56 | } 57 | 58 | private: 59 | Array buf_; 60 | std::size_t endpos_; 61 | std::size_t rpos_; 62 | std::size_t wpos_; 63 | }; 64 | 65 | template 66 | void RingBuffer::reset(std::size_t size) { 67 | endpos_ = size + 1; 68 | rpos_ = wpos_ = 0; 69 | buf_.reset(size ? endpos_ : 0); 70 | } 71 | 72 | template 73 | void RingBuffer::fill(T value) { 74 | std::fill(buf_.get(), buf_.get() + buf_.size(), value); 75 | rpos_ = 0; 76 | wpos_ = endpos_ - 1; 77 | } 78 | 79 | template 80 | void RingBuffer::read(T *out, std::size_t num) { 81 | if (rpos_ + num > endpos_) { 82 | std::size_t const n = endpos_ - rpos_; 83 | std::memcpy(out, buf_ + rpos_, n * sizeof *out); 84 | rpos_ = 0; 85 | num -= n; 86 | out += n; 87 | } 88 | 89 | std::memcpy(out, buf_ + rpos_, num * sizeof *out); 90 | if ((rpos_ += num) == endpos_) 91 | rpos_ = 0; 92 | } 93 | 94 | template 95 | void RingBuffer::write(T const *in, std::size_t num) { 96 | if (wpos_ + num > endpos_) { 97 | std::size_t const n = endpos_ - wpos_; 98 | std::memcpy(buf_ + wpos_, in, n * sizeof *buf_); 99 | wpos_ = 0; 100 | num -= n; 101 | in += n; 102 | } 103 | 104 | std::memcpy(buf_ + wpos_, in, num * sizeof *buf_); 105 | if ((wpos_ += num) == endpos_) 106 | wpos_ = 0; 107 | } 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /common/scoped_ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef SCOPED_PTR_H 2 | #define SCOPED_PTR_H 3 | 4 | #include "transfer_ptr.h" 5 | #include "uncopyable.h" 6 | 7 | template 8 | class scoped_ptr : Uncopyable { 9 | public: 10 | explicit scoped_ptr(T *p = 0) : p_(p) {} 11 | template explicit scoped_ptr(transfer_ptr p) : p_(p.release()) {} 12 | ~scoped_ptr() { Deleter::del(p_); } 13 | T * get() const { return p_; } 14 | void reset(T *p = 0) { Deleter::del(p_); p_ = p; } 15 | T & operator*() const { return *p_; } 16 | T * operator->() const { return p_; } 17 | operator bool() const { return p_; } 18 | 19 | template 20 | scoped_ptr & operator=(transfer_ptr p) { 21 | reset(p.release()); 22 | return *this; 23 | } 24 | 25 | private: 26 | T *p_; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /common/skipsched.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "skipsched.h" 20 | 21 | bool SkipSched::skipNext(bool skip) { 22 | if (skipped_) { 23 | if (skipped_ < skippedmax_ / 2) 24 | skip = true; 25 | else 26 | skipped_ = skip = 0; 27 | } else if (skip) { 28 | skippedmax_ += skippedmax_ / 2 < 8; 29 | } else if (skippedmax_ / 2) 30 | --skippedmax_; 31 | 32 | skipped_ += skip; 33 | 34 | return skip; 35 | } 36 | -------------------------------------------------------------------------------- /common/skipsched.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef SKIPSCHED_H 20 | #define SKIPSCHED_H 21 | 22 | class SkipSched { 23 | public: 24 | SkipSched() : skipped_(0), skippedmax_(2 - 1) {} 25 | bool skipNext(bool wantskip); 26 | 27 | private: 28 | unsigned skipped_; 29 | unsigned skippedmax_; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /common/transfer_ptr.h: -------------------------------------------------------------------------------- 1 | #ifndef TRANSFER_PTR_H 2 | #define TRANSFER_PTR_H 3 | 4 | #include "defined_ptr.h" 5 | 6 | template 7 | class transfer_ptr { 8 | private: 9 | struct released { T *p; explicit released(T *p) : p(p) {} }; 10 | public: 11 | explicit transfer_ptr(T *p = 0) : p_(p) {} 12 | transfer_ptr(transfer_ptr &p) : p_(p.release()) {} 13 | transfer_ptr(released r) : p_(r.p) {} 14 | ~transfer_ptr() { Deleter::del(p_); } 15 | T * get() const { return p_; } 16 | T * release() { T *p = p_; p_ = 0; return p; } 17 | operator released const () { return released(release()); } 18 | T & operator*() const { return *p_; } 19 | T * operator->() const { return p_; } 20 | operator bool() const { return p_; } 21 | 22 | private: 23 | T *p_; 24 | transfer_ptr & operator=(transfer_ptr const &); 25 | }; 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /common/uncopyable.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef UNCOPYABLE_H 20 | #define UNCOPYABLE_H 21 | 22 | class Uncopyable { 23 | protected: 24 | Uncopyable() {} 25 | private: 26 | Uncopyable(Uncopyable const &); 27 | Uncopyable& operator=(Uncopyable const &); 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /common/usec.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2008 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef USEC_H 20 | #define USEC_H 21 | 22 | typedef unsigned long usec_t; 23 | 24 | usec_t getusecs(); 25 | void usecsleep(usec_t usecs); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /common/videolink/rgb32conv.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef RGB32CONV_H 20 | #define RGB32CONV_H 21 | 22 | class VideoLink; 23 | 24 | class Rgb32Conv { 25 | public: 26 | enum PixelFormat { RGB32, RGB16, UYVY }; 27 | static VideoLink * create(PixelFormat pf, unsigned width, unsigned height); 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /common/videolink/vfilterinfo.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #include "vfilterinfo.h" 20 | 21 | static VideoLink * createNone() { return 0; } 22 | 23 | template 24 | static VideoLink * createT() { return new T; } 25 | 26 | #define VFINFO(handle, Type) { handle, Type::out_width, Type::out_height, createT } 27 | 28 | static VfilterInfo const vfinfos[] = { 29 | { "None", VfilterInfo::in_width, VfilterInfo::in_height, createNone }, 30 | }; 31 | 32 | std::size_t VfilterInfo::numVfilters() { 33 | return sizeof vfinfos / sizeof vfinfos[0]; 34 | } 35 | 36 | VfilterInfo const & VfilterInfo::get(std::size_t n) { 37 | return vfinfos[n]; 38 | } 39 | -------------------------------------------------------------------------------- /common/videolink/vfilterinfo.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef VFILTERINFO_H 20 | #define VFILTERINFO_H 21 | 22 | #include 23 | 24 | class VideoLink; 25 | 26 | struct VfilterInfo { 27 | enum { in_width = 160 }; 28 | enum { in_height = 144 }; 29 | 30 | char const *handle; 31 | unsigned outWidth; 32 | unsigned outHeight; 33 | VideoLink * (*create)(); 34 | 35 | static VfilterInfo const & get(std::size_t n); 36 | static std::size_t numVfilters(); 37 | }; 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /common/videolink/videolink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2009 by Sindre Aamås * 3 | * sinamas@users.sourceforge.net * 4 | * * 5 | * This program is free software; you can redistribute it and/or modify * 6 | * it under the terms of the GNU General Public License version 2 as * 7 | * published by the Free Software Foundation. * 8 | * * 9 | * This program is distributed in the hope that it will be useful, * 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 | * GNU General Public License version 2 for more details. * 13 | * * 14 | * You should have received a copy of the GNU General Public License * 15 | * version 2 along with this program; if not, write to the * 16 | * Free Software Foundation, Inc., * 17 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 18 | ***************************************************************************/ 19 | #ifndef VIDEOLINK_H 20 | #define VIDEOLINK_H 21 | 22 | #include 23 | 24 | class VideoLink { 25 | public: 26 | virtual ~VideoLink() {} 27 | virtual void * inBuf() const = 0; 28 | virtual std::ptrdiff_t inPitch() const = 0; 29 | virtual void draw(void *dst, std::ptrdiff_t dstpitch) = 0; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /dist/funkeys/default.funkey-s.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Gambatte-DMS 3 | Comment=GB/GBC emulator 4 | Icon=gambatte_dms 5 | Exec=gambatte-dms.funkeys 6 | Categories=emulators 7 | -------------------------------------------------------------------------------- /dist/gambatte_dmg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bardeci/gambatte-dms/41453c497e3802a16acba8bd7f500e4d3b412ae4/dist/gambatte_dmg.png -------------------------------------------------------------------------------- /dist/gambatte_dms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bardeci/gambatte-dms/41453c497e3802a16acba8bd7f500e4d3b412ae4/dist/gambatte_dms.png -------------------------------------------------------------------------------- /dist/gambatte_gbc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bardeci/gambatte-dms/41453c497e3802a16acba8bd7f500e4d3b412ae4/dist/gambatte_gbc.png -------------------------------------------------------------------------------- /dist/gcw0/default.gcw0.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Gambatte-DMS 3 | Comment=GB/GBC emulator 4 | Exec=gambatte-dms.gcw0 %f 5 | Terminal=false 6 | Type=Application 7 | StartupNotify=true 8 | Icon=gambatte_dms 9 | Categories=emulators; 10 | X-OD-NeedsDownscaling=true 11 | X-OD-Manual=manual.txt 12 | MimeType=application/x-gameboy-rom;application/x-gbc-rom;application/x-gameboy-color-rom;application/x-gzip;application/zip;application/gzip; 13 | -------------------------------------------------------------------------------- /dist/manual.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bardeci/gambatte-dms/41453c497e3802a16acba8bd7f500e4d3b412ae4/dist/manual.txt -------------------------------------------------------------------------------- /dist/retrofw/control: -------------------------------------------------------------------------------- 1 | Package: Gambatte-DMS 2 | Version: 3 | Description: port of Gambatte 4 | Section: emus 5 | Priority: optional 6 | Maintainer: hi-ban 7 | Architecture: mipsel 8 | Homepage: 9 | Depends: 10 | Source: 11 | -------------------------------------------------------------------------------- /dist/retrofw/default.retrofw.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Gambatte-DMS 3 | Comment=GB/GBC emulator 4 | Exec=gambatte-dms.retrofw 5 | Terminal=false 6 | Type=Application 7 | StartupNotify=true 8 | Icon=gambatte_dms 9 | Categories=emulators; 10 | X-OD-Manual=manual.txt 11 | X-OD-Selector=/home/retrofw/roms/gb 12 | X-OD-Filter=.zip,.gb,.gbc 13 | -------------------------------------------------------------------------------- /dist/retrofw/gambatte.lnk: -------------------------------------------------------------------------------- 1 | title=Gambatte-DMS 2 | description=GB/GBC Emulator 3 | exec=/home/retrofw/emus/gambatte/gambatte-dms.dge 4 | selectordir=/home/retrofw/roms/gb 5 | selectorfilter=.zip,.gb,.gbc 6 | clock=600 7 | -------------------------------------------------------------------------------- /dist/retrofw/gb.gambatte.lnk: -------------------------------------------------------------------------------- 1 | title=GB 2 | description=Gambatte-DMS Emulator 3 | exec=/home/retrofw/emus/gambatte/gambatte-dms.dge 4 | selectordir=/home/retrofw/roms/gb 5 | selectorfilter=.zip,.gb,.gbc 6 | clock=600 7 | -------------------------------------------------------------------------------- /dist/retrofw/gb.retrofw.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=GB 3 | Comment=Gambatte-DMS emulator 4 | Exec=gambatte-dms.retrofw 5 | Terminal=false 6 | Type=Application 7 | StartupNotify=true 8 | Icon=gambatte_dmg 9 | Categories=emulators.systems; 10 | X-OD-Manual=manual.txt 11 | X-OD-Selector=/home/retrofw/roms/gb 12 | X-OD-Filter=.zip,.gb 13 | -------------------------------------------------------------------------------- /dist/retrofw/gbc.gambatte.lnk: -------------------------------------------------------------------------------- 1 | title=GBC 2 | description=Gambatte-DMS Emulator 3 | exec=/home/retrofw/emus/gambatte/gambatte-dms.dge 4 | selectordir=/home/retrofw/roms/gbc 5 | selectorfilter=.zip,.gb,.gbc 6 | clock=600 7 | -------------------------------------------------------------------------------- /dist/retrofw/gbc.retrofw.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=GBC 3 | Comment=Gambatte-DMS emulator 4 | Exec=gambatte-dms.retrofw 5 | Terminal=false 6 | Type=Application 7 | StartupNotify=true 8 | Icon=gambatte_gbc 9 | Categories=emulators.systems; 10 | X-OD-Manual=manual.txt 11 | X-OD-Selector=/home/retrofw/roms/gbc 12 | X-OD-Filter=.zip,.gbc 13 | -------------------------------------------------------------------------------- /gambatte_sdl/SConstruct: -------------------------------------------------------------------------------- 1 | # OPTIONAL DEFINES: 2 | # -DROM_BROWSER: Enables internal rom browser (gb and gbc romdirs are hardcoded for each system) 3 | # -DPOWEROFF: Replaces the "Quit" option with a "Power Off" option. 4 | 5 | target = ARGUMENTS.get('target', 0) 6 | if target == 'gcw0': 7 | include_path = ' -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include' 8 | bin_path = '/opt/gcw0-toolchain/usr/bin/mipsel-linux-' 9 | sdl_path = '/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/bin/' 10 | version_defines = ' -DVERSION_GCW0' 11 | extra_cflags = '' 12 | print "Building Gambatte SDL with GCW0 toolchain..." 13 | elif target == 'retrofw': 14 | include_path = ' -I/opt/rs97-toolchain/mipsel-buildroot-linux-uclibc/sysroot/usr/include' 15 | bin_path = '/opt/rs97-toolchain/bin/mipsel-linux-' 16 | sdl_path = '/opt/rs97-toolchain/mipsel-buildroot-linux-uclibc/sysroot/usr/bin/' 17 | version_defines = ' -DVERSION_RETROFW' 18 | extra_cflags = ' -Ofast -fdata-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fno-common -mips32 -fno-PIC -mno-abicalls -flto -fwhole-program' 19 | print "Building Gambatte SDL with RetroFW toolchain..." 20 | else: 21 | include_path = '' 22 | bin_path = '' 23 | sdl_path = '' 24 | version_defines = '' 25 | extra_cflags = '' 26 | 27 | global_cflags = ARGUMENTS.get('CFLAGS', '-Wall -Wextra -O2 -fomit-frame-pointer -ffunction-sections -ffast-math -fsingle-precision-constant -g0' + extra_cflags + include_path) 28 | global_cxxflags = ARGUMENTS.get('CXXFLAGS', global_cflags + ' -fno-exceptions -fno-rtti') 29 | global_linkflags = ARGUMENTS.get('LINKFLAGS', '-Wl,--gc-sections') 30 | global_defines = ' -DHAVE_STDINT_H' + version_defines 31 | 32 | vars = Variables() 33 | vars.Add('CC') 34 | vars.Add('CXX') 35 | 36 | env = Environment(CPPPATH = ['src', '../libgambatte/include', '../common'], 37 | CFLAGS = global_cflags + global_defines, 38 | CXXFLAGS = global_cxxflags + global_defines, 39 | CC = bin_path + 'gcc', 40 | CXX = bin_path + 'g++', 41 | LINKFLAGS = global_linkflags + ' -lSDL_image -lSDL_mixer', 42 | variables = vars) 43 | 44 | env.ParseConfig(sdl_path + 'sdl-config --cflags --libs') 45 | 46 | sourceFiles = Split(''' 47 | src/audiosink.cpp 48 | src/blitterwrapper.cpp 49 | src/parser.cpp 50 | src/sdlblitter.cpp 51 | src/str_to_sdlkey.cpp 52 | src/usec.cpp 53 | SFont.c 54 | menu.cpp 55 | libmenu.cpp 56 | scaler.c 57 | ../common/adaptivesleep.cpp 58 | ../common/resample/src/chainresampler.cpp 59 | ../common/resample/src/i0.cpp 60 | ../common/resample/src/kaiser50sinc.cpp 61 | ../common/resample/src/kaiser70sinc.cpp 62 | ../common/resample/src/makesinckernel.cpp 63 | ../common/resample/src/resamplerinfo.cpp 64 | ../common/resample/src/u48div.cpp 65 | ../common/rateest.cpp 66 | ../common/skipsched.cpp 67 | ../common/videolink/rgb32conv.cpp 68 | ../common/videolink/vfilterinfo.cpp 69 | ../libgambatte/libgambatte.a 70 | ''') 71 | 72 | conf = env.Configure() 73 | conf.CheckLib('z') 74 | conf.Finish() 75 | 76 | version_str_def = [ 'GAMBATTE_SDL_VERSION_STR', r'\"r572u4\"' ] 77 | 78 | env.Program('gambatte_sdl', 79 | [env.Object('src/gambatte_sdl.cpp', 80 | CPPDEFINES = env['CPPDEFINES'] + [version_str_def])] 81 | + sourceFiles) 82 | -------------------------------------------------------------------------------- /gambatte_sdl/SFont.h: -------------------------------------------------------------------------------- 1 | /* SFont: a simple font-library that uses special bitmaps as fonts 2 | Copyright (C) 2003 Karl Bartel 3 | 4 | License: GPL or LGPL (at your choice) 5 | WWW: http://www.linux-games.com/sfont/ 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program; if not, write to the Free Software 19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | 21 | Karl Bartel 22 | Cecilienstr. 14 23 | 12307 Berlin 24 | GERMANY 25 | karlb@gmx.net 26 | */ 27 | 28 | /************************************************************************ 29 | * SFONT - SDL Font Library by Karl Bartel * 30 | * * 31 | * All functions are explained below. For further information, take a * 32 | * look at the example files, the links at the SFont web site, or * 33 | * contact me, if you problem isn' addressed anywhere. * 34 | * * 35 | ************************************************************************/ 36 | #ifndef SFONT_H 37 | #define SFONT_H 38 | 39 | #include 40 | 41 | #ifdef __cplusplus 42 | extern "C" { 43 | #endif 44 | 45 | // Delcare one variable of this type for each font you are using. 46 | // To load the fonts, load the font image into YourFont->Surface 47 | // and call InitFont( YourFont ); 48 | typedef struct { 49 | SDL_Surface *Surface; 50 | int CharPos[512]; 51 | int MaxPos; 52 | } SFont_Font; 53 | 54 | // Initializes the font 55 | // Font: this contains the suface with the font. 56 | // The Surface must be loaded before calling this function 57 | SFont_Font* SFont_InitFont (SDL_Surface *Font); 58 | 59 | // Frees the font 60 | // Font: The font to free 61 | // The font must be loaded before using this function. 62 | void SFont_FreeFont(SFont_Font* Font); 63 | 64 | // Blits a string to a surface 65 | // Destination: the suface you want to blit to 66 | // text: a string containing the text you want to blit. 67 | void SFont_Write(SDL_Surface *Surface, const SFont_Font *Font, int x, int y, 68 | const char *text); 69 | 70 | // Returns the width of "text" in pixels 71 | int SFont_TextWidth(const SFont_Font* Font, const char *text); 72 | // Returns the height of "text" in pixels (which is always equal to Font->Surface->h) 73 | int SFont_TextHeight(const SFont_Font* Font); 74 | 75 | // Blits a string to Surface with centered x position 76 | void SFont_WriteCenter(SDL_Surface *Surface, const SFont_Font* Font, int y, 77 | const char *text); 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | #endif /* SFONT_H */ 84 | -------------------------------------------------------------------------------- /gambatte_sdl/builddate.h: -------------------------------------------------------------------------------- 1 | #define BUILDDATE "20231203-020959" 2 | -------------------------------------------------------------------------------- /gambatte_sdl/menu.h: -------------------------------------------------------------------------------- 1 | #ifndef _MENU_H 2 | #define _MENU_H 3 | 4 | #include 5 | #include "src/blitterwrapper.h" 6 | #include "libmenu.h" 7 | 8 | extern gambatte::GB *gambatte_p; 9 | extern BlitterWrapper *blitter_p; 10 | extern SDL_Surface *surface; 11 | 12 | void menu_set_screen(SDL_Surface *set_screen); 13 | int init_fps_font(); 14 | void init_globals(gambatte::GB *gambatte, BlitterWrapper *blitter); 15 | int init_menu(); 16 | void main_menu(); 17 | void main_menu_with_anim(); 18 | void show_fps(SDL_Surface *surface, int fps); 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /gambatte_sdl/scaler.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _SCALER_H 3 | #define _SCALER_H 4 | 5 | #include 6 | #include 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | 13 | void scale15x(uint32_t *to, uint32_t *from); 14 | void scale15x_fast(uint32_t* dst, uint32_t* src); 15 | void scale15x_pseudobilinear(uint32_t* dst, uint32_t* src, int dstwidth); 16 | void scale166x_fast(uint32_t* dst, uint32_t* src); 17 | void scale166x_pseudobilinear(uint32_t* dst, uint32_t* src); 18 | void fullscreen_upscale(uint32_t *to, uint32_t *from); 19 | void fullscreen_upscale_pseudobilinear(uint32_t* dst, uint32_t* src); 20 | void scaleborder15x(uint32_t* dst, uint32_t* src); 21 | void scaleborder166x(uint32_t* dst, uint32_t* src); 22 | 23 | void scale15x_2(uint32_t* dst, uint32_t* src); 24 | void scale166x_2(uint32_t* dst, uint32_t* src); 25 | void fullscreen_2(uint32_t* dst, uint32_t* src); 26 | 27 | void scale15x_dotmatrix2(uint32_t* dst, uint32_t* src, const uint32_t gridcolor); 28 | void scale166x_dotmatrix2(uint32_t* dst, uint32_t* src, const uint32_t gridcolor); 29 | void fullscreen_dotmatrix2(uint32_t* dst, uint32_t* src, const uint32_t gridcolor); 30 | void scaleborder15x_2(uint32_t* dst, uint32_t* src); 31 | void scaleborder166x_2(uint32_t* dst, uint32_t* src); 32 | 33 | void scale15x_crt2(uint32_t* dst, uint32_t* src); 34 | void scale166x_crt2(uint32_t* dst, uint32_t* src); 35 | void fullscreen_crt2(uint32_t* dst, uint32_t* src); 36 | void scaleborder15x_crt2(uint32_t* dst, uint32_t* src); 37 | void scaleborder166x_crt2(uint32_t* dst, uint32_t* src); 38 | 39 | void scale15x_dotmatrix3(uint32_t* dst, uint32_t* src, const uint32_t gridcolor); 40 | void scale166x_dotmatrix3(uint32_t* dst, uint32_t* src, const uint32_t gridcolor); 41 | void fullscreen_dotmatrix3(uint32_t* dst, uint32_t* src, const uint32_t gridcolor); 42 | void scaleborder15x_3(uint32_t* dst, uint32_t* src); 43 | void scaleborder166x_3(uint32_t* dst, uint32_t* src); 44 | 45 | void scale15x_crt3(uint32_t* dst, uint32_t* src); 46 | void scale166x_crt3(uint32_t* dst, uint32_t* src); 47 | void fullscreen_crt3(uint32_t* dst, uint32_t* src); 48 | void scaleborder15x_crt3(uint32_t* dst, uint32_t* src); 49 | void scaleborder166x_crt3(uint32_t* dst, uint32_t* src); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /gambatte_sdl/src/audiosink.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef AUDIOSINK_H 20 | #define AUDIOSINK_H 21 | 22 | #include "ringbuffer.h" 23 | #include "rateest.h" 24 | #include "scoped_ptr.h" 25 | #include 26 | #include 27 | 28 | class AudioSink { 29 | public: 30 | struct Status { 31 | long fromUnderrun; 32 | long fromOverflow; 33 | long rate; 34 | 35 | Status(long fromUnderrun, long fromOverflow, long rate) 36 | : fromUnderrun(fromUnderrun), fromOverflow(fromOverflow), rate(rate) 37 | { 38 | } 39 | }; 40 | 41 | AudioSink(long sampleRate, int latency, int periods); 42 | ~AudioSink(); 43 | Status write(Sint16 const *inBuf, std::size_t samples); 44 | 45 | private: 46 | struct SdlDeleter; 47 | 48 | RingBuffer rbuf_; 49 | RateEst rateEst_; 50 | scoped_ptr const mut_; 51 | scoped_ptr const bufReadyCond_; 52 | bool const failed_; 53 | 54 | static void fillBuffer(void *data, Uint8 *stream, int len) { 55 | static_cast(data)->read(stream, len); 56 | } 57 | 58 | void read(Uint8 *stream, std::size_t len); 59 | }; 60 | 61 | int reopenAudio(); 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /gambatte_sdl/src/blitterwrapper.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2009 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "blitterwrapper.h" 20 | #include "videolink/rgb32conv.h" 21 | #include "videolink/vfilterinfo.h" 22 | #include "videolink/videolink.h" 23 | 24 | BlitterWrapper::BlitterWrapper(VfilterInfo const &vfinfo, int scale, bool yuv, bool full) 25 | : blitter_(vfinfo.outWidth, vfinfo.outHeight, scale, yuv, full) 26 | , cconvert_(Rgb32Conv::create(static_cast(blitter_.inBuffer().format), 27 | vfinfo.outWidth, vfinfo.outHeight)) 28 | , vfilter_(vfinfo.create()) 29 | { 30 | } 31 | 32 | BlitterWrapper::~BlitterWrapper() { 33 | } 34 | 35 | BlitterWrapper::Buf BlitterWrapper::inBuf() const { 36 | Buf buf; 37 | if (VideoLink *const gblink = vfilter_ ? vfilter_.get() : cconvert_.get()) { 38 | buf.pixels = static_cast(gblink->inBuf()); 39 | buf.pitch = gblink->inPitch(); 40 | } else { 41 | SdlBlitter::PixelBuffer const &pxbuf = blitter_.inBuffer(); 42 | buf.pixels = static_cast(pxbuf.pixels); 43 | buf.pitch = pxbuf.pitch; 44 | } 45 | 46 | return buf; 47 | } 48 | 49 | void BlitterWrapper::draw() { 50 | SdlBlitter::PixelBuffer const &pb = blitter_.inBuffer(); 51 | if (pb.pixels) { 52 | if (vfilter_) { 53 | vfilter_->draw(cconvert_ ? cconvert_->inBuf() : pb.pixels, 54 | cconvert_ ? cconvert_->inPitch() : pb.pitch); 55 | } 56 | if (cconvert_) 57 | cconvert_->draw(pb.pixels, pb.pitch); 58 | } 59 | 60 | blitter_.draw(); 61 | } 62 | -------------------------------------------------------------------------------- /gambatte_sdl/src/blitterwrapper.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2009 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef BLITTERWRAPPER_H 20 | #define BLITTERWRAPPER_H 21 | 22 | #include "gbint.h" 23 | #include "scoped_ptr.h" 24 | #include "sdlblitter.h" 25 | 26 | class VideoLink; 27 | struct VfilterInfo; 28 | 29 | class BlitterWrapper { 30 | public: 31 | struct Buf { gambatte::uint_least32_t *pixels; std::ptrdiff_t pitch; }; 32 | 33 | BlitterWrapper(VfilterInfo const &, int scale, bool yuv, bool full); 34 | ~BlitterWrapper(); 35 | Buf inBuf() const; 36 | void draw(); 37 | void present() { blitter_.present(); } 38 | void toggleFullScreen() { blitter_.toggleFullScreen(); } 39 | void CheckIPU() { blitter_.CheckIPU(); } 40 | void setBufferDimensions() { blitter_.setBufferDimensions(); } 41 | void setScreenRes() { blitter_.setScreenRes(); } 42 | void force320x240() { blitter_.force320x240(); } 43 | void scaleMenu() { blitter_.scaleMenu(); } 44 | SdlBlitter blitter_; 45 | 46 | private: 47 | 48 | scoped_ptr const cconvert_; 49 | scoped_ptr const vfilter_; 50 | }; 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /gambatte_sdl/src/parser.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "parser.h" 20 | #include 21 | 22 | Parser::Option::Option(char const *s, char c, int nArgs) 23 | : s_(s) 24 | , nArgs_(nArgs) 25 | , c_(c) 26 | { 27 | } 28 | 29 | void Parser::addLong(Option *o) { 30 | lMap.insert(std::make_pair(o->str(), o)); 31 | } 32 | 33 | int Parser::parseLong(int const argc, char const *const argv[], int const index) const { 34 | lmap_t::const_iterator it = lMap.find(argv[index] + 2); 35 | if (it == lMap.end()) 36 | return 0; 37 | 38 | Option &e = *(it->second); 39 | if (e.neededArgs() >= argc - index) 40 | return 0; 41 | 42 | e.exec(argv, index); 43 | return index + e.neededArgs(); 44 | } 45 | 46 | void Parser::addShort(Option *o) { 47 | sMap.insert(std::make_pair(o->character(), o)); 48 | } 49 | 50 | int Parser::parseShort(int const argc, char const *const argv[], int const index) const { 51 | char const *s = argv[index]; 52 | ++s; 53 | 54 | if (!(*s)) 55 | return 0; 56 | 57 | do { 58 | smap_t::const_iterator const it = sMap.find(*s); 59 | if (it == sMap.end()) 60 | return 0; 61 | 62 | Option &e = *(it->second); 63 | if (e.neededArgs()) { 64 | if (s[1] || e.neededArgs() >= argc - index) 65 | return 0; 66 | 67 | e.exec(argv, index); 68 | return index + e.neededArgs(); 69 | } 70 | 71 | e.exec(argv, index); 72 | } while (*++s); 73 | 74 | return index; 75 | } 76 | 77 | void Parser::add(Option *o) { 78 | addLong(o); 79 | 80 | if (o->character()) 81 | addShort(o); 82 | } 83 | 84 | int Parser::parse(int argc, char const *const *argv, int index) const { 85 | return argv[index][1] == '-' 86 | ? parseLong(argc, argv, index) 87 | : parseShort(argc, argv, index); 88 | } 89 | -------------------------------------------------------------------------------- /gambatte_sdl/src/parser.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef PARSER_H 20 | #define PARSER_H 21 | 22 | #include 23 | #include 24 | 25 | class Parser { 26 | public: 27 | class Option { 28 | public: 29 | explicit Option(char const *s, char c = 0, int nArgs = 0); 30 | virtual ~Option() {} 31 | virtual void exec(char const *const *argv, int index) = 0; 32 | char character() const { return c_; } 33 | char const * str() const { return s_; } 34 | int neededArgs() const { return nArgs_; } 35 | 36 | private: 37 | char const *const s_; 38 | int const nArgs_; 39 | char const c_; 40 | }; 41 | 42 | void add(Option *o); 43 | int parse(int argc, char const *const *argv, int index) const; 44 | 45 | private: 46 | struct StrLess { 47 | bool operator()(char const *l, char const *r) const { 48 | return std::strcmp(l, r) < 0; 49 | } 50 | }; 51 | 52 | typedef std::map smap_t; 53 | typedef std::map lmap_t; 54 | 55 | smap_t sMap; 56 | lmap_t lMap; 57 | 58 | void addLong(Option *o); 59 | void addShort(Option *o); 60 | int parseLong(int argc, char const *const *argv, int index) const; 61 | int parseShort(int argc, char const *const *argv, int index) const; 62 | }; 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /gambatte_sdl/src/scalebuffer.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SCALEBUFFER_H_ 20 | #define SCALEBUFFER_H_ 21 | 22 | #include 23 | #include 24 | 25 | template 26 | inline void do_scaleBuffer(const T *s, T *d, 27 | const unsigned srcW, const unsigned srcH, 28 | const std::ptrdiff_t dstPitch, const unsigned scale) { 29 | const unsigned dstW = srcW * scale; 30 | 31 | for (unsigned h = srcH; h--;) { 32 | for (unsigned w = srcW; w--;) { 33 | for (unsigned n = scale; n--;) 34 | *d++ = *s; 35 | 36 | ++s; 37 | } 38 | 39 | s += dstPitch - std::ptrdiff_t(dstW); 40 | 41 | for (unsigned n = scale; --n; d += dstPitch) 42 | std::memcpy(d, d - dstPitch, dstW * sizeof *d); 43 | } 44 | } 45 | 46 | template 47 | void scaleBuffer(const T *s, T *d, 48 | const unsigned srcW, const unsigned srcH, 49 | const std::ptrdiff_t dstPitch, const unsigned scale) { 50 | switch (scale) { 51 | case 2: do_scaleBuffer(s, d, srcW, srcH, dstPitch, 2); break; 52 | case 3: do_scaleBuffer(s, d, srcW, srcH, dstPitch, 3); break; 53 | case 4: do_scaleBuffer(s, d, srcW, srcH, dstPitch, 4); break; 54 | case 5: do_scaleBuffer(s, d, srcW, srcH, dstPitch, 5); break; 55 | case 6: do_scaleBuffer(s, d, srcW, srcH, dstPitch, 6); break; 56 | case 7: do_scaleBuffer(s, d, srcW, srcH, dstPitch, 7); break; 57 | case 8: do_scaleBuffer(s, d, srcW, srcH, dstPitch, 8); break; 58 | default: do_scaleBuffer(s, d, srcW, srcH, dstPitch, scale); break; 59 | } 60 | } 61 | 62 | #endif /*SCALEBUFFER_H_*/ 63 | -------------------------------------------------------------------------------- /gambatte_sdl/src/sdlblitter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SDLBLITTER_H 20 | #define SDLBLITTER_H 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "scoped_ptr.h" 29 | #include 30 | 31 | struct SDL_Overlay; 32 | struct SDL_Surface; 33 | 34 | class SdlBlitter { 35 | public: 36 | enum PixelFormat { RGB32, RGB16, UYVY }; 37 | 38 | struct PixelBuffer { 39 | void *pixels; 40 | std::ptrdiff_t pitch; 41 | PixelFormat format; 42 | }; 43 | 44 | SdlBlitter(unsigned inwidth, unsigned inheight, 45 | int scale, bool yuv, bool full); 46 | ~SdlBlitter(); 47 | PixelBuffer inBuffer() const; 48 | void draw(); 49 | void present(); 50 | void toggleFullScreen(); 51 | void CheckIPU(); 52 | void SetVid(int w, int h, int bpp); 53 | void SetIPUAspectRatio(const char *ratiovalue); 54 | void SetIPUSharpness(const char *svalue); 55 | void setBufferDimensions(); 56 | void setScreenRes(); 57 | void force320x240(); 58 | void applyScalerToSurface(SDL_Surface *sourcesurface); 59 | void scaleMenu(); 60 | SDL_Surface *screen; 61 | SDL_Surface *surface; 62 | 63 | 64 | private: 65 | struct SurfaceDeleter; 66 | 67 | 68 | //scoped_ptr const surface_; 69 | scoped_ptr const overlay_; 70 | 71 | template void swScale(); 72 | }; 73 | 74 | extern SDL_Surface *borderimg; 75 | 76 | #endif 77 | 78 | -------------------------------------------------------------------------------- /gambatte_sdl/src/str_to_sdlkey.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef STR_TO_SDLKEY_H 20 | #define STR_TO_SDLKEY_H 21 | 22 | #include 23 | 24 | SDLKey const * strToSdlkey(char const *str); 25 | void printStrSdlkeys(); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /gambatte_sdl/src/usec.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "usec.h" 20 | #include 21 | 22 | usec_t getusecs() { 23 | return SDL_GetTicks() * usec_t(1000); 24 | } 25 | 26 | void usecsleep(usec_t usecs) { 27 | SDL_Delay((usecs + 999) / 1000); 28 | } 29 | -------------------------------------------------------------------------------- /libgambatte/SConstruct: -------------------------------------------------------------------------------- 1 | # OPTIONAL DEFINES: 2 | # -DROM_BROWSER: Enables internal rom browser (gb and gbc romdirs are hardcoded for each system) 3 | # -DPOWEROFF: Replaces the "Quit" option with a "Power Off" option. 4 | 5 | target = ARGUMENTS.get('target', 0) 6 | if target == 'gcw0': 7 | include_path = ' -I/opt/gcw0-toolchain/usr/mipsel-gcw0-linux-uclibc/sysroot/usr/include' 8 | bin_path = '/opt/gcw0-toolchain/usr/bin/mipsel-linux-' 9 | version_defines = ' -DVERSION_GCW0' 10 | extra_cflags = '' 11 | print "Building Gambatte library with GCW0 toolchain..." 12 | elif target == 'retrofw': 13 | include_path = ' -I/opt/rs97-toolchain/mipsel-buildroot-linux-uclibc/sysroot/usr/include' 14 | bin_path = '/opt/rs97-toolchain/bin/mipsel-linux-' 15 | version_defines = ' -DVERSION_RETROFW' 16 | extra_cflags = ' -Ofast -fdata-sections -mno-fp-exceptions -mno-check-zero-division -mframe-header-opt -fno-common -mips32 -fno-PIC -mno-abicalls -flto -fwhole-program' 17 | print "Building Gambatte library with RetroFW toolchain..." 18 | else: 19 | include_path = '' 20 | bin_path = '' 21 | version_defines = '' 22 | extra_cflags = '' 23 | 24 | global_cflags = ARGUMENTS.get('CFLAGS', '-Wall -Wextra -O2 -fomit-frame-pointer -ffunction-sections -ffast-math -fsingle-precision-constant -g0' + extra_cflags + include_path) 25 | global_cxxflags = ARGUMENTS.get('CXXFLAGS', global_cflags + ' -fno-exceptions -fno-rtti') 26 | global_linkflags = ARGUMENTS.get('LINKFLAGS', '-Wl,--gc-sections') 27 | global_defines = ' -DHAVE_STDINT_H' + version_defines 28 | vars = Variables() 29 | vars.Add('CC') 30 | vars.Add('CXX') 31 | 32 | env = Environment(CPPPATH = ['src', 'include', '../common'], 33 | CFLAGS = global_cflags + global_defines, 34 | CXXFLAGS = global_cxxflags + global_defines, 35 | LINKFLAGS = global_linkflags, 36 | variables = vars, 37 | CC = bin_path + 'gcc', 38 | CXX = bin_path + 'g++' 39 | ) 40 | 41 | sourceFiles = Split(''' 42 | src/bitmap_font.cpp 43 | src/bootloader.cpp 44 | src/cpu.cpp 45 | src/gambatte.cpp 46 | src/initstate.cpp 47 | src/interrupter.cpp 48 | src/interruptrequester.cpp 49 | src/loadres.cpp 50 | src/memory.cpp 51 | src/sound.cpp 52 | src/state_osd_elements.cpp 53 | src/statesaver.cpp 54 | src/tima.cpp 55 | src/video.cpp 56 | src/mem/cartridge.cpp 57 | src/mem/memptrs.cpp 58 | src/mem/pakinfo.cpp 59 | src/mem/rtc.cpp 60 | src/sound/channel1.cpp 61 | src/sound/channel2.cpp 62 | src/sound/channel3.cpp 63 | src/sound/channel4.cpp 64 | src/sound/duty_unit.cpp 65 | src/sound/envelope_unit.cpp 66 | src/sound/length_counter.cpp 67 | src/video/ly_counter.cpp 68 | src/video/lyc_irq.cpp 69 | src/video/next_m0_time.cpp 70 | src/video/ppu.cpp 71 | src/video/sprite_mapper.cpp 72 | ''') 73 | 74 | conf = env.Configure() 75 | 76 | if conf.CheckHeader('zlib.h'): 77 | sourceFiles.append('src/file/unzip/unzip.c') 78 | sourceFiles.append('src/file/unzip/ioapi.c') 79 | sourceFiles.append('src/file/file_zip.cpp') 80 | else: 81 | sourceFiles.append('src/file/file.cpp') 82 | 83 | conf.Finish() 84 | 85 | env.Library('gambatte', sourceFiles) 86 | -------------------------------------------------------------------------------- /libgambatte/include/gbint.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef GAMBATTE_INT_H 20 | #define GAMBATTE_INT_H 21 | 22 | #ifdef HAVE_CSTDINT 23 | 24 | #include 25 | 26 | namespace gambatte { 27 | using std::uint_least32_t; 28 | using std::uint_least16_t; 29 | } 30 | 31 | #elif defined(HAVE_STDINT_H) 32 | 33 | #include 34 | 35 | namespace gambatte { 36 | using ::uint_least32_t; 37 | using ::uint_least16_t; 38 | } 39 | 40 | #else 41 | 42 | namespace gambatte { 43 | #ifdef CHAR_LEAST_32 44 | typedef unsigned char uint_least32_t; 45 | #elif defined(SHORT_LEAST_32) 46 | typedef unsigned short uint_least32_t; 47 | #elif defined(INT_LEAST_32) 48 | typedef unsigned uint_least32_t; 49 | #else 50 | typedef unsigned long uint_least32_t; 51 | #endif 52 | 53 | #ifdef CHAR_LEAST_16 54 | typedef unsigned char uint_least16_t; 55 | #else 56 | typedef unsigned short uint_least16_t; 57 | #endif 58 | } 59 | 60 | #endif 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /libgambatte/include/inputgetter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef GAMBATTE_INPUTGETTER_H 20 | #define GAMBATTE_INPUTGETTER_H 21 | 22 | namespace gambatte { 23 | 24 | class InputGetter { 25 | public: 26 | enum Button { A = 0x01, B = 0x02, SELECT = 0x04, START = 0x08, 27 | RIGHT = 0x10, LEFT = 0x20, UP = 0x40, DOWN = 0x80 }; 28 | 29 | virtual ~InputGetter() {} 30 | 31 | /** @return A|B|SELECT|START|RIGHT|LEFT|UP|DOWN if those buttons are pressed. */ 32 | virtual unsigned operator()() = 0; 33 | }; 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /libgambatte/include/loadres.h: -------------------------------------------------------------------------------- 1 | #ifndef GAMBATTE_LOADRES_H 2 | #define GAMBATTE_LOADRES_H 3 | 4 | #include 5 | 6 | namespace gambatte { 7 | 8 | enum LoadRes { 9 | LOADRES_BAD_FILE_OR_UNKNOWN_MBC = -0x7FFF, 10 | LOADRES_IO_ERROR, 11 | LOADRES_UNSUPPORTED_MBC_HUC3 = -0x1FE, 12 | LOADRES_UNSUPPORTED_MBC_TAMA5, 13 | LOADRES_UNSUPPORTED_MBC_POCKET_CAMERA, 14 | LOADRES_UNSUPPORTED_MBC_MBC7 = -0x122, 15 | LOADRES_UNSUPPORTED_MBC_MBC6 = -0x120, 16 | LOADRES_UNSUPPORTED_MBC_MBC4 = -0x117, 17 | LOADRES_UNSUPPORTED_MBC_MMM01 = -0x10D, 18 | LOADRES_OK = 0 19 | }; 20 | 21 | std::string const to_string(LoadRes); 22 | 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /libgambatte/include/pakinfo.h: -------------------------------------------------------------------------------- 1 | #ifndef GAMBATTE_PAKINFO_H 2 | #define GAMBATTE_PAKINFO_H 3 | 4 | #include 5 | 6 | namespace gambatte { 7 | 8 | class PakInfo { 9 | public: 10 | PakInfo(); 11 | PakInfo(bool multipak, unsigned rombanks, unsigned char const romheader[]); 12 | bool headerChecksumOk() const; 13 | std::string const mbc() const; 14 | unsigned rambanks() const; 15 | unsigned rombanks() const; 16 | 17 | private: 18 | unsigned short flags_; 19 | unsigned short rombanks_; 20 | unsigned char h144x_[12]; 21 | }; 22 | 23 | } 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /libgambatte/src/bitmap_font.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2008 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef BITMAP_FONT_H 20 | #define BITMAP_FONT_H 21 | 22 | #include "gbint.h" 23 | #include 24 | 25 | namespace bitmapfont { 26 | 27 | enum Char { 28 | NUL, 29 | N0, N1, N2, N3, N4, N5, N6, N7, N8, N9, 30 | A, B, C, D, E, F, G, H, I, J, K, L, M, 31 | N, O, P, Q, R, S, T, U, V, W, X, Y, Z, 32 | a, b, c, d, e, f, g, h, i, j, k, l, m, 33 | n, o, p, q, r, s, t, u, v, w, x, y, z, 34 | SPC 35 | }; 36 | 37 | enum { HEIGHT = 10 }; 38 | enum { MAX_WIDTH = 9 }; 39 | enum { NUMBER_WIDTH = 6 }; 40 | 41 | std::size_t getWidth(char const *chars); 42 | 43 | // struct Fill { void operator()(RandomAccessIterator dest, std::ptrdiff_t pitch) { fill pixels at dest } } 44 | template 45 | void print(RandomAccessIterator dest, std::ptrdiff_t pitch, Fill fill, char const *chars); 46 | 47 | void print(gambatte::uint_least32_t *dest, std::ptrdiff_t pitch, unsigned long color, char const *chars); 48 | void utoa(unsigned u, char *a); 49 | 50 | // --- INTERFACE END --- 51 | 52 | 53 | extern unsigned char const *const font[]; 54 | 55 | template 56 | void print(RandomAccessIterator dest, std::ptrdiff_t const pitch, Fill fill, char const *chars) { 57 | while (int const character = *chars++) { 58 | RandomAccessIterator dst = dest; 59 | unsigned char const *s = font[character]; 60 | unsigned const width = *s >> 4; 61 | unsigned h = *s++ & 0xF; 62 | 63 | while (h--) { 64 | RandomAccessIterator d = dst; 65 | unsigned line = *s++; 66 | 67 | if (width > 8) 68 | line |= *s++ << 8; 69 | 70 | while (line) { 71 | if (line & 1) 72 | fill(d, pitch); 73 | 74 | line >>= 1; 75 | ++d; 76 | } 77 | 78 | dst += pitch; 79 | } 80 | 81 | dest += width; 82 | } 83 | } 84 | 85 | } 86 | 87 | #endif 88 | -------------------------------------------------------------------------------- /libgambatte/src/bootloader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "bootloader.h" 6 | 7 | namespace gambatte { 8 | 9 | Bootloader::Bootloader() { 10 | get_raw_bootloader_data = NULL; 11 | } 12 | 13 | void Bootloader::patch_gbc_to_gba_mode() { 14 | /*moves one jump over another and puts ld b,0x01 into the original position*/ 15 | uint16_t patchloc = 0xF2; 16 | uint8_t patch[0x7] = {0xCD,0xD0,0x05/*<-call systemsetup*/,0x06,0x01/*<-ld b,0x1*/,0x00/*<-nop*/,0x00/*<-nop*/}; 17 | std::memcpy(bootromswapspace + patchloc, patch, 0x7); 18 | } 19 | 20 | void Bootloader::load(bool isgbc, bool isgba) { 21 | if (get_raw_bootloader_data == NULL) { 22 | using_bootloader = false; 23 | return; 24 | } 25 | 26 | //the gba only uses the gbc bios 27 | if (isgba) 28 | isgbc = true; 29 | 30 | bool bootloaderavail = get_raw_bootloader_data((void*)this, isgbc, bootromswapspace, 0x900/*buf_size*/); 31 | if (!bootloaderavail) { 32 | using_bootloader = false; 33 | return; 34 | } 35 | 36 | if (isgbc) 37 | bootloadersize = 0x900; 38 | else 39 | bootloadersize = 0x100; 40 | 41 | if (isgba)//patch bootloader to fake gba mode 42 | patch_gbc_to_gba_mode(); 43 | 44 | //backup rom segment that is shared with bootloader 45 | std::memcpy(rombackup, (uint8_t*)addrspace_start, bootloadersize); 46 | 47 | //put back cartridge data in a 256 byte window of the bios that is not mapped(GBC only) 48 | if (isgbc) 49 | std::memcpy(bootromswapspace + 0x100, rombackup + 0x100, 0x100); 50 | 51 | //put bootloader in main memory 52 | std::memcpy((uint8_t*)addrspace_start, bootromswapspace, bootloadersize); 53 | 54 | using_bootloader = true; 55 | } 56 | 57 | void Bootloader::reset() { 58 | bootloadersize = 0; 59 | has_called_FF50 = false; 60 | addrspace_start = NULL; 61 | using_bootloader = false; 62 | } 63 | 64 | void Bootloader::set_bootloader_getter(bool (*getter)(void* userdata, bool isgbc, uint8_t* data, uint32_t buf_size)) { 65 | get_raw_bootloader_data = getter; 66 | } 67 | 68 | void Bootloader::set_address_space_start(void* start) { 69 | addrspace_start = start; 70 | } 71 | 72 | void Bootloader::choosebank(bool inbootloader) { 73 | //inbootloader = (state.mem.ioamhram.get()[0x150] != 0xFF);//do not uncomment this is just for reference 74 | if (using_bootloader) { 75 | 76 | //switching from game to bootloader with savestate 77 | if (inbootloader && has_called_FF50) 78 | uncall_FF50(); 79 | 80 | //switching from bootloader to game with savestate 81 | else if (!inbootloader && !has_called_FF50) 82 | call_FF50(); 83 | 84 | //switching from game to game or bootloader to bootloader needs no changes 85 | 86 | } 87 | } 88 | 89 | void Bootloader::call_FF50() { 90 | if (!has_called_FF50 && using_bootloader) { 91 | //put rom back in main memory when bootloader has finished 92 | std::memcpy((uint8_t*)addrspace_start, rombackup, bootloadersize); 93 | has_called_FF50 = true; 94 | } 95 | } 96 | 97 | //this is a developer function only,a real gameboy can never undo calling 0xFF50,this function is for savestate functionality 98 | void Bootloader::uncall_FF50() { 99 | std::memcpy((uint8_t*)addrspace_start, bootromswapspace, bootloadersize); 100 | has_called_FF50 = false; 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /libgambatte/src/bootloader.h: -------------------------------------------------------------------------------- 1 | #ifndef BOOTLOADER_H 2 | #define BOOTLOADER_H 3 | 4 | #include 5 | #include 6 | 7 | namespace gambatte { 8 | 9 | class Bootloader { 10 | 11 | private: 12 | uint8_t bootromswapspace[0x900]; 13 | uint8_t rombackup[0x900]; 14 | void* addrspace_start; 15 | unsigned int bootloadersize; 16 | bool has_called_FF50; 17 | 18 | //Set this to NULL or return false if you want to ignore bootloaders completely 19 | //(initial value is NULL and so the bootloader is disabled by default) 20 | bool (*get_raw_bootloader_data)(void* userdata, bool isgbc, uint8_t* data, uint32_t buf_size); 21 | 22 | void patch_gbc_to_gba_mode(); 23 | void uncall_FF50(); 24 | 25 | public: 26 | bool using_bootloader; 27 | 28 | Bootloader(); 29 | void load(bool isgbc,bool isgba); 30 | void reset(); 31 | 32 | void set_bootloader_getter(bool (*getter)(void* userdata, bool isgbc, uint8_t* data, uint32_t buf_size)); 33 | 34 | void set_address_space_start(void* start); 35 | 36 | void choosebank(bool inbootloader); 37 | 38 | void call_FF50(); 39 | }; 40 | 41 | } 42 | 43 | #endif 44 | 45 | -------------------------------------------------------------------------------- /libgambatte/src/counterdef.h: -------------------------------------------------------------------------------- 1 | #ifndef COUNTERDEF_H 2 | #define COUNTERDEF_H 3 | 4 | namespace gambatte { 5 | 6 | enum { disabled_time = 0xfffffffful }; 7 | 8 | } 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /libgambatte/src/cpu.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef CPU_H 20 | #define CPU_H 21 | 22 | #include "memory.h" 23 | 24 | namespace gambatte { 25 | 26 | class CPU { 27 | public: 28 | CPU(); 29 | long runFor(unsigned long cycles); 30 | void setStatePtrs(SaveState &state); 31 | void saveState(SaveState &state); 32 | void loadState(SaveState const &state); 33 | void loadSavedata() { mem_.loadSavedata(); } 34 | void saveSavedata() { mem_.saveSavedata(); } 35 | 36 | void setVideoBuffer(uint_least32_t *videoBuf, std::ptrdiff_t pitch) { 37 | mem_.setVideoBuffer(videoBuf, pitch); 38 | } 39 | 40 | void setInputGetter(InputGetter *getInput) { 41 | mem_.setInputGetter(getInput); 42 | } 43 | 44 | void setSaveDir(std::string const &sdir) { 45 | mem_.setSaveDir(sdir); 46 | } 47 | 48 | std::string const saveBasePath() const { 49 | return mem_.saveBasePath(); 50 | } 51 | 52 | void setOsdElement(transfer_ptr osdElement) { 53 | mem_.setOsdElement(osdElement); 54 | } 55 | 56 | LoadRes load(std::string const &romfile, bool forceDmg, bool multicartCompat, int preferCGB) { 57 | return mem_.loadROM(romfile, forceDmg, multicartCompat, preferCGB); 58 | } 59 | 60 | bool loaded() const { return mem_.loaded(); } 61 | char const * romTitle() const { return mem_.romTitle(); } 62 | PakInfo const pakInfo(bool multicartCompat) const { return mem_.pakInfo(multicartCompat); } 63 | void setSoundBuffer(uint_least32_t *buf) { mem_.setSoundBuffer(buf); } 64 | std::size_t fillSoundBuffer() { return mem_.fillSoundBuffer(cycleCounter_); } 65 | bool isCgb() const { return mem_.isCgb(); } 66 | 67 | void setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32) { 68 | mem_.setDmgPaletteColor(palNum, colorNum, rgb32); 69 | } 70 | 71 | void setColorFilter(int activated, int filtercolors[12]) { 72 | mem_.setColorFilter(activated, filtercolors); 73 | } 74 | 75 | void setGameGenie(std::string const &codes) { mem_.setGameGenie(codes); } 76 | void setGameShark(std::string const &codes) { mem_.setGameShark(codes); } 77 | 78 | Memory mem_; 79 | void *rombank0_ptr() const { return mem_.rombank0_ptr(); } 80 | 81 | private: 82 | 83 | unsigned long cycleCounter_; 84 | unsigned short pc_; 85 | unsigned short sp; 86 | unsigned hf1, hf2, zf, cf; 87 | unsigned char a_, b, c, d, e, /*f,*/ h, l; 88 | bool skip_; 89 | 90 | void process(unsigned long cycles); 91 | }; 92 | 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /libgambatte/src/file/file.cpp: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (C) 2007 by Nach 3 | http://nsrt.edgeemu.com 4 | 5 | Copyright (C) 2007-2011 by sinamas 6 | sinamas@users.sourceforge.net 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License version 2 as 10 | published by the Free Software Foundation. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License version 2 for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | version 2 along with this program; if not, write to the 19 | Free Software Foundation, Inc., 20 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 | ***************************************************************************/ 22 | #include "stdfile.h" 23 | 24 | transfer_ptr gambatte::newFileInstance(std::string const &filepath) { 25 | return transfer_ptr(new StdFile(filepath.c_str())); 26 | } 27 | -------------------------------------------------------------------------------- /libgambatte/src/file/file.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (C) 2007 by Nach 3 | http://nsrt.edgeemu.com 4 | 5 | Copyright (C) 2007-2011 by sinamas 6 | sinamas@users.sourceforge.net 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License version 2 as 10 | published by the Free Software Foundation. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License version 2 for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | version 2 along with this program; if not, write to the 19 | Free Software Foundation, Inc., 20 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 | ***************************************************************************/ 22 | #ifndef GAMBATTE_FILE_H 23 | #define GAMBATTE_FILE_H 24 | 25 | #include "transfer_ptr.h" 26 | #include 27 | 28 | namespace gambatte { 29 | 30 | class File { 31 | public: 32 | virtual ~File() {} 33 | virtual void rewind() = 0; 34 | virtual std::size_t size() const = 0; 35 | virtual void read(char *buffer, std::size_t amount) = 0; 36 | virtual bool fail() const = 0; 37 | }; 38 | 39 | transfer_ptr newFileInstance(std::string const &filepath); 40 | 41 | } 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /libgambatte/src/file/stdfile.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | Copyright (C) 2007 by Nach 3 | http://nsrt.edgeemu.com 4 | 5 | Copyright (C) 2007-2011 by sinamas 6 | sinamas@users.sourceforge.net 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License version 2 as 10 | published by the Free Software Foundation. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License version 2 for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | version 2 along with this program; if not, write to the 19 | Free Software Foundation, Inc., 20 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 | ***************************************************************************/ 22 | #ifndef GAMBATTE_STD_FILE_H 23 | #define GAMBATTE_STD_FILE_H 24 | 25 | #include "file.h" 26 | #include 27 | 28 | namespace gambatte { 29 | 30 | class StdFile : public File { 31 | public: 32 | explicit StdFile(char const *filename) 33 | : stream_(filename, std::ios::in | std::ios::binary) 34 | , fsize_(0) 35 | { 36 | if (stream_) { 37 | stream_.seekg(0, std::ios::end); 38 | fsize_ = stream_.tellg(); 39 | stream_.seekg(0, std::ios::beg); 40 | } 41 | } 42 | 43 | virtual void rewind() { stream_.seekg(0, std::ios::beg); } 44 | virtual std::size_t size() const { return fsize_; }; 45 | virtual void read(char *buffer, std::size_t amount) { stream_.read(buffer, amount); } 46 | virtual bool fail() const { return stream_.fail(); } 47 | 48 | private: 49 | std::ifstream stream_; 50 | std::size_t fsize_; 51 | }; 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /libgambatte/src/file/unzip/ioapi.h: -------------------------------------------------------------------------------- 1 | /* ioapi.h -- IO base function header for compress/uncompress .zip 2 | files using zlib + zip or unzip API 3 | 4 | Version 1.01e, February 12th, 2005 5 | 6 | Copyright (C) 1998-2005 Gilles Vollant 7 | */ 8 | 9 | #ifndef _ZLIBIOAPI_H 10 | #define _ZLIBIOAPI_H 11 | 12 | 13 | #define ZLIB_FILEFUNC_SEEK_CUR (1) 14 | #define ZLIB_FILEFUNC_SEEK_END (2) 15 | #define ZLIB_FILEFUNC_SEEK_SET (0) 16 | 17 | #define ZLIB_FILEFUNC_MODE_READ (1) 18 | #define ZLIB_FILEFUNC_MODE_WRITE (2) 19 | #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) 20 | 21 | #define ZLIB_FILEFUNC_MODE_EXISTING (4) 22 | #define ZLIB_FILEFUNC_MODE_CREATE (8) 23 | 24 | 25 | #ifndef ZCALLBACK 26 | 27 | #if (defined(WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) 28 | #define ZCALLBACK CALLBACK 29 | #else 30 | #define ZCALLBACK 31 | #endif 32 | #endif 33 | 34 | #ifdef __cplusplus 35 | extern "C" { 36 | #endif 37 | 38 | typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); 39 | typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); 40 | typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); 41 | typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); 42 | typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); 43 | typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); 44 | typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); 45 | 46 | typedef struct zlib_filefunc_def_s 47 | { 48 | open_file_func zopen_file; 49 | read_file_func zread_file; 50 | write_file_func zwrite_file; 51 | tell_file_func ztell_file; 52 | seek_file_func zseek_file; 53 | close_file_func zclose_file; 54 | testerror_file_func zerror_file; 55 | voidpf opaque; 56 | } zlib_filefunc_def; 57 | 58 | 59 | 60 | void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); 61 | 62 | #define ZREAD(filefunc,filestream,buf,size) ((*((filefunc).zread_file))((filefunc).opaque,filestream,buf,size)) 63 | #define ZWRITE(filefunc,filestream,buf,size) ((*((filefunc).zwrite_file))((filefunc).opaque,filestream,buf,size)) 64 | #define ZTELL(filefunc,filestream) ((*((filefunc).ztell_file))((filefunc).opaque,filestream)) 65 | #define ZSEEK(filefunc,filestream,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque,filestream,pos,mode)) 66 | #define ZCLOSE(filefunc,filestream) ((*((filefunc).zclose_file))((filefunc).opaque,filestream)) 67 | #define ZERROR(filefunc,filestream) ((*((filefunc).zerror_file))((filefunc).opaque,filestream)) 68 | 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif 75 | 76 | -------------------------------------------------------------------------------- /libgambatte/src/initstate.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2008 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef INITSTATE_H 20 | #define INITSTATE_H 21 | 22 | namespace gambatte { 23 | 24 | void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode); 25 | 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /libgambatte/src/insertion_sort.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef INSERTION_SORT_H 20 | #define INSERTION_SORT_H 21 | 22 | #include 23 | 24 | template 25 | void insertionSort(T *const start, T *const end, Less less) { 26 | if (start >= end) 27 | return; 28 | 29 | T *a = start; 30 | 31 | while (++a < end) { 32 | T const e = *a; 33 | T *b = a; 34 | 35 | while (b != start && less(e, *(b - 1))) { 36 | *b = *(b - 1); 37 | b = b - 1; 38 | } 39 | 40 | *b = e; 41 | } 42 | } 43 | 44 | template 45 | inline void insertionSort(T *start, T *end) { 46 | insertionSort(start, end, std::less()); 47 | } 48 | 49 | #endif /*INSERTION_SORT_H*/ 50 | -------------------------------------------------------------------------------- /libgambatte/src/interrupter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "interrupter.h" 20 | #include "memory.h" 21 | 22 | namespace gambatte { 23 | 24 | Interrupter::Interrupter(unsigned short &sp, unsigned short &pc) 25 | : sp_(sp) 26 | , pc_(pc) 27 | { 28 | } 29 | 30 | unsigned long Interrupter::interrupt(unsigned const address, unsigned long cc, Memory &memory) { 31 | cc += 8; 32 | sp_ = (sp_ - 1) & 0xFFFF; 33 | memory.write(sp_, pc_ >> 8, cc); 34 | cc += 4; 35 | sp_ = (sp_ - 1) & 0xFFFF; 36 | memory.write(sp_, pc_ & 0xFF, cc); 37 | pc_ = address; 38 | cc += 8; 39 | 40 | if (address == 0x40 && !gsCodes_.empty()) 41 | applyVblankCheats(cc, memory); 42 | 43 | return cc; 44 | } 45 | 46 | static int asHex(char c) { 47 | return c >= 'A' ? c - 'A' + 0xA : c - '0'; 48 | } 49 | 50 | void Interrupter::setGameShark(std::string const &codes) { 51 | std::string code; 52 | gsCodes_.clear(); 53 | 54 | for (std::size_t pos = 0; pos < codes.length(); pos += code.length() + 1) { 55 | code = codes.substr(pos, codes.find(';', pos) - pos); 56 | if (code.length() >= 8) { 57 | GsCode gs; 58 | gs.type = asHex(code[0]) << 4 | asHex(code[1]); 59 | gs.value = (asHex(code[2]) << 4 | asHex(code[3])) & 0xFF; 60 | gs.address = ( asHex(code[4]) << 4 61 | | asHex(code[5]) 62 | | asHex(code[6]) << 12 63 | | asHex(code[7]) << 8) & 0xFFFF; 64 | gsCodes_.push_back(gs); 65 | } 66 | } 67 | } 68 | 69 | void Interrupter::applyVblankCheats(unsigned long const cc, Memory &memory) { 70 | for (std::size_t i = 0, size = gsCodes_.size(); i < size; ++i) { 71 | if (gsCodes_[i].type == 0x01) 72 | memory.write(gsCodes_[i].address, gsCodes_[i].value, cc); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /libgambatte/src/interrupter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef INTERRUPTER_H 20 | #define INTERRUPTER_H 21 | 22 | #include 23 | #include 24 | 25 | namespace gambatte { 26 | 27 | struct GsCode { 28 | unsigned short address; 29 | unsigned char value; 30 | unsigned char type; 31 | }; 32 | 33 | class Memory; 34 | 35 | class Interrupter { 36 | public: 37 | Interrupter(unsigned short &sp, unsigned short &pc); 38 | unsigned long interrupt(unsigned address, unsigned long cycleCounter, Memory &memory); 39 | void setGameShark(std::string const &codes); 40 | 41 | private: 42 | unsigned short &sp_; 43 | unsigned short &pc_; 44 | std::vector gsCodes_; 45 | 46 | void applyVblankCheats(unsigned long cc, Memory &mem); 47 | }; 48 | 49 | } 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /libgambatte/src/interruptrequester.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2010 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "interruptrequester.h" 20 | #include "savestate.h" 21 | 22 | namespace gambatte { 23 | 24 | InterruptRequester::InterruptRequester() 25 | : eventTimes_(disabled_time) 26 | , minIntTime_(0) 27 | , ifreg_(0) 28 | , iereg_(0) 29 | { 30 | } 31 | 32 | void InterruptRequester::saveState(SaveState &state) const { 33 | state.mem.minIntTime = minIntTime_; 34 | state.mem.IME = ime(); 35 | state.mem.halted = halted(); 36 | } 37 | 38 | void InterruptRequester::loadState(SaveState const &state) { 39 | minIntTime_ = state.mem.minIntTime; 40 | ifreg_ = state.mem.ioamhram.get()[0x10F]; 41 | iereg_ = state.mem.ioamhram.get()[0x1FF] & 0x1F; 42 | intFlags_.set(state.mem.IME, state.mem.halted); 43 | 44 | eventTimes_.setValue(intFlags_.imeOrHalted() && pendingIrqs() 45 | ? minIntTime_ 46 | : static_cast(disabled_time)); 47 | } 48 | 49 | void InterruptRequester::resetCc(unsigned long oldCc, unsigned long newCc) { 50 | minIntTime_ = minIntTime_ < oldCc ? 0 : minIntTime_ - (oldCc - newCc); 51 | 52 | if (eventTimes_.value(intevent_interrupts) != disabled_time) 53 | eventTimes_.setValue(minIntTime_); 54 | } 55 | 56 | void InterruptRequester::ei(unsigned long cc) { 57 | intFlags_.setIme(); 58 | minIntTime_ = cc + 1; 59 | 60 | if (pendingIrqs()) 61 | eventTimes_.setValue(minIntTime_); 62 | } 63 | 64 | void InterruptRequester::di() { 65 | intFlags_.unsetIme(); 66 | 67 | if (!intFlags_.imeOrHalted()) 68 | eventTimes_.setValue(disabled_time); 69 | } 70 | 71 | void InterruptRequester::halt() { 72 | intFlags_.setHalted(); 73 | 74 | if (pendingIrqs()) 75 | eventTimes_.setValue(minIntTime_); 76 | } 77 | 78 | void InterruptRequester::unhalt() { 79 | intFlags_.unsetHalted(); 80 | 81 | if (!intFlags_.imeOrHalted()) 82 | eventTimes_.setValue(disabled_time); 83 | } 84 | 85 | void InterruptRequester::flagIrq(unsigned bit) { 86 | ifreg_ |= bit; 87 | 88 | if (intFlags_.imeOrHalted() && pendingIrqs()) 89 | eventTimes_.setValue(minIntTime_); 90 | } 91 | 92 | void InterruptRequester::ackIrq(unsigned bit) { 93 | ifreg_ ^= bit; 94 | di(); 95 | } 96 | 97 | void InterruptRequester::setIereg(unsigned iereg) { 98 | iereg_ = iereg & 0x1F; 99 | 100 | if (intFlags_.imeOrHalted()) { 101 | eventTimes_.setValue(pendingIrqs() 102 | ? minIntTime_ 103 | : static_cast(disabled_time)); 104 | } 105 | } 106 | 107 | void InterruptRequester::setIfreg(unsigned ifreg) { 108 | ifreg_ = ifreg; 109 | 110 | if (intFlags_.imeOrHalted()) { 111 | eventTimes_.setValue(pendingIrqs() 112 | ? minIntTime_ 113 | : static_cast(disabled_time)); 114 | } 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /libgambatte/src/loadres.cpp: -------------------------------------------------------------------------------- 1 | #include "loadres.h" 2 | 3 | namespace gambatte { 4 | 5 | static char const * to_cstr(LoadRes const loadres) { 6 | switch (loadres) { 7 | case LOADRES_BAD_FILE_OR_UNKNOWN_MBC: return "Bad file or unknown MBC"; 8 | case LOADRES_IO_ERROR: return "I/O error"; 9 | case LOADRES_UNSUPPORTED_MBC_HUC3: return "Unsupported MBC: HuC3"; 10 | case LOADRES_UNSUPPORTED_MBC_TAMA5: return "Unsupported MBC: Tama5"; 11 | case LOADRES_UNSUPPORTED_MBC_POCKET_CAMERA: return "Unsupported MBC: Pocket Camera"; 12 | case LOADRES_UNSUPPORTED_MBC_MBC7: return "Unsupported MBC: MBC7"; 13 | case LOADRES_UNSUPPORTED_MBC_MBC6: return "Unsupported MBC: MBC6"; 14 | case LOADRES_UNSUPPORTED_MBC_MBC4: return "Unsupported MBC: MBC4"; 15 | case LOADRES_UNSUPPORTED_MBC_MMM01: return "Unsupported MBC: MMM01"; 16 | case LOADRES_OK: return "OK"; 17 | } 18 | 19 | return ""; 20 | } 21 | 22 | std::string const to_string(LoadRes loadres) { return to_cstr(loadres); } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /libgambatte/src/mem/cartridge.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007-2010 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef CARTRIDGE_H 20 | #define CARTRIDGE_H 21 | 22 | #include "loadres.h" 23 | #include "memptrs.h" 24 | #include "rtc.h" 25 | #include "savestate.h" 26 | #include "scoped_ptr.h" 27 | #include 28 | #include 29 | 30 | namespace gambatte { 31 | 32 | class Mbc { 33 | public: 34 | virtual ~Mbc() {} 35 | virtual void romWrite(unsigned P, unsigned data) = 0; 36 | virtual void saveState(SaveState::Mem &ss) const = 0; 37 | virtual void loadState(SaveState::Mem const &ss) = 0; 38 | virtual bool isAddressWithinAreaRombankCanBeMappedTo(unsigned address, unsigned rombank) const = 0; 39 | }; 40 | 41 | class Cartridge { 42 | public: 43 | void setStatePtrs(SaveState &); 44 | void saveState(SaveState &) const; 45 | void loadState(SaveState const &); 46 | bool loaded() const { return mbc_.get(); } 47 | unsigned char const * rmem(unsigned area) const { return memptrs_.rmem(area); } 48 | unsigned char * wmem(unsigned area) const { return memptrs_.wmem(area); } 49 | unsigned char * vramdata() const { return memptrs_.vramdata(); } 50 | unsigned char * romdata(unsigned area) const { return memptrs_.romdata(area); } 51 | unsigned char * wramdata(unsigned area) const { return memptrs_.wramdata(area); } 52 | unsigned char const * rdisabledRam() const { return memptrs_.rdisabledRam(); } 53 | unsigned char const * rsrambankptr() const { return memptrs_.rsrambankptr(); } 54 | unsigned char * wsrambankptr() const { return memptrs_.wsrambankptr(); } 55 | unsigned char * vrambankptr() const { return memptrs_.vrambankptr(); } 56 | OamDmaSrc oamDmaSrc() const { return memptrs_.oamDmaSrc(); } 57 | void setVrambank(unsigned bank) { memptrs_.setVrambank(bank); } 58 | void setWrambank(unsigned bank) { memptrs_.setWrambank(bank); } 59 | void setOamDmaSrc(OamDmaSrc oamDmaSrc) { memptrs_.setOamDmaSrc(oamDmaSrc); } 60 | void mbcWrite(unsigned addr, unsigned data) { mbc_->romWrite(addr, data); } 61 | bool isCgb() const { return gambatte::isCgb(memptrs_); } 62 | void rtcWrite(unsigned data) { rtc_.write(data); } 63 | unsigned char rtcRead() const { return *rtc_.activeData(); } 64 | void loadSavedata(); 65 | void saveSavedata(); 66 | std::string const saveBasePath() const; 67 | void setSaveDir(std::string const &dir); 68 | LoadRes loadROM(std::string const &romfile, bool forceDmg, bool multicartCompat, int preferCGB); 69 | char const * romTitle() const { return reinterpret_cast(memptrs_.romdata() + 0x134); } 70 | class PakInfo const pakInfo(bool multicartCompat) const; 71 | void setGameGenie(std::string const &codes); 72 | 73 | private: 74 | struct AddrData { 75 | unsigned long addr; 76 | unsigned char data; 77 | AddrData(unsigned long addr, unsigned data) : addr(addr), data(data) {} 78 | }; 79 | 80 | MemPtrs memptrs_; 81 | Rtc rtc_; 82 | scoped_ptr mbc_; 83 | std::string defaultSaveBasePath_; 84 | std::string saveDir_; 85 | std::vector ggUndoList_; 86 | 87 | void applyGameGenie(std::string const &code); 88 | }; 89 | 90 | } 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /libgambatte/src/mem/memptrs.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007-2010 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef MEMPTRS_H 20 | #define MEMPTRS_H 21 | 22 | namespace gambatte { 23 | 24 | enum OamDmaSrc { oam_dma_src_rom, 25 | oam_dma_src_sram, 26 | oam_dma_src_vram, 27 | oam_dma_src_wram, 28 | oam_dma_src_invalid, 29 | oam_dma_src_off, }; 30 | 31 | class MemPtrs { 32 | public: 33 | enum RamFlag { read_en = 1, write_en = 2, rtc_en = 4 }; 34 | 35 | MemPtrs(); 36 | ~MemPtrs(); 37 | void reset(unsigned rombanks, unsigned rambanks, unsigned wrambanks); 38 | 39 | unsigned char const * rmem(unsigned area) const { return rmem_[area]; } 40 | unsigned char * wmem(unsigned area) const { return wmem_[area]; } 41 | unsigned char * vramdata() const { return rambankdata_ - 0x4000; } 42 | unsigned char * vramdataend() const { return rambankdata_; } 43 | unsigned char * romdata() const { return memchunk_ + 0x4000; } 44 | unsigned char * romdata(unsigned area) const { return romdata_[area]; } 45 | unsigned char * romdataend() const { return rambankdata_ - 0x4000; } 46 | unsigned char * wramdata(unsigned area) const { return wramdata_[area]; } 47 | unsigned char * wramdataend() const { return wramdataend_; } 48 | unsigned char * rambankdata() const { return rambankdata_; } 49 | unsigned char * rambankdataend() const { return wramdata_[0]; } 50 | unsigned char const * rdisabledRam() const { return rdisabledRamw(); } 51 | unsigned char const * rsrambankptr() const { return rsrambankptr_; } 52 | unsigned char * wsrambankptr() const { return wsrambankptr_; } 53 | unsigned char * vrambankptr() const { return vrambankptr_; } 54 | OamDmaSrc oamDmaSrc() const { return oamDmaSrc_; } 55 | 56 | void setRombank0(unsigned bank); 57 | void setRombank(unsigned bank); 58 | void setRambank(unsigned ramFlags, unsigned rambank); 59 | void setVrambank(unsigned bank) { vrambankptr_ = vramdata() + bank * 0x2000ul - 0x8000; } 60 | void setWrambank(unsigned bank); 61 | void setOamDmaSrc(OamDmaSrc oamDmaSrc); 62 | 63 | private: 64 | unsigned char const *rmem_[0x10]; 65 | unsigned char *wmem_[0x10]; 66 | unsigned char *romdata_[2]; 67 | unsigned char *wramdata_[2]; 68 | unsigned char *vrambankptr_; 69 | unsigned char *rsrambankptr_; 70 | unsigned char *wsrambankptr_; 71 | unsigned char *memchunk_; 72 | unsigned char *rambankdata_; 73 | unsigned char *wramdataend_; 74 | OamDmaSrc oamDmaSrc_; 75 | 76 | MemPtrs(MemPtrs const &); 77 | MemPtrs & operator=(MemPtrs const &); 78 | void disconnectOamDmaAreas(); 79 | unsigned char * rdisabledRamw() const { return wramdataend_ ; } 80 | unsigned char * wdisabledRam() const { return wramdataend_ + 0x2000; } 81 | }; 82 | 83 | inline bool isCgb(MemPtrs const &memptrs) { 84 | return memptrs.wramdataend() - memptrs.wramdata(0) == 0x8000; 85 | } 86 | 87 | } 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /libgambatte/src/mem/pakinfo.cpp: -------------------------------------------------------------------------------- 1 | #include "pakinfo_internal.h" 2 | #include 3 | 4 | namespace gambatte { 5 | 6 | enum { flag_multipak = 1, flag_header_checksum_ok = 2, }; 7 | 8 | static bool isHeaderChecksumOk(unsigned const char header[]) { 9 | unsigned csum = 0; 10 | for (int i = 0x134; i < 0x14D; ++i) 11 | csum -= header[i] + 1; 12 | 13 | return (csum & 0xFF) == header[0x14D]; 14 | } 15 | 16 | static bool isMbc2(unsigned char h147) { return h147 == 5 || h147 == 6; } 17 | 18 | unsigned numRambanksFromH14x(unsigned char h147, unsigned char h149) { 19 | switch (h149) { 20 | case 0x00: return isMbc2(h147) ? 1 : 0; 21 | case 0x01: 22 | case 0x02: return 1; 23 | default: case 0x03: return 4; 24 | case 0x04: return 16; 25 | case 0x05: return 8; 26 | } 27 | } 28 | 29 | PakInfo::PakInfo() 30 | : flags_(), rombanks_() 31 | { 32 | std::memset(h144x_, 0 , sizeof h144x_); 33 | } 34 | 35 | PakInfo::PakInfo(bool multipak, unsigned rombanks, unsigned char const romheader[]) 36 | : flags_( multipak * flag_multipak 37 | + isHeaderChecksumOk(romheader) * flag_header_checksum_ok), 38 | rombanks_(rombanks) 39 | { 40 | std::memcpy(h144x_, romheader + 0x144, sizeof h144x_); 41 | } 42 | 43 | bool PakInfo::headerChecksumOk() const { return flags_ & flag_header_checksum_ok; } 44 | 45 | static char const * h147ToCstr(unsigned char const h147) { 46 | switch (h147) { 47 | case 0x00: return "NULL"; 48 | case 0x01: return "MBC1"; 49 | case 0x02: return "MBC1 [RAM]"; 50 | case 0x03: return "MBC1 [RAM,battery]"; 51 | case 0x05: return "MBC2"; 52 | case 0x06: return "MBC2 [battery]"; 53 | case 0x08: return "NULL [RAM]"; 54 | case 0x09: return "NULL [RAM,battery]"; 55 | case 0x0B: return "MMM01"; 56 | case 0x0C: return "MMM01 [RAM]"; 57 | case 0x0D: return "MMM01 [RAM,battery]"; 58 | case 0x0F: return "MBC3 [RTC,battery]"; 59 | case 0x10: return "MBC3 [RAM,RTC,battery]"; 60 | case 0x11: return "MBC3"; 61 | case 0x12: return "MBC3 [RAM]"; 62 | case 0x13: return "MBC3 [RAM,battery]"; 63 | case 0x15: return "MBC4"; 64 | case 0x16: return "MBC4 [RAM]"; 65 | case 0x17: return "MBC4 [RAM,battery]"; 66 | case 0x19: return "MBC5"; 67 | case 0x1A: return "MBC5 [RAM]"; 68 | case 0x1B: return "MBC5 [RAM,battery]"; 69 | case 0x1C: return "MBC5 [rumble]"; 70 | case 0x1D: return "MBC5 [RAM,rumble]"; 71 | case 0x1E: return "MBC5 [RAM,rumble,battery]"; 72 | case 0xFC: return "Pocket Camera"; 73 | case 0xFD: return "Bandai TAMA5"; 74 | case 0xFE: return "HuC3"; 75 | case 0xFF: return "HuC1 [RAM,battery]"; 76 | } 77 | 78 | return "Unknown"; 79 | } 80 | 81 | std::string const PakInfo::mbc() const { 82 | std::string h147str = h147ToCstr(h144x_[3]); 83 | 84 | if (flags_ & flag_multipak) 85 | h147str += " (Custom MultiPak)"; 86 | 87 | return h147str; 88 | } 89 | 90 | unsigned PakInfo::rambanks() const { return numRambanksFromH14x(h144x_[3], h144x_[5]); } 91 | unsigned PakInfo::rombanks() const { return rombanks_; } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /libgambatte/src/mem/pakinfo_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef PAKINFO_INTERNAL_H 2 | #define PAKINFO_INTERNAL_H 3 | 4 | #include "pakinfo.h" 5 | 6 | namespace gambatte { 7 | 8 | unsigned numRambanksFromH14x(unsigned char h147, unsigned char h149); 9 | 10 | } 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /libgambatte/src/mem/rtc.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef RTC_H 20 | #define RTC_H 21 | 22 | #include 23 | 24 | namespace gambatte { 25 | 26 | struct SaveState; 27 | 28 | class Rtc { 29 | public: 30 | Rtc(); 31 | unsigned char const * activeData() const { return activeData_; } 32 | std::time_t baseTime() const { return baseTime_; } 33 | void setBaseTime(std::time_t baseTime) { baseTime_ = baseTime; } 34 | 35 | void latch(unsigned data) { 36 | if (!lastLatchData_ && data == 1) 37 | doLatch(); 38 | 39 | lastLatchData_ = data; 40 | } 41 | 42 | void saveState(SaveState &state) const; 43 | void loadState(SaveState const &state); 44 | 45 | void set(bool enabled, unsigned bank) { 46 | bank &= 0xF; 47 | bank -= 8; 48 | 49 | enabled_ = enabled; 50 | index_ = bank; 51 | doSwapActive(); 52 | } 53 | 54 | void write(unsigned data) { 55 | (this->*activeSet_)(data); 56 | *activeData_ = data; 57 | } 58 | 59 | private: 60 | unsigned char *activeData_; 61 | void (Rtc::*activeSet_)(unsigned); 62 | std::time_t baseTime_; 63 | std::time_t haltTime_; 64 | unsigned char index_; 65 | unsigned char dataDh_; 66 | unsigned char dataDl_; 67 | unsigned char dataH_; 68 | unsigned char dataM_; 69 | unsigned char dataS_; 70 | bool enabled_; 71 | bool lastLatchData_; 72 | 73 | void doLatch(); 74 | void doSwapActive(); 75 | void setDh(unsigned newDh); 76 | void setDl(unsigned newLowdays); 77 | void setH(unsigned newHours); 78 | void setM(unsigned newMinutes); 79 | void setS(unsigned newSeconds); 80 | }; 81 | 82 | } 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /libgambatte/src/osd_element.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2008 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef OSD_ELEMENT_H 20 | #define OSD_ELEMENT_H 21 | 22 | #include "gbint.h" 23 | 24 | namespace gambatte { 25 | 26 | class OsdElement { 27 | public: 28 | enum Opacity { seven_eighths, three_fourths }; 29 | enum { pixel_transparent = 0xfffffffful }; 30 | 31 | virtual ~OsdElement() {} 32 | unsigned x() const { return x_; } 33 | unsigned y() const { return y_; } 34 | unsigned w() const { return w_; } 35 | unsigned h() const { return h_; } 36 | Opacity opacity() const { return opacity_; } 37 | virtual uint_least32_t const * update() = 0; 38 | 39 | protected: 40 | explicit OsdElement(unsigned x = 0, unsigned y = 0, unsigned w = 0, unsigned h = 0, 41 | Opacity opacity = seven_eighths) 42 | : opacity_(opacity), x_(x), y_(y), w_(w), h_(h) 43 | { 44 | } 45 | 46 | void setPos(unsigned x, unsigned y) { 47 | x_ = x; 48 | y_ = y; 49 | } 50 | 51 | void setSize(unsigned w, unsigned h) { 52 | w_ = w; 53 | h_ = h; 54 | } 55 | 56 | void setOpacity(Opacity opacity) { opacity_ = opacity; } 57 | 58 | private: 59 | Opacity opacity_; 60 | unsigned x_; 61 | unsigned y_; 62 | unsigned w_; 63 | unsigned h_; 64 | }; 65 | 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /libgambatte/src/sound.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SOUND_H 20 | #define SOUND_H 21 | 22 | #include "sound/channel1.h" 23 | #include "sound/channel2.h" 24 | #include "sound/channel3.h" 25 | #include "sound/channel4.h" 26 | 27 | namespace gambatte { 28 | 29 | class PSG { 30 | public: 31 | PSG(); 32 | void init(bool cgb); 33 | void reset(); 34 | void setStatePtrs(SaveState &state); 35 | void saveState(SaveState &state); 36 | void loadState(SaveState const &state); 37 | 38 | void generateSamples(unsigned long cycleCounter, bool doubleSpeed); 39 | void resetCounter(unsigned long newCc, unsigned long oldCc, bool doubleSpeed); 40 | std::size_t fillBuffer(); 41 | void setBuffer(uint_least32_t *buf) { buffer_ = buf; bufferPos_ = 0; } 42 | 43 | bool isEnabled() const { return enabled_; } 44 | void setEnabled(bool value) { enabled_ = value; } 45 | 46 | void setNr10(unsigned data) { ch1_.setNr0(data); } 47 | void setNr11(unsigned data) { ch1_.setNr1(data); } 48 | void setNr12(unsigned data) { ch1_.setNr2(data); } 49 | void setNr13(unsigned data) { ch1_.setNr3(data); } 50 | void setNr14(unsigned data) { ch1_.setNr4(data); } 51 | 52 | void setNr21(unsigned data) { ch2_.setNr1(data); } 53 | void setNr22(unsigned data) { ch2_.setNr2(data); } 54 | void setNr23(unsigned data) { ch2_.setNr3(data); } 55 | void setNr24(unsigned data) { ch2_.setNr4(data); } 56 | 57 | void setNr30(unsigned data) { ch3_.setNr0(data); } 58 | void setNr31(unsigned data) { ch3_.setNr1(data); } 59 | void setNr32(unsigned data) { ch3_.setNr2(data); } 60 | void setNr33(unsigned data) { ch3_.setNr3(data); } 61 | void setNr34(unsigned data) { ch3_.setNr4(data); } 62 | unsigned waveRamRead(unsigned index) const { return ch3_.waveRamRead(index); } 63 | void waveRamWrite(unsigned index, unsigned data) { ch3_.waveRamWrite(index, data); } 64 | 65 | void setNr41(unsigned data) { ch4_.setNr1(data); } 66 | void setNr42(unsigned data) { ch4_.setNr2(data); } 67 | void setNr43(unsigned data) { ch4_.setNr3(data); } 68 | void setNr44(unsigned data) { ch4_.setNr4(data); } 69 | 70 | void setSoVolume(unsigned nr50); 71 | void mapSo(unsigned nr51); 72 | unsigned getStatus() const; 73 | 74 | private: 75 | Channel1 ch1_; 76 | Channel2 ch2_; 77 | Channel3 ch3_; 78 | Channel4 ch4_; 79 | uint_least32_t *buffer_; 80 | std::size_t bufferPos_; 81 | unsigned long lastUpdate_; 82 | unsigned long soVol_; 83 | uint_least32_t rsum_; 84 | bool enabled_; 85 | 86 | void accumulateChannels(unsigned long cycles); 87 | }; 88 | 89 | } 90 | 91 | #endif 92 | -------------------------------------------------------------------------------- /libgambatte/src/sound/channel1.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SOUND_CHANNEL1_H 20 | #define SOUND_CHANNEL1_H 21 | 22 | #include "duty_unit.h" 23 | #include "envelope_unit.h" 24 | #include "gbint.h" 25 | #include "length_counter.h" 26 | #include "master_disabler.h" 27 | #include "static_output_tester.h" 28 | 29 | namespace gambatte { 30 | 31 | struct SaveState; 32 | 33 | class Channel1 { 34 | public: 35 | Channel1(); 36 | void setNr0(unsigned data); 37 | void setNr1(unsigned data); 38 | void setNr2(unsigned data); 39 | void setNr3(unsigned data); 40 | void setNr4(unsigned data); 41 | void setSo(unsigned long soMask); 42 | bool isActive() const { return master_; } 43 | void update(uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); 44 | void reset(); 45 | void init(bool cgb); 46 | void saveState(SaveState &state); 47 | void loadState(SaveState const &state); 48 | 49 | private: 50 | class SweepUnit : public SoundUnit { 51 | public: 52 | SweepUnit(MasterDisabler &disabler, DutyUnit &dutyUnit); 53 | virtual void event(); 54 | void nr0Change(unsigned newNr0); 55 | void nr4Init(unsigned long cycleCounter); 56 | void reset(); 57 | void init(bool cgb) { cgb_ = cgb; } 58 | void saveState(SaveState &state) const; 59 | void loadState(SaveState const &state); 60 | 61 | private: 62 | MasterDisabler &disableMaster_; 63 | DutyUnit &dutyUnit_; 64 | unsigned short shadow_; 65 | unsigned char nr0_; 66 | bool negging_; 67 | bool cgb_; 68 | 69 | unsigned calcFreq(); 70 | }; 71 | 72 | friend class StaticOutputTester; 73 | 74 | StaticOutputTester staticOutputTest_; 75 | DutyMasterDisabler disableMaster_; 76 | LengthCounter lengthCounter_; 77 | DutyUnit dutyUnit_; 78 | EnvelopeUnit envelopeUnit_; 79 | SweepUnit sweepUnit_; 80 | SoundUnit *nextEventUnit_; 81 | unsigned long cycleCounter_; 82 | unsigned long soMask_; 83 | unsigned long prevOut_; 84 | unsigned char nr4_; 85 | bool master_; 86 | 87 | void setEvent(); 88 | }; 89 | 90 | } 91 | 92 | #endif 93 | -------------------------------------------------------------------------------- /libgambatte/src/sound/channel2.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SOUND_CHANNEL2_H 20 | #define SOUND_CHANNEL2_H 21 | 22 | #include "duty_unit.h" 23 | #include "envelope_unit.h" 24 | #include "gbint.h" 25 | #include "length_counter.h" 26 | #include "static_output_tester.h" 27 | 28 | namespace gambatte { 29 | 30 | struct SaveState; 31 | 32 | class Channel2 { 33 | public: 34 | Channel2(); 35 | void setNr1(unsigned data); 36 | void setNr2(unsigned data); 37 | void setNr3(unsigned data); 38 | void setNr4(unsigned data); 39 | void setSo(unsigned long soMask); 40 | bool isActive() const { return master_; } 41 | void update(uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); 42 | void reset(); 43 | void saveState(SaveState &state); 44 | void loadState(SaveState const &state); 45 | 46 | private: 47 | friend class StaticOutputTester; 48 | 49 | StaticOutputTester staticOutputTest_; 50 | DutyMasterDisabler disableMaster_; 51 | LengthCounter lengthCounter_; 52 | DutyUnit dutyUnit_; 53 | EnvelopeUnit envelopeUnit_; 54 | SoundUnit *nextEventUnit; 55 | unsigned long cycleCounter_; 56 | unsigned long soMask_; 57 | unsigned long prevOut_; 58 | unsigned char nr4_; 59 | bool master_; 60 | 61 | void setEvent(); 62 | }; 63 | 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /libgambatte/src/sound/channel3.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SOUND_CHANNEL3_H 20 | #define SOUND_CHANNEL3_H 21 | 22 | #include "gbint.h" 23 | #include "length_counter.h" 24 | #include "master_disabler.h" 25 | 26 | namespace gambatte { 27 | 28 | struct SaveState; 29 | 30 | class Channel3 { 31 | public: 32 | Channel3(); 33 | bool isActive() const { return master_; } 34 | void reset(); 35 | void init(bool cgb); 36 | void setStatePtrs(SaveState &state); 37 | void saveState(SaveState &state) const; 38 | void loadState(const SaveState &state); 39 | void setNr0(unsigned data); 40 | void setNr1(unsigned data) { lengthCounter_.nr1Change(data, nr4_, cycleCounter_); } 41 | void setNr2(unsigned data); 42 | void setNr3(unsigned data) { nr3_ = data; } 43 | void setNr4(unsigned data); 44 | void setSo(unsigned long soMask); 45 | void update(uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); 46 | 47 | unsigned waveRamRead(unsigned index) const { 48 | if (master_) { 49 | if (!cgb_ && cycleCounter_ != lastReadTime_) 50 | return 0xFF; 51 | 52 | index = wavePos_ >> 1; 53 | } 54 | 55 | return waveRam_[index]; 56 | } 57 | 58 | void waveRamWrite(unsigned index, unsigned data) { 59 | if (master_) { 60 | if (!cgb_ && cycleCounter_ != lastReadTime_) 61 | return; 62 | 63 | index = wavePos_ >> 1; 64 | } 65 | 66 | waveRam_[index] = data; 67 | } 68 | 69 | private: 70 | class Ch3MasterDisabler : public MasterDisabler { 71 | public: 72 | Ch3MasterDisabler(bool &m, unsigned long &wC) : MasterDisabler(m), waveCounter_(wC) {} 73 | 74 | virtual void operator()() { 75 | MasterDisabler::operator()(); 76 | waveCounter_ = SoundUnit::counter_disabled; 77 | } 78 | 79 | private: 80 | unsigned long &waveCounter_; 81 | }; 82 | 83 | unsigned char waveRam_[0x10]; 84 | Ch3MasterDisabler disableMaster_; 85 | LengthCounter lengthCounter_; 86 | unsigned long cycleCounter_; 87 | unsigned long soMask_; 88 | unsigned long prevOut_; 89 | unsigned long waveCounter_; 90 | unsigned long lastReadTime_; 91 | unsigned char nr0_; 92 | unsigned char nr3_; 93 | unsigned char nr4_; 94 | unsigned char wavePos_; 95 | unsigned char rshift_; 96 | unsigned char sampleBuf_; 97 | bool master_; 98 | bool cgb_; 99 | 100 | void updateWaveCounter(unsigned long cc); 101 | }; 102 | 103 | } 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /libgambatte/src/sound/channel4.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SOUND_CHANNEL4_H 20 | #define SOUND_CHANNEL4_H 21 | 22 | #include "envelope_unit.h" 23 | #include "gbint.h" 24 | #include "length_counter.h" 25 | #include "master_disabler.h" 26 | #include "static_output_tester.h" 27 | 28 | namespace gambatte { 29 | 30 | struct SaveState; 31 | 32 | class Channel4 { 33 | public: 34 | Channel4(); 35 | void setNr1(unsigned data); 36 | void setNr2(unsigned data); 37 | void setNr3(unsigned data) { lfsr_.nr3Change(data, cycleCounter_); } 38 | void setNr4(unsigned data); 39 | void setSo(unsigned long soMask); 40 | bool isActive() const { return master_; } 41 | void update(uint_least32_t *buf, unsigned long soBaseVol, unsigned long cycles); 42 | void reset(); 43 | void saveState(SaveState &state); 44 | void loadState(SaveState const &state); 45 | 46 | private: 47 | class Lfsr : public SoundUnit { 48 | public: 49 | Lfsr(); 50 | virtual void event(); 51 | virtual void resetCounters(unsigned long oldCc); 52 | bool isHighState() const { return ~reg_ & 1; } 53 | void nr3Change(unsigned newNr3, unsigned long cc); 54 | void nr4Init(unsigned long cc); 55 | void reset(unsigned long cc); 56 | void saveState(SaveState &state, unsigned long cc); 57 | void loadState(SaveState const &state); 58 | void disableMaster() { killCounter(); master_ = false; reg_ = 0x7FFF; } 59 | void killCounter() { counter_ = counter_disabled; } 60 | void reviveCounter(unsigned long cc); 61 | 62 | private: 63 | unsigned long backupCounter_; 64 | unsigned short reg_; 65 | unsigned char nr3_; 66 | bool master_; 67 | 68 | void updateBackupCounter(unsigned long cc); 69 | }; 70 | 71 | class Ch4MasterDisabler : public MasterDisabler { 72 | public: 73 | Ch4MasterDisabler(bool &m, Lfsr &lfsr) : MasterDisabler(m), lfsr_(lfsr) {} 74 | virtual void operator()() { MasterDisabler::operator()(); lfsr_.disableMaster(); } 75 | 76 | private: 77 | Lfsr &lfsr_; 78 | }; 79 | 80 | friend class StaticOutputTester; 81 | 82 | StaticOutputTester staticOutputTest_; 83 | Ch4MasterDisabler disableMaster_; 84 | LengthCounter lengthCounter_; 85 | EnvelopeUnit envelopeUnit_; 86 | Lfsr lfsr_; 87 | SoundUnit *nextEventUnit_; 88 | unsigned long cycleCounter_; 89 | unsigned long soMask_; 90 | unsigned long prevOut_; 91 | unsigned char nr4_; 92 | bool master_; 93 | 94 | void setEvent(); 95 | }; 96 | 97 | } 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /libgambatte/src/sound/duty_unit.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef DUTY_UNIT_H 20 | #define DUTY_UNIT_H 21 | 22 | #include "sound_unit.h" 23 | #include "master_disabler.h" 24 | #include "../savestate.h" 25 | 26 | namespace gambatte { 27 | 28 | class DutyUnit : public SoundUnit { 29 | public: 30 | DutyUnit(); 31 | virtual void event(); 32 | virtual void resetCounters(unsigned long oldCc); 33 | bool isHighState() const { return high_; } 34 | void nr1Change(unsigned newNr1, unsigned long cc); 35 | void nr3Change(unsigned newNr3, unsigned long cc); 36 | void nr4Change(unsigned newNr4, unsigned long cc); 37 | void reset(); 38 | void saveState(SaveState::SPU::Duty &dstate, unsigned long cc); 39 | void loadState(SaveState::SPU::Duty const &dstate, unsigned nr1, unsigned nr4, unsigned long cc); 40 | void killCounter(); 41 | void reviveCounter(unsigned long cc); 42 | 43 | //intended for use by SweepUnit only. 44 | unsigned freq() const { return 2048 - (period_ >> 1); } 45 | void setFreq(unsigned newFreq, unsigned long cc); 46 | 47 | private: 48 | unsigned long nextPosUpdate_; 49 | unsigned short period_; 50 | unsigned char pos_; 51 | unsigned char duty_; 52 | unsigned char inc_; 53 | bool high_; 54 | bool enableEvents_; 55 | 56 | void setCounter(); 57 | void setDuty(unsigned nr1); 58 | void updatePos(unsigned long cc); 59 | }; 60 | 61 | class DutyMasterDisabler : public MasterDisabler { 62 | public: 63 | DutyMasterDisabler(bool &m, DutyUnit &dutyUnit) : MasterDisabler(m), dutyUnit_(dutyUnit) {} 64 | virtual void operator()() { MasterDisabler::operator()(); dutyUnit_.killCounter(); } 65 | 66 | private: 67 | DutyUnit &dutyUnit_; 68 | }; 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /libgambatte/src/sound/envelope_unit.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "envelope_unit.h" 20 | #include 21 | 22 | namespace gambatte { 23 | 24 | EnvelopeUnit::VolOnOffEvent EnvelopeUnit::nullEvent_; 25 | 26 | EnvelopeUnit::EnvelopeUnit(VolOnOffEvent &volOnOffEvent) 27 | : volOnOffEvent_(volOnOffEvent) 28 | , nr2_(0) 29 | , volume_(0) 30 | { 31 | } 32 | 33 | void EnvelopeUnit::reset() { 34 | counter_ = counter_disabled; 35 | } 36 | 37 | void EnvelopeUnit::saveState(SaveState::SPU::Env &estate) const { 38 | estate.counter = counter_; 39 | estate.volume = volume_; 40 | } 41 | 42 | void EnvelopeUnit::loadState(SaveState::SPU::Env const &estate, unsigned nr2, unsigned long cc) { 43 | counter_ = std::max(estate.counter, cc); 44 | volume_ = estate.volume; 45 | nr2_ = nr2; 46 | } 47 | 48 | void EnvelopeUnit::event() { 49 | unsigned long const period = nr2_ & 7; 50 | 51 | if (period) { 52 | unsigned newVol = volume_; 53 | if (nr2_ & 8) 54 | ++newVol; 55 | else 56 | --newVol; 57 | 58 | if (newVol < 0x10U) { 59 | volume_ = newVol; 60 | if (volume_ < 2) 61 | volOnOffEvent_(counter_); 62 | 63 | counter_ += period << 15; 64 | } else 65 | counter_ = counter_disabled; 66 | } else 67 | counter_ += 8ul << 15; 68 | } 69 | 70 | bool EnvelopeUnit::nr2Change(unsigned const newNr2) { 71 | if (!(nr2_ & 7) && counter_ != counter_disabled) 72 | ++volume_; 73 | else if (!(nr2_ & 8)) 74 | volume_ += 2; 75 | 76 | if ((nr2_ ^ newNr2) & 8) 77 | volume_ = 0x10 - volume_; 78 | 79 | volume_ &= 0xF; 80 | nr2_ = newNr2; 81 | return !(newNr2 & 0xF8); 82 | } 83 | 84 | bool EnvelopeUnit::nr4Init(unsigned long const cc) { 85 | unsigned long period = (nr2_ & 7) ? nr2_ & 7 : 8; 86 | 87 | if (((cc + 2) & 0x7000) == 0x0000) 88 | ++period; 89 | 90 | counter_ = cc - ((cc - 0x1000) & 0x7FFF) + period * 0x8000; 91 | 92 | volume_ = nr2_ >> 4; 93 | return !(nr2_ & 0xF8); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /libgambatte/src/sound/envelope_unit.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef ENVELOPE_UNIT_H 20 | #define ENVELOPE_UNIT_H 21 | 22 | #include "sound_unit.h" 23 | #include "../savestate.h" 24 | 25 | namespace gambatte { 26 | 27 | class EnvelopeUnit : public SoundUnit { 28 | public: 29 | struct VolOnOffEvent { 30 | virtual ~VolOnOffEvent() {} 31 | virtual void operator()(unsigned long /*cc*/) {} 32 | }; 33 | 34 | explicit EnvelopeUnit(VolOnOffEvent &volOnOffEvent = nullEvent_); 35 | void event(); 36 | bool dacIsOn() const { return nr2_ & 0xF8; } 37 | unsigned getVolume() const { return volume_; } 38 | bool nr2Change(unsigned newNr2); 39 | bool nr4Init(unsigned long cycleCounter); 40 | void reset(); 41 | void saveState(SaveState::SPU::Env &estate) const; 42 | void loadState(SaveState::SPU::Env const &estate, unsigned nr2, unsigned long cc); 43 | 44 | private: 45 | static VolOnOffEvent nullEvent_; 46 | VolOnOffEvent &volOnOffEvent_; 47 | unsigned char nr2_; 48 | unsigned char volume_; 49 | }; 50 | 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /libgambatte/src/sound/length_counter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "length_counter.h" 20 | #include "master_disabler.h" 21 | #include 22 | 23 | namespace gambatte { 24 | 25 | LengthCounter::LengthCounter(MasterDisabler &disabler, unsigned const mask) 26 | : disableMaster_(disabler) 27 | , lengthCounter_(0) 28 | , lengthMask_(mask) 29 | { 30 | nr1Change(0, 0, 0); 31 | } 32 | 33 | void LengthCounter::event() { 34 | counter_ = counter_disabled; 35 | lengthCounter_ = 0; 36 | disableMaster_(); 37 | } 38 | 39 | void LengthCounter::nr1Change(unsigned const newNr1, unsigned const nr4, unsigned long const cc) { 40 | lengthCounter_ = (~newNr1 & lengthMask_) + 1; 41 | counter_ = (nr4 & 0x40) 42 | ? ((cc >> 13) + lengthCounter_) << 13 43 | : static_cast(counter_disabled); 44 | } 45 | 46 | void LengthCounter::nr4Change(unsigned const oldNr4, unsigned const newNr4, unsigned long const cc) { 47 | if (counter_ != counter_disabled) 48 | lengthCounter_ = (counter_ >> 13) - (cc >> 13); 49 | 50 | { 51 | unsigned dec = 0; 52 | 53 | if (newNr4 & 0x40) { 54 | dec = ~cc >> 12 & 1; 55 | 56 | if (!(oldNr4 & 0x40) && lengthCounter_) { 57 | if (!(lengthCounter_ -= dec)) 58 | disableMaster_(); 59 | } 60 | } 61 | 62 | if ((newNr4 & 0x80) && !lengthCounter_) 63 | lengthCounter_ = lengthMask_ + 1 - dec; 64 | } 65 | 66 | if ((newNr4 & 0x40) && lengthCounter_) 67 | counter_ = ((cc >> 13) + lengthCounter_) << 13; 68 | else 69 | counter_ = counter_disabled; 70 | } 71 | 72 | void LengthCounter::saveState(SaveState::SPU::LCounter &lstate) const { 73 | lstate.counter = counter_; 74 | lstate.lengthCounter = lengthCounter_; 75 | } 76 | 77 | void LengthCounter::loadState(SaveState::SPU::LCounter const &lstate, unsigned long const cc) { 78 | counter_ = std::max(lstate.counter, cc); 79 | lengthCounter_ = lstate.lengthCounter; 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /libgambatte/src/sound/length_counter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef LENGTH_COUNTER_H 20 | #define LENGTH_COUNTER_H 21 | 22 | #include "sound_unit.h" 23 | #include "../savestate.h" 24 | 25 | namespace gambatte { 26 | 27 | class MasterDisabler; 28 | 29 | class LengthCounter : public SoundUnit { 30 | public: 31 | LengthCounter(MasterDisabler &disabler, unsigned lengthMask); 32 | virtual void event(); 33 | void nr1Change(unsigned newNr1, unsigned nr4, unsigned long cc); 34 | void nr4Change(unsigned oldNr4, unsigned newNr4, unsigned long cc); 35 | void saveState(SaveState::SPU::LCounter &lstate) const; 36 | void loadState(SaveState::SPU::LCounter const &lstate, unsigned long cc); 37 | 38 | private: 39 | MasterDisabler &disableMaster_; 40 | unsigned short lengthCounter_; 41 | unsigned char const lengthMask_; 42 | }; 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /libgambatte/src/sound/master_disabler.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef MASTER_DISABLER_H 20 | #define MASTER_DISABLER_H 21 | 22 | namespace gambatte { 23 | 24 | class MasterDisabler { 25 | public: 26 | explicit MasterDisabler(bool &master) : master_(master) {} 27 | virtual ~MasterDisabler() {} 28 | virtual void operator()() { master_ = false; } 29 | 30 | private: 31 | bool &master_; 32 | }; 33 | 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /libgambatte/src/sound/sound_unit.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef SOUND_UNIT_H 20 | #define SOUND_UNIT_H 21 | 22 | namespace gambatte { 23 | 24 | class SoundUnit { 25 | public: 26 | enum { counter_max = 0x80000000u, counter_disabled = 0xFFFFFFFFu }; 27 | 28 | virtual ~SoundUnit() {} 29 | virtual void event() = 0; 30 | 31 | virtual void resetCounters(unsigned long /*oldCc*/) { 32 | if (counter_ != counter_disabled) 33 | counter_ -= counter_max; 34 | } 35 | 36 | unsigned long counter() const { return counter_; } 37 | 38 | protected: 39 | SoundUnit() : counter_(counter_disabled) {} 40 | unsigned long counter_; 41 | }; 42 | 43 | } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /libgambatte/src/sound/static_output_tester.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef STATIC_OUTPUT_TESTER_H 20 | #define STATIC_OUTPUT_TESTER_H 21 | 22 | #include "envelope_unit.h" 23 | 24 | namespace gambatte { 25 | 26 | template 27 | class StaticOutputTester : public EnvelopeUnit::VolOnOffEvent { 28 | public: 29 | StaticOutputTester(Channel const &ch, Unit &unit) : ch_(ch), unit_(unit) {} 30 | void operator()(unsigned long cc); 31 | 32 | private: 33 | Channel const &ch_; 34 | Unit &unit_; 35 | }; 36 | 37 | template 38 | void StaticOutputTester::operator()(unsigned long cc) { 39 | if (ch_.soMask_ && ch_.master_ && ch_.envelopeUnit_.getVolume()) 40 | unit_.reviveCounter(cc); 41 | else 42 | unit_.killCounter(); 43 | } 44 | 45 | } 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /libgambatte/src/state_osd_elements.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2008 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef STATE_OSD_ELEMENTS_H 20 | #define STATE_OSD_ELEMENTS_H 21 | 22 | #include "osd_element.h" 23 | #include "transfer_ptr.h" 24 | #include 25 | 26 | namespace gambatte { 27 | transfer_ptr newStateLoadedOsdElement(unsigned stateNo); 28 | transfer_ptr newStateSavedOsdElement(unsigned stateNo); 29 | transfer_ptr newSaveStateOsdElement(const std::string &fileName, unsigned stateNo); 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /libgambatte/src/statesaver.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2008 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef STATESAVER_H 20 | #define STATESAVER_H 21 | 22 | #include "gbint.h" 23 | #include 24 | #include 25 | 26 | namespace gambatte { 27 | 28 | struct SaveState; 29 | 30 | class StateSaver { 31 | public: 32 | enum { ss_shift = 1 }; 33 | enum { ss_div = 1 << 1}; 34 | enum { ss_width = 160 >> ss_shift }; 35 | enum { ss_height = 144 >> ss_shift }; 36 | 37 | static bool saveState(SaveState const &state, 38 | uint_least32_t const *videoBuf, std::ptrdiff_t pitch, 39 | std::string const &filename); 40 | static bool loadState(SaveState &state, std::string const &filename); 41 | 42 | private: 43 | StateSaver(); 44 | }; 45 | 46 | } 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /libgambatte/src/tima.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef TIMA_H 20 | #define TIMA_H 21 | 22 | #include "interruptrequester.h" 23 | 24 | namespace gambatte { 25 | 26 | class TimaInterruptRequester { 27 | public: 28 | explicit TimaInterruptRequester(InterruptRequester &intreq) : intreq_(intreq) {} 29 | void flagIrq() const { intreq_.flagIrq(4); } 30 | unsigned long nextIrqEventTime() const { return intreq_.eventTime(intevent_tima); } 31 | void setNextIrqEventTime(unsigned long time) const { intreq_.setEventTime(time); } 32 | 33 | private: 34 | InterruptRequester &intreq_; 35 | }; 36 | 37 | class Tima { 38 | public: 39 | Tima(); 40 | void saveState(SaveState &) const; 41 | void loadState(const SaveState &, TimaInterruptRequester timaIrq); 42 | void resetCc(unsigned long oldCc, unsigned long newCc, TimaInterruptRequester timaIrq); 43 | void setTima(unsigned tima, unsigned long cc, TimaInterruptRequester timaIrq); 44 | void setTma(unsigned tma, unsigned long cc, TimaInterruptRequester timaIrq); 45 | void setTac(unsigned tac, unsigned long cc, TimaInterruptRequester timaIrq); 46 | unsigned tima(unsigned long cc); 47 | void doIrqEvent(TimaInterruptRequester timaIrq); 48 | 49 | private: 50 | unsigned long lastUpdate_; 51 | unsigned long tmatime_; 52 | unsigned char tima_; 53 | unsigned char tma_; 54 | unsigned char tac_; 55 | 56 | void updateIrq(unsigned long const cc, TimaInterruptRequester timaIrq) { 57 | while (cc >= timaIrq.nextIrqEventTime()) 58 | doIrqEvent(timaIrq); 59 | } 60 | 61 | void updateTima(unsigned long cc); 62 | }; 63 | 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /libgambatte/src/video/lcddef.h: -------------------------------------------------------------------------------- 1 | #ifndef LCDDEF_H 2 | #define LCDDEF_H 3 | 4 | namespace gambatte { 5 | 6 | enum { lcdc_bgen = 0x01, 7 | lcdc_objen = 0x02, 8 | lcdc_obj2x = 0x04, 9 | lcdc_tdsel = 0x10, 10 | lcdc_we = 0x20, 11 | lcdc_en = 0x80 }; 12 | 13 | enum { lcdstat_lycflag = 0x04, 14 | lcdstat_m0irqen = 0x08, 15 | lcdstat_m1irqen = 0x10, 16 | lcdstat_m2irqen = 0x20, 17 | lcdstat_lycirqen = 0x40 }; 18 | 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /libgambatte/src/video/ly_counter.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "ly_counter.h" 20 | #include "../savestate.h" 21 | 22 | namespace gambatte { 23 | 24 | LyCounter::LyCounter() 25 | : time_(0) 26 | , lineTime_(0) 27 | , ly_(0) 28 | , ds_(false) 29 | { 30 | setDoubleSpeed(false); 31 | reset(0, 0); 32 | } 33 | 34 | void LyCounter::doEvent() { 35 | ++ly_; 36 | if (ly_ == 154) 37 | ly_ = 0; 38 | 39 | time_ = time_ + lineTime_; 40 | } 41 | 42 | unsigned long LyCounter::nextLineCycle(unsigned const lineCycle, unsigned long const cc) const { 43 | unsigned long tmp = time_ + (lineCycle << ds_); 44 | if (tmp - cc > lineTime_) 45 | tmp -= lineTime_; 46 | 47 | return tmp; 48 | } 49 | 50 | unsigned long LyCounter::nextFrameCycle(unsigned long const frameCycle, unsigned long const cc) const { 51 | unsigned long tmp = time_ + (((153U - ly()) * 456U + frameCycle) << ds_); 52 | if (tmp - cc > 70224U << ds_) 53 | tmp -= 70224U << ds_; 54 | 55 | return tmp; 56 | } 57 | 58 | void LyCounter::reset(unsigned long videoCycles, unsigned long lastUpdate) { 59 | ly_ = videoCycles / 456; 60 | time_ = lastUpdate + ((456 - (videoCycles - ly_ * 456ul)) << isDoubleSpeed()); 61 | } 62 | 63 | void LyCounter::setDoubleSpeed(bool ds) { 64 | ds_ = ds; 65 | lineTime_ = 456U << ds; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /libgambatte/src/video/ly_counter.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef LY_COUNTER_H 20 | #define LY_COUNTER_H 21 | 22 | namespace gambatte { 23 | 24 | struct SaveState; 25 | 26 | class LyCounter { 27 | public: 28 | LyCounter(); 29 | void doEvent(); 30 | bool isDoubleSpeed() const { return ds_; } 31 | 32 | unsigned long frameCycles(unsigned long cc) const { 33 | return ly_ * 456ul + lineCycles(cc); 34 | } 35 | 36 | unsigned lineCycles(unsigned long cc) const { 37 | return 456u - ((time_ - cc) >> isDoubleSpeed()); 38 | } 39 | 40 | unsigned lineTime() const { return lineTime_; } 41 | unsigned ly() const { return ly_; } 42 | unsigned long nextLineCycle(unsigned lineCycle, unsigned long cycleCounter) const; 43 | unsigned long nextFrameCycle(unsigned long frameCycle, unsigned long cycleCounter) const; 44 | void reset(unsigned long videoCycles, unsigned long lastUpdate); 45 | void setDoubleSpeed(bool ds); 46 | unsigned long time() const { return time_; } 47 | 48 | private: 49 | unsigned long time_; 50 | unsigned short lineTime_; 51 | unsigned char ly_; 52 | bool ds_; 53 | }; 54 | 55 | } 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /libgambatte/src/video/lyc_irq.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #include "lyc_irq.h" 20 | #include "counterdef.h" 21 | #include "lcddef.h" 22 | #include "ly_counter.h" 23 | #include "savestate.h" 24 | #include 25 | 26 | namespace gambatte { 27 | 28 | LycIrq::LycIrq() 29 | : time_(disabled_time) 30 | , lycRegSrc_(0) 31 | , statRegSrc_(0) 32 | , lycReg_(0) 33 | , statReg_(0) 34 | , cgb_(false) 35 | { 36 | } 37 | 38 | static unsigned long schedule(unsigned statReg, 39 | unsigned lycReg, LyCounter const &lyCounter, unsigned long cc) { 40 | return (statReg & lcdstat_lycirqen) && lycReg < 154 41 | ? lyCounter.nextFrameCycle(lycReg ? lycReg * 456 : 153 * 456 + 8, cc) 42 | : static_cast(disabled_time); 43 | } 44 | 45 | void LycIrq::regChange(unsigned const statReg, 46 | unsigned const lycReg, LyCounter const &lyCounter, unsigned long const cc) { 47 | unsigned long const timeSrc = schedule(statReg, lycReg, lyCounter, cc); 48 | statRegSrc_ = statReg; 49 | lycRegSrc_ = lycReg; 50 | time_ = std::min(time_, timeSrc); 51 | 52 | if (cgb_) { 53 | if (time_ - cc > 8 || (timeSrc != time_ && time_ - cc > 4U - lyCounter.isDoubleSpeed() * 4U)) 54 | lycReg_ = lycReg; 55 | 56 | if (time_ - cc > 4U - lyCounter.isDoubleSpeed() * 4U) 57 | statReg_ = statReg; 58 | } else { 59 | if (time_ - cc > 4 || timeSrc != time_) 60 | lycReg_ = lycReg; 61 | 62 | if (time_ - cc > 4 || lycReg_ != 0) 63 | statReg_ = statReg; 64 | 65 | statReg_ = (statReg_ & lcdstat_lycirqen) | (statReg & ~lcdstat_lycirqen); 66 | } 67 | } 68 | 69 | static bool lycIrqBlockedByM2OrM1StatIrq(unsigned ly, unsigned statreg) { 70 | return ly - 1u < 144u - 1u 71 | ? statreg & lcdstat_m2irqen 72 | : statreg & lcdstat_m1irqen; 73 | } 74 | 75 | void LycIrq::doEvent(unsigned char *const ifreg, LyCounter const &lyCounter) { 76 | if ((statReg_ | statRegSrc_) & lcdstat_lycirqen) { 77 | unsigned cmpLy = lyCounter.time() - time_ < lyCounter.lineTime() ? 0 : lyCounter.ly(); 78 | if (lycReg_ == cmpLy && !lycIrqBlockedByM2OrM1StatIrq(lycReg_, statReg_)) 79 | *ifreg |= 2; 80 | } 81 | 82 | lycReg_ = lycRegSrc_; 83 | statReg_ = statRegSrc_; 84 | time_ = schedule(statReg_, lycReg_, lyCounter, time_); 85 | } 86 | 87 | void LycIrq::loadState(SaveState const &state) { 88 | lycRegSrc_ = state.mem.ioamhram.get()[0x145]; 89 | statRegSrc_ = state.mem.ioamhram.get()[0x141]; 90 | lycReg_ = state.ppu.lyc; 91 | statReg_ = statRegSrc_; 92 | } 93 | 94 | void LycIrq::saveState(SaveState &state) const { 95 | state.ppu.lyc = lycReg_; 96 | } 97 | 98 | void LycIrq::reschedule(LyCounter const &lyCounter, unsigned long cc) { 99 | time_ = std::min(schedule(statReg_ , lycReg_ , lyCounter, cc), 100 | schedule(statRegSrc_, lycRegSrc_, lyCounter, cc)); 101 | } 102 | 103 | void LycIrq::lcdReset() { 104 | statReg_ = statRegSrc_; 105 | lycReg_ = lycRegSrc_; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /libgambatte/src/video/lyc_irq.h: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2007 by sinamas 3 | // 4 | // This program is free software; you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License version 2 as 6 | // published by the Free Software Foundation. 7 | // 8 | // This program is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU General Public License version 2 for more details. 12 | // 13 | // You should have received a copy of the GNU General Public License 14 | // version 2 along with this program; if not, write to the 15 | // Free Software Foundation, Inc., 16 | // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | // 18 | 19 | #ifndef VIDEO_LYC_IRQ_H 20 | #define VIDEO_LYC_IRQ_H 21 | 22 | namespace gambatte { 23 | 24 | struct SaveState; 25 | class LyCounter; 26 | 27 | class LycIrq { 28 | public: 29 | LycIrq(); 30 | void doEvent(unsigned char *ifreg, LyCounter const &lyCounter); 31 | unsigned lycReg() const { return lycRegSrc_; } 32 | void loadState(SaveState const &state); 33 | void saveState(SaveState &state) const; 34 | unsigned long time() const { return time_; } 35 | void setCgb(bool cgb) { cgb_ = cgb; } 36 | void lcdReset(); 37 | void reschedule(LyCounter const &lyCounter, unsigned long cc); 38 | 39 | void statRegChange(unsigned statReg, LyCounter const &lyCounter, unsigned long cc) { 40 | regChange(statReg, lycRegSrc_, lyCounter, cc); 41 | } 42 | 43 | void lycRegChange(unsigned lycReg, LyCounter const &lyCounter, unsigned long cc) { 44 | regChange(statRegSrc_, lycReg, lyCounter, cc); 45 | } 46 | 47 | private: 48 | unsigned long time_; 49 | unsigned char lycRegSrc_; 50 | unsigned char statRegSrc_; 51 | unsigned char lycReg_; 52 | unsigned char statReg_; 53 | bool cgb_; 54 | 55 | void regChange(unsigned statReg, unsigned lycReg, 56 | LyCounter const &lyCounter, unsigned long cc); 57 | }; 58 | 59 | } 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /libgambatte/src/video/m0_irq.h: -------------------------------------------------------------------------------- 1 | #ifndef M0_IRQ_H 2 | #define M0_IRQ_H 3 | 4 | #include "lcddef.h" 5 | #include "../savestate.h" 6 | 7 | namespace gambatte { 8 | 9 | class M0Irq { 10 | public: 11 | M0Irq() 12 | : statReg_(0) 13 | , lycReg_(0) 14 | { 15 | } 16 | 17 | void lcdReset(unsigned statReg, unsigned lycReg) { 18 | statReg_ = statReg; 19 | lycReg_ = lycReg; 20 | } 21 | 22 | void statRegChange(unsigned statReg, 23 | unsigned long nextM0IrqTime, unsigned long cc, bool cgb) { 24 | if (nextM0IrqTime - cc > cgb * 2U) 25 | statReg_ = statReg; 26 | } 27 | 28 | void lycRegChange(unsigned lycReg, 29 | unsigned long nextM0IrqTime, unsigned long cc, 30 | bool ds, bool cgb) { 31 | if (nextM0IrqTime - cc > cgb * 5 + 1U - ds) 32 | lycReg_ = lycReg; 33 | } 34 | 35 | void doEvent(unsigned char *ifreg, unsigned ly, unsigned statReg, unsigned lycReg) { 36 | if (((statReg_ | statReg) & lcdstat_m0irqen) 37 | && (!(statReg_ & lcdstat_lycirqen) || ly != lycReg_)) { 38 | *ifreg |= 2; 39 | } 40 | 41 | statReg_ = statReg; 42 | lycReg_ = lycReg; 43 | } 44 | 45 | void saveState(SaveState &state) const { 46 | state.ppu.m0lyc = lycReg_; 47 | } 48 | 49 | void loadState(SaveState const &state) { 50 | lycReg_ = state.ppu.m0lyc; 51 | statReg_ = state.mem.ioamhram.get()[0x141]; 52 | } 53 | 54 | unsigned statReg() const { return statReg_; } 55 | 56 | private: 57 | unsigned char statReg_; 58 | unsigned char lycReg_; 59 | }; 60 | 61 | } 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /libgambatte/src/video/next_m0_time.cpp: -------------------------------------------------------------------------------- 1 | #include "next_m0_time.h" 2 | #include "ppu.h" 3 | 4 | void gambatte::NextM0Time::predictNextM0Time(PPU const &ppu) { 5 | predictedNextM0Time_ = ppu.predictedNextXposTime(167); 6 | } 7 | -------------------------------------------------------------------------------- /libgambatte/src/video/next_m0_time.h: -------------------------------------------------------------------------------- 1 | #ifndef NEXT_M0_TIME_H_ 2 | #define NEXT_M0_TIME_H_ 3 | 4 | namespace gambatte { 5 | 6 | class NextM0Time { 7 | public: 8 | NextM0Time() : predictedNextM0Time_(0) {} 9 | void predictNextM0Time(class PPU const &v); 10 | void invalidatePredictedNextM0Time() { predictedNextM0Time_ = 0; } 11 | unsigned predictedNextM0Time() const { return predictedNextM0Time_; } 12 | 13 | private: 14 | unsigned predictedNextM0Time_; 15 | }; 16 | 17 | } 18 | 19 | #endif 20 | --------------------------------------------------------------------------------