Update to v075 release.

byuu says:

This release brings improved Super Game Boy emulation, the final SHA256
hashes for the DSP-(1,1B,2,3,4) and ST-(0010,0011) coprocessors, user
interface improvements, and major internal code restructuring.

Changelog (since v074):
- completely rewrote memory sub-system to support 1-byte granularity in
  XML mapping
- removed Memory inheritance and MMIO class completely, any address can
  be mapped to any function now
- SuperFX: removed SuperFXBus : Bus, now implemented manually
- SA-1: removed SA1Bus : Bus, now implemented manually
- entire bus mapping is now static, happens once on cartridge load
- as a result, read/write handlers now handle MMC mapping; slower
  average case, far faster worst case
- namespace memory is no more, RAM arrays are stored inside the chips
  they are owned by now
- GameBoy: improved CPU HALT emulation, fixes Zelda: Link's Awakening
  scrolling
- GameBoy: added serial emulation (cannot connect to another GB yet),
  fixes Shin Megami Tensei - Devichil
- GameBoy: improved LCD STAT emulation, fixes Sagaia
- ui: added fullscreen support (F11 key), video settings allows for
  three scale settings
- ui: fixed brightness, contrast, gamma, audio volume, input frequency
  values on program startup
- ui: since Qt is dead, config file becomes bsnes.cfg once again
- Super Game Boy: you can now load the BIOS without a game inserted to
  see a pretty white box
- ui-gameboy: can be built without SNES components now
- libsnes: now a UI target, compile with 'make ui=ui-libsnes'
- libsnes: added WRAM, APURAM, VRAM, OAM, CGRAM access (cheat search,
  etc)
- source: removed launcher/, as the Qt port is now gone
- source: Makefile restructuring to better support new ui targets
- source: lots of other internal code cleanup work
This commit is contained in:
Tim Allen 2011-01-27 19:52:34 +11:00
parent 53fe43afd8
commit 6b4104867f
59 changed files with 7121 additions and 6238 deletions

View File

@ -1,7 +1,7 @@
include nall/Makefile include nall/Makefile
snes := snes snes := snes
gameboy := gameboy gameboy := gameboy
profile := compatibility profile := accuracy
ui := ui ui := ui
# compiler # compiler
@ -50,39 +50,8 @@ obj/libco.o: libco/libco.c libco/*
include $(ui)/Makefile include $(ui)/Makefile
objects := $(patsubst %,obj/%.o,$(objects))
# targets # targets
build: ui_build $(objects) clean:
ifeq ($(platform),osx)
test -d ../$(output).app || mkdir -p ../$(output).app/Contents/MacOS
$(strip $(cpp) -o ../$(output).app/Contents/MacOS/$(output) $(objects) $(link))
else
$(strip $(cpp) -o out/$(output) $(objects) $(link))
endif
install:
ifeq ($(platform),x)
install -D -m 755 out/$(output) $(DESTDIR)$(prefix)/bin/$(output)
endif
ifeq ($(output),bsnes)
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
test -d ~/.bsnes || mkdir ~/.bsnes
cp data/cheats.xml ~/.bsnes/cheats.xml
chmod 777 ~/.bsnes ~/.bsnes/cheats.xml
endif
uninstall:
ifeq ($(platform),x)
rm $(DESTDIR)$(prefix)/bin/$(output)
endif
ifeq ($(output),bsnes)
rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
endif
clean: ui_clean
-@$(call delete,obj/*.o) -@$(call delete,obj/*.o)
-@$(call delete,obj/*.a) -@$(call delete,obj/*.a)
-@$(call delete,obj/*.so) -@$(call delete,obj/*.so)

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ Cartridge cartridge;
void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) { void Cartridge::load(const string &xml, const uint8_t *data, unsigned size) {
if(size == 0) size = 32768; if(size == 0) size = 32768;
romdata = new uint8[romsize = size](); romdata = allocate<uint8>(romsize = size, 0xff);
if(data) memcpy(romdata, data, size); if(data) memcpy(romdata, data, size);
//uint32_t crc = crc32_calculate(data, size); //uint32_t crc = crc32_calculate(data, size);

View File

@ -28,8 +28,6 @@ else ifeq ($(profile),performance)
snesppu := $(snes)/alt/ppu-performance snesppu := $(snes)/alt/ppu-performance
endif endif
obj/libsnes.o: $(snes)/libsnes/libsnes.cpp $(snes)/libsnes/*
obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/) obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/)
obj/snes-memory.o : $(snes)/memory/memory.cpp $(call rwildcard,$(snes)/memory/) obj/snes-memory.o : $(snes)/memory/memory.cpp $(call rwildcard,$(snes)/memory/)
obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/) obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/)
@ -55,37 +53,3 @@ obj/snes-st0018.o : $(snes)/chip/st0018/st0018.cpp $(snes)/chip/st0018/*
obj/snes-sufamiturbo.o: $(snes)/chip/sufamiturbo/sufamiturbo.cpp $(snes)/chip/sufamiturbo/* obj/snes-sufamiturbo.o: $(snes)/chip/sufamiturbo/sufamiturbo.cpp $(snes)/chip/sufamiturbo/*
obj/snes-msu1.o : $(snes)/chip/msu1/msu1.cpp $(snes)/chip/msu1/* obj/snes-msu1.o : $(snes)/chip/msu1/msu1.cpp $(snes)/chip/msu1/*
obj/snes-serial.o : $(snes)/chip/serial/serial.cpp $(snes)/chip/serial/* obj/snes-serial.o : $(snes)/chip/serial/serial.cpp $(snes)/chip/serial/*
###########
# library #
###########
snes_objects := $(patsubst %,obj/%.o,$(snes_objects))
library: $(snes_objects) obj/libsnes.o
ifeq ($(platform),x)
ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o
$(cpp) -o out/libsnes.so -shared -Wl,-soname,libsnes.so.1 $(snes_objects) obj/libsnes.o
else ifeq ($(platform),osx)
ar rcs out/libsnes.a $(snes_objects) obj/libsnes.o
$(cpp) -o out/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(snes_objects) obj/libsnes.o
else ifeq ($(platform),win)
$(cpp) -o out/snes.dll -shared -Wl,--out-implib,libsnes.a $(snes_objects) obj/libsnes.o
endif
library-install:
ifeq ($(platform),x)
install -D -m 755 out/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a
install -D -m 755 out/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so
ldconfig -n $(DESTDIR)$(prefix)/lib
else ifeq ($(platform),osx)
cp out/libsnes.dylib /usr/local/lib/libsnes.dylib
endif
library-uninstall:
ifeq ($(platform),x)
rm $(DESTDIR)$(prefix)/lib/libsnes.a
rm $(DESTDIR)$(prefix)/lib/libsnes.so
else ifeq ($(platform),osx)
rm /usr/local/lib/libsnes.dylib
endif

View File

@ -61,10 +61,12 @@ void Cartridge::load(Mode cartridge_mode, const lstring &xml_list) {
} }
void Cartridge::unload() { void Cartridge::unload() {
if(loaded == false) return;
system.unload();
rom.reset(); rom.reset();
ram.reset(); ram.reset();
if(loaded == false) return;
loaded = false; loaded = false;
} }

View File

@ -52,6 +52,7 @@ void Cartridge::parse_xml_cartridge(const char *data) {
} }
void Cartridge::parse_xml_bsx(const char *data) { void Cartridge::parse_xml_bsx(const char *data) {
has_bsx_slot = true;
} }
void Cartridge::parse_xml_sufami_turbo(const char *data, bool slot) { void Cartridge::parse_xml_sufami_turbo(const char *data, bool slot) {
@ -70,7 +71,7 @@ void Cartridge::xml_parse_rom(xml_element &root) {
if(attr.name == "offset") m.offset = hex(attr.content); if(attr.name == "offset") m.offset = hex(attr.content);
if(attr.name == "size") m.size = hex(attr.content); if(attr.name == "size") m.size = hex(attr.content);
} }
if(m.size == 0) m.size = rom.size() - m.offset; if(m.size == 0) m.size = rom.size();
mapping.append(m); mapping.append(m);
} }
} }
@ -90,7 +91,7 @@ void Cartridge::xml_parse_ram(xml_element &root) {
if(attr.name == "offset") m.offset = hex(attr.content); if(attr.name == "offset") m.offset = hex(attr.content);
if(attr.name == "size") m.size = hex(attr.content); if(attr.name == "size") m.size = hex(attr.content);
} }
if(m.size == 0) m.size = ram_size - m.offset; if(m.size == 0) m.size = ram_size;
mapping.append(m); mapping.append(m);
} }
} }

View File

@ -5,7 +5,7 @@ BSXCartridge bsxcartridge;
void BSXCartridge::init() { void BSXCartridge::init() {
} }
void BSXCartridge::enable() { void BSXCartridge::load() {
sram.map(allocate<uint8>(32 * 1024, 0xff), 32 * 1024); sram.map(allocate<uint8>(32 * 1024, 0xff), 32 * 1024);
sram.write_protect(false); sram.write_protect(false);
cartridge.nvram.append({ "bss", sram.data(), sram.size() }); cartridge.nvram.append({ "bss", sram.data(), sram.size() });
@ -15,6 +15,9 @@ void BSXCartridge::enable() {
cartridge.nvram.append({ "bsp", psram.data(), psram.size() }); cartridge.nvram.append({ "bsp", psram.data(), psram.size() });
} }
void BSXCartridge::unload() {
}
void BSXCartridge::power() { void BSXCartridge::power() {
reset(); reset();
} }

View File

@ -4,7 +4,8 @@ public:
MappedRAM psram; MappedRAM psram;
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -5,7 +5,14 @@ BSXFlash bsxflash;
void BSXFlash::init() { void BSXFlash::init() {
} }
void BSXFlash::enable() { void BSXFlash::load() {
if(memory.size() == 0) {
memory.map(allocate<uint8>(1024 * 1024, 0xff), 1024 * 1024);
}
}
void BSXFlash::unload() {
memory.reset();
} }
void BSXFlash::power() { void BSXFlash::power() {

View File

@ -3,7 +3,8 @@ public:
MappedRAM memory; MappedRAM memory;
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -5,11 +5,14 @@ BSXSatellaview bsxsatellaview;
void BSXSatellaview::init() { void BSXSatellaview::init() {
} }
void BSXSatellaview::enable() { void BSXSatellaview::load() {
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2188, 0x219f, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview }); bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2188, 0x219f, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview });
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2188, 0x219f, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview }); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2188, 0x219f, { &BSXSatellaview::mmio_read, &bsxsatellaview }, { &BSXSatellaview::mmio_write, &bsxsatellaview });
} }
void BSXSatellaview::unload() {
}
void BSXSatellaview::power() { void BSXSatellaview::power() {
reset(); reset();
} }

View File

@ -1,7 +1,8 @@
class BSXSatellaview { class BSXSatellaview {
public: public:
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -20,7 +20,10 @@ Cx4 cx4;
void Cx4::init() { void Cx4::init() {
} }
void Cx4::enable() { void Cx4::load() {
}
void Cx4::unload() {
} }
uint32 Cx4::ldr(uint8 r) { uint32 Cx4::ldr(uint8 r) {

View File

@ -1,7 +1,8 @@
class Cx4 { class Cx4 {
public: public:
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -31,13 +31,16 @@ void ICD2::enter() {
void ICD2::init() { void ICD2::init() {
} }
void ICD2::enable() { void ICD2::load() {
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2181, 0x2182, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 }); bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2181, 0x2182, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 });
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x420b, 0x420b, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 }); bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x420b, 0x420b, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 });
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2181, 0x2182, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 }); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2181, 0x2182, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 });
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x420b, 0x420b, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 }); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x420b, 0x420b, { &ICD2::mmio_read, &icd2 }, { &ICD2::mmio_write, &icd2 });
} }
void ICD2::unload() {
}
void ICD2::power() { void ICD2::power() {
reset(); reset();
} }

View File

@ -6,7 +6,8 @@ public:
void enter(); void enter();
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -48,11 +48,15 @@ void MSU1::enter() {
void MSU1::init() { void MSU1::init() {
} }
void MSU1::enable() { void MSU1::load() {
if(datafile.open()) datafile.close(); if(datafile.open()) datafile.close();
datafile.open(string(cartridge.basename(), ".msu"), file::mode::read); datafile.open(string(cartridge.basename(), ".msu"), file::mode::read);
} }
void MSU1::unload() {
if(datafile.open()) datafile.close();
}
void MSU1::power() { void MSU1::power() {
audio.coprocessor_enable(true); audio.coprocessor_enable(true);
audio.coprocessor_frequency(44100.0); audio.coprocessor_frequency(44100.0);

View File

@ -3,7 +3,8 @@ public:
static void Enter(); static void Enter();
void enter(); void enter();
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -245,12 +245,15 @@ void NECDSP::exec_ld(uint24 opcode) {
void NECDSP::init() { void NECDSP::init() {
} }
void NECDSP::enable() { void NECDSP::load() {
if(revision == Revision::uPD96050) { if(revision == Revision::uPD96050) {
cartridge.nvram.append({ "nec", (uint8_t*)dataRAM, 4096 }); cartridge.nvram.append({ "nec", (uint8_t*)dataRAM, 4096 });
} }
} }
void NECDSP::unload() {
}
void NECDSP::power() { void NECDSP::power() {
if(revision == Revision::uPD7725) { if(revision == Revision::uPD7725) {
regs.pc.bits(11); regs.pc.bits(11);

View File

@ -33,7 +33,8 @@ public:
void dp_write(unsigned addr, uint8 data); void dp_write(unsigned addr, uint8 data);
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -10,7 +10,10 @@ OBC1 obc1;
void OBC1::init() { void OBC1::init() {
} }
void OBC1::enable() { void OBC1::load() {
}
void OBC1::unload() {
} }
void OBC1::power() { void OBC1::power() {

View File

@ -1,7 +1,8 @@
class OBC1 { class OBC1 {
public: public:
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -118,7 +118,10 @@ void SA1::trigger_irq() {
void SA1::init() { void SA1::init() {
} }
void SA1::enable() { void SA1::load() {
}
void SA1::unload() {
} }
void SA1::power() { void SA1::power() {

View File

@ -26,7 +26,8 @@ public:
alwaysinline bool interrupt_pending(); alwaysinline bool interrupt_pending();
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -11,13 +11,16 @@ SDD1 sdd1;
void SDD1::init() { void SDD1::init() {
} }
void SDD1::enable() { void SDD1::load() {
//hook S-CPU DMA MMIO registers to gather information for struct dma[]; //hook S-CPU DMA MMIO registers to gather information for struct dma[];
//buffer address and transfer size information for use in SDD1::mcu_read() //buffer address and transfer size information for use in SDD1::mcu_read()
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 }); bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 }); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4300, 0x437f, { &SDD1::mmio_read, &sdd1 }, { &SDD1::mmio_write, &sdd1 });
} }
void SDD1::unload() {
}
void SDD1::power() { void SDD1::power() {
reset(); reset();
} }

View File

@ -3,7 +3,8 @@
class SDD1 { class SDD1 {
public: public:
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -77,7 +77,7 @@ void Serial::mmio_write(unsigned addr, uint8 data) {
void Serial::init() { void Serial::init() {
} }
void Serial::enable() { void Serial::load() {
if(opened()) close(); if(opened()) close();
string name = notdir(cartridge.basename()); string name = notdir(cartridge.basename());
string path = dir(cartridge.basename()); string path = dir(cartridge.basename());
@ -91,6 +91,10 @@ void Serial::enable() {
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, { &Serial::mmio_read, &serial }, { &Serial::mmio_write, &serial }); bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x4016, 0x4017, { &Serial::mmio_read, &serial }, { &Serial::mmio_write, &serial });
} }
void Serial::unload() {
if(opened()) close();
}
void Serial::power() { void Serial::power() {
reset(); reset();
} }

View File

@ -3,7 +3,8 @@ public:
static void Enter(); static void Enter();
void enter(); void enter();
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();
void serialize(serializer&); void serialize(serializer&);

View File

@ -13,11 +13,14 @@ const unsigned SPC7110::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 3
void SPC7110::init() { void SPC7110::init() {
} }
void SPC7110::enable() { void SPC7110::load() {
for(unsigned n = 0; n < 20; n++) rtc[n] = 0xff; for(unsigned n = 0; n < 20; n++) rtc[n] = 0xff;
if(cartridge.has_spc7110rtc()) cartridge.nvram.append({ "rtc", rtc, 20 }); if(cartridge.has_spc7110rtc()) cartridge.nvram.append({ "rtc", rtc, 20 });
} }
void SPC7110::unload() {
}
void SPC7110::power() { void SPC7110::power() {
reset(); reset();
} }

View File

@ -23,7 +23,8 @@ public:
unsigned data_rom_offset; unsigned data_rom_offset;
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -12,11 +12,14 @@ const unsigned SRTC::months[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30,
void SRTC::init() { void SRTC::init() {
} }
void SRTC::enable() { void SRTC::load() {
for(unsigned n = 0; n < 20; n++) rtc[n] = 0xff; for(unsigned n = 0; n < 20; n++) rtc[n] = 0xff;
cartridge.nvram.append({ "rtc", rtc, 20 }); cartridge.nvram.append({ "rtc", rtc, 20 });
} }
void SRTC::unload() {
}
void SRTC::power() { void SRTC::power() {
reset(); reset();
} }

View File

@ -3,7 +3,8 @@ public:
uint8 rtc[20]; uint8 rtc[20];
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -48,7 +48,10 @@ void ST0018::mmio_write(unsigned addr, uint8 data) {
void ST0018::init() { void ST0018::init() {
} }
void ST0018::enable() { void ST0018::load() {
}
void ST0018::unload() {
} }
void ST0018::power() { void ST0018::power() {

View File

@ -1,7 +1,8 @@
class ST0018 { class ST0018 {
public: public:
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();

View File

@ -6,16 +6,28 @@ namespace SNES {
#include "serialization.cpp" #include "serialization.cpp"
SufamiTurbo sufamiturbo; SufamiTurbo sufamiturbo;
void SufamiTurbo::enable() { void SufamiTurbo::load() {
if(slotA.rom.data()) {
slotA.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024); slotA.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
slotB.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
if(slotA.rom.data()) {
cartridge.nvram.append({ "srm", slotA.ram.data(), slotA.ram.size(), 1 }); cartridge.nvram.append({ "srm", slotA.ram.data(), slotA.ram.size(), 1 });
} else {
slotA.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
} }
if(slotB.rom.data()) { if(slotB.rom.data()) {
slotB.ram.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
cartridge.nvram.append({ "srm", slotB.ram.data(), slotB.ram.size(), 2 }); cartridge.nvram.append({ "srm", slotB.ram.data(), slotB.ram.size(), 2 });
} else {
slotB.rom.map(allocate<uint8>(128 * 1024, 0xff), 128 * 1024);
} }
} }
void SufamiTurbo::unload() {
slotA.rom.reset();
slotA.ram.reset();
slotB.rom.reset();
slotB.ram.reset();
}
} }

View File

@ -5,7 +5,8 @@ public:
MappedRAM ram; MappedRAM ram;
} slotA, slotB; } slotA, slotB;
void enable(); void load();
void unload();
void serialize(serializer&); void serialize(serializer&);
}; };

View File

@ -43,7 +43,10 @@ void SuperFX::init() {
regs.r[15].on_modify = { &SuperFX::r15_modify, this }; regs.r[15].on_modify = { &SuperFX::r15_modify, this };
} }
void SuperFX::enable() { void SuperFX::load() {
}
void SuperFX::unload() {
} }
void SuperFX::power() { void SuperFX::power() {

View File

@ -10,7 +10,8 @@ public:
static void Enter(); static void Enter();
void enter(); void enter();
void init(); void init();
void enable(); void load();
void unload();
void power(); void power();
void reset(); void reset();
void serialize(serializer&); void serialize(serializer&);

View File

@ -45,10 +45,10 @@ void Bus::map(
for(unsigned addr = addr_lo; addr <= addr_hi; addr++) { for(unsigned addr = addr_lo; addr <= addr_hi; addr++) {
unsigned destaddr = (bank << 16) | addr; unsigned destaddr = (bank << 16) | addr;
if(mode == MapMode::Linear) { if(mode == MapMode::Linear) {
destaddr = base + mirror(offset, length); destaddr = mirror(base + offset, length);
offset = (offset + 1) % length; offset = (offset + 1) % length;
} else if(mode == MapMode::Shadow) { } else if(mode == MapMode::Shadow) {
destaddr = base + mirror(destaddr, length); destaddr = mirror(base + destaddr, length);
} }
lookup[(bank << 16) | addr] = id; lookup[(bank << 16) | addr] = id;
target[(bank << 16) | addr] = destaddr; target[(bank << 16) | addr] = destaddr;

View File

@ -1,7 +1,7 @@
namespace SNES { namespace SNES {
namespace Info { namespace Info {
static const char Name[] = "bsnes"; static const char Name[] = "bsnes";
static const char Version[] = "074.11"; static const char Version[] = "075";
static const unsigned SerializerVersion = 17; static const unsigned SerializerVersion = 17;
} }
} }

View File

@ -104,23 +104,43 @@ void System::load() {
cpu.enable(); cpu.enable();
ppu.enable(); ppu.enable();
if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.enable(); if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.load();
if(cartridge.mode() == Cartridge::Mode::Bsx) bsxcartridge.enable(); if(cartridge.mode() == Cartridge::Mode::Bsx) bsxcartridge.load();
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.enable(); if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.load();
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.enable(); if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.load();
if(cartridge.has_bsx_slot()) bsxflash.enable(); if(cartridge.has_bsx_slot()) bsxflash.load();
if(cartridge.has_superfx()) superfx.enable(); if(cartridge.has_superfx()) superfx.load();
if(cartridge.has_sa1()) sa1.enable(); if(cartridge.has_sa1()) sa1.load();
if(cartridge.has_necdsp()) necdsp.enable(); if(cartridge.has_necdsp()) necdsp.load();
if(cartridge.has_srtc()) srtc.enable(); if(cartridge.has_srtc()) srtc.load();
if(cartridge.has_sdd1()) sdd1.enable(); if(cartridge.has_sdd1()) sdd1.load();
if(cartridge.has_spc7110()) spc7110.enable(); if(cartridge.has_spc7110()) spc7110.load();
if(cartridge.has_cx4()) cx4.enable(); if(cartridge.has_cx4()) cx4.load();
if(cartridge.has_obc1()) obc1.enable(); if(cartridge.has_obc1()) obc1.load();
if(cartridge.has_st0018()) st0018.enable(); if(cartridge.has_st0018()) st0018.load();
if(cartridge.has_msu1()) msu1.enable(); if(cartridge.has_msu1()) msu1.load();
if(cartridge.has_serial()) serial.enable(); if(cartridge.has_serial()) serial.load();
}
void System::unload() {
if(expansion() == ExpansionPortDevice::BSX) bsxsatellaview.unload();
if(cartridge.mode() == Cartridge::Mode::Bsx) bsxcartridge.unload();
if(cartridge.mode() == Cartridge::Mode::SufamiTurbo) sufamiturbo.unload();
if(cartridge.mode() == Cartridge::Mode::SuperGameBoy) icd2.unload();
if(cartridge.has_bsx_slot()) bsxflash.unload();
if(cartridge.has_superfx()) superfx.unload();
if(cartridge.has_sa1()) sa1.unload();
if(cartridge.has_necdsp()) necdsp.unload();
if(cartridge.has_srtc()) srtc.unload();
if(cartridge.has_sdd1()) sdd1.unload();
if(cartridge.has_spc7110()) spc7110.unload();
if(cartridge.has_cx4()) cx4.unload();
if(cartridge.has_obc1()) obc1.unload();
if(cartridge.has_st0018()) st0018.unload();
if(cartridge.has_msu1()) msu1.unload();
if(cartridge.has_serial()) serial.unload();
} }
void System::power() { void System::power() {
@ -209,9 +229,6 @@ void System::reset() {
input.update(); input.update();
} }
void System::unload() {
}
void System::scanline() { void System::scanline() {
video.scanline(); video.scanline();
if(cpu.vcounter() == 241) scheduler.exit(Scheduler::ExitReason::FrameEvent); if(cpu.vcounter() == 241) scheduler.exit(Scheduler::ExitReason::FrameEvent);

View File

@ -11,9 +11,9 @@ public:
void init(Interface*); void init(Interface*);
void term(); void term();
void load(); void load();
void unload();
void power(); void power();
void reset(); void reset();
void unload();
void frame(); void frame();
void scanline(); void scanline();

View File

@ -1,4 +1,3 @@
output := bgameboy
include $(gameboy)/Makefile include $(gameboy)/Makefile
ui_objects := ui-main ui-utility ui_objects := ui-main ui-utility
@ -58,6 +57,7 @@ rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
# rules # rules
objects := $(ui_objects) $(objects) objects := $(ui_objects) $(objects)
objects := $(patsubst %,obj/%.o,$(objects))
obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*); $(phoenix_compile) obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*); $(phoenix_compile)
obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/utility/*); $(phoenix_compile) obj/ui-utility.o: $(ui)/utility/utility.cpp $(call rwildcard,$(ui)/utility/*); $(phoenix_compile)
@ -69,6 +69,20 @@ obj/phoenix.o: phoenix/phoenix.cpp $(call rwildcard,phoenix/*)
$(phoenix_compile) $(phoenix_compile)
# targets # targets
ui_build:; build: $(objects)
ifeq ($(platform),osx)
test -d ../bgameboy.app || mkdir -p ../bgameboy.app/Contents/MacOS
$(strip $(cpp) -o ../bgameboy.app/Contents/MacOS/bgameboy $(objects) $(link))
else
$(strip $(cpp) -o out/bgameboy $(objects) $(link))
endif
ui_clean:; install:
ifeq ($(platform),x)
install -D -m 755 out/bgameboy $(DESTDIR)$(prefix)/bin/bgameboy
endif
uninstall:
ifeq ($(platform),x)
rm $(DESTDIR)$(prefix)/bin/bgameboy
endif

45
bsnes/ui-libsnes/Makefile Executable file
View File

@ -0,0 +1,45 @@
include $(snes)/Makefile
include $(gameboy)/Makefile
output := libsnes
ifeq ($(platform),x)
flags += -fPIC
else ifeq ($(platform),osx)
flags += -fPIC
else ifeq ($(platform),win)
endif
#rules
objects := $(objects) libsnes
objects := $(patsubst %,obj/%.o,$(objects))
obj/libsnes.o: $(ui)/libsnes.cpp $(ui)/*
#targets
build: $(objects)
ifeq ($(platform),x)
ar rcs out/libsnes.a $(objects)
$(cpp) -o out/libsnes.so -shared -Wl,-soname,libsnes.so.1 $(objects)
else ifeq ($(platform),osx)
ar rcs out/libsnes.a $(objects)
$(cpp) -o out/libsnes.dylib -install_name @executable_path/../Libraries/libsnes.dylib -shared -dynamiclib $(objects)
else ifeq ($(platform),win)
$(cpp) -o out/snes.dll -shared -Wl,--out-implib,libsnes.a $(objects)
endif
install:
ifeq ($(platform),x)
install -D -m 755 out/libsnes.a $(DESTDIR)$(prefix)/lib/libsnes.a
install -D -m 755 out/libsnes.so $(DESTDIR)$(prefix)/lib/libsnes.so
ldconfig -n $(DESTDIR)$(prefix)/lib
else ifeq ($(platform),osx)
cp out/libsnes.dylib /usr/local/lib/libsnes.dylib
endif
uninstall:
ifeq ($(platform),x)
rm $(DESTDIR)$(prefix)/lib/libsnes.a
rm $(DESTDIR)$(prefix)/lib/libsnes.so
else ifeq ($(platform),osx)
rm /usr/local/lib/libsnes.dylib
endif

View File

@ -1,4 +1,3 @@
output := bsnes
include $(snes)/Makefile include $(snes)/Makefile
include $(gameboy)/Makefile include $(gameboy)/Makefile
@ -60,6 +59,7 @@ rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),-D$c)
# rules # rules
objects := $(ui_objects) $(objects) objects := $(ui_objects) $(objects)
objects := $(patsubst %,obj/%.o,$(objects))
obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*); $(phoenix_compile) obj/ui-main.o: $(ui)/main.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/*); $(phoenix_compile)
obj/ui-general.o: $(ui)/general/general.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/general/*); $(phoenix_compile) obj/ui-general.o: $(ui)/general/general.cpp $(call rwildcard,$(ui)/*.hpp) $(call rwildcard,$(ui)/general/*); $(phoenix_compile)
@ -80,6 +80,27 @@ obj/resource.o: $(ui)/resource.rc
windres $(ui)/resource.rc obj/resource.o windres $(ui)/resource.rc obj/resource.o
# targets # targets
ui_build:; build: $(objects)
ifeq ($(platform),osx)
test -d ../bsnes.app || mkdir -p ../bsnes.app/Contents/MacOS
$(strip $(cpp) -o ../bsnes.app/Contents/MacOS/bsnes $(objects) $(link))
else
$(strip $(cpp) -o out/bsnes $(objects) $(link))
endif
ui_clean:; install:
ifeq ($(platform),x)
install -D -m 755 out/bsnes $(DESTDIR)$(prefix)/bin/bsnes
endif
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
test -d ~/.bsnes || mkdir ~/.bsnes
cp data/cheats.xml ~/.bsnes/cheats.xml
chmod 777 ~/.bsnes ~/.bsnes/cheats.xml
uninstall:
ifeq ($(platform),x)
rm $(DESTDIR)$(prefix)/bin/bsnes
endif
rm $(DESTDIR)$(prefix)/share/pixmaps/bsnes.png
rm $(DESTDIR)$(prefix)/share/applications/bsnes.desktop

View File

@ -22,6 +22,7 @@ void Configuration::create() {
attach(video.shader = "", "video.shader"); attach(video.shader = "", "video.shader");
attach(video.region = 0, "video.region"); attach(video.region = 0, "video.region");
attach(video.scale = 2, "video.scale"); attach(video.scale = 2, "video.scale");
attach(video.fullscreenScale = 0, "video.fullscreenScale");
attach(video.aspectRatioCorrection = true, "video.aspectRatioCorrection"); attach(video.aspectRatioCorrection = true, "video.aspectRatioCorrection");
attach(video.brightness = 100, "video.brightness"); attach(video.brightness = 100, "video.brightness");
attach(video.contrast = 100, "video.contrast"); attach(video.contrast = 100, "video.contrast");

View File

@ -16,6 +16,7 @@ struct Configuration : public configuration {
string shader; string shader;
bool region; bool region;
unsigned scale; unsigned scale;
unsigned fullscreenScale;
bool aspectRatioCorrection; bool aspectRatioCorrection;
unsigned brightness; unsigned brightness;
unsigned contrast; unsigned contrast;

View File

@ -7,14 +7,12 @@ void AudioSettings::create() {
unsigned x = 5, y = 5; unsigned x = 5, y = 5;
volumeLabel.create(*this, x, y, 70, Style::SliderHeight, "Volume:"); volumeLabel.create(*this, x, y, 70, Style::SliderHeight, "Volume:");
volumeValue.create(*this, x + 70, y, 60, Style::SliderHeight, "100%"); volumeValue.create(*this, x + 70, y, 60, Style::SliderHeight);
volumeSlider.create(*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight + 5; volumeSlider.create(*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight + 5;
volumeSlider.setPosition(config.audio.volume);
frequencyLabel.create(*this, x, y, 70, Style::SliderHeight, "Frequency:"); frequencyLabel.create(*this, x, y, 70, Style::SliderHeight, "Frequency:");
frequencyValue.create(*this, x + 70, y, 60, Style::SliderHeight, "32000hz"); frequencyValue.create(*this, x + 70, y, 60, Style::SliderHeight);
frequencySlider.create(*this, x + 130, y, 300, Style::SliderHeight, 2001); y += Style::SliderHeight + 5; frequencySlider.create(*this, x + 130, y, 300, Style::SliderHeight, 2001); y += Style::SliderHeight + 5;
frequencySlider.setPosition(config.audio.inputFrequency - 31000);
volumeSlider.onChange = []() { volumeSlider.onChange = []() {
config.audio.volume = audioSettings.volumeSlider.position(); config.audio.volume = audioSettings.volumeSlider.position();
@ -29,4 +27,10 @@ void AudioSettings::create() {
}; };
setGeometry(0, 0, 440, y); setGeometry(0, 0, 440, y);
volumeSlider.setPosition(config.audio.volume);
volumeValue.setText({ config.audio.volume, "%" });
frequencySlider.setPosition(config.audio.inputFrequency - 31000);
frequencyValue.setText({ config.audio.inputFrequency, "hz" });
} }

View File

@ -10,19 +10,26 @@ void VideoSettings::create() {
colorAdjustmentLabel.setFont(application.proportionalFontBold); colorAdjustmentLabel.setFont(application.proportionalFontBold);
brightnessLabel.create (*this, x, y, 80, Style::SliderHeight, "Brightness:"); brightnessLabel.create (*this, x, y, 80, Style::SliderHeight, "Brightness:");
brightnessValue.create (*this, x + 80, y, 40, Style::SliderHeight, "100%"); brightnessValue.create (*this, x + 80, y, 40, Style::SliderHeight);
brightnessSlider.create(*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight; brightnessSlider.create(*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight;
contrastLabel.create (*this, x, y, 80, Style::SliderHeight, "Contrast:"); contrastLabel.create (*this, x, y, 80, Style::SliderHeight, "Contrast:");
contrastValue.create (*this, x + 80, y, 50, Style::SliderHeight, "100%"); contrastValue.create (*this, x + 80, y, 50, Style::SliderHeight);
contrastSlider.create (*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight; contrastSlider.create (*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight;
gammaLabel.create (*this, x, y, 80, Style::SliderHeight, "Gamma:"); gammaLabel.create (*this, x, y, 80, Style::SliderHeight, "Gamma:");
gammaValue.create (*this, x + 80, y, 50, Style::SliderHeight, "100%"); gammaValue.create (*this, x + 80, y, 50, Style::SliderHeight);
gammaSlider.create (*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight + 5; gammaSlider.create (*this, x + 130, y, 300, Style::SliderHeight, 201); y += Style::SliderHeight + 5;
gammaRampCheck.create (*this, x, y, 430, Style::CheckBoxHeight, "Enable NTSC gamma ramp simulation"); y += Style::CheckBoxHeight + 5; gammaRampCheck.create (*this, x, y, 430, Style::CheckBoxHeight, "Enable NTSC gamma ramp simulation"); y += Style::CheckBoxHeight + 5;
fullscreenLabel.create(*this, x, y, 340, Style::LabelHeight, "Fullscreen :."); y += Style::LabelHeight + 5;
fullscreenLabel.setFont(application.proportionalFontBold);
fullscreenCenter.create (*this, x, y, 135, Style::CheckBoxHeight, "Center");
fullscreenScale.create (fullscreenCenter, x + 140, y, 135, Style::CheckBoxHeight, "Scale");
fullscreenStretch.create(fullscreenCenter, x + 280, y, 135, Style::CheckBoxHeight, "Stretch"); y += Style::CheckBoxHeight + 5;
filterLabel.create(*this, x, y, 340, Style::LabelHeight, "Video Filter :."); y += Style::LabelHeight + 5; filterLabel.create(*this, x, y, 340, Style::LabelHeight, "Video Filter :."); y += Style::LabelHeight + 5;
filterLabel.setFont(application.proportionalFontBold); filterLabel.setFont(application.proportionalFontBold);
@ -44,13 +51,29 @@ void VideoSettings::create() {
setGeometry(0, 0, 440, y); setGeometry(0, 0, 440, y);
brightnessSlider.setPosition(config.video.brightness); brightnessSlider.setPosition(config.video.brightness);
brightnessValue.setText({ config.video.brightness, "%" });
contrastSlider.setPosition(config.video.contrast); contrastSlider.setPosition(config.video.contrast);
contrastValue.setText({ config.video.contrast, "%" });
gammaSlider.setPosition(config.video.gamma); gammaSlider.setPosition(config.video.gamma);
gammaValue.setText({ config.video.gamma, "%" });
gammaRampCheck.setChecked(config.video.useGammaRamp); gammaRampCheck.setChecked(config.video.useGammaRamp);
switch(config.video.fullscreenScale) { default:
case 0: fullscreenCenter.setChecked(); break;
case 1: fullscreenScale.setChecked(); break;
case 2: fullscreenStretch.setChecked(); break;
}
contrastSlider.onChange = brightnessSlider.onChange = gammaSlider.onChange = gammaRampCheck.onTick = contrastSlider.onChange = brightnessSlider.onChange = gammaSlider.onChange = gammaRampCheck.onTick =
{ &VideoSettings::adjust, this }; { &VideoSettings::adjust, this };
fullscreenCenter.onTick = []() { config.video.fullscreenScale = 0; };
fullscreenScale.onTick = []() { config.video.fullscreenScale = 1; };
fullscreenStretch.onTick = []() { config.video.fullscreenScale = 2; };
filterClear.onTick = []() { filterClear.onTick = []() {
config.video.filter = ""; config.video.filter = "";
videoSettings.filterPath.setText(config.video.filter); videoSettings.filterPath.setText(config.video.filter);

View File

@ -11,6 +11,11 @@ struct VideoSettings : TopLevelWindow {
HorizontalSlider gammaSlider; HorizontalSlider gammaSlider;
CheckBox gammaRampCheck; CheckBox gammaRampCheck;
Label fullscreenLabel;
RadioBox fullscreenCenter;
RadioBox fullscreenScale;
RadioBox fullscreenStretch;
Label filterLabel; Label filterLabel;
TextBox filterPath; TextBox filterPath;
Button filterClear; Button filterClear;

View File

@ -82,10 +82,36 @@ void Utility::setFullscreen(bool fullscreen) {
if(fullscreen == false) { if(fullscreen == false) {
setScale(); setScale();
} else { } else {
unsigned width, height;
switch(config.video.fullscreenScale) { default:
case 0: { //center (even multiple of base height)
unsigned baseHeight = config.video.region == 0 ? 224 : 239; unsigned baseHeight = config.video.region == 0 ? 224 : 239;
unsigned heightScale = OS::desktopHeight() / baseHeight; unsigned heightScale = OS::desktopHeight() / baseHeight;
unsigned height = baseHeight * heightScale; height = baseHeight * heightScale;
unsigned width = min(OS::desktopWidth(), (unsigned)(256.0 / baseHeight * height)); width = 256 * heightScale;
if(config.video.region == 0 && config.video.aspectRatioCorrection) width *= 54.0 / 47.0;
if(config.video.region == 1 && config.video.aspectRatioCorrection) width *= 32.0 / 23.0;
width = min(width, OS::desktopWidth());
break;
}
case 1: { //scale (100% screen height, aspect-corrected width)
unsigned baseHeight = config.video.region == 0 ? 224 : 239;
height = OS::desktopHeight();
width = 256.0 / baseHeight * height;
if(config.video.region == 0 && config.video.aspectRatioCorrection) width *= 54.0 / 47.0;
if(config.video.region == 1 && config.video.aspectRatioCorrection) width *= 32.0 / 23.0;
width = min(width, OS::desktopWidth());
break;
}
case 2: { //stretch (100% screen width and 100% screen height)
width = OS::desktopWidth();
height = OS::desktopHeight();
break;
}
}
mainWindow.viewport.setGeometry( mainWindow.viewport.setGeometry(
(OS::desktopWidth() - width) / 2, (OS::desktopWidth() - width) / 2,
(OS::desktopHeight() - height) / 2, (OS::desktopHeight() - height) / 2,