Update to v106r26 release.
byuu says: Changelog: - nall: added -static-libgcc -static-libstdc++ to Windows/GCC link flags - bsnes, higan: added program icons to main window when game isn't loaded - bsnes: improved recent games menu sorting - bsnes: fixed multi-game recent game loading on Windows - bsnes: completed path override support - bsnes, higan: added screensaver suppression on Windows - icarus: add 32K volatile RAM to SuperFX boards that report no RAM (fixes Starfox) - bsnes, higan: added automatic dependency generation [Talarubi] - hiro/GTK: appending actions to menus restores enabled() state - higan: use board node inside manifest.bml if it exists - bsnes: added blur emulation and color emulation options to view menu - ruby: upgraded input.sdl to SDL 2.0 (though it makes no functional difference sadly) - ruby: removed video.sdl (due to deprecating SDL 1.2) - nall, ruby: improvements to HID class (generic vendor and product IDs) Errata: - bsnes, higan: on Windows, Application::Windows::onScreenSaver needs `[&]` lambda capture, not `[]` - find it in presentation/presentation.cpp
|
@ -39,9 +39,9 @@ endif
|
|||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(compiler) $(cflags) $(flags) $1 -c $< -o $@, \
|
||||
$(compiler) $(cflags) $(flags) $1 -c $< -o $@ -MMD -MP -MF $(@:.o=.d), \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(compiler) $(cppflags) $(flags) $1 -c $< -o $@ \
|
||||
$(compiler) $(cppflags) $(flags) $1 -c $< -o $@ -MMD -MP -MF $(@:.o=.d) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
@ -50,14 +50,15 @@ compile = \
|
|||
|
||||
all: build;
|
||||
|
||||
obj/libco.o: ../libco/libco.c $(call rwildcard,../libco)
|
||||
obj/emulator.o: emulator/emulator.cpp $(call rwildcard,emulator)
|
||||
obj/audio.o: audio/audio.cpp $(call rwildcard,audio)
|
||||
obj/video.o: video/video.cpp $(call rwildcard,video)
|
||||
obj/resource.o: resource/resource.cpp $(call rwildcard,resource)
|
||||
obj/libco.o: ../libco/libco.c
|
||||
obj/emulator.o: emulator/emulator.cpp
|
||||
obj/audio.o: audio/audio.cpp
|
||||
obj/video.o: video/video.cpp
|
||||
obj/resource.o: resource/resource.cpp
|
||||
|
||||
ui := target-$(target)
|
||||
include $(ui)/GNUmakefile
|
||||
-include obj/*.d
|
||||
|
||||
clean:
|
||||
$(call rm,out/*)
|
||||
|
|
|
@ -12,7 +12,7 @@ using namespace nall;
|
|||
|
||||
namespace Emulator {
|
||||
static const string Name = "higan";
|
||||
static const string Version = "106.25";
|
||||
static const string Version = "106.26";
|
||||
static const string Author = "byuu";
|
||||
static const string License = "GPLv3";
|
||||
static const string Website = "https://byuu.org/";
|
||||
|
|
|
@ -3,11 +3,11 @@ processors += mos6502
|
|||
objects += fc-interface fc-system fc-controller
|
||||
objects += fc-memory fc-cartridge fc-cpu fc-apu fc-ppu
|
||||
|
||||
obj/fc-interface.o: fc/interface/interface.cpp $(call rwildcard,fc/interface/)
|
||||
obj/fc-system.o: fc/system/system.cpp $(call rwildcard,fc/system/)
|
||||
obj/fc-controller.o: fc/controller/controller.cpp $(call rwildcard,fc/controller/)
|
||||
obj/fc-memory.o: fc/memory/memory.cpp $(call rwildcard,fc/memory/)
|
||||
obj/fc-cartridge.o: fc/cartridge/cartridge.cpp $(call rwildcard,fc/cartridge/)
|
||||
obj/fc-cpu.o: fc/cpu/cpu.cpp $(call rwildcard,fc/cpu/)
|
||||
obj/fc-apu.o: fc/apu/apu.cpp $(call rwildcard,fc/apu/)
|
||||
obj/fc-ppu.o: fc/ppu/ppu.cpp $(call rwildcard,fc/ppu/)
|
||||
obj/fc-interface.o: fc/interface/interface.cpp
|
||||
obj/fc-system.o: fc/system/system.cpp
|
||||
obj/fc-controller.o: fc/controller/controller.cpp
|
||||
obj/fc-memory.o: fc/memory/memory.cpp
|
||||
obj/fc-cartridge.o: fc/cartridge/cartridge.cpp
|
||||
obj/fc-cpu.o: fc/cpu/cpu.cpp
|
||||
obj/fc-apu.o: fc/apu/apu.cpp
|
||||
obj/fc-ppu.o: fc/ppu/ppu.cpp
|
||||
|
|
|
@ -4,10 +4,10 @@ objects += gb-interface gb-system
|
|||
objects += gb-memory gb-cartridge
|
||||
objects += gb-cpu gb-ppu gb-apu
|
||||
|
||||
obj/gb-interface.o: gb/interface/interface.cpp $(call rwildcard,gb/interface/)
|
||||
obj/gb-system.o: gb/system/system.cpp $(call rwildcard,gb/system/)
|
||||
obj/gb-cartridge.o: gb/cartridge/cartridge.cpp $(call rwildcard,gb/cartridge/)
|
||||
obj/gb-memory.o: gb/memory/memory.cpp $(call rwildcard,gb/memory/)
|
||||
obj/gb-cpu.o: gb/cpu/cpu.cpp $(call rwildcard,gb/cpu/)
|
||||
obj/gb-ppu.o: gb/ppu/ppu.cpp $(call rwildcard,gb/ppu/)
|
||||
obj/gb-apu.o: gb/apu/apu.cpp $(call rwildcard,gb/apu/)
|
||||
obj/gb-interface.o: gb/interface/interface.cpp
|
||||
obj/gb-system.o: gb/system/system.cpp
|
||||
obj/gb-cartridge.o: gb/cartridge/cartridge.cpp
|
||||
obj/gb-memory.o: gb/memory/memory.cpp
|
||||
obj/gb-cpu.o: gb/cpu/cpu.cpp
|
||||
obj/gb-ppu.o: gb/ppu/ppu.cpp
|
||||
obj/gb-apu.o: gb/apu/apu.cpp
|
||||
|
|
|
@ -4,11 +4,11 @@ objects += gba-memory gba-interface gba-system
|
|||
objects += gba-cartridge gba-player
|
||||
objects += gba-cpu gba-ppu gba-apu
|
||||
|
||||
obj/gba-memory.o: gba/memory/memory.cpp $(call rwildcard,gba/memory)
|
||||
obj/gba-interface.o: gba/interface/interface.cpp $(call rwildcard,gba/interface)
|
||||
obj/gba-system.o: gba/system/system.cpp $(call rwildcard,gba/system)
|
||||
obj/gba-cartridge.o: gba/cartridge/cartridge.cpp $(call rwildcard,gba/cartridge)
|
||||
obj/gba-player.o: gba/player/player.cpp $(call rwildcard,gba/player)
|
||||
obj/gba-cpu.o: gba/cpu/cpu.cpp $(call rwildcard,gba/cpu)
|
||||
obj/gba-ppu.o: gba/ppu/ppu.cpp $(call rwildcard,gba/ppu)
|
||||
obj/gba-apu.o: gba/apu/apu.cpp $(call rwildcard,gba/apu)
|
||||
obj/gba-memory.o: gba/memory/memory.cpp
|
||||
obj/gba-interface.o: gba/interface/interface.cpp
|
||||
obj/gba-system.o: gba/system/system.cpp
|
||||
obj/gba-cartridge.o: gba/cartridge/cartridge.cpp
|
||||
obj/gba-player.o: gba/player/player.cpp
|
||||
obj/gba-cpu.o: gba/cpu/cpu.cpp
|
||||
obj/gba-ppu.o: gba/ppu/ppu.cpp
|
||||
obj/gba-apu.o: gba/apu/apu.cpp
|
||||
|
|
|
@ -5,12 +5,12 @@ objects += md-cpu md-apu md-vdp md-psg md-ym2612
|
|||
objects += md-system md-cartridge
|
||||
objects += md-controller
|
||||
|
||||
obj/md-interface.o: md/interface/interface.cpp $(call rwildcard,md/interface)
|
||||
obj/md-cpu.o: md/cpu/cpu.cpp $(call rwildcard,md/cpu)
|
||||
obj/md-apu.o: md/apu/apu.cpp $(call rwildcard,md/apu)
|
||||
obj/md-vdp.o: md/vdp/vdp.cpp $(call rwildcard,md/vdp)
|
||||
obj/md-psg.o: md/psg/psg.cpp $(call rwildcard,md/psg)
|
||||
obj/md-ym2612.o: md/ym2612/ym2612.cpp $(call rwildcard,md/ym2612)
|
||||
obj/md-system.o: md/system/system.cpp $(call rwildcard,md/system)
|
||||
obj/md-cartridge.o: md/cartridge/cartridge.cpp $(call rwildcard,md/cartridge)
|
||||
obj/md-controller.o: md/controller/controller.cpp $(call rwildcard,md/controller)
|
||||
obj/md-interface.o: md/interface/interface.cpp
|
||||
obj/md-cpu.o: md/cpu/cpu.cpp
|
||||
obj/md-apu.o: md/apu/apu.cpp
|
||||
obj/md-vdp.o: md/vdp/vdp.cpp
|
||||
obj/md-psg.o: md/psg/psg.cpp
|
||||
obj/md-ym2612.o: md/ym2612/ym2612.cpp
|
||||
obj/md-system.o: md/system/system.cpp
|
||||
obj/md-cartridge.o: md/cartridge/cartridge.cpp
|
||||
obj/md-controller.o: md/controller/controller.cpp
|
||||
|
|
|
@ -5,10 +5,10 @@ objects += ms-cpu ms-vdp ms-psg
|
|||
objects += ms-system ms-cartridge
|
||||
objects += ms-controller
|
||||
|
||||
obj/ms-interface.o: ms/interface/interface.cpp $(call rwildcard,ms/interface)
|
||||
obj/ms-cpu.o: ms/cpu/cpu.cpp $(call rwildcard,ms/cpu)
|
||||
obj/ms-vdp.o: ms/vdp/vdp.cpp $(call rwildcard,ms/vdp)
|
||||
obj/ms-psg.o: ms/psg/psg.cpp $(call rwildcard,ms/psg)
|
||||
obj/ms-system.o: ms/system/system.cpp $(call rwildcard,ms/system)
|
||||
obj/ms-cartridge.o: ms/cartridge/cartridge.cpp $(call rwildcard,ms/cartridge)
|
||||
obj/ms-controller.o: ms/controller/controller.cpp $(call rwildcard,ms/controller)
|
||||
obj/ms-interface.o: ms/interface/interface.cpp
|
||||
obj/ms-cpu.o: ms/cpu/cpu.cpp
|
||||
obj/ms-vdp.o: ms/vdp/vdp.cpp
|
||||
obj/ms-psg.o: ms/psg/psg.cpp
|
||||
obj/ms-system.o: ms/system/system.cpp
|
||||
obj/ms-cartridge.o: ms/cartridge/cartridge.cpp
|
||||
obj/ms-controller.o: ms/controller/controller.cpp
|
||||
|
|
|
@ -5,12 +5,12 @@ objects += pce-cpu pce-vpc pce-vce pce-vdc pce-psg
|
|||
objects += pce-system pce-cartridge
|
||||
objects += pce-controller
|
||||
|
||||
obj/pce-interface.o: pce/interface/interface.cpp $(call rwildcard,pce/interface)
|
||||
obj/pce-cpu.o: pce/cpu/cpu.cpp $(call rwildcard,pce/cpu)
|
||||
obj/pce-vpc.o: pce/vpc/vpc.cpp $(call rwildcard,pce/vpc)
|
||||
obj/pce-vce.o: pce/vce/vce.cpp $(call rwildcard,pce/vce)
|
||||
obj/pce-vdc.o: pce/vdc/vdc.cpp $(call rwildcard,pce/vdc)
|
||||
obj/pce-psg.o: pce/psg/psg.cpp $(call rwildcard,pce/psg)
|
||||
obj/pce-system.o: pce/system/system.cpp $(call rwildcard,pce/system)
|
||||
obj/pce-cartridge.o: pce/cartridge/cartridge.cpp $(call rwildcard,pce/cartridge)
|
||||
obj/pce-controller.o: pce/controller/controller.cpp $(call rwildcard,pce/controller)
|
||||
obj/pce-interface.o: pce/interface/interface.cpp
|
||||
obj/pce-cpu.o: pce/cpu/cpu.cpp
|
||||
obj/pce-vpc.o: pce/vpc/vpc.cpp
|
||||
obj/pce-vce.o: pce/vce/vce.cpp
|
||||
obj/pce-vdc.o: pce/vdc/vdc.cpp
|
||||
obj/pce-psg.o: pce/psg/psg.cpp
|
||||
obj/pce-system.o: pce/system/system.cpp
|
||||
obj/pce-cartridge.o: pce/cartridge/cartridge.cpp
|
||||
obj/pce-controller.o: pce/controller/controller.cpp
|
||||
|
|
|
@ -13,15 +13,15 @@ objects += $(if $(findstring v30mz,$(processors)),processor-v30mz)
|
|||
objects += $(if $(findstring wdc65816,$(processors)),processor-wdc65816)
|
||||
objects += $(if $(findstring z80,$(processors)),processor-z80)
|
||||
|
||||
obj/processor-arm7tdmi.o: processor/arm7tdmi/arm7tdmi.cpp $(call rwildcard,processor/arm7tdmi/)
|
||||
obj/processor-gsu.o: processor/gsu/gsu.cpp $(call rwildcard,processor/gsu/)
|
||||
obj/processor-hg51b.o: processor/hg51b/hg51b.cpp $(call rwildcard,processor/hg51b/)
|
||||
obj/processor-huc6280.o: processor/huc6280/huc6280.cpp $(call rwildcard,processor/huc6280/)
|
||||
obj/processor-lr35902.o: processor/lr35902/lr35902.cpp $(call rwildcard,processor/lr35902/)
|
||||
obj/processor-m68k.o: processor/m68k/m68k.cpp $(call rwildcard,processor/m68k/)
|
||||
obj/processor-mos6502.o: processor/mos6502/mos6502.cpp $(call rwildcard,processor/mos6502/)
|
||||
obj/processor-spc700.o: processor/spc700/spc700.cpp $(call rwildcard,processor/spc700/)
|
||||
obj/processor-upd96050.o: processor/upd96050/upd96050.cpp $(call rwildcard,processor/upd96050/)
|
||||
obj/processor-v30mz.o: processor/v30mz/v30mz.cpp $(call rwildcard,processor/v30mz/)
|
||||
obj/processor-wdc65816.o: processor/wdc65816/wdc65816.cpp $(call rwildcard,processor/wdc65816/)
|
||||
obj/processor-z80.o: processor/z80/z80.cpp $(call rwildcard,processor/z80/)
|
||||
obj/processor-arm7tdmi.o: processor/arm7tdmi/arm7tdmi.cpp
|
||||
obj/processor-gsu.o: processor/gsu/gsu.cpp
|
||||
obj/processor-hg51b.o: processor/hg51b/hg51b.cpp
|
||||
obj/processor-huc6280.o: processor/huc6280/huc6280.cpp
|
||||
obj/processor-lr35902.o: processor/lr35902/lr35902.cpp
|
||||
obj/processor-m68k.o: processor/m68k/m68k.cpp
|
||||
obj/processor-mos6502.o: processor/mos6502/mos6502.cpp
|
||||
obj/processor-spc700.o: processor/spc700/spc700.cpp
|
||||
obj/processor-upd96050.o: processor/upd96050/upd96050.cpp
|
||||
obj/processor-v30mz.o: processor/v30mz/v30mz.cpp
|
||||
obj/processor-wdc65816.o: processor/wdc65816/wdc65816.cpp
|
||||
obj/processor-z80.o: processor/z80/z80.cpp
|
||||
|
|
|
@ -12,41 +12,41 @@ objects += sfc-spc7110 sfc-sdd1
|
|||
objects += sfc-obc1 sfc-msu1
|
||||
objects += sfc-bsmemory sfc-sufamiturbo
|
||||
|
||||
obj/sfc-interface.o: sfc/interface/interface.cpp $(call rwildcard,sfc/interface)
|
||||
obj/sfc-system.o: sfc/system/system.cpp $(call rwildcard,sfc/system/)
|
||||
obj/sfc-controller.o: sfc/controller/controller.cpp $(call rwildcard,sfc/controller/)
|
||||
obj/sfc-cartridge.o: sfc/cartridge/cartridge.cpp $(call rwildcard,sfc/cartridge/)
|
||||
obj/sfc-memory.o: sfc/memory/memory.cpp $(call rwildcard,sfc/memory/)
|
||||
obj/sfc-interface.o: sfc/interface/interface.cpp
|
||||
obj/sfc-system.o: sfc/system/system.cpp
|
||||
obj/sfc-controller.o: sfc/controller/controller.cpp
|
||||
obj/sfc-cartridge.o: sfc/cartridge/cartridge.cpp
|
||||
obj/sfc-memory.o: sfc/memory/memory.cpp
|
||||
|
||||
obj/sfc-cpu.o: sfc/cpu/cpu.cpp $(call rwildcard,sfc/cpu/)
|
||||
obj/sfc-smp.o: sfc/smp/smp.cpp $(call rwildcard,sfc/smp/)
|
||||
obj/sfc-dsp.o: sfc/dsp/dsp.cpp $(call rwildcard,sfc/dsp/)
|
||||
obj/sfc-ppu.o: sfc/ppu/ppu.cpp $(call rwildcard,sfc/ppu/)
|
||||
obj/sfc-cpu.o: sfc/cpu/cpu.cpp
|
||||
obj/sfc-smp.o: sfc/smp/smp.cpp
|
||||
obj/sfc-dsp.o: sfc/dsp/dsp.cpp
|
||||
obj/sfc-ppu.o: sfc/ppu/ppu.cpp
|
||||
|
||||
obj/sfc-expansion.o: sfc/expansion/expansion.cpp $(call rwildcard,sfc/expansion/)
|
||||
obj/sfc-satellaview.o: sfc/expansion/satellaview/satellaview.cpp $(call rwildcard,sfc/expansion/satellaview/)
|
||||
obj/sfc-21fx.o: sfc/expansion/21fx/21fx.cpp $(call rwildcard,sfc/expansion/21fx/)
|
||||
obj/sfc-expansion.o: sfc/expansion/expansion.cpp
|
||||
obj/sfc-satellaview.o: sfc/expansion/satellaview/satellaview.cpp
|
||||
obj/sfc-21fx.o: sfc/expansion/21fx/21fx.cpp
|
||||
|
||||
obj/sfc-icd.o: sfc/coprocessor/icd/icd.cpp $(call rwildcard,sfc/coprocessor/icd/)
|
||||
obj/sfc-mcc.o: sfc/coprocessor/mcc/mcc.cpp $(call rwildcard,sfc/coprocessor/mcc/)
|
||||
obj/sfc-dip.o: sfc/coprocessor/dip/dip.cpp $(call rwildcard,sfc/coprocessor/dip/)
|
||||
obj/sfc-event.o: sfc/coprocessor/event/event.cpp $(call rwildcard,sfc/coprocessor/event/)
|
||||
obj/sfc-icd.o: sfc/coprocessor/icd/icd.cpp
|
||||
obj/sfc-mcc.o: sfc/coprocessor/mcc/mcc.cpp
|
||||
obj/sfc-dip.o: sfc/coprocessor/dip/dip.cpp
|
||||
obj/sfc-event.o: sfc/coprocessor/event/event.cpp
|
||||
|
||||
obj/sfc-sa1.o: sfc/coprocessor/sa1/sa1.cpp $(call rwildcard,sfc/coprocessor/sa1/)
|
||||
obj/sfc-superfx.o: sfc/coprocessor/superfx/superfx.cpp $(call rwildcard,sfc/coprocessor/superfx/)
|
||||
obj/sfc-sa1.o: sfc/coprocessor/sa1/sa1.cpp
|
||||
obj/sfc-superfx.o: sfc/coprocessor/superfx/superfx.cpp
|
||||
|
||||
obj/sfc-armdsp.o: sfc/coprocessor/armdsp/armdsp.cpp $(call rwildcard,sfc/coprocessor/armdsp/)
|
||||
obj/sfc-hitachidsp.o: sfc/coprocessor/hitachidsp/hitachidsp.cpp $(call rwildcard,sfc/coprocessor/hitachidsp/)
|
||||
obj/sfc-necdsp.o: sfc/coprocessor/necdsp/necdsp.cpp $(call rwildcard,sfc/coprocessor/necdsp/)
|
||||
obj/sfc-armdsp.o: sfc/coprocessor/armdsp/armdsp.cpp
|
||||
obj/sfc-hitachidsp.o: sfc/coprocessor/hitachidsp/hitachidsp.cpp
|
||||
obj/sfc-necdsp.o: sfc/coprocessor/necdsp/necdsp.cpp
|
||||
|
||||
obj/sfc-epsonrtc.o: sfc/coprocessor/epsonrtc/epsonrtc.cpp $(call rwildcard,sfc/coprocessor/epsonrtc/)
|
||||
obj/sfc-sharprtc.o: sfc/coprocessor/sharprtc/sharprtc.cpp $(call rwildcard,sfc/coprocessor/sharprtc/)
|
||||
obj/sfc-epsonrtc.o: sfc/coprocessor/epsonrtc/epsonrtc.cpp
|
||||
obj/sfc-sharprtc.o: sfc/coprocessor/sharprtc/sharprtc.cpp
|
||||
|
||||
obj/sfc-spc7110.o: sfc/coprocessor/spc7110/spc7110.cpp $(call rwildcard,sfc/coprocessor/spc7110/)
|
||||
obj/sfc-sdd1.o: sfc/coprocessor/sdd1/sdd1.cpp $(call rwildcard,sfc/coprocessor/sdd1/)
|
||||
obj/sfc-obc1.o: sfc/coprocessor/obc1/obc1.cpp $(call rwildcard,sfc/coprocessor/obc1/)
|
||||
obj/sfc-spc7110.o: sfc/coprocessor/spc7110/spc7110.cpp
|
||||
obj/sfc-sdd1.o: sfc/coprocessor/sdd1/sdd1.cpp
|
||||
obj/sfc-obc1.o: sfc/coprocessor/obc1/obc1.cpp
|
||||
|
||||
obj/sfc-msu1.o: sfc/coprocessor/msu1/msu1.cpp $(call rwildcard,sfc/coprocessor/msu1/)
|
||||
obj/sfc-msu1.o: sfc/coprocessor/msu1/msu1.cpp
|
||||
|
||||
obj/sfc-bsmemory.o: sfc/slot/bsmemory/bsmemory.cpp $(call rwildcard,sfc/slot/bsmemory/)
|
||||
obj/sfc-sufamiturbo.o: sfc/slot/sufamiturbo/sufamiturbo.cpp $(call rwildcard,sfc/slot/sufamiturbo/)
|
||||
obj/sfc-bsmemory.o: sfc/slot/bsmemory/bsmemory.cpp
|
||||
obj/sfc-sufamiturbo.o: sfc/slot/sufamiturbo/sufamiturbo.cpp
|
||||
|
|
|
@ -5,6 +5,7 @@ auto Cartridge::loadBoard(string board) -> Markup::Node {
|
|||
if(board.beginsWith("MAXI-")) board.replace("MAXI-", "SHVC-", 1L);
|
||||
if(board.beginsWith("MJSC-")) board.replace("MJSC-", "SHVC-", 1L);
|
||||
if(board.beginsWith("EA-" )) board.replace("EA-", "SHVC-", 1L);
|
||||
if(board.beginsWith("WEI-" )) board.replace("WEI-", "SHVC-", 1L);
|
||||
|
||||
if(auto fp = platform->open(ID::System, "boards.bml", File::Read, File::Required)) {
|
||||
auto document = BML::unserialize(fp->reads());
|
||||
|
@ -25,7 +26,8 @@ auto Cartridge::loadBoard(string board) -> Markup::Node {
|
|||
}
|
||||
|
||||
auto Cartridge::loadCartridge(Markup::Node node) -> void {
|
||||
board = loadBoard(game.board);
|
||||
board = node["board"];
|
||||
if(!board) board = loadBoard(game.board);
|
||||
|
||||
if(region() == "Auto") {
|
||||
auto region = game.region;
|
||||
|
|
|
@ -19,11 +19,11 @@ else ifeq ($(platform),macos)
|
|||
ruby += audio.openal
|
||||
ruby += input.quartz input.carbon
|
||||
else ifeq ($(platform),linux)
|
||||
ruby += video.glx video.xvideo video.xshm video.sdl
|
||||
ruby += video.glx video.xvideo video.xshm
|
||||
ruby += audio.oss audio.alsa audio.openal audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||
ruby += input.sdl input.xlib input.udev
|
||||
else ifeq ($(platform),bsd)
|
||||
ruby += video.glx video.xvideo video.xshm video.sdl
|
||||
ruby += video.glx video.xvideo video.xshm
|
||||
ruby += audio.oss audio.openal
|
||||
ruby += input.sdl input.xlib
|
||||
endif
|
||||
|
@ -38,7 +38,7 @@ link += $(hirolink)
|
|||
|
||||
# rules
|
||||
objects := $(ui_objects) $(objects)
|
||||
objects := $(patsubst %,obj/%.o,$(objects))
|
||||
objects := $(objects:%=obj/%.o)
|
||||
|
||||
obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/)
|
||||
$(compiler) $(rubyflags) -c $< -o $@
|
||||
|
@ -46,15 +46,15 @@ obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/)
|
|||
obj/hiro.o: ../hiro/hiro.cpp $(call rwildcard,../hiro/)
|
||||
$(compiler) $(hiroflags) -c $< -o $@
|
||||
|
||||
obj/ui-bsnes.o: $(ui)/bsnes.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-program.o: $(ui)/program/program.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-input.o: $(ui)/input/input.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-presentation.o: $(ui)/presentation/presentation.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-resource.o: $(ui)/resource/resource.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-bsnes.o: $(ui)/bsnes.cpp
|
||||
obj/ui-program.o: $(ui)/program/program.cpp
|
||||
obj/ui-input.o: $(ui)/input/input.cpp
|
||||
obj/ui-presentation.o: $(ui)/presentation/presentation.cpp
|
||||
obj/ui-settings.o: $(ui)/settings/settings.cpp
|
||||
obj/ui-resource.o: $(ui)/resource/resource.cpp
|
||||
|
||||
obj/ui-windows.o:
|
||||
$(windres) data/bsnes.rc obj/ui-resource.o
|
||||
$(windres) $(ui)/resource/bsnes.rc obj/ui-windows.o
|
||||
|
||||
# targets
|
||||
build: $(objects)
|
||||
|
@ -64,8 +64,8 @@ ifeq ($(platform),macos)
|
|||
mkdir -p out/$(name).app/Contents/MacOS/
|
||||
mkdir -p out/$(name).app/Contents/Resources/
|
||||
mv out/$(name) out/$(name).app/Contents/MacOS/$(name)
|
||||
cp data/$(name).plist out/$(name).app/Contents/Info.plist
|
||||
sips -s format icns data/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns
|
||||
cp $(ui)/resource/$(name).plist out/$(name).app/Contents/Info.plist
|
||||
sips -s format icns $(ui)/resource/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns
|
||||
endif
|
||||
|
||||
install:
|
||||
|
@ -81,8 +81,8 @@ else ifneq ($(filter $(platform),linux bsd),)
|
|||
mkdir -p $(prefix)/share/icons/
|
||||
mkdir -p $(prefix)/share/$(name)/
|
||||
cp out/$(name) $(prefix)/bin/$(name)
|
||||
cp data/$(name).desktop $(prefix)/share/applications/$(name).desktop
|
||||
cp data/$(name).png $(prefix)/share/icons/$(name).png
|
||||
cp $(ui)/resource/$(name).desktop $(prefix)/share/applications/$(name).desktop
|
||||
cp $(ui)/resource/$(name).png $(prefix)/share/icons/$(name).png
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
|
|
|
@ -78,6 +78,14 @@ Presentation::Presentation() {
|
|||
settings["View/IntegralScaling"].setValue(integralScaling.checked());
|
||||
resizeViewport();
|
||||
});
|
||||
blurEmulation.setText("Blur Emulation").setChecked(settings["View/BlurEmulation"].boolean()).onToggle([&] {
|
||||
settings["View/BlurEmulation"].setValue(blurEmulation.checked());
|
||||
emulator->set("Blur Emulation", blurEmulation.checked());
|
||||
}).doToggle();
|
||||
colorEmulation.setText("Color Emulation").setChecked(settings["View/ColorEmulation"].boolean()).onToggle([&] {
|
||||
settings["View/ColorEmulation"].setValue(colorEmulation.checked());
|
||||
emulator->set("Color Emulation", colorEmulation.checked());
|
||||
}).doToggle();
|
||||
shaderMenu.setText("Shader");
|
||||
updateShaders();
|
||||
muteAudio.setText("Mute Audio").setChecked(settings["Audio/Mute"].boolean()).onToggle([&] {
|
||||
|
@ -86,6 +94,7 @@ Presentation::Presentation() {
|
|||
showStatusBar.setText("Show Status Bar").setChecked(settings["UserInterface/ShowStatusBar"].boolean()).onToggle([&] {
|
||||
settings["UserInterface/ShowStatusBar"].setValue(showStatusBar.checked());
|
||||
statusBar.setVisible(showStatusBar.checked());
|
||||
if(visible()) resizeWindow();
|
||||
});
|
||||
inputSettings.setText("Input ...").onActivate([&] { settingsWindow->show(0); });
|
||||
hotkeySettings.setText("Hotkeys ...").onActivate([&] { settingsWindow->show(1); });
|
||||
|
@ -113,6 +122,10 @@ Presentation::Presentation() {
|
|||
aboutWindow->setCentered(*this).setVisible().setFocused();
|
||||
});
|
||||
|
||||
image icon{Resource::Icon};
|
||||
icon.alphaBlend(0xff000000);
|
||||
canvas.setIcon(icon).setVisible(false);
|
||||
|
||||
viewport.setDroppable().onDrop([&](auto locations) {
|
||||
program->gameQueue = locations;
|
||||
program->load();
|
||||
|
@ -139,6 +152,14 @@ Presentation::Presentation() {
|
|||
Application::Windows::onModalChange([](bool modal) {
|
||||
if(modal && audio) audio->clear();
|
||||
});
|
||||
Application::Windows::onScreenSaver([]() -> bool {
|
||||
if(emulator->loaded()) {
|
||||
if(pauseEmulation.checked()) return true;
|
||||
if(!program->focused() && settingsWindow->input.pauseEmulation.checked()) return true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_MACOS)
|
||||
|
@ -149,8 +170,24 @@ Presentation::Presentation() {
|
|||
#endif
|
||||
}
|
||||
|
||||
auto Presentation::showIcon() -> void {
|
||||
Application::processEvents();
|
||||
int width = geometry().width();
|
||||
int height = geometry().height();
|
||||
int x = width - 144;
|
||||
int y = height - 128;
|
||||
if(x >= 0 && y >= 0) {
|
||||
canvas.setVisible(true).setGeometry({x, y, 128, 128});
|
||||
} else {
|
||||
canvas.setVisible(false);
|
||||
}
|
||||
viewport.setGeometry({0, 0, 1, 1});
|
||||
}
|
||||
|
||||
auto Presentation::clearViewport() -> void {
|
||||
if(!emulator->loaded()) showIcon();
|
||||
if(!video) return;
|
||||
|
||||
uint32_t* output;
|
||||
uint length;
|
||||
uint width = viewport.geometry().width();
|
||||
|
@ -166,6 +203,8 @@ auto Presentation::clearViewport() -> void {
|
|||
}
|
||||
|
||||
auto Presentation::resizeViewport() -> void {
|
||||
if(emulator->loaded()) canvas.setVisible(false);
|
||||
|
||||
uint windowWidth = geometry().width();
|
||||
uint windowHeight = geometry().height();
|
||||
|
||||
|
@ -235,19 +274,19 @@ auto Presentation::updateRecentGames() -> void {
|
|||
MenuItem item;
|
||||
if(auto game = settings[string{"Game/Recent/", 1 + index}].text()) {
|
||||
string displayName;
|
||||
for(auto part : game.split(":")) {
|
||||
auto games = game.split("|");
|
||||
for(auto& part : games) {
|
||||
displayName.append(Location::prefix(part), " + ");
|
||||
}
|
||||
displayName.trimRight(" + ", 1L);
|
||||
item.setText(displayName).onActivate([=] {
|
||||
program->gameQueue = game.split(":");
|
||||
program->gameQueue = games;
|
||||
program->load();
|
||||
});
|
||||
} else {
|
||||
item.setText("<empty>").setEnabled(false);
|
||||
}
|
||||
loadRecentGame.append(item);
|
||||
if(item.text() == "<empty>") item.setEnabled(false); //todo: temporary hack; fix hiro/GTK!!
|
||||
}
|
||||
loadRecentGame.append(MenuSeparator());
|
||||
loadRecentGame.append(MenuItem().setText("Clear List").onActivate([&] {
|
||||
|
@ -267,12 +306,21 @@ auto Presentation::addRecentGame(string location) -> void {
|
|||
auto game4 = settings["Game/Recent/4"].text();
|
||||
auto game5 = settings["Game/Recent/5"].text();
|
||||
|
||||
if(game1 == location);
|
||||
else if(game2 == location) swap(game1, game2);
|
||||
else if(game3 == location) swap(game1, game3);
|
||||
else if(game4 == location) swap(game1, game4);
|
||||
else if(game5 == location) swap(game1, game5);
|
||||
else {
|
||||
if(game1 == location) {
|
||||
game1 = location;
|
||||
} else if(game2 == location) {
|
||||
game2 = game1;
|
||||
game1 = location;
|
||||
} else if(game3 == location) {
|
||||
game3 = game2;
|
||||
game2 = game1;
|
||||
game1 = location;
|
||||
} else if(game4 == location) {
|
||||
game4 = game3;
|
||||
game3 = game2;
|
||||
game2 = game1;
|
||||
game1 = location;
|
||||
} else {
|
||||
game5 = game4;
|
||||
game4 = game3;
|
||||
game3 = game2;
|
||||
|
|
|
@ -10,6 +10,7 @@ struct AboutWindow : Window {
|
|||
|
||||
struct Presentation : Window {
|
||||
Presentation();
|
||||
auto showIcon() -> void;
|
||||
auto clearViewport() -> void;
|
||||
auto resizeViewport() -> void;
|
||||
auto resizeWindow() -> void;
|
||||
|
@ -39,6 +40,8 @@ struct Presentation : Window {
|
|||
MenuCheckItem aspectCorrection{&viewMenu};
|
||||
MenuCheckItem overscanCropping{&viewMenu};
|
||||
MenuCheckItem integralScaling{&viewMenu};
|
||||
MenuCheckItem blurEmulation{&viewMenu};
|
||||
MenuCheckItem colorEmulation{&viewMenu};
|
||||
Menu shaderMenu{&settingsMenu};
|
||||
MenuCheckItem muteAudio{&settingsMenu};
|
||||
MenuCheckItem showStatusBar{&settingsMenu};
|
||||
|
@ -64,6 +67,7 @@ struct Presentation : Window {
|
|||
MenuItem about{&helpMenu};
|
||||
|
||||
FixedLayout layout{this};
|
||||
Canvas canvas{&layout, Geometry{0, 0, 1, 1}};
|
||||
Viewport viewport{&layout, Geometry{0, 0, 1, 1}};
|
||||
|
||||
StatusBar statusBar{this};
|
||||
|
|
|
@ -14,9 +14,10 @@ auto Program::load() -> void {
|
|||
presentation->unloadGame.setEnabled(true);
|
||||
presentation->saveState.setEnabled(true);
|
||||
presentation->loadState.setEnabled(true);
|
||||
presentation->resizeViewport();
|
||||
|
||||
string locations = superNintendo.location;
|
||||
if(auto location = gameBoy.location) locations.append(":", location);
|
||||
if(auto location = gameBoy.location) locations.append("|", location);
|
||||
presentation->addRecentGame(locations);
|
||||
}
|
||||
|
||||
|
|
|
@ -119,38 +119,31 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) ->
|
|||
}
|
||||
|
||||
if(id == 1 && name == "save.ram") {
|
||||
string location = {Location::notsuffix(superNintendo.location), ".srm"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", superNintendo.location, ".srm"), mode);
|
||||
}
|
||||
|
||||
if(id == 1 && name == "download.ram") {
|
||||
string location = {Location::notsuffix(superNintendo.location), ".psr"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", superNintendo.location, ".psr"), mode);
|
||||
}
|
||||
|
||||
if(id == 1 && name == "time.rtc") {
|
||||
string location = {Location::notsuffix(superNintendo.location), ".rtc"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", superNintendo.location, ".rtc"), mode);
|
||||
}
|
||||
|
||||
if(id == 1 && name == "arm6.data.ram") {
|
||||
string location = {Location::notsuffix(superNintendo.location), ".srm"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", superNintendo.location, ".srm"), mode);
|
||||
}
|
||||
|
||||
if(id == 1 && name == "hg51bs169.data.ram") {
|
||||
string location = {Location::notsuffix(superNintendo.location), ".srm"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", superNintendo.location, ".srm"), mode);
|
||||
}
|
||||
|
||||
if(id == 1 && name == "upd7725.data.ram") {
|
||||
string location = {Location::notsuffix(superNintendo.location), ".srm"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", superNintendo.location, ".srm"), mode);
|
||||
}
|
||||
|
||||
if(id == 1 && name == "upd96050.data.ram") {
|
||||
string location = {Location::notsuffix(superNintendo.location), ".srm"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", superNintendo.location, ".srm"), mode);
|
||||
}
|
||||
|
||||
//Game Boy
|
||||
|
@ -164,13 +157,11 @@ auto Program::open(uint id, string name, vfs::file::mode mode, bool required) ->
|
|||
}
|
||||
|
||||
if(id == 2 && name == "save.ram") {
|
||||
string location = {Location::path(gameBoy.location), Location::prefix(gameBoy.location), ".sav"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", gameBoy.location, ".sav"), mode);
|
||||
}
|
||||
|
||||
if(id == 2 && name == "time.rtc") {
|
||||
string location = {Location::path(gameBoy.location), Location::prefix(gameBoy.location), ".rtc"};
|
||||
return vfs::fs::file::open(location, mode);
|
||||
return vfs::fs::file::open(path("Saves", gameBoy.location, ".sav"), mode);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -183,7 +174,7 @@ auto Program::load(uint id, string name, string type, string_vector options) ->
|
|||
} else {
|
||||
BrowserDialog dialog;
|
||||
dialog.setTitle("Load Super Nintendo");
|
||||
dialog.setPath(settings["Path/Recent/SuperNintendo"].text());
|
||||
dialog.setPath(path("Games", settings["Path/Recent/SuperNintendo"].text()));
|
||||
dialog.setFilters({string{"Super Nintendo Games|*.sfc:*.smc:*.zip"}});
|
||||
superNintendo.location = dialog.openFile();
|
||||
}
|
||||
|
@ -200,7 +191,7 @@ auto Program::load(uint id, string name, string type, string_vector options) ->
|
|||
} else {
|
||||
BrowserDialog dialog;
|
||||
dialog.setTitle("Load Game Boy");
|
||||
dialog.setPath(settings["Path/Recent/GameBoy"].text());
|
||||
dialog.setPath(path("Games", settings["Path/Recent/GameBoy"].text()));
|
||||
dialog.setFilters({string{"Game Boy Games|*.gb:*.gbc:*.zip"}});
|
||||
gameBoy.location = dialog.openFile();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
auto Program::path(string type, string location, string extension) -> string {
|
||||
auto pathname = Location::path(location);
|
||||
auto filename = Location::file(location);
|
||||
auto prefix = Location::prefix(filename);
|
||||
auto suffix = Location::suffix(filename);
|
||||
|
||||
if(type == "Games") {
|
||||
if(auto path = settings["Path/Games"].text()) {
|
||||
pathname = path;
|
||||
}
|
||||
}
|
||||
|
||||
if(type == "Patches") {
|
||||
if(auto path = settings["Path/Patches"].text()) {
|
||||
pathname = path;
|
||||
}
|
||||
}
|
||||
|
||||
if(type == "Saves") {
|
||||
if(auto path = settings["Path/Saves"].text()) {
|
||||
pathname = path;
|
||||
}
|
||||
}
|
||||
|
||||
if(type == "States") {
|
||||
if(auto path = settings["Path/States"].text()) {
|
||||
pathname = path;
|
||||
}
|
||||
}
|
||||
|
||||
if(type == "Cheats") {
|
||||
if(auto path = settings["Path/Cheats"].text()) {
|
||||
pathname = path;
|
||||
}
|
||||
}
|
||||
|
||||
if(extension) {
|
||||
suffix = extension;
|
||||
}
|
||||
|
||||
return {pathname, prefix, suffix};
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#include "../bsnes.hpp"
|
||||
#include "interface.cpp"
|
||||
#include "game.cpp"
|
||||
#include "paths.cpp"
|
||||
#include "state.cpp"
|
||||
#include "utility.cpp"
|
||||
unique_pointer<Program> program;
|
||||
|
|
|
@ -20,6 +20,9 @@ struct Program : Emulator::Platform {
|
|||
auto save() -> void;
|
||||
auto unload() -> void;
|
||||
|
||||
//paths.cpp
|
||||
auto path(string type, string location, string extension = "") -> string;
|
||||
|
||||
//state.cpp
|
||||
auto loadState(uint slot) -> bool;
|
||||
auto saveState(uint slot) -> bool;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
auto Program::loadState(uint slot) -> bool {
|
||||
if(!emulator->loaded()) return false;
|
||||
string location = {Location::notsuffix(superNintendo.location), ".bs", slot};
|
||||
auto location = path("States", superNintendo.location, {".bs", slot});
|
||||
if(!file::exists(location)) return showMessage({"Slot ", slot, " state does not exist"}), false;
|
||||
auto memory = file::read(location);
|
||||
serializer s{memory.data(), memory.size()};
|
||||
|
@ -10,7 +10,7 @@ auto Program::loadState(uint slot) -> bool {
|
|||
|
||||
auto Program::saveState(uint slot) -> bool {
|
||||
if(!emulator->loaded()) return false;
|
||||
string location = {Location::notsuffix(superNintendo.location), ".bs", slot};
|
||||
auto location = path("States", superNintendo.location, {".bs", slot});
|
||||
serializer s = emulator->serialize();
|
||||
if(!s.size()) return showMessage({"Failed to save state to slot ", slot}), false;
|
||||
if(!file::write(location, s.data(), s.size())) return showMessage({"Unable to write state to slot ", slot}), false;
|
||||
|
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 954 B After Width: | Height: | Size: 954 B |
After Width: | Height: | Size: 3.4 KiB |
|
@ -1,5 +1,6 @@
|
|||
namespace name=Resource
|
||||
binary name=Logo file="logo.png"
|
||||
binary name=Icon file=icon.png
|
||||
binary name=Logo file=logo.png
|
||||
namespace name=System
|
||||
binary name=Manifest file="../../systems/Super Famicom.sys/manifest.bml"
|
||||
binary name=Boards file="../../systems/Super Famicom.sys/boards.bml"
|
||||
|
|
|
@ -2,6 +2,117 @@
|
|||
#include "resource.hpp"
|
||||
|
||||
namespace Resource {
|
||||
const nall::vector<uint8_t> Icon = { //size: 3463
|
||||
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,128,0,0,0,128,8,6,0,0,0,195,62,97,
|
||||
203,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
|
||||
132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0,
|
||||
9,112,72,89,115,0,0,0,90,0,0,0,90,0,112,35,184,125,0,0,0,6,98,75,71,68,0,0,0,0,0,0,
|
||||
249,67,187,127,0,0,12,67,73,68,65,84,120,218,237,157,9,144,84,213,21,134,223,44,56,12,204,2,204,244,52,8,
|
||||
34,171,36,65,217,75,16,152,133,145,17,45,64,194,162,144,136,90,98,130,82,166,64,4,37,130,5,21,41,147,88,24,
|
||||
49,36,26,16,144,97,16,17,130,134,45,154,40,132,93,9,48,3,72,72,81,26,22,17,18,246,77,96,96,182,151,255,
|
||||
188,62,221,211,52,211,51,189,188,215,253,222,235,115,170,190,26,138,101,166,125,255,127,207,61,247,222,243,174,138,34,33,
|
||||
33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,33,
|
||||
97,246,104,242,158,170,52,89,168,42,142,66,53,62,107,177,154,144,85,164,38,58,241,213,89,164,198,53,165,63,91,166,
|
||||
202,67,178,75,56,22,67,204,71,84,5,66,39,131,246,96,32,152,8,102,131,34,176,18,124,12,62,4,243,192,12,240,
|
||||
56,232,9,50,97,12,50,137,60,72,43,69,179,34,77,112,226,54,208,5,76,6,159,130,99,224,58,80,235,160,18,92,
|
||||
0,123,192,159,192,143,129,35,3,223,215,81,36,102,48,239,104,127,223,35,124,125,80,0,150,130,147,160,42,0,209,107,
|
||||
131,76,179,11,76,2,119,100,174,129,17,150,136,17,76,21,36,188,195,149,174,187,179,240,151,194,20,221,95,102,248,10,
|
||||
60,3,210,179,10,85,197,41,70,136,110,164,46,244,140,250,52,30,161,223,25,32,188,47,55,192,106,208,45,107,129,235,
|
||||
231,75,68,169,192,99,241,91,241,168,47,139,128,248,222,28,2,163,240,57,18,197,4,209,19,191,19,216,18,97,225,189,
|
||||
185,160,173,42,10,81,112,22,138,9,34,51,223,87,87,249,93,184,56,83,163,204,21,240,75,94,117,136,64,70,70,163,
|
||||
234,57,191,29,216,110,2,241,189,77,240,139,44,217,55,48,190,218,7,141,121,3,71,53,25,103,192,195,52,61,53,21,
|
||||
19,24,147,250,29,69,218,8,155,14,42,76,104,0,98,31,184,75,178,128,206,225,172,46,250,242,192,41,147,138,239,102,
|
||||
62,72,18,19,232,159,250,83,193,90,147,139,175,242,38,212,32,237,51,47,18,19,232,89,245,143,4,165,22,48,128,202,
|
||||
103,15,105,146,5,244,27,253,41,224,111,22,17,159,184,10,134,208,103,207,144,44,160,139,1,238,7,151,45,100,0,98,
|
||||
153,236,13,132,43,126,33,196,95,161,25,96,182,197,196,39,142,131,31,137,1,194,31,253,153,160,196,130,6,160,99,232,
|
||||
177,244,223,224,148,109,226,176,12,208,199,160,227,221,72,80,36,187,131,33,198,237,11,60,213,255,56,139,138,175,114,230,
|
||||
202,16,3,132,58,250,93,75,192,57,22,54,0,117,36,117,20,3,132,178,251,7,241,65,61,60,188,85,22,54,192,53,
|
||||
94,193,136,160,97,172,255,183,90,216,0,21,188,129,37,130,134,104,128,70,96,3,56,15,46,242,78,96,165,197,86,2,
|
||||
63,19,3,132,186,5,92,164,181,91,117,0,93,185,87,255,1,240,36,152,201,83,195,55,1,182,122,71,147,103,245,54,
|
||||
128,218,173,219,45,196,76,100,98,77,221,121,149,167,239,191,37,24,204,47,117,28,49,97,118,160,12,240,116,168,6,80,
|
||||
115,115,21,53,39,39,1,95,29,224,94,48,10,76,1,179,192,59,96,46,152,3,102,130,113,96,0,104,7,26,168,189,
|
||||
123,211,191,141,153,76,145,192,111,254,76,5,7,117,120,23,64,207,26,96,68,48,6,32,209,64,28,68,108,14,126,10,
|
||||
222,3,251,192,5,80,1,84,63,84,129,82,240,29,248,28,76,7,189,64,178,154,151,103,127,51,56,93,59,110,113,120,
|
||||
216,109,193,44,112,214,36,173,98,185,129,24,64,27,237,121,121,36,252,15,192,171,224,95,160,172,22,193,3,225,28,88,
|
||||
5,134,131,84,205,8,217,217,246,54,130,195,213,57,148,200,245,194,151,81,54,192,9,174,97,252,11,207,163,19,2,57,
|
||||
193,52,112,152,71,179,170,35,215,192,58,144,15,18,201,108,246,63,68,114,109,34,221,9,150,128,242,40,25,96,7,175,
|
||||
100,106,155,227,227,241,181,63,216,10,42,117,22,190,166,140,240,27,144,165,253,236,126,253,98,98,41,153,14,222,228,55,
|
||||
122,34,109,128,185,14,63,111,15,177,248,201,248,58,1,156,50,88,120,111,200,100,127,7,157,200,0,182,159,18,52,19,
|
||||
20,170,13,185,46,136,228,219,67,148,117,30,163,159,159,228,211,20,162,137,79,115,178,171,154,47,141,160,248,222,236,7,
|
||||
185,252,89,98,34,19,80,79,225,187,17,92,33,208,171,99,109,124,71,63,63,240,20,48,91,135,34,47,92,190,214,76,
|
||||
64,117,72,140,152,160,25,248,60,82,233,223,247,40,152,197,191,141,215,237,209,22,223,59,19,116,181,125,38,200,172,110,
|
||||
45,239,197,151,69,24,253,206,96,222,77,226,243,18,12,15,249,41,112,197,36,226,187,89,15,154,197,68,22,104,50,95,
|
||||
51,193,100,131,95,46,249,192,185,88,77,114,178,1,88,120,162,59,47,243,84,147,65,203,206,223,129,122,177,50,21,56,
|
||||
12,60,101,60,197,93,76,138,99,161,234,59,239,175,52,161,248,110,46,130,129,182,159,10,188,222,51,24,109,192,210,144,
|
||||
10,204,215,232,6,50,199,226,155,196,87,120,91,183,212,196,6,32,54,128,38,177,146,5,50,12,120,195,120,35,23,154,
|
||||
190,133,31,61,212,205,38,23,159,184,1,158,176,125,22,160,110,35,190,100,98,146,206,203,190,94,238,86,54,159,185,127,
|
||||
36,184,110,1,3,184,11,194,212,88,201,2,247,128,255,233,52,239,15,211,182,160,111,29,253,73,224,207,22,17,159,184,
|
||||
12,238,15,207,0,37,96,23,40,86,226,65,10,104,1,186,128,2,48,18,140,3,147,193,203,224,21,48,21,188,4,198,
|
||||
131,39,192,32,208,11,180,5,141,65,162,114,0,223,111,175,238,199,200,201,252,30,95,56,226,159,166,122,2,203,204,56,
|
||||
71,205,155,62,29,193,9,11,25,64,213,118,40,251,247,15,242,137,238,246,8,238,4,185,96,2,88,4,54,131,255,128,
|
||||
179,160,20,84,2,181,22,232,207,203,192,69,112,12,236,6,31,129,95,129,33,160,61,72,210,76,86,28,222,52,192,35,
|
||||
118,70,24,226,83,19,202,8,136,31,127,139,248,125,251,186,13,240,180,1,167,123,70,179,3,100,214,253,20,139,53,226,
|
||||
64,115,240,40,152,15,246,131,239,65,85,29,66,135,194,13,54,197,26,54,88,39,205,12,197,161,153,129,167,129,33,33,
|
||||
156,17,84,113,1,217,167,241,59,46,35,213,120,216,147,155,75,231,251,243,45,38,62,113,6,244,174,75,248,122,160,7,
|
||||
152,5,14,240,168,85,35,8,25,236,36,88,1,134,129,116,45,43,236,14,218,0,157,249,122,151,96,118,249,126,79,183,
|
||||
134,146,240,254,174,143,101,3,164,129,47,44,104,128,114,240,108,205,194,151,104,105,158,230,243,121,224,84,132,69,247,7,
|
||||
77,45,27,192,112,208,128,63,103,160,6,104,14,190,14,240,149,239,191,130,1,160,94,93,93,62,108,128,86,224,168,5,
|
||||
13,64,188,229,59,191,43,92,144,77,225,52,172,154,144,171,224,3,112,143,242,239,186,167,5,175,75,167,118,213,146,234,
|
||||
169,200,91,193,83,69,170,86,60,46,10,176,197,203,181,245,123,206,162,6,248,75,117,69,239,18,191,29,23,99,229,38,
|
||||
21,223,155,131,96,40,23,165,117,25,32,197,235,178,73,234,42,254,158,215,244,235,192,139,218,149,176,69,174,59,127,110,
|
||||
127,63,136,230,78,151,1,242,185,29,203,138,6,216,162,120,138,171,98,229,110,176,221,2,194,123,115,6,60,197,83,86,
|
||||
109,6,160,246,242,49,124,217,35,253,191,2,178,185,221,60,169,225,50,85,113,134,211,210,237,106,240,124,19,188,13,10,
|
||||
185,47,175,4,156,52,209,113,176,63,118,187,197,111,206,243,171,106,65,78,131,193,218,20,86,18,157,13,39,173,225,211,
|
||||
213,112,17,135,95,83,47,64,6,239,13,60,66,243,44,216,99,210,51,130,93,244,208,18,241,0,223,176,168,248,110,74,
|
||||
64,171,112,246,12,12,49,70,245,50,145,26,52,135,241,110,225,69,19,25,96,35,141,254,222,224,191,22,55,128,170,237,
|
||||
52,6,185,68,140,152,17,184,29,11,212,7,5,96,181,73,206,13,150,147,1,94,183,129,248,42,215,47,233,102,203,2,
|
||||
53,100,4,119,179,232,88,112,40,202,6,248,45,25,96,189,77,12,64,89,172,131,153,13,112,83,70,40,40,32,35,116,
|
||||
3,159,69,105,27,153,50,208,227,100,128,93,54,49,192,89,222,188,178,68,120,101,131,102,188,122,168,136,176,1,232,240,
|
||||
170,43,25,96,173,77,12,112,20,180,177,138,1,124,140,208,24,204,139,176,9,180,158,0,50,192,139,160,194,6,6,248,
|
||||
4,36,91,205,0,62,29,69,75,35,104,128,87,92,253,0,197,202,93,124,208,99,101,241,203,180,13,161,98,115,174,2,
|
||||
130,48,65,75,218,157,139,128,248,167,65,15,151,1,92,77,29,207,241,49,172,85,13,64,211,88,35,43,142,254,155,54,
|
||||
147,92,38,200,6,199,13,54,192,135,220,197,228,217,6,78,225,147,191,74,11,138,255,21,232,28,106,191,128,233,178,0,
|
||||
221,250,225,186,33,196,168,122,224,18,120,240,230,166,80,215,195,203,0,11,44,114,16,228,102,15,184,79,75,251,123,236,
|
||||
209,199,200,194,56,248,85,114,35,12,176,132,55,164,106,108,0,73,3,211,121,73,101,102,225,201,164,171,65,71,59,140,
|
||||
124,63,203,195,199,12,216,45,252,150,143,175,181,118,54,127,93,64,9,96,0,216,24,133,14,160,64,56,2,38,113,223,
|
||||
130,173,196,175,97,85,176,77,231,247,1,198,215,253,62,192,14,78,167,174,41,97,44,216,6,174,71,89,116,170,77,14,
|
||||
113,107,90,71,165,68,137,139,214,201,95,132,179,192,243,58,26,96,33,104,24,120,43,120,177,103,133,208,4,140,224,46,
|
||||
156,227,17,46,20,47,131,77,224,5,173,83,152,206,253,117,22,94,85,53,226,64,3,224,4,237,65,15,208,15,12,4,
|
||||
67,193,163,204,80,254,189,60,208,157,255,174,147,255,45,125,15,189,77,160,87,187,249,167,124,35,89,8,159,100,167,167,
|
||||
99,136,26,68,127,8,198,128,37,92,125,95,210,185,51,248,58,239,232,209,166,206,52,144,173,29,240,108,215,231,172,159,
|
||||
197,38,146,65,91,240,16,152,8,230,131,127,128,3,224,4,56,15,174,130,50,80,14,42,152,114,254,61,250,179,115,252,
|
||||
119,233,223,108,0,243,192,4,240,0,104,13,234,187,127,94,24,6,160,98,109,173,14,59,126,109,245,121,21,108,167,103,
|
||||
122,160,58,33,11,244,225,13,24,234,39,88,5,254,201,169,250,36,247,252,95,101,81,203,120,159,225,26,143,234,51,220,
|
||||
115,184,23,124,198,173,230,19,193,67,188,157,91,95,217,167,187,232,233,160,47,152,6,62,1,223,130,235,64,213,153,82,
|
||||
112,4,172,3,83,192,125,32,173,170,42,56,51,120,77,3,211,194,184,39,136,142,157,219,24,251,30,224,30,143,41,234,
|
||||
241,102,76,11,206,20,61,65,30,191,41,244,32,23,150,249,108,26,234,245,111,13,50,53,177,75,180,247,14,140,72,237,
|
||||
9,160,3,120,9,108,5,151,12,16,188,46,46,128,77,224,5,208,14,196,7,106,4,22,110,80,8,171,129,43,220,137,
|
||||
228,208,190,71,126,190,18,51,193,194,211,67,238,4,102,131,163,160,42,10,194,251,82,9,14,129,89,160,99,32,53,3,
|
||||
27,224,238,32,110,24,171,226,235,96,70,171,57,57,73,182,127,249,211,79,170,167,162,108,58,56,102,2,209,253,65,83,
|
||||
196,203,192,81,91,157,224,117,92,124,48,0,225,143,81,131,7,104,173,245,26,196,194,29,194,53,84,242,125,57,221,86,
|
||||
154,88,124,55,84,84,174,7,61,253,153,128,13,208,8,236,172,165,169,99,31,95,72,69,43,134,248,152,26,245,62,41,
|
||||
127,148,201,71,189,63,14,131,225,53,77,9,94,215,206,108,246,154,219,233,162,232,77,224,13,240,48,104,170,221,63,156,
|
||||
151,167,196,92,120,165,253,145,224,180,5,197,119,115,18,12,243,205,4,108,128,68,190,215,135,46,160,200,225,171,226,83,
|
||||
212,236,236,184,152,74,243,181,136,127,47,207,169,170,197,249,6,116,13,103,239,32,22,13,208,16,124,100,3,241,221,44,
|
||||
227,77,42,137,0,13,208,31,92,182,145,1,104,207,32,71,12,16,120,250,127,205,70,226,187,153,33,211,64,224,187,124,
|
||||
43,109,104,128,165,193,236,22,198,178,1,18,193,26,27,26,96,37,155,91,34,128,41,96,174,13,13,48,71,166,128,192,
|
||||
13,240,36,239,168,217,69,124,58,106,254,137,24,32,112,19,180,0,123,109,100,128,221,160,153,136,31,92,22,24,3,174,
|
||||
217,64,252,43,96,180,140,254,224,77,64,27,39,111,89,124,42,168,224,99,226,36,17,63,52,19,52,230,150,172,114,139,
|
||||
206,251,127,224,142,37,137,48,76,144,198,155,40,231,45,36,62,245,21,78,5,41,34,190,126,123,3,131,193,151,38,159,
|
||||
18,232,179,109,227,166,212,68,17,95,255,194,176,41,152,204,29,187,149,38,19,126,63,120,30,100,73,193,103,172,17,168,
|
||||
193,162,37,183,106,111,137,242,161,17,53,163,110,4,207,129,59,68,248,200,103,4,170,15,242,193,235,224,11,62,117,51,
|
||||
178,81,180,146,107,17,74,243,191,230,23,73,82,69,120,115,100,133,70,220,135,247,12,88,0,54,115,67,201,229,16,235,
|
||||
134,114,30,225,135,185,31,241,93,240,115,110,84,73,23,209,205,157,25,226,185,2,167,55,121,250,128,17,60,101,204,4,
|
||||
111,131,37,96,57,248,152,89,206,191,247,71,240,42,24,207,253,124,189,193,157,220,160,18,39,130,219,203,32,9,92,169,
|
||||
39,242,175,227,101,84,75,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,72,
|
||||
72,72,72,72,72,72,72,152,54,254,15,126,72,246,126,174,120,107,6,0,0,0,37,116,69,88,116,100,97,116,101,58,
|
||||
99,114,101,97,116,101,0,50,48,49,56,45,48,53,45,49,55,84,49,48,58,51,53,58,49,48,45,48,52,58,48,48,
|
||||
240,186,255,164,0,0,0,37,116,69,88,116,100,97,116,101,58,109,111,100,105,102,121,0,50,48,49,56,45,48,53,45,
|
||||
49,55,84,49,48,58,51,53,58,49,48,45,48,52,58,48,48,129,231,71,24,0,0,0,58,116,69,88,116,115,118,103,
|
||||
58,98,97,115,101,45,117,114,105,0,102,105,108,101,58,47,47,47,99,111,114,101,47,102,105,108,101,115,47,109,101,100,
|
||||
105,97,47,98,115,110,101,115,47,105,99,111,110,47,98,115,110,101,115,46,115,118,103,188,87,222,120,0,0,0,0,73,
|
||||
69,78,68,174,66,96,130,
|
||||
};
|
||||
const nall::vector<uint8_t> Logo = { //size: 23165
|
||||
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,144,0,0,0,86,8,6,0,0,0,225,121,192,
|
||||
209,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
namespace Resource {
|
||||
extern const nall::vector<uint8_t> Icon;
|
||||
extern const nall::vector<uint8_t> Logo;
|
||||
namespace System {
|
||||
extern const nall::vector<uint8_t> Manifest;
|
||||
|
|
|
@ -34,6 +34,8 @@ Settings::Settings() {
|
|||
set("View/AspectCorrection", true);
|
||||
set("View/OverscanCropping", true);
|
||||
set("View/IntegralScaling", true);
|
||||
set("View/BlurEmulation", true);
|
||||
set("View/ColorEmulation", true);
|
||||
|
||||
set("Path/Games", "");
|
||||
set("Path/Patches", "");
|
||||
|
|
|
@ -11,7 +11,7 @@ include gba/GNUmakefile
|
|||
include ws/GNUmakefile
|
||||
include processor/GNUmakefile
|
||||
|
||||
ui_objects := ui-higan ui-program ui-configuration ui-input
|
||||
ui_objects := ui-higan ui-program ui-input
|
||||
ui_objects += ui-settings ui-tools ui-presentation ui-resource
|
||||
ui_objects += ruby hiro
|
||||
ui_objects += $(if $(call streq,$(platform),windows),ui-windows)
|
||||
|
@ -26,11 +26,11 @@ else ifeq ($(platform),macos)
|
|||
ruby += audio.openal
|
||||
ruby += input.quartz input.carbon
|
||||
else ifeq ($(platform),linux)
|
||||
ruby += video.glx video.xvideo video.xshm video.sdl
|
||||
ruby += video.glx video.xvideo video.xshm
|
||||
ruby += audio.oss audio.alsa audio.openal audio.pulseaudio audio.pulseaudiosimple audio.ao
|
||||
ruby += input.sdl input.xlib input.udev
|
||||
else ifeq ($(platform),bsd)
|
||||
ruby += video.glx video.xvideo video.xshm video.sdl
|
||||
ruby += video.glx video.xvideo video.xshm
|
||||
ruby += audio.oss audio.openal
|
||||
ruby += input.sdl input.xlib
|
||||
endif
|
||||
|
@ -45,7 +45,7 @@ link += $(hirolink)
|
|||
|
||||
# rules
|
||||
objects := $(ui_objects) $(objects)
|
||||
objects := $(patsubst %,obj/%.o,$(objects))
|
||||
objects := $(objects:%=obj/%.o)
|
||||
|
||||
obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/)
|
||||
$(compiler) $(rubyflags) -c $< -o $@
|
||||
|
@ -53,18 +53,16 @@ obj/ruby.o: ../ruby/ruby.cpp $(call rwildcard,../ruby/)
|
|||
obj/hiro.o: ../hiro/hiro.cpp $(call rwildcard,../hiro/)
|
||||
$(compiler) $(hiroflags) -c $< -o $@
|
||||
|
||||
obj/ui-higan.o: $(ui)/higan.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-program.o: $(ui)/program/program.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-configuration.o: $(ui)/configuration/configuration.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-input.o: $(ui)/input/input.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-library.o: $(ui)/library/library.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-settings.o: $(ui)/settings/settings.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-tools.o: $(ui)/tools/tools.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-presentation.o: $(ui)/presentation/presentation.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-resource.o: $(ui)/resource/resource.cpp $(call rwildcard,$(ui)/)
|
||||
obj/ui-higan.o: $(ui)/higan.cpp
|
||||
obj/ui-program.o: $(ui)/program/program.cpp
|
||||
obj/ui-input.o: $(ui)/input/input.cpp
|
||||
obj/ui-settings.o: $(ui)/settings/settings.cpp
|
||||
obj/ui-tools.o: $(ui)/tools/tools.cpp
|
||||
obj/ui-presentation.o: $(ui)/presentation/presentation.cpp
|
||||
obj/ui-resource.o: $(ui)/resource/resource.cpp
|
||||
|
||||
obj/ui-windows.o:
|
||||
$(windres) data/higan.rc obj/ui-resource.o
|
||||
$(windres) $(ui)/resource/higan.rc obj/ui-windows.o
|
||||
|
||||
# targets
|
||||
build: $(objects)
|
||||
|
@ -74,8 +72,8 @@ ifeq ($(platform),macos)
|
|||
mkdir -p out/$(name).app/Contents/MacOS/
|
||||
mkdir -p out/$(name).app/Contents/Resources/
|
||||
mv out/$(name) out/$(name).app/Contents/MacOS/$(name)
|
||||
cp data/$(name).plist out/$(name).app/Contents/Info.plist
|
||||
sips -s format icns data/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns
|
||||
cp $(ui)/resource/$(name).plist out/$(name).app/Contents/Info.plist
|
||||
sips -s format icns $(ui)/resource/$(name).png --out out/$(name).app/Contents/Resources/$(name).icns
|
||||
endif
|
||||
|
||||
install:
|
||||
|
@ -96,8 +94,8 @@ else ifneq ($(filter $(platform),linux bsd),)
|
|||
mkdir -p $(prefix)/share/$(name)/systems/
|
||||
cp out/$(name) $(prefix)/bin/$(name)
|
||||
cp -R systems/* $(prefix)/share/$(name)/systems/
|
||||
cp data/$(name).desktop $(prefix)/share/applications/$(name).desktop
|
||||
cp data/$(name).png $(prefix)/share/icons/$(name).png
|
||||
cp $(ui)/resource/$(name).desktop $(prefix)/share/applications/$(name).desktop
|
||||
cp $(ui)/resource/$(name).png $(prefix)/share/icons/$(name).png
|
||||
endif
|
||||
|
||||
uninstall:
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
#include "../higan.hpp"
|
||||
Settings settings;
|
||||
|
||||
Settings::Settings() {
|
||||
Markup::Node::operator=(BML::unserialize(string::read(locate("settings.bml"))));
|
||||
|
||||
auto set = [&](const string& name, const string& value) {
|
||||
//create node and set to default value only if it does not already exist
|
||||
if(!operator[](name)) operator()(name).setValue(value);
|
||||
};
|
||||
|
||||
set("UserInterface/ShowStatusBar", true);
|
||||
|
||||
set("Library/Location", {Path::user(), "Emulation/"});
|
||||
set("Library/IgnoreManifests", false);
|
||||
|
||||
set("Video/Driver", ruby::Video::safestDriver());
|
||||
set("Video/Synchronize", false);
|
||||
set("Video/Shader", "Blur");
|
||||
set("Video/BlurEmulation", true);
|
||||
set("Video/ColorEmulation", true);
|
||||
set("Video/ScanlineEmulation", false);
|
||||
|
||||
set("Video/Saturation", 100);
|
||||
set("Video/Gamma", 100);
|
||||
set("Video/Luminance", 100);
|
||||
|
||||
set("Video/Overscan/Horizontal", 0);
|
||||
set("Video/Overscan/Vertical", 0);
|
||||
|
||||
set("Video/Windowed/AspectCorrection", true);
|
||||
set("Video/Windowed/IntegralScaling", true);
|
||||
set("Video/Windowed/Adaptive", true);
|
||||
set("Video/Windowed/Scale", "Small");
|
||||
set("Video/Windowed/Scale/Small", "640x480");
|
||||
set("Video/Windowed/Scale/Medium", "960x720");
|
||||
set("Video/Windowed/Scale/Large", "1280x960");
|
||||
|
||||
set("Video/Fullscreen/AspectCorrection", true);
|
||||
set("Video/Fullscreen/IntegralScaling", true);
|
||||
set("Video/Fullscreen/Exclusive", false);
|
||||
|
||||
set("Audio/Driver", ruby::Audio::safestDriver());
|
||||
set("Audio/Device", "");
|
||||
set("Audio/Frequency", 48000);
|
||||
set("Audio/Latency", 0);
|
||||
set("Audio/Exclusive", false);
|
||||
set("Audio/Synchronize", true);
|
||||
set("Audio/Mute", false);
|
||||
set("Audio/Volume", 100);
|
||||
set("Audio/Balance", 50);
|
||||
set("Audio/Reverb/Enable", false);
|
||||
|
||||
set("Input/Driver", ruby::Input::safestDriver());
|
||||
set("Input/Frequency", 5);
|
||||
set("Input/FocusLoss/Pause", false);
|
||||
set("Input/FocusLoss/AllowInput", false);
|
||||
|
||||
set("Emulation/AutoSaveMemory/Enable", true);
|
||||
set("Emulation/AutoSaveMemory/Interval", 30);
|
||||
|
||||
set("Systems", "");
|
||||
|
||||
set("Crashed", false);
|
||||
}
|
||||
|
||||
auto Settings::save() -> void {
|
||||
file::write(locate("settings.bml"), BML::serialize(*this));
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
struct Settings : Markup::Node {
|
||||
Settings();
|
||||
auto save() -> void;
|
||||
};
|
||||
|
||||
extern Settings settings;
|
|
@ -12,7 +12,6 @@ extern unique_pointer<Input> input;
|
|||
extern Emulator::Interface* emulator;
|
||||
|
||||
#include "program/program.hpp"
|
||||
#include "configuration/configuration.hpp"
|
||||
#include "input/input.hpp"
|
||||
#include "settings/settings.hpp"
|
||||
#include "tools/tools.hpp"
|
||||
|
|
|
@ -104,7 +104,7 @@ auto InputManager::appendHotkeys() -> void {
|
|||
}
|
||||
|
||||
auto InputManager::pollHotkeys() -> void {
|
||||
if(!program->focused() && !settings["Input/FocusLoss/AllowInput"].boolean()) return;
|
||||
if(!program->focused()) return;
|
||||
|
||||
for(auto& hotkey : hotkeys) {
|
||||
int16 state = hotkey->poll();
|
||||
|
|
|
@ -119,6 +119,10 @@ Presentation::Presentation() {
|
|||
statusBar.setFont(Font().setBold());
|
||||
statusBar.setVisible(settings["UserInterface/ShowStatusBar"].boolean());
|
||||
|
||||
image icon{Resource::Icon};
|
||||
icon.alphaBlend(0xff000000);
|
||||
canvas.setIcon(icon).setVisible(false);
|
||||
|
||||
viewport.setDroppable().onDrop([&](auto locations) {
|
||||
if(!directory::exists(locations(0))) return;
|
||||
program->mediumQueue.append(locations(0));
|
||||
|
@ -139,7 +143,17 @@ Presentation::Presentation() {
|
|||
setCentered();
|
||||
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
Application::Windows::onModalChange([](bool modal) { if(modal && audio) audio->clear(); });
|
||||
Application::Windows::onModalChange([](bool modal) {
|
||||
if(modal && audio) audio->clear();
|
||||
});
|
||||
Application::Windows::onScreenSaver([]() -> bool {
|
||||
if(emulator && emulator->loaded()) {
|
||||
if(program->pause) return true;
|
||||
if(!program->focused() && settingsManager->input.pauseEmulation.checked()) return true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_MACOS)
|
||||
|
@ -191,7 +205,22 @@ auto Presentation::updateEmulator() -> void {
|
|||
emulator->set("Scanline Emulation", scanlineEmulation.checked());
|
||||
}
|
||||
|
||||
auto Presentation::showIcon() -> void {
|
||||
Application::processEvents();
|
||||
int width = geometry().width();
|
||||
int height = geometry().height();
|
||||
int x = width - 128;
|
||||
int y = height - 128;
|
||||
if(x >= 0 && y >= 0) {
|
||||
canvas.setVisible(true).setGeometry({x, y, 112, 112});
|
||||
} else {
|
||||
canvas.setVisible(false);
|
||||
}
|
||||
viewport.setGeometry({0, 0, 1, 1});
|
||||
}
|
||||
|
||||
auto Presentation::clearViewport() -> void {
|
||||
if(!emulator || !emulator->loaded()) showIcon();
|
||||
if(!video) return;
|
||||
|
||||
uint32_t* output;
|
||||
|
@ -200,8 +229,8 @@ auto Presentation::clearViewport() -> void {
|
|||
uint height = viewport.geometry().height();
|
||||
if(video->lock(output, length, width, height)) {
|
||||
for(uint y : range(height)) {
|
||||
auto dp = output + y * (length >> 2);
|
||||
for(uint x : range(width)) *dp++ = 0xff000000;
|
||||
auto line = output + y * (length >> 2);
|
||||
for(uint x : range(width)) *line++ = 0xff000000;
|
||||
}
|
||||
|
||||
video->unlock();
|
||||
|
@ -210,6 +239,8 @@ auto Presentation::clearViewport() -> void {
|
|||
}
|
||||
|
||||
auto Presentation::resizeViewport(bool resizeWindow) -> void {
|
||||
if(emulator && emulator->loaded()) canvas.setVisible(false);
|
||||
|
||||
//clear video area before resizing to avoid seeing distorted video momentarily
|
||||
clearViewport();
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ struct AboutWindow : Window {
|
|||
struct Presentation : Window {
|
||||
Presentation();
|
||||
auto updateEmulator() -> void;
|
||||
auto showIcon() -> void;
|
||||
auto clearViewport() -> void;
|
||||
auto resizeViewport(bool resizeWindow = true) -> void;
|
||||
auto toggleFullScreen() -> void;
|
||||
|
@ -78,6 +79,7 @@ struct Presentation : Window {
|
|||
MenuItem about{&helpMenu};
|
||||
|
||||
FixedLayout layout{this};
|
||||
Canvas canvas{&layout, Geometry{0, 0, 1, 1}};
|
||||
Viewport viewport{&layout, Geometry{0, 0, 1, 1}};
|
||||
|
||||
StatusBar statusBar{this};
|
||||
|
|
|
@ -95,7 +95,7 @@ auto Program::audioSample(const double* samples, uint channels) -> void {
|
|||
}
|
||||
|
||||
auto Program::inputPoll(uint port, uint device, uint input) -> int16 {
|
||||
if(focused() || settings["Input/FocusLoss/AllowInput"].boolean()) {
|
||||
if(focused() || settingsManager->input.allowInput.checked()) {
|
||||
inputManager->poll();
|
||||
if(auto mapping = inputManager->mapping(port, device, input)) {
|
||||
return mapping->poll();
|
||||
|
@ -105,7 +105,7 @@ auto Program::inputPoll(uint port, uint device, uint input) -> int16 {
|
|||
}
|
||||
|
||||
auto Program::inputRumble(uint port, uint device, uint input, bool enable) -> void {
|
||||
if(focused() || settings["Input/FocusLoss/AllowInput"].boolean() || !enable) {
|
||||
if(focused() || settingsManager->input.allowInput.checked() || !enable) {
|
||||
if(auto mapping = inputManager->mapping(port, device, input)) {
|
||||
return mapping->rumble(enable);
|
||||
}
|
||||
|
|
|
@ -85,7 +85,11 @@ auto Program::main() -> void {
|
|||
inputManager->poll();
|
||||
inputManager->pollHotkeys();
|
||||
|
||||
if(!emulator || !emulator->loaded() || pause || (!focused() && settings["Input/FocusLoss/Pause"].boolean())) {
|
||||
if(!emulator
|
||||
|| !emulator->loaded()
|
||||
|| pause
|
||||
|| (!focused() && settingsManager->input.pauseEmulation.checked())
|
||||
) {
|
||||
audio->clear();
|
||||
usleep(20 * 1000);
|
||||
return;
|
||||
|
|
|
@ -120,8 +120,8 @@ auto Program::updateStatusText() -> void {
|
|||
if((currentTime - statusTime) <= 2) {
|
||||
text = statusMessage;
|
||||
} else if(!emulator || emulator->loaded() == false) {
|
||||
text = "No cartridge loaded";
|
||||
} else if(pause || (!presentation->focused() && settings["Input/FocusLoss/Pause"].boolean())) {
|
||||
text = "No game loaded";
|
||||
} else if(pause || (!focused() && settingsManager->input.pauseEmulation.checked())) {
|
||||
text = "Paused";
|
||||
} else {
|
||||
text = statusText;
|
||||
|
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 3.0 KiB |
|
@ -1,2 +1,3 @@
|
|||
namespace name=Resource
|
||||
binary name=Icon file=icon.png
|
||||
binary name=Logo file=logo.png
|
||||
|
|
|
@ -2,6 +2,105 @@
|
|||
#include "resource.hpp"
|
||||
|
||||
namespace Resource {
|
||||
const nall::vector<uint8_t> Icon = { //size: 3088
|
||||
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,0,112,0,0,0,112,8,6,0,0,0,198,224,244,
|
||||
75,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
|
||||
132,0,0,250,0,0,0,128,232,0,0,117,48,0,0,234,96,0,0,58,152,0,0,23,112,156,186,81,60,0,0,0,
|
||||
9,112,72,89,115,0,0,0,90,0,0,0,90,0,112,35,184,125,0,0,0,6,98,75,71,68,0,0,0,0,0,0,
|
||||
249,67,187,127,0,0,10,195,73,68,65,84,120,218,237,93,9,144,84,213,21,5,201,36,200,152,81,116,152,97,70,4,
|
||||
151,138,154,42,17,81,199,141,12,150,22,184,27,68,145,224,46,110,8,106,161,40,106,84,18,141,152,224,146,136,82,70,
|
||||
75,147,148,198,4,203,221,24,81,179,184,175,41,165,10,119,81,161,167,21,20,80,80,145,153,97,16,102,114,111,247,249,
|
||||
244,99,104,186,239,125,255,119,247,159,158,123,171,78,81,5,244,239,215,239,252,247,222,221,95,143,30,38,38,38,38,38,
|
||||
38,38,38,38,38,38,38,38,38,38,38,38,38,27,73,83,255,254,140,45,9,39,16,174,33,76,34,52,16,250,18,122,
|
||||
242,191,155,196,155,188,31,17,102,17,190,39,116,16,218,9,43,8,111,18,254,72,24,67,216,150,176,153,145,25,79,2,
|
||||
135,16,150,129,188,108,88,67,248,144,112,11,161,145,208,155,63,183,96,224,64,155,192,152,16,184,63,97,101,14,2,93,
|
||||
124,67,120,152,48,154,183,216,4,125,62,105,171,178,228,4,214,19,222,23,18,24,96,53,225,57,194,8,59,39,75,76,
|
||||
96,71,67,3,255,121,189,146,192,0,159,19,142,194,139,96,19,90,194,85,248,83,194,2,79,18,95,37,108,99,4,150,
|
||||
144,192,68,154,68,223,85,248,45,97,63,35,176,244,171,240,32,194,119,30,4,242,103,126,102,4,150,158,192,254,30,202,
|
||||
12,227,3,194,0,35,176,244,4,86,16,30,247,32,240,122,83,98,226,65,32,99,166,146,188,85,216,122,109,18,99,66,
|
||||
224,84,143,237,179,206,8,140,15,137,167,43,9,124,130,240,67,35,48,62,4,142,118,156,218,18,220,20,245,249,151,172,
|
||||
173,13,198,82,141,241,76,32,28,66,216,58,97,103,109,94,2,15,133,155,76,74,224,132,168,39,20,227,24,72,152,227,
|
||||
188,76,173,132,23,9,199,33,122,98,132,109,98,226,14,198,100,73,200,107,197,202,136,118,12,233,21,248,187,28,74,211,
|
||||
29,132,237,2,7,132,201,134,4,30,72,104,17,18,248,37,97,183,200,9,76,7,151,255,151,231,187,95,70,208,217,182,
|
||||
212,78,147,55,76,225,141,153,31,181,6,138,49,112,240,248,19,225,247,143,72,26,137,27,76,94,3,98,126,18,2,95,
|
||||
34,108,81,0,2,135,96,117,75,198,144,8,182,241,88,146,152,200,216,103,172,145,141,34,156,10,199,113,101,212,131,198,
|
||||
243,246,32,44,23,78,222,131,132,94,81,141,193,177,69,47,83,154,50,188,90,135,199,146,68,12,138,183,169,127,66,35,
|
||||
107,199,10,121,10,26,89,106,5,36,6,12,136,234,187,6,19,190,18,78,220,173,81,77,154,67,30,135,181,62,242,244,
|
||||
199,14,139,21,137,206,234,155,8,226,58,15,154,149,141,39,9,71,6,121,42,17,76,226,110,138,237,235,151,17,175,190,
|
||||
42,194,125,158,33,45,198,92,194,142,177,33,208,121,43,103,8,194,57,127,39,236,157,8,145,57,230,65,224,248,8,87,
|
||||
31,123,115,174,85,58,17,178,225,218,216,172,66,135,192,243,132,131,95,76,184,50,136,142,39,234,234,124,190,111,119,225,
|
||||
22,186,38,72,165,136,224,55,254,128,112,17,161,57,36,121,140,103,8,155,199,109,21,14,37,44,21,254,128,181,132,127,
|
||||
19,246,89,76,231,162,230,135,56,74,204,10,193,247,52,195,102,12,247,219,234,234,120,199,56,87,145,21,151,15,255,136,
|
||||
149,111,214,217,94,102,43,127,8,171,215,99,53,201,184,74,51,226,107,194,158,161,182,235,154,26,206,102,59,89,161,245,
|
||||
230,3,191,4,227,226,170,200,140,80,216,103,1,120,98,206,144,146,168,52,228,151,16,118,241,153,168,212,246,158,118,151,
|
||||
29,139,231,132,37,174,25,10,204,105,8,74,199,210,148,96,7,238,61,30,63,142,21,146,99,36,111,165,147,23,211,34,
|
||||
92,225,131,180,147,229,156,235,124,126,46,10,65,218,119,56,239,166,98,204,253,240,82,196,218,152,223,203,243,71,191,71,
|
||||
216,89,72,32,155,36,109,66,187,171,86,125,198,146,98,69,127,30,65,72,134,200,128,187,31,81,147,45,216,241,173,85,
|
||||
214,74,173,145,78,219,132,77,152,15,51,18,245,245,57,223,80,60,255,120,40,66,18,155,171,175,230,124,93,152,126,62,
|
||||
147,215,228,49,254,86,228,235,140,12,194,73,171,135,14,237,146,190,202,90,196,197,180,19,240,22,161,70,64,224,120,133,
|
||||
31,180,82,122,182,194,225,124,52,225,83,229,184,219,241,178,156,20,120,157,186,108,45,134,179,10,15,81,24,219,1,86,
|
||||
228,210,26,147,233,173,141,49,89,248,188,127,73,2,171,136,239,245,132,219,111,177,114,204,172,224,92,151,138,78,240,249,
|
||||
214,21,182,74,33,137,172,85,254,154,176,78,49,25,45,185,178,199,156,151,227,87,194,231,61,10,3,92,50,214,147,149,
|
||||
218,38,143,245,1,56,237,123,149,93,168,8,19,179,53,18,138,52,233,127,141,2,2,111,22,62,111,118,174,170,36,199,
|
||||
195,114,174,194,206,91,139,64,238,47,8,125,82,219,101,57,172,186,28,90,233,16,20,94,74,38,231,11,194,174,185,38,
|
||||
60,153,38,228,110,225,243,254,148,172,174,206,170,20,57,73,194,83,20,30,150,143,9,151,4,154,109,217,7,104,157,21,
|
||||
115,140,208,119,249,58,97,171,60,43,166,2,174,40,201,132,207,202,54,209,248,59,126,17,46,192,170,151,156,115,191,103,
|
||||
51,135,86,91,247,170,51,116,206,152,243,4,147,53,51,215,155,141,127,171,84,104,184,55,166,60,42,100,154,100,121,206,
|
||||
254,130,51,143,93,113,127,225,8,74,89,158,115,74,18,43,224,145,88,149,195,71,56,82,160,112,112,212,255,109,77,216,
|
||||
198,67,17,90,9,5,229,32,75,8,222,152,196,115,178,168,234,108,71,221,153,47,224,139,103,12,82,24,217,211,54,34,
|
||||
48,99,138,76,202,162,33,179,31,247,17,152,64,189,203,86,65,9,73,98,79,68,19,238,128,241,203,26,221,213,88,89,
|
||||
169,140,231,60,159,215,4,115,47,203,161,192,240,247,221,6,5,107,174,211,221,98,243,38,107,138,32,34,178,23,20,150,
|
||||
42,105,3,2,143,110,21,23,11,20,162,90,184,219,172,191,76,145,136,63,92,232,200,238,128,199,198,38,46,102,4,158,
|
||||
170,112,148,95,104,89,209,241,35,240,82,101,89,217,86,70,96,28,200,203,148,115,105,170,115,57,123,108,106,162,95,63,
|
||||
91,133,49,89,125,236,183,124,200,163,201,207,112,219,74,227,65,96,21,220,109,218,56,227,243,232,110,97,19,89,98,2,
|
||||
119,240,76,115,104,135,47,179,194,72,44,45,129,141,158,77,126,130,4,163,147,108,43,45,45,129,103,132,76,237,251,24,
|
||||
9,200,169,148,65,147,226,146,167,9,228,230,194,211,249,242,110,76,10,67,32,251,40,255,27,1,129,237,240,123,90,19,
|
||||
130,34,19,184,147,66,129,89,39,200,103,153,24,219,36,219,50,37,240,231,66,31,104,27,114,97,150,11,210,55,14,181,
|
||||
46,18,197,59,255,102,8,87,223,34,132,156,110,20,252,223,119,80,237,107,36,22,193,128,127,73,72,224,83,56,223,234,
|
||||
209,230,35,223,255,255,15,58,78,216,100,23,144,192,125,133,245,128,235,75,170,157,106,169,101,130,207,252,21,125,95,108,
|
||||
194,11,180,125,94,161,184,110,96,152,243,57,14,20,95,37,168,163,88,139,45,183,183,145,24,61,129,91,42,182,207,87,
|
||||
221,240,145,147,92,60,71,88,152,114,105,190,76,110,19,161,116,100,8,24,169,112,159,77,119,93,101,78,8,170,65,152,
|
||||
8,197,101,97,103,39,44,189,34,178,213,215,11,217,106,210,237,179,49,91,26,97,50,211,6,69,210,225,240,43,92,176,
|
||||
101,54,98,4,4,14,81,84,11,61,15,109,117,83,207,226,132,224,123,21,49,196,209,102,232,135,35,111,51,165,239,115,
|
||||
202,166,86,141,83,167,193,245,242,239,42,72,28,147,176,43,123,148,228,101,18,111,247,129,183,68,50,217,159,161,253,149,
|
||||
68,163,29,171,72,75,92,130,237,212,206,68,229,234,99,117,254,111,138,213,247,103,73,237,130,147,11,170,201,171,225,51,
|
||||
241,172,110,93,27,33,38,47,163,53,142,83,116,68,90,9,131,93,148,6,239,244,250,124,69,217,180,224,34,139,96,228,
|
||||
144,68,102,235,228,168,195,60,197,228,62,30,20,90,74,36,153,217,74,71,10,189,52,110,4,99,122,212,189,71,203,109,
|
||||
235,236,131,114,46,77,243,156,81,65,15,107,205,119,37,229,94,154,206,189,215,238,90,95,224,105,81,253,141,38,116,178,
|
||||
178,27,253,3,154,213,151,229,133,233,171,44,1,15,2,194,115,82,149,196,188,107,116,119,18,59,117,69,90,170,152,200,
|
||||
197,112,114,231,172,104,18,156,183,123,163,163,147,54,178,63,15,219,112,247,53,51,156,243,104,95,52,7,151,78,30,111,
|
||||
123,151,135,53,180,157,151,103,130,114,229,187,102,198,249,177,106,29,89,2,141,115,48,174,18,215,76,220,99,81,213,60,
|
||||
56,103,239,221,158,57,54,173,56,23,7,117,27,247,155,243,230,115,228,252,53,229,132,189,31,68,209,163,168,158,117,180,
|
||||
223,159,160,83,148,111,178,212,27,40,125,43,239,104,70,211,134,77,241,222,80,78,210,50,180,194,42,68,39,252,160,181,
|
||||
228,183,33,72,92,129,212,143,250,178,92,141,206,68,29,140,238,132,218,59,0,39,21,74,105,112,138,103,110,240,108,212,
|
||||
231,106,169,65,35,160,170,178,73,34,118,194,67,39,192,119,169,189,15,126,90,161,107,27,156,70,125,207,70,144,127,218,
|
||||
138,94,109,199,5,68,54,117,241,6,120,125,208,229,232,107,229,68,172,193,245,169,5,215,244,156,29,162,209,163,233,93,
|
||||
46,34,57,33,249,68,110,172,144,172,169,233,58,68,58,119,236,241,165,32,183,123,168,234,107,80,85,84,89,172,31,157,
|
||||
218,242,210,237,185,46,196,247,119,68,132,54,108,173,147,81,101,21,239,8,71,160,37,34,44,244,172,199,185,178,26,10,
|
||||
65,101,177,127,40,94,186,31,135,188,224,35,87,214,56,95,195,243,7,194,1,235,219,154,196,169,31,141,179,101,78,240,
|
||||
172,231,91,133,51,175,36,6,114,18,93,131,97,90,204,45,0,137,110,43,47,118,203,157,73,216,190,228,171,50,200,112,
|
||||
134,125,55,219,211,187,177,28,125,213,74,218,226,170,147,198,188,168,128,36,6,158,165,79,144,255,51,42,165,72,165,27,
|
||||
208,22,221,171,178,13,206,142,133,158,63,100,1,167,49,36,99,114,62,240,24,150,166,143,129,83,60,174,83,240,197,106,
|
||||
164,252,207,130,205,59,32,8,38,47,36,5,168,80,190,76,142,145,141,33,188,224,121,175,208,58,104,106,13,139,98,214,
|
||||
81,194,49,127,166,40,110,13,141,146,204,143,112,149,195,241,65,59,178,208,243,19,132,81,144,116,123,44,110,39,107,9,
|
||||
225,189,248,109,80,116,25,199,34,19,231,78,140,105,138,187,123,163,70,27,220,142,163,188,243,86,147,153,51,142,223,132,
|
||||
179,209,183,179,53,196,190,255,2,74,188,98,239,63,116,114,117,174,16,54,137,45,20,150,4,109,83,124,223,194,49,200,
|
||||
39,249,62,132,171,105,62,182,164,234,174,228,161,112,146,162,38,42,211,49,162,198,213,170,57,115,204,130,25,33,222,190,
|
||||
192,254,249,13,242,94,186,164,107,9,169,20,188,133,29,134,48,88,123,145,201,91,7,243,76,24,110,201,104,152,99,61,
|
||||
205,130,22,236,221,23,227,230,202,46,31,193,118,18,133,7,162,170,233,139,34,145,215,140,82,184,106,241,28,58,38,194,
|
||||
85,202,158,44,243,160,10,115,140,172,239,2,190,39,176,204,186,223,58,26,234,30,200,88,123,5,25,221,205,202,251,50,
|
||||
220,213,213,134,249,251,18,169,30,111,34,128,61,29,41,28,186,139,165,59,42,43,131,129,14,207,98,208,182,99,75,77,
|
||||
98,149,221,131,252,201,225,169,183,164,155,116,120,119,106,17,171,112,129,215,129,216,177,38,162,224,148,39,255,38,148,10,
|
||||
204,132,27,237,6,244,244,190,18,182,243,89,8,65,29,142,26,199,193,88,225,156,121,80,49,191,190,222,95,67,119,106,
|
||||
21,14,192,96,110,193,65,58,30,158,251,237,225,59,76,169,183,47,143,27,215,195,196,196,196,196,196,196,196,196,196,196,
|
||||
196,196,196,196,196,196,196,164,124,228,255,132,119,141,168,125,48,16,122,0,0,0,37,116,69,88,116,100,97,116,101,58,
|
||||
99,114,101,97,116,101,0,50,48,49,56,45,48,53,45,50,51,84,49,51,58,48,53,58,48,56,45,48,52,58,48,48,
|
||||
172,124,172,145,0,0,0,37,116,69,88,116,100,97,116,101,58,109,111,100,105,102,121,0,50,48,49,56,45,48,53,45,
|
||||
50,51,84,49,51,58,48,53,58,48,56,45,48,52,58,48,48,221,33,20,45,0,0,0,67,116,69,88,116,115,118,103,
|
||||
58,98,97,115,101,45,117,114,105,0,102,105,108,101,58,47,47,47,99,111,114,101,47,102,105,108,101,115,47,109,101,100,
|
||||
105,97,47,104,105,103,97,110,47,105,99,111,110,47,104,105,103,97,110,45,110,111,99,105,114,99,108,101,46,115,118,103,
|
||||
144,27,14,155,0,0,0,0,73,69,78,68,174,66,96,130,
|
||||
};
|
||||
const nall::vector<uint8_t> Logo = { //size: 25128
|
||||
137,80,78,71,13,10,26,10,0,0,0,13,73,72,68,82,0,0,1,143,0,0,0,95,8,6,0,0,0,16,211,75,
|
||||
124,0,0,0,4,103,65,77,65,0,0,177,143,11,252,97,5,0,0,0,32,99,72,82,77,0,0,122,38,0,0,128,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
namespace Resource {
|
||||
extern const nall::vector<uint8_t> Icon;
|
||||
extern const nall::vector<uint8_t> Logo;
|
||||
}
|
||||
|
|
|
@ -3,14 +3,20 @@ InputSettings::InputSettings(TabFrame* parent) : TabFrameItem(parent) {
|
|||
setText("Input");
|
||||
|
||||
layout.setMargin(5);
|
||||
focusLabel.setText("When Focus is Lost:");
|
||||
pauseEmulation.setText("Pause Emulation").setChecked(settings["Input/FocusLoss/Pause"].boolean()).onToggle([&] {
|
||||
settings["Input/FocusLoss/Pause"].setValue(pauseEmulation.checked());
|
||||
defocusLabel.setText("When Focus is Lost:");
|
||||
pauseEmulation.setText("Pause Emulation").onActivate([&] {
|
||||
settings["Input/Defocus"].setValue("Pause");
|
||||
allowInput.setEnabled(!pauseEmulation.checked());
|
||||
}).doToggle();
|
||||
allowInput.setText("Allow Input").setChecked(settings["Input/FocusLoss/AllowInput"].boolean()).onToggle([&] {
|
||||
settings["Input/FocusLoss/AllowInput"].setValue(allowInput.checked());
|
||||
});
|
||||
blockInput.setText("Block Input").onActivate([&] {
|
||||
settings["Input/Defocus"].setValue("Block");
|
||||
});
|
||||
allowInput.setText("Allow Input").onActivate([&] {
|
||||
settings["Input/Defocus"].setValue("Allow");
|
||||
});
|
||||
if(settings["Input/Defocus"].text() == "Pause") pauseEmulation.setChecked();
|
||||
if(settings["Input/Defocus"].text() == "Block") blockInput.setChecked();
|
||||
if(settings["Input/Defocus"].text() == "Allow") allowInput.setChecked();
|
||||
for(auto& emulator : inputManager->emulators) {
|
||||
emulatorList.append(ComboButtonItem().setText(emulator.name));
|
||||
}
|
||||
|
|
|
@ -1,15 +1,82 @@
|
|||
#include "../higan.hpp"
|
||||
|
||||
#include "system-properties.cpp"
|
||||
unique_pointer<SystemProperties> systemProperties;
|
||||
|
||||
#include "systems.cpp"
|
||||
#include "video.cpp"
|
||||
#include "audio.cpp"
|
||||
#include "input.cpp"
|
||||
#include "hotkeys.cpp"
|
||||
#include "advanced.cpp"
|
||||
Settings settings;
|
||||
unique_pointer<SettingsManager> settingsManager;
|
||||
unique_pointer<SystemProperties> systemProperties;
|
||||
|
||||
Settings::Settings() {
|
||||
Markup::Node::operator=(BML::unserialize(string::read(locate("settings.bml"))));
|
||||
|
||||
auto set = [&](const string& name, const string& value) {
|
||||
//create node and set to default value only if it does not already exist
|
||||
if(!operator[](name)) operator()(name).setValue(value);
|
||||
};
|
||||
|
||||
set("UserInterface/ShowStatusBar", true);
|
||||
|
||||
set("Library/Location", {Path::user(), "Emulation/"});
|
||||
set("Library/IgnoreManifests", false);
|
||||
|
||||
set("Video/Driver", ruby::Video::safestDriver());
|
||||
set("Video/Synchronize", false);
|
||||
set("Video/Shader", "Blur");
|
||||
set("Video/BlurEmulation", true);
|
||||
set("Video/ColorEmulation", true);
|
||||
set("Video/ScanlineEmulation", false);
|
||||
|
||||
set("Video/Saturation", 100);
|
||||
set("Video/Gamma", 100);
|
||||
set("Video/Luminance", 100);
|
||||
|
||||
set("Video/Overscan/Horizontal", 0);
|
||||
set("Video/Overscan/Vertical", 0);
|
||||
|
||||
set("Video/Windowed/AspectCorrection", true);
|
||||
set("Video/Windowed/IntegralScaling", true);
|
||||
set("Video/Windowed/Adaptive", true);
|
||||
set("Video/Windowed/Scale", "Small");
|
||||
set("Video/Windowed/Scale/Small", "640x480");
|
||||
set("Video/Windowed/Scale/Medium", "960x720");
|
||||
set("Video/Windowed/Scale/Large", "1280x960");
|
||||
|
||||
set("Video/Fullscreen/AspectCorrection", true);
|
||||
set("Video/Fullscreen/IntegralScaling", true);
|
||||
set("Video/Fullscreen/Exclusive", false);
|
||||
|
||||
set("Audio/Driver", ruby::Audio::safestDriver());
|
||||
set("Audio/Device", "");
|
||||
set("Audio/Frequency", 48000);
|
||||
set("Audio/Latency", 0);
|
||||
set("Audio/Exclusive", false);
|
||||
set("Audio/Synchronize", true);
|
||||
set("Audio/Mute", false);
|
||||
set("Audio/Volume", 100);
|
||||
set("Audio/Balance", 50);
|
||||
set("Audio/Reverb/Enable", false);
|
||||
|
||||
set("Input/Driver", ruby::Input::safestDriver());
|
||||
set("Input/Frequency", 5);
|
||||
set("Input/Defocus", "Pause");
|
||||
|
||||
set("Emulation/AutoSaveMemory/Enable", true);
|
||||
set("Emulation/AutoSaveMemory/Interval", 30);
|
||||
|
||||
set("Systems", "");
|
||||
|
||||
set("Crashed", false);
|
||||
}
|
||||
|
||||
auto Settings::save() -> void {
|
||||
file::write(locate("settings.bml"), BML::serialize(*this));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
SettingsManager::SettingsManager() {
|
||||
settingsManager = this;
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
struct Settings : Markup::Node {
|
||||
Settings();
|
||||
auto save() -> void;
|
||||
};
|
||||
|
||||
struct SystemProperties : Window {
|
||||
SystemProperties();
|
||||
auto append() -> void;
|
||||
|
@ -115,9 +120,11 @@ struct InputSettings : TabFrameItem {
|
|||
|
||||
VerticalLayout layout{this};
|
||||
HorizontalLayout focusLayout{&layout, Size{~0, 0}};
|
||||
Label focusLabel{&focusLayout, Size{0, 0}};
|
||||
CheckLabel pauseEmulation{&focusLayout, Size{0, 0}};
|
||||
CheckLabel allowInput{&focusLayout, Size{0, 0}};
|
||||
Label defocusLabel{&focusLayout, Size{0, 0}};
|
||||
RadioLabel pauseEmulation{&focusLayout, Size{0, 0}};
|
||||
RadioLabel blockInput{&focusLayout, Size{0, 0}};
|
||||
RadioLabel allowInput{&focusLayout, Size{0, 0}};
|
||||
Group focusGroup{&pauseEmulation, &blockInput, &allowInput};
|
||||
HorizontalLayout selectionLayout{&layout, Size{~0, 0}};
|
||||
ComboButton emulatorList{&selectionLayout, Size{~0, 0}};
|
||||
ComboButton portList{&selectionLayout, Size{~0, 0}};
|
||||
|
@ -205,5 +212,6 @@ struct SettingsManager : Window {
|
|||
auto show(uint setting) -> void;
|
||||
};
|
||||
|
||||
extern Settings settings;
|
||||
extern unique_pointer<SystemProperties> systemProperties;
|
||||
extern unique_pointer<SettingsManager> settingsManager;
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
#include "../higan.hpp"
|
||||
|
||||
#include "cheat-database.cpp"
|
||||
unique_pointer<CheatDatabase> cheatDatabase;
|
||||
|
||||
#include "cheat-editor.cpp"
|
||||
#include "state-manager.cpp"
|
||||
#include "manifest-viewer.cpp"
|
||||
#include "game-notes.cpp"
|
||||
unique_pointer<CheatDatabase> cheatDatabase;
|
||||
unique_pointer<ToolsManager> toolsManager;
|
||||
|
||||
ToolsManager::ToolsManager() {
|
||||
|
|
|
@ -4,11 +4,11 @@ objects += ws-interface ws-system
|
|||
objects += ws-memory ws-eeprom ws-cartridge
|
||||
objects += ws-cpu ws-ppu ws-apu
|
||||
|
||||
obj/ws-interface.o: ws/interface/interface.cpp $(call rwildcard,ws/interface/)
|
||||
obj/ws-system.o: ws/system/system.cpp $(call rwildcard,ws/system/)
|
||||
obj/ws-memory.o: ws/memory/memory.cpp $(call rwildcard,ws/memory/)
|
||||
obj/ws-eeprom.o: ws/eeprom/eeprom.cpp $(call rwildcard,ws/eeprom/)
|
||||
obj/ws-cartridge.o: ws/cartridge/cartridge.cpp $(call rwildcard,ws/cartridge/)
|
||||
obj/ws-cpu.o: ws/cpu/cpu.cpp $(call rwildcard,ws/cpu/)
|
||||
obj/ws-ppu.o: ws/ppu/ppu.cpp $(call rwildcard,ws/ppu/)
|
||||
obj/ws-apu.o: ws/apu/apu.cpp $(call rwildcard,ws/apu/)
|
||||
obj/ws-interface.o: ws/interface/interface.cpp
|
||||
obj/ws-system.o: ws/system/system.cpp
|
||||
obj/ws-memory.o: ws/memory/memory.cpp
|
||||
obj/ws-eeprom.o: ws/eeprom/eeprom.cpp
|
||||
obj/ws-cartridge.o: ws/cartridge/cartridge.cpp
|
||||
obj/ws-cpu.o: ws/cpu/cpu.cpp
|
||||
obj/ws-ppu.o: ws/ppu/ppu.cpp
|
||||
obj/ws-apu.o: ws/apu/apu.cpp
|
||||
|
|
|
@ -66,10 +66,19 @@ auto Application::Windows::doModalChange(bool modal) -> void {
|
|||
if(state.windows.onModalChange) return state.windows.onModalChange(modal);
|
||||
}
|
||||
|
||||
auto Application::Windows::doScreenSaver() -> bool {
|
||||
if(state.windows.onScreenSaver) return state.windows.onScreenSaver();
|
||||
return true; //true = allow screen saver (default); false = suppress screen saver
|
||||
}
|
||||
|
||||
auto Application::Windows::onModalChange(const function<void (bool)>& callback) -> void {
|
||||
state.windows.onModalChange = callback;
|
||||
}
|
||||
|
||||
auto Application::Windows::onScreenSaver(const function<bool ()>& callback) -> void {
|
||||
state.windows.onScreenSaver = callback;
|
||||
}
|
||||
|
||||
//Cocoa
|
||||
//=====
|
||||
|
||||
|
|
|
@ -389,7 +389,9 @@ struct Application {
|
|||
|
||||
struct Windows {
|
||||
static auto doModalChange(bool modal) -> void;
|
||||
static auto doScreenSaver() -> bool;
|
||||
static auto onModalChange(const function<void (bool)>& callback = {}) -> void;
|
||||
static auto onScreenSaver(const function<bool ()>& callback = {}) -> void;
|
||||
};
|
||||
|
||||
struct Cocoa {
|
||||
|
@ -413,6 +415,7 @@ struct Application {
|
|||
|
||||
struct Windows {
|
||||
function<void (bool)> onModalChange;
|
||||
function<bool ()> onScreenSaver;
|
||||
} windows;
|
||||
|
||||
struct Cocoa {
|
||||
|
|
|
@ -20,6 +20,7 @@ auto pMenu::destruct() -> void {
|
|||
auto pMenu::append(sAction action) -> void {
|
||||
if(action->self()) {
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(gtkMenu), action->self()->widget);
|
||||
action->self()->setEnabled(action->enabled(true));
|
||||
action->self()->setFont(action->font(true));
|
||||
action->self()->setVisible(action->visible()); //hidden parent will hide child; no need to inherit visibility
|
||||
}
|
||||
|
|
|
@ -259,6 +259,10 @@ static auto CALLBACK Application_windowProc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||
case WM_ERASEBKGND: if(pWindow->onEraseBackground()) return true; break;
|
||||
case WM_ENTERMENULOOP: case WM_ENTERSIZEMOVE: pWindow->onModalBegin(); return false;
|
||||
case WM_EXITMENULOOP: case WM_EXITSIZEMOVE: pWindow->onModalEnd(); return false;
|
||||
case WM_SYSCOMMAND:
|
||||
if(wparam == SC_SCREENSAVE || wparam == SC_MONITORPOWER) {
|
||||
if(!Application::Windows::doScreenSaver()) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return Shared_windowProc(DefWindowProc, hwnd, msg, wparam, lparam);
|
||||
|
|
|
@ -86,6 +86,11 @@ auto SuperFamicom::manifest() const -> string {
|
|||
output.append(Memory{}.type("RAM").size(size).content("Save").text());
|
||||
}
|
||||
|
||||
if(board(0) == "GSU" && !ramSize() && !expansionRamSize()) {
|
||||
//Starfox / Starwing reports having no RAM; but all GSU boards contain expansion RAM
|
||||
output.append(Memory{}.type("RAM").size(0x8000).content("Save").isVolatile().text());
|
||||
}
|
||||
|
||||
if(0) {
|
||||
} else if(board(0) == "ARM") {
|
||||
output.append(Memory{}.type("ROM").size(0x20000).content("Program").manufacturer("SETA").architecture("ARM6").identifier(firmwareARM()).text());
|
||||
|
|
|
@ -89,6 +89,7 @@ endif
|
|||
# windows settings
|
||||
ifeq ($(platform),windows)
|
||||
link += -lws2_32 -lole32
|
||||
link += $(if $(findstring $(compiler),g++),-static-libgcc -static-libstdc++)
|
||||
link += $(if $(findstring $(console),true),-mconsole,-mwindows)
|
||||
windres := windres
|
||||
endif
|
||||
|
|
17
nall/hid.hpp
|
@ -37,10 +37,14 @@ private:
|
|||
struct Device : vector<Group> {
|
||||
Device(const string& name) : _name(name) {}
|
||||
|
||||
auto pathID() const -> uint32_t { return (uint32_t)(_id >> 32); }
|
||||
auto deviceID() const -> uint32_t { return (uint32_t)(_id >> 0); }
|
||||
auto vendorID() const -> uint16_t { return (uint16_t)(_id >> 16); }
|
||||
auto productID() const -> uint16_t { return (uint16_t)(_id >> 0); }
|
||||
//id => {pathID}-{vendorID}-{productID}
|
||||
auto pathID() const -> uint32_t { return (uint32_t)(_id >> 32); } //32-63
|
||||
auto vendorID() const -> uint16_t { return (uint16_t)(_id >> 16); } //16-31
|
||||
auto productID() const -> uint16_t { return (uint16_t)(_id >> 0); } // 0-15
|
||||
|
||||
auto setPathID (uint32_t pathID ) -> void { _id = (uint64_t)pathID << 32 | vendorID() << 16 | productID() << 0; }
|
||||
auto setVendorID (uint16_t vendorID ) -> void { _id = (uint64_t)pathID() << 32 | vendorID << 16 | productID() << 0; }
|
||||
auto setProductID(uint16_t productID) -> void { _id = (uint64_t)pathID() << 32 | vendorID() << 16 | productID << 0; }
|
||||
|
||||
virtual auto isNull() const -> bool { return false; }
|
||||
virtual auto isKeyboard() const -> bool { return false; }
|
||||
|
@ -66,11 +70,14 @@ private:
|
|||
};
|
||||
|
||||
struct Null : Device {
|
||||
enum : uint16_t { GenericVendorID = 0x0000, GenericProductID = 0x0000 };
|
||||
|
||||
Null() : Device("Null") {}
|
||||
auto isNull() const -> bool { return true; }
|
||||
};
|
||||
|
||||
struct Keyboard : Device {
|
||||
enum : uint16_t { GenericVendorID = 0x0000, GenericProductID = 0x0001 };
|
||||
enum GroupID : uint { Button };
|
||||
|
||||
Keyboard() : Device("Keyboard") { append("Button"); }
|
||||
|
@ -79,6 +86,7 @@ struct Keyboard : Device {
|
|||
};
|
||||
|
||||
struct Mouse : Device {
|
||||
enum : uint16_t { GenericVendorID = 0x0000, GenericProductID = 0x0002 };
|
||||
enum GroupID : uint { Axis, Button };
|
||||
|
||||
Mouse() : Device("Mouse") { append("Axis"), append("Button"); }
|
||||
|
@ -88,6 +96,7 @@ struct Mouse : Device {
|
|||
};
|
||||
|
||||
struct Joypad : Device {
|
||||
enum : uint16_t { GenericVendorID = 0x0000, GenericProductID = 0x0003 };
|
||||
enum GroupID : uint { Axis, Hat, Trigger, Button };
|
||||
|
||||
Joypad() : Device("Joypad") { append("Axis"), append("Hat"), append("Trigger"), append("Button"); }
|
||||
|
|
|
@ -5,7 +5,7 @@ else
|
|||
endif
|
||||
|
||||
rubyflags += $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
|
||||
rubyflags += $(if $(findstring .sdl,$(ruby)),$(shell sdl-config --cflags))
|
||||
rubyflags += $(if $(findstring input.sdl,$(ruby)),$(shell sdl2-config --cflags))
|
||||
|
||||
rubylink =
|
||||
|
||||
|
@ -24,11 +24,10 @@ rubylink += $(if $(findstring audio.pulseaudiosimple,$(ruby)),-lpulse-simple)
|
|||
rubylink += $(if $(findstring audio.wasapi,$(ruby)),-lavrt -luuid)
|
||||
rubylink += $(if $(findstring audio.xaudio2,$(ruby)),-lole32)
|
||||
|
||||
rubylink += $(if $(findstring input.sdl,$(ruby)),$(shell sdl2-config --libs))
|
||||
rubylink += $(if $(findstring input.udev,$(ruby)),-ludev)
|
||||
rubylink += $(if $(findstring input.windows,$(ruby)),-ldinput8 -ldxguid)
|
||||
|
||||
rubylink += $(if $(findstring .sdl,$(ruby)),$(shell sdl-config --libs))
|
||||
|
||||
ifeq ($(platform),windows)
|
||||
rubylink += $(if $(findstring audio.openal,$(ruby)),-lopenal32)
|
||||
endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_JOYPAD_DIRECTINPUT
|
||||
#define RUBY_INPUT_JOYPAD_DIRECTINPUT
|
||||
#pragma once
|
||||
|
||||
auto CALLBACK DirectInput_EnumJoypadsCallback(const DIDEVICEINSTANCE* instance, void* p) -> BOOL;
|
||||
auto CALLBACK DirectInput_EnumJoypadAxesCallback(const DIDEVICEOBJECTINSTANCE* instance, void* p) -> BOOL;
|
||||
|
@ -26,9 +25,9 @@ struct InputJoypadDirectInput {
|
|||
LPDIRECTINPUT8 context = nullptr;
|
||||
LPDIRECTINPUTDEVICE8 device = nullptr;
|
||||
bool xinputAvailable = false;
|
||||
unsigned effects = 0;
|
||||
uint effects = 0;
|
||||
|
||||
auto assign(shared_pointer<HID::Joypad> hid, unsigned groupID, unsigned inputID, int16_t value) -> void {
|
||||
auto assign(shared_pointer<HID::Joypad> hid, uint groupID, uint inputID, int16_t value) -> void {
|
||||
auto& group = hid->group(groupID);
|
||||
if(group.input(inputID).value() == value) return;
|
||||
input.doChange(hid, groupID, inputID, group.input(inputID).value(), value);
|
||||
|
@ -42,7 +41,7 @@ struct InputJoypadDirectInput {
|
|||
DIJOYSTATE2 state;
|
||||
if(FAILED(jp.device->GetDeviceState(sizeof(DIJOYSTATE2), &state))) continue;
|
||||
|
||||
for(unsigned n = 0; n < 4; n++) {
|
||||
for(auto n : range(4)) {
|
||||
assign(jp.hid, HID::Joypad::GroupID::Axis, 0, state.lX);
|
||||
assign(jp.hid, HID::Joypad::GroupID::Axis, 1, state.lY);
|
||||
assign(jp.hid, HID::Joypad::GroupID::Axis, 2, state.lZ);
|
||||
|
@ -50,7 +49,7 @@ struct InputJoypadDirectInput {
|
|||
assign(jp.hid, HID::Joypad::GroupID::Axis, 4, state.lRy);
|
||||
assign(jp.hid, HID::Joypad::GroupID::Axis, 5, state.lRz);
|
||||
|
||||
unsigned pov = state.rgdwPOV[n];
|
||||
uint pov = state.rgdwPOV[n];
|
||||
int16_t xaxis = 0;
|
||||
int16_t yaxis = 0;
|
||||
|
||||
|
@ -65,7 +64,7 @@ struct InputJoypadDirectInput {
|
|||
assign(jp.hid, HID::Joypad::GroupID::Hat, n * 2 + 1, yaxis);
|
||||
}
|
||||
|
||||
for(unsigned n = 0; n < 128; n++) {
|
||||
for(auto n : range(128)) {
|
||||
assign(jp.hid, HID::Joypad::GroupID::Button, n, (bool)state.rgbButtons[n]);
|
||||
}
|
||||
|
||||
|
@ -140,7 +139,9 @@ struct InputJoypadDirectInput {
|
|||
device->GetProperty(DIPROP_GUIDANDPATH, &property.diph);
|
||||
string devicePath = (const char*)utf8_t(property.wszPath);
|
||||
jp.pathID = Hash::CRC32(devicePath.data(), devicePath.size()).value();
|
||||
jp.hid->setID((uint64_t)jp.pathID << 32 | jp.vendorID << 16 | jp.productID << 0);
|
||||
jp.hid->setVendorID(jp.vendorID);
|
||||
jp.hid->setProductID(jp.productID);
|
||||
jp.hid->setPathID(jp.pathID);
|
||||
|
||||
if(jp.hid->rumble()) {
|
||||
//disable auto-centering spring for rumble support
|
||||
|
@ -176,9 +177,9 @@ struct InputJoypadDirectInput {
|
|||
device->CreateEffect(GUID_ConstantForce, &effect, &jp.effect, NULL);
|
||||
}
|
||||
|
||||
for(unsigned n = 0; n < 6; n++) jp.hid->axes().append(n);
|
||||
for(unsigned n = 0; n < 8; n++) jp.hid->hats().append(n);
|
||||
for(unsigned n = 0; n < 128; n++) jp.hid->buttons().append(n);
|
||||
for(auto n : range(6)) jp.hid->axes().append(n);
|
||||
for(auto n : range(8)) jp.hid->hats().append(n);
|
||||
for(auto n : range(128)) jp.hid->buttons().append(n);
|
||||
joypads.append(jp);
|
||||
|
||||
return DIENUM_CONTINUE;
|
||||
|
@ -214,5 +215,3 @@ auto CALLBACK DirectInput_EnumJoypadAxesCallback(const DIDEVICEOBJECTINSTANCE* i
|
|||
auto CALLBACK DirectInput_EnumJoypadEffectsCallback(const DIDEVICEOBJECTINSTANCE* instance, void* p) -> BOOL {
|
||||
return ((InputJoypadDirectInput*)p)->initEffect(instance);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_JOYPAD_SDL
|
||||
#define RUBY_INPUT_JOYPAD_SDL
|
||||
#pragma once
|
||||
|
||||
struct InputJoypadSDL {
|
||||
Input& input;
|
||||
|
@ -8,12 +7,12 @@ struct InputJoypadSDL {
|
|||
struct Joypad {
|
||||
shared_pointer<HID::Joypad> hid{new HID::Joypad};
|
||||
|
||||
unsigned id = 0;
|
||||
uint id = 0;
|
||||
SDL_Joystick* handle = nullptr;
|
||||
};
|
||||
vector<Joypad> joypads;
|
||||
|
||||
auto assign(shared_pointer<HID::Joypad> hid, unsigned groupID, unsigned inputID, int16_t value) -> void {
|
||||
auto assign(shared_pointer<HID::Joypad> hid, uint groupID, uint inputID, int16_t value) -> void {
|
||||
auto& group = hid->group(groupID);
|
||||
if(group.input(inputID).value() == value) return;
|
||||
input.doChange(hid, groupID, inputID, group.input(inputID).value(), value);
|
||||
|
@ -28,10 +27,10 @@ struct InputJoypadSDL {
|
|||
assign(jp.hid, HID::Joypad::GroupID::Axis, n, (int16_t)SDL_JoystickGetAxis(jp.handle, n));
|
||||
}
|
||||
|
||||
for(signed n = 0; n < (signed)jp.hid->hats().size() - 1; n += 2) {
|
||||
for(int n = 0; n < (int)jp.hid->hats().size() - 1; n += 2) {
|
||||
uint8_t state = SDL_JoystickGetHat(jp.handle, n >> 1);
|
||||
assign(jp.hid, HID::Joypad::GroupID::Hat, n + 0, state & SDL_HAT_LEFT ? -32767 : state & SDL_HAT_RIGHT ? +32767 : 0);
|
||||
assign(jp.hid, HID::Joypad::GroupID::Hat, n + 1, state & SDL_HAT_UP ? -32767 : state & SDL_HAT_DOWN ? +32767 : 0);
|
||||
assign(jp.hid, HID::Joypad::GroupID::Hat, n + 1, state & SDL_HAT_UP ? -32767 : state & SDL_HAT_DOWN ? +32767 : 0);
|
||||
}
|
||||
|
||||
for(auto n : range(jp.hid->buttons())) {
|
||||
|
@ -49,13 +48,15 @@ struct InputJoypadSDL {
|
|||
for(auto id : range(SDL_NumJoysticks())) {
|
||||
Joypad jp;
|
||||
jp.id = id;
|
||||
jp.handle = SDL_JoystickOpen(id);
|
||||
jp.handle = SDL_JoystickOpen(jp.id);
|
||||
|
||||
unsigned axes = SDL_JoystickNumAxes(jp.handle);
|
||||
unsigned hats = SDL_JoystickNumHats(jp.handle) * 2;
|
||||
unsigned buttons = 32; //there is no SDL_JoystickNumButtons()
|
||||
uint axes = SDL_JoystickNumAxes(jp.handle);
|
||||
uint hats = SDL_JoystickNumHats(jp.handle) * 2;
|
||||
uint buttons = SDL_JoystickNumButtons(jp.handle);
|
||||
|
||||
jp.hid->setID(3 + jp.id);
|
||||
jp.hid->setVendorID(HID::Joypad::GenericVendorID);
|
||||
jp.hid->setProductID(HID::Joypad::GenericProductID);
|
||||
jp.hid->setPathID(jp.id);
|
||||
for(auto n : range(axes)) jp.hid->axes().append(n);
|
||||
for(auto n : range(hats)) jp.hid->hats().append(n);
|
||||
for(auto n : range(buttons)) jp.hid->buttons().append(n);
|
||||
|
@ -75,5 +76,3 @@ struct InputJoypadSDL {
|
|||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_JOYPAD_UDEV
|
||||
#define RUBY_INPUT_JOYPAD_UDEV
|
||||
#pragma once
|
||||
|
||||
struct InputJoypadUdev {
|
||||
Input& input;
|
||||
|
@ -265,8 +264,9 @@ private:
|
|||
}
|
||||
|
||||
auto createJoypadHID(Joypad& jp) -> void {
|
||||
uint64_t pathID = Hash::CRC32(jp.deviceName.data(), jp.deviceName.size()).value();
|
||||
jp.hid->setID(pathID << 32 | jp.vendorID.hex() << 16 | jp.productID.hex() << 0);
|
||||
jp.hid->setVendorID(jp.vendorID.hex());
|
||||
jp.hid->setProductID(jp.productID.hex());
|
||||
jp.hid->setPathID(Hash::CRC32(jp.deviceName.data(), jp.deviceName.size()).value());
|
||||
|
||||
for(uint n : range(jp.axes.size())) jp.hid->axes().append(n);
|
||||
for(uint n : range(jp.hats.size())) jp.hid->hats().append(n);
|
||||
|
@ -284,5 +284,3 @@ private:
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_JOYPAD_XINPUT
|
||||
#define RUBY_INPUT_JOYPAD_XINPUT
|
||||
#pragma once
|
||||
|
||||
//documented functionality
|
||||
#define oXInputGetState "XInputGetState"
|
||||
|
@ -29,11 +28,11 @@ struct InputJoypadXInput {
|
|||
|
||||
struct Joypad {
|
||||
shared_pointer<HID::Joypad> hid{new HID::Joypad};
|
||||
unsigned id = 0;
|
||||
uint id = 0;
|
||||
};
|
||||
vector<Joypad> joypads;
|
||||
|
||||
auto assign(shared_pointer<HID::Joypad> hid, unsigned groupID, unsigned inputID, int16_t value) -> void {
|
||||
auto assign(shared_pointer<HID::Joypad> hid, uint groupID, uint inputID, int16_t value) -> void {
|
||||
auto& group = hid->group(groupID);
|
||||
if(group.input(inputID).value() == value) return;
|
||||
input.doChange(hid, groupID, inputID, group.input(inputID).value(), value);
|
||||
|
@ -116,10 +115,12 @@ struct InputJoypadXInput {
|
|||
|
||||
//XInput supports a maximum of four controllers
|
||||
//add all four to devices list now. If they are not connected, they will not show up in poll() results
|
||||
for(unsigned id = 0; id < 4; id++) {
|
||||
for(auto id : range(4)) {
|
||||
Joypad jp;
|
||||
jp.id = id;
|
||||
jp.hid->setID((uint64_t)(1 + id) << 32 | 0x045e << 16 | 0x028e << 0); //Xbox 360 Player# + VendorID + ProductID
|
||||
jp.hid->setVendorID(0x045e);
|
||||
jp.hid->setProductID(0x028e);
|
||||
jp.hid->setPathID(id);
|
||||
jp.hid->setRumble(true);
|
||||
|
||||
jp.hid->axes().append("LeftThumbX");
|
||||
|
@ -158,5 +159,3 @@ struct InputJoypadXInput {
|
|||
libxinput = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
struct InputKeyboardCarbon {
|
||||
Input& input;
|
||||
InputKeyboardCarbon(Input& input) : input(input) {}
|
||||
|
@ -145,7 +147,9 @@ struct InputKeyboardCarbon {
|
|||
keys.append({0x3a, "Alt"});
|
||||
keys.append({0x37, "Super"});
|
||||
|
||||
hid->setID(1);
|
||||
hid->setVendorID(HID::Keyboard::GenericVendorID);
|
||||
hid->setProductID(HID::Keyboard::GenericProductID);
|
||||
hid->setPathID(0);
|
||||
for(auto& key : keys) {
|
||||
hid->buttons().append(key.name);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
struct InputKeyboardQuartz {
|
||||
Input& input;
|
||||
InputKeyboardQuartz(Input& input) : input(input) {}
|
||||
|
@ -140,7 +142,9 @@ struct InputKeyboardQuartz {
|
|||
keys.append({"Option", kVK_Option});
|
||||
keys.append({"Command", kVK_Command});
|
||||
|
||||
hid->setID(1);
|
||||
hid->setVendorID(HID::Keyboard::GenericVendorID);
|
||||
hid->setProductID(HID::Keyboard::GenericProductID);
|
||||
hid->setPath(0);
|
||||
for(auto& key : keys) {
|
||||
hid->buttons().append(key.name);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_KEYBOARD_RAWINPUT
|
||||
#define RUBY_INPUT_KEYBOARD_RAWINPUT
|
||||
#pragma once
|
||||
|
||||
struct InputKeyboardRawInput {
|
||||
Input& input;
|
||||
|
@ -18,8 +17,8 @@ struct InputKeyboardRawInput {
|
|||
} kb;
|
||||
|
||||
auto update(RAWINPUT* input) -> void {
|
||||
unsigned code = input->data.keyboard.MakeCode;
|
||||
unsigned flag = input->data.keyboard.Flags;
|
||||
uint code = input->data.keyboard.MakeCode;
|
||||
uint flag = input->data.keyboard.Flags;
|
||||
|
||||
for(auto& key : keys) {
|
||||
if(key.code != code) continue;
|
||||
|
@ -27,7 +26,7 @@ struct InputKeyboardRawInput {
|
|||
}
|
||||
}
|
||||
|
||||
auto assign(unsigned inputID, bool value) -> void {
|
||||
auto assign(uint inputID, bool value) -> void {
|
||||
auto& group = kb.hid->buttons();
|
||||
if(group.input(inputID).value() == value) return;
|
||||
input.doChange(kb.hid, HID::Keyboard::GroupID::Button, inputID, group.input(inputID).value(), value);
|
||||
|
@ -35,7 +34,7 @@ struct InputKeyboardRawInput {
|
|||
}
|
||||
|
||||
auto poll(vector<shared_pointer<HID::Device>>& devices) -> void {
|
||||
for(unsigned n = 0; n < keys.size(); n++) assign(n, keys[n].value);
|
||||
for(auto n : range(keys)) assign(n, keys[n].value);
|
||||
devices.append(kb.hid);
|
||||
}
|
||||
|
||||
|
@ -164,7 +163,9 @@ struct InputKeyboardRawInput {
|
|||
keys.append({0x005c, 2, "RightSuper"});
|
||||
keys.append({0x005d, 2, "Menu"});
|
||||
|
||||
kb.hid->setID(1);
|
||||
kb.hid->setVendorID(HID::Keyboard::GenericVendorID);
|
||||
kb.hid->setProductID(HID::Keyboard::GenericProductID);
|
||||
kb.hid->setPathID(0);
|
||||
for(auto& key : keys) kb.hid->buttons().append(key.name);
|
||||
|
||||
return true;
|
||||
|
@ -174,5 +175,3 @@ struct InputKeyboardRawInput {
|
|||
rawinput.updateKeyboard.reset();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_KEYBOARD_XLIB
|
||||
#define RUBY_INPUT_KEYBOARD_XLIB
|
||||
#pragma once
|
||||
|
||||
struct InputKeyboardXlib {
|
||||
Input& input;
|
||||
|
@ -153,7 +152,9 @@ struct InputKeyboardXlib {
|
|||
keys.append({"RightSuper", XK_Super_R});
|
||||
keys.append({"Menu", XK_Menu});
|
||||
|
||||
hid->setID(1);
|
||||
hid->setVendorID(HID::Keyboard::GenericVendorID);
|
||||
hid->setProductID(HID::Keyboard::GenericProductID);
|
||||
hid->setPathID(0);
|
||||
|
||||
for(auto& key : keys) {
|
||||
hid->buttons().append(key.name);
|
||||
|
@ -170,5 +171,3 @@ struct InputKeyboardXlib {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_MOUSE_RAWINPUT
|
||||
#define RUBY_INPUT_MOUSE_RAWINPUT
|
||||
#pragma once
|
||||
|
||||
struct InputMouseRawInput {
|
||||
Input& input;
|
||||
|
@ -11,9 +10,9 @@ struct InputMouseRawInput {
|
|||
struct Mouse {
|
||||
shared_pointer<HID::Mouse> hid{new HID::Mouse};
|
||||
|
||||
signed relativeX = 0;
|
||||
signed relativeY = 0;
|
||||
signed relativeZ = 0;
|
||||
int relativeX = 0;
|
||||
int relativeY = 0;
|
||||
int relativeZ = 0;
|
||||
bool buttons[5] = {0};
|
||||
} ms;
|
||||
|
||||
|
@ -68,7 +67,7 @@ struct InputMouseRawInput {
|
|||
if(input->data.mouse.usButtonFlags & RI_MOUSE_BUTTON_5_UP ) ms.buttons[4] = 0;
|
||||
}
|
||||
|
||||
auto assign(unsigned groupID, unsigned inputID, int16_t value) -> void {
|
||||
auto assign(uint groupID, uint inputID, int16_t value) -> void {
|
||||
auto& group = ms.hid->group(groupID);
|
||||
if(group.input(inputID).value() == value) return;
|
||||
input.doChange(ms.hid, groupID, inputID, group.input(inputID).value(), value);
|
||||
|
@ -99,7 +98,9 @@ struct InputMouseRawInput {
|
|||
if(!handle) return false;
|
||||
this->handle = handle;
|
||||
|
||||
ms.hid->setID(2);
|
||||
ms.hid->setVendorID(HID::Mouse::GenericVendorID);
|
||||
ms.hid->setProductID(HID::Mouse::GenericProductID);
|
||||
ms.hid->setPathID(0);
|
||||
|
||||
ms.hid->axes().append("X");
|
||||
ms.hid->axes().append("Y");
|
||||
|
@ -120,5 +121,3 @@ struct InputMouseRawInput {
|
|||
release();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_MOUSE_XLIB
|
||||
#define RUBY_INPUT_MOUSE_XLIB
|
||||
#pragma once
|
||||
|
||||
struct InputMouseXlib {
|
||||
Input& input;
|
||||
|
@ -12,16 +11,16 @@ struct InputMouseXlib {
|
|||
Display* display = nullptr;
|
||||
Window rootWindow = 0;
|
||||
Cursor invisibleCursor = 0;
|
||||
unsigned screenWidth = 0;
|
||||
unsigned screenHeight = 0;
|
||||
uint screenWidth = 0;
|
||||
uint screenHeight = 0;
|
||||
|
||||
struct Mouse {
|
||||
bool acquired = false;
|
||||
signed numerator = 0;
|
||||
signed denominator = 0;
|
||||
signed threshold = 0;
|
||||
unsigned relativeX = 0;
|
||||
unsigned relativeY = 0;
|
||||
int numerator = 0;
|
||||
int denominator = 0;
|
||||
int threshold = 0;
|
||||
uint relativeX = 0;
|
||||
uint relativeY = 0;
|
||||
} ms;
|
||||
|
||||
auto acquired() -> bool {
|
||||
|
@ -57,7 +56,7 @@ struct InputMouseXlib {
|
|||
return true;
|
||||
}
|
||||
|
||||
auto assign(unsigned groupID, unsigned inputID, int16_t value) -> void {
|
||||
auto assign(uint groupID, uint inputID, int16_t value) -> void {
|
||||
auto& group = hid->group(groupID);
|
||||
if(group.input(inputID).value() == value) return;
|
||||
input.doChange(hid, groupID, inputID, group.input(inputID).value(), value);
|
||||
|
@ -67,11 +66,11 @@ struct InputMouseXlib {
|
|||
auto poll(vector<shared_pointer<HID::Device>>& devices) -> void {
|
||||
Window rootReturn;
|
||||
Window childReturn;
|
||||
signed rootXReturn = 0;
|
||||
signed rootYReturn = 0;
|
||||
signed windowXReturn = 0;
|
||||
signed windowYReturn = 0;
|
||||
unsigned maskReturn = 0;
|
||||
int rootXReturn = 0;
|
||||
int rootYReturn = 0;
|
||||
int windowXReturn = 0;
|
||||
int windowYReturn = 0;
|
||||
uint maskReturn = 0;
|
||||
XQueryPointer(display, handle, &rootReturn, &childReturn, &rootXReturn, &rootYReturn, &windowXReturn, &windowYReturn, &maskReturn);
|
||||
|
||||
if(acquired()) {
|
||||
|
@ -132,7 +131,9 @@ struct InputMouseXlib {
|
|||
ms.relativeX = 0;
|
||||
ms.relativeY = 0;
|
||||
|
||||
hid->setID(2);
|
||||
hid->setVendorID(HID::Mouse::GenericVendorID);
|
||||
hid->setProductID(HID::Mouse::GenericProductID);
|
||||
hid->setPathID(0);
|
||||
|
||||
hid->axes().append("X");
|
||||
hid->axes().append("Y");
|
||||
|
@ -158,5 +159,3 @@ struct InputMouseXlib {
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include <SDL/SDL.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#ifndef RUBY_INPUT_SHARED_RAWINPUT
|
||||
#define RUBY_INPUT_SHARED_RAWINPUT
|
||||
#pragma once
|
||||
|
||||
auto CALLBACK RawInputWindowProc(HWND, UINT, WPARAM, LPARAM) -> LRESULT;
|
||||
|
||||
|
@ -14,7 +13,7 @@ struct RawInput {
|
|||
struct Device {
|
||||
HANDLE handle = nullptr;
|
||||
string path;
|
||||
enum class Type : unsigned { Keyboard, Mouse, Joypad } type;
|
||||
enum class Type : uint { Keyboard, Mouse, Joypad } type;
|
||||
uint16_t vendorID = 0;
|
||||
uint16_t productID = 0;
|
||||
bool isXInputDevice = false;
|
||||
|
@ -31,14 +30,14 @@ struct RawInput {
|
|||
auto scanDevices() -> void {
|
||||
devices.reset();
|
||||
|
||||
unsigned deviceCount = 0;
|
||||
uint deviceCount = 0;
|
||||
GetRawInputDeviceList(NULL, &deviceCount, sizeof(RAWINPUTDEVICELIST));
|
||||
RAWINPUTDEVICELIST* list = new RAWINPUTDEVICELIST[deviceCount];
|
||||
GetRawInputDeviceList(list, &deviceCount, sizeof(RAWINPUTDEVICELIST));
|
||||
|
||||
for(unsigned n = 0; n < deviceCount; n++) {
|
||||
for(auto n : range(deviceCount)) {
|
||||
wchar_t path[4096];
|
||||
unsigned size = sizeof(path) - 1;
|
||||
uint size = sizeof(path) - 1;
|
||||
GetRawInputDeviceInfo(list[n].hDevice, RIDI_DEVICENAME, &path, &size);
|
||||
|
||||
RID_DEVICE_INFO info;
|
||||
|
@ -80,7 +79,7 @@ struct RawInput {
|
|||
auto windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
|
||||
if(msg != WM_INPUT) return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
|
||||
unsigned size = 0;
|
||||
uint size = 0;
|
||||
GetRawInputData((HRAWINPUT)lparam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER));
|
||||
RAWINPUT* input = new RAWINPUT[size];
|
||||
GetRawInputData((HRAWINPUT)lparam, RID_INPUT, input, &size, sizeof(RAWINPUTHEADER));
|
||||
|
@ -154,5 +153,3 @@ auto WINAPI RawInputThreadProc(void*) -> DWORD {
|
|||
auto CALLBACK RawInputWindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) -> LRESULT {
|
||||
return rawinput.windowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -54,10 +54,6 @@ using namespace ruby;
|
|||
#include <ruby/video/glx2.cpp>
|
||||
#endif
|
||||
|
||||
#if defined(VIDEO_SDL)
|
||||
#include <ruby/video/sdl.cpp>
|
||||
#endif
|
||||
|
||||
#if defined(VIDEO_WGL)
|
||||
#include <ruby/video/wgl.cpp>
|
||||
#endif
|
||||
|
@ -99,10 +95,6 @@ auto Video::create(const string& driver) -> Video* {
|
|||
if(driver == "OpenGL2") return new VideoGLX2;
|
||||
#endif
|
||||
|
||||
#if defined(VIDEO_SDL)
|
||||
if(driver == "SDL") return new VideoSDL;
|
||||
#endif
|
||||
|
||||
#if defined(VIDEO_WGL)
|
||||
if(driver == "OpenGL") return new VideoWGL;
|
||||
#endif
|
||||
|
@ -137,8 +129,6 @@ auto Video::optimalDriver() -> string {
|
|||
return "XVideo";
|
||||
#elif defined(VIDEO_XSHM)
|
||||
return "XShm";
|
||||
#elif defined(VIDEO_SDL)
|
||||
return "SDL";
|
||||
#else
|
||||
return "None";
|
||||
#endif
|
||||
|
@ -157,8 +147,6 @@ auto Video::safestDriver() -> string {
|
|||
return "OpenGL";
|
||||
#elif defined(VIDEO_XSHM)
|
||||
return "XShm";
|
||||
#elif defined(VIDEO_SDL)
|
||||
return "SDL";
|
||||
#elif defined(VIDEO_XVIDEO)
|
||||
return "XVideo";
|
||||
#elif defined(VIDEO_GLX2)
|
||||
|
@ -209,10 +197,6 @@ auto Video::availableDrivers() -> string_vector {
|
|||
"XShm",
|
||||
#endif
|
||||
|
||||
#if defined(VIDEO_SDL)
|
||||
"SDL",
|
||||
#endif
|
||||
|
||||
"None"};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
#include <X11/extensions/Xv.h>
|
||||
#include <X11/extensions/Xvlib.h>
|
||||
#include <X11/extensions/XShm.h>
|
||||
#include <SDL/SDL.h>
|
||||
|
||||
struct VideoSDL : Video {
|
||||
VideoSDL() { initialize(); }
|
||||
~VideoSDL() { terminate(); }
|
||||
|
||||
auto ready() -> bool { return _ready; }
|
||||
|
||||
auto context() -> uintptr { return _context; }
|
||||
|
||||
auto setContext(uintptr context) -> bool {
|
||||
if(_context == context) return true;
|
||||
_context = context;
|
||||
return initialize();
|
||||
}
|
||||
|
||||
auto clear() -> void {
|
||||
if(!ready()) return;
|
||||
if(SDL_MUSTLOCK(_buffer)) SDL_LockSurface(_buffer);
|
||||
for(uint y : range(_bufferHeight)) {
|
||||
uint32_t* data = (uint32_t*)_buffer->pixels + y * (_buffer->pitch >> 2);
|
||||
for(uint x : range(_bufferWidth)) *data++ = 0xff000000;
|
||||
}
|
||||
if(SDL_MUSTLOCK(_buffer)) SDL_UnlockSurface(_buffer);
|
||||
output();
|
||||
}
|
||||
|
||||
auto lock(uint32_t*& data, uint& pitch, uint width, uint height) -> bool {
|
||||
if(!ready()) return false;
|
||||
if(width != _width || height != _height) resize(_width = width, _height = height);
|
||||
if(SDL_MUSTLOCK(_buffer)) SDL_LockSurface(_buffer);
|
||||
pitch = _buffer->pitch;
|
||||
return data = (uint32_t*)_buffer->pixels;
|
||||
}
|
||||
|
||||
auto unlock() -> void {
|
||||
if(!ready()) return;
|
||||
if(SDL_MUSTLOCK(_buffer)) SDL_UnlockSurface(_buffer);
|
||||
}
|
||||
|
||||
auto output() -> void {
|
||||
if(!ready()) return;
|
||||
|
||||
//ruby input is X8R8G8B8, top 8-bits are ignored.
|
||||
//as SDL forces us to use a 32-bit buffer, we must set alpha to 255 (full opacity)
|
||||
//to prevent blending against the window beneath when X window visual is 32-bits.
|
||||
if(SDL_MUSTLOCK(_buffer)) SDL_LockSurface(_buffer);
|
||||
for(uint y : range(_height)) {
|
||||
uint32_t* data = (uint32_t*)_buffer->pixels + y * (_buffer->pitch >> 2);
|
||||
for(uint x : range(_width)) *data++ |= 0xff000000;
|
||||
}
|
||||
if(SDL_MUSTLOCK(_buffer)) SDL_UnlockSurface(_buffer);
|
||||
|
||||
XWindowAttributes attributes;
|
||||
XGetWindowAttributes(_display, _context, &attributes);
|
||||
|
||||
SDL_Rect source;
|
||||
SDL_Rect target;
|
||||
|
||||
source.x = 0;
|
||||
source.y = 0;
|
||||
source.w = _width;
|
||||
source.h = _height;
|
||||
|
||||
target.x = 0;
|
||||
target.y = 0;
|
||||
target.w = attributes.width;
|
||||
target.h = attributes.height;
|
||||
|
||||
SDL_SoftStretch(_buffer, &source, _screen, &target);
|
||||
SDL_UpdateRect(_screen, target.x, target.y, target.w, target.h);
|
||||
}
|
||||
|
||||
private:
|
||||
auto initialize() -> bool {
|
||||
terminate();
|
||||
if(!_context) return false;
|
||||
|
||||
_display = XOpenDisplay(0);
|
||||
|
||||
char env[512];
|
||||
sprintf(env, "SDL_WINDOWID=%ld", (long)_context);
|
||||
putenv(env);
|
||||
|
||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||
_screen = SDL_SetVideoMode(2560, 1600, 32, SDL_HWSURFACE);
|
||||
XUndefineCursor(_display, _context);
|
||||
|
||||
_buffer = nullptr;
|
||||
_bufferWidth = 0;
|
||||
_bufferHeight = 0;
|
||||
resize(_width = 256, _height = 256);
|
||||
|
||||
return _ready = true;
|
||||
}
|
||||
|
||||
auto terminate() -> void {
|
||||
_ready = false;
|
||||
if(_buffer) SDL_FreeSurface(_buffer), _buffer = nullptr;
|
||||
if(_screen) SDL_QuitSubSystem(SDL_INIT_VIDEO), _screen = nullptr;
|
||||
if(_display) XCloseDisplay(_display), _display = nullptr;
|
||||
}
|
||||
|
||||
auto resize(uint width, uint height) -> void {
|
||||
if(_bufferWidth >= width && _bufferHeight >= height) return;
|
||||
|
||||
_bufferWidth = max(width, _bufferWidth);
|
||||
_bufferHeight = max(height, _bufferHeight);
|
||||
|
||||
if(_buffer) SDL_FreeSurface(_buffer);
|
||||
_buffer = SDL_CreateRGBSurface(
|
||||
SDL_SWSURFACE, _bufferWidth, _bufferHeight, 32,
|
||||
0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000
|
||||
);
|
||||
}
|
||||
|
||||
bool _ready = false;
|
||||
uintptr _context = 0;
|
||||
|
||||
Display* _display = nullptr;
|
||||
SDL_Surface* _screen = nullptr;
|
||||
SDL_Surface* _buffer = nullptr;
|
||||
uint _bufferWidth = 0;
|
||||
uint _bufferHeight = 0;
|
||||
uint _width = 0;
|
||||
uint _height = 0;
|
||||
};
|