diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index f023a238..e1a86f6f 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -6,7 +6,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "096.05"; + static const string Version = "096.06"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/sfc/coprocessor/hitachidsp/memory.cpp b/higan/sfc/coprocessor/hitachidsp/memory.cpp index 9a3a2614..669fb2e5 100644 --- a/higan/sfc/coprocessor/hitachidsp/memory.cpp +++ b/higan/sfc/coprocessor/hitachidsp/memory.cpp @@ -1,11 +1,14 @@ auto HitachiDSP::bus_read(uint24 addr) -> uint8 { - if((addr & 0x40e000) == 0x006000) { //$00-3f,80-bf:6000-7fff + if((addr & 0x40ec00) == 0x006c00) { //$00-3f,80-bf:6c00-6cff,7c00-7cff return dsp_read(addr, 0x00); } + if((addr & 0x40e000) == 0x006000) { //$00-3f,80-bf:6000-6bff,7000-7bff + return dram_read(addr, 0x00); + } if((addr & 0x408000) == 0x008000) { //$00-3f,80-bf:8000-ffff if(rom.size() == 0) return 0x00; addr = ((addr & 0x3f0000) >> 1) | (addr & 0x7fff); - addr = bus.mirror(addr, rom.size()); + addr = Bus::mirror(addr, rom.size()); return rom.read(addr, 0); } if((addr & 0xf88000) == 0x700000) { //$70-77:0000-7fff @@ -18,8 +21,11 @@ auto HitachiDSP::bus_read(uint24 addr) -> uint8 { } auto HitachiDSP::bus_write(uint24 addr, uint8 data) -> void { - if((addr & 0x40e000) == 0x006000) { //$00-3f,80-bf:6000-7fff - return dsp_write(addr & 0x1fff, data); + if((addr & 0x40ec00) == 0x006c00) { //$00-3f,80-bf:6c00-6fff,7c00-7fff + return dsp_write(addr, data); + } + if((addr & 0x40e000) == 0x006000) { //$00-3f,80-bf:6000-6bff,7000-7bff + return dram_write(addr, data); } if((addr & 0xf88000) == 0x700000) { //$70-77:0000-7fff if(ram.size() == 0) return; @@ -31,7 +37,7 @@ auto HitachiDSP::bus_write(uint24 addr, uint8 data) -> void { auto HitachiDSP::rom_read(uint addr, uint8 data) -> uint8 { if(co_active() == hitachidsp.thread || regs.halt) { - addr = bus.mirror(addr, rom.size()); + addr = Bus::mirror(addr, rom.size()); //if(Roms == 2 && mmio.r1f52 == 1 && addr >= (bit::round(rom.size()) >> 1)) return 0x00; return rom.read(addr, data); } @@ -44,12 +50,12 @@ auto HitachiDSP::rom_write(uint addr, uint8 data) -> void { auto HitachiDSP::ram_read(uint addr, uint8 data) -> uint8 { if(ram.size() == 0) return 0x00; //not open bus - return ram.read(bus.mirror(addr, ram.size()), data); + return ram.read(Bus::mirror(addr, ram.size()), data); } auto HitachiDSP::ram_write(uint addr, uint8 data) -> void { if(ram.size() == 0) return; - return ram.write(bus.mirror(addr, ram.size()), data); + return ram.write(Bus::mirror(addr, ram.size()), data); } auto HitachiDSP::dram_read(uint addr, uint8 data) -> uint8 { diff --git a/higan/target-tomoko/presentation/presentation.cpp b/higan/target-tomoko/presentation/presentation.cpp index b8024437..3f675f57 100644 --- a/higan/target-tomoko/presentation/presentation.cpp +++ b/higan/target-tomoko/presentation/presentation.cpp @@ -23,6 +23,19 @@ Presentation::Presentation() { loadBootableMedia.append(item); } } + //add icarus menu options -- but only if icarus binary is present + if(execute("icarus", "--name").strip() == "icarus") { + libraryMenu.append(MenuSeparator()); + libraryMenu.append(MenuItem().setText("Load ROM File ...").onActivate([&] { + audio->clear(); + if(auto location = execute("icarus", "--import")) { + program->loadMedia(location.strip()); + } + })); + libraryMenu.append(MenuItem().setText("Import ROM Files ...").onActivate([&] { + invoke("icarus"); + })); + } systemMenu.setText("System").setVisible(false); powerSystem.setText("Power").onActivate([&] { program->powerCycle(); }); diff --git a/higan/target-tomoko/presentation/presentation.hpp b/higan/target-tomoko/presentation/presentation.hpp index f56aa180..b8c9ba30 100644 --- a/higan/target-tomoko/presentation/presentation.hpp +++ b/higan/target-tomoko/presentation/presentation.hpp @@ -9,6 +9,7 @@ struct Presentation : Window { MenuBar menuBar{this}; Menu libraryMenu{&menuBar}; vector loadBootableMedia; + MenuSeparator librarySeparator; Menu systemMenu{&menuBar}; MenuItem powerSystem{&systemMenu}; MenuItem resetSystem{&systemMenu}; diff --git a/higan/target-tomoko/program/interface.cpp b/higan/target-tomoko/program/interface.cpp index b10cbbbf..6f8773ed 100644 --- a/higan/target-tomoko/program/interface.cpp +++ b/higan/target-tomoko/program/interface.cpp @@ -19,7 +19,7 @@ auto Program::loadRequest(uint id, string filename, bool required) -> void { if(filename == "manifest.bml" && !pathname.find(".sys/")) { if(!file::exists(location) || settings["Library/IgnoreManifests"].boolean()) { - if(auto manifest = execute("icarus", "-m", pathname)) { + if(auto manifest = execute("icarus", "--manifest", pathname)) { memorystream stream{(const uint8*)manifest.data(), manifest.size()}; return emulator->load(id, stream); } diff --git a/higan/target-tomoko/program/program.cpp b/higan/target-tomoko/program/program.cpp index bf40829a..87422f6d 100644 --- a/higan/target-tomoko/program/program.cpp +++ b/higan/target-tomoko/program/program.cpp @@ -73,8 +73,13 @@ Program::Program(lstring args) { presentation->toggleFullScreen(); } else { auto location = argument; - if(file::exists(location)) location = dirname(location); - if(directory::exists(location)) loadMedia(location); + if(directory::exists(location)) { + loadMedia(location); + } else if(file::exists(location)) { + if(auto result = execute("icarus", "--import", location)) { + loadMedia(result.strip()); + } + } } } } diff --git a/icarus/GNUmakefile b/icarus/GNUmakefile index 35253c2a..138dd0ac 100644 --- a/icarus/GNUmakefile +++ b/icarus/GNUmakefile @@ -37,7 +37,7 @@ install: ifeq ($(platform),macosx) cp -r out/icarus.app /Applications/icarus.app else - if [ -f ./icarus ]; then cp ./icarus $(prefix)/bin/icarus; fi + if [ -f out/icarus ]; then cp out/icarus $(prefix)/bin/icarus; fi endif uninstall: diff --git a/icarus/core/bs-memory.cpp b/icarus/core/bs-memory.cpp index 2348fe68..bc32d71f 100644 --- a/icarus/core/bs-memory.cpp +++ b/icarus/core/bs-memory.cpp @@ -31,7 +31,7 @@ auto Icarus::bsMemoryManifest(vector& buffer, string location) -> string return markup; } -auto Icarus::bsMemoryImport(vector& buffer, string location) -> bool { +auto Icarus::bsMemoryImport(vector& buffer, string location) -> string { auto name = prefixname(location); auto source = pathname(location); string target{settings["Library/Location"].text(), "BS Memory/", name, ".bs/"}; @@ -43,5 +43,5 @@ auto Icarus::bsMemoryImport(vector& buffer, string location) -> bool { if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup); file::write({target, "program.rom"}, buffer); - return success(); + return success(target); } diff --git a/icarus/core/core.cpp b/icarus/core/core.cpp index 839b5748..c462b627 100644 --- a/icarus/core/core.cpp +++ b/icarus/core/core.cpp @@ -12,14 +12,14 @@ auto Icarus::error() const -> string { return errorMessage; } -auto Icarus::success() -> bool { +auto Icarus::success(string location) -> string { errorMessage = ""; - return true; + return location; } -auto Icarus::failure(string message) -> bool { +auto Icarus::failure(string message) -> string { errorMessage = message; - return false; + return {}; } auto Icarus::manifest(string location) -> string { @@ -38,7 +38,7 @@ auto Icarus::manifest(string location) -> string { return ""; } -auto Icarus::import(string location) -> bool { +auto Icarus::import(string location) -> string { location.transform("\\", "/").rtrim("/"); if(!file::exists(location)) return failure("file does not exist"); if(!file::readable(location)) return failure("file is unreadable"); diff --git a/icarus/core/core.hpp b/icarus/core/core.hpp index 8b072498..7e6e098b 100644 --- a/icarus/core/core.hpp +++ b/icarus/core/core.hpp @@ -3,49 +3,49 @@ struct Icarus { Icarus(); auto error() const -> string; - auto success() -> bool; - auto failure(string message) -> bool; + auto success(string location) -> string; + auto failure(string message) -> string; auto manifest(string location) -> string; - auto import(string location) -> bool; + auto import(string location) -> string; auto concatenate(vector& output, string location) -> void; //famicom.cpp auto famicomManifest(string location) -> string; auto famicomManifest(vector& buffer, string location, uint* prgrom = nullptr, uint* chrrom = nullptr) -> string; - auto famicomImport(vector& buffer, string location) -> bool; + auto famicomImport(vector& buffer, string location) -> string; //super-famicom.cpp auto superFamicomManifest(string location) -> string; auto superFamicomManifest(vector& buffer, string location, bool* firmwareAppended = nullptr) -> string; auto superFamicomManifestScan(vector& roms, Markup::Node node) -> void; - auto superFamicomImport(vector& buffer, string location) -> bool; + auto superFamicomImport(vector& buffer, string location) -> string; //game-boy.cpp auto gameBoyManifest(string location) -> string; auto gameBoyManifest(vector& buffer, string location) -> string; - auto gameBoyImport(vector& buffer, string location) -> bool; + auto gameBoyImport(vector& buffer, string location) -> string; //game-boy-color.cpp auto gameBoyColorManifest(string location) -> string; auto gameBoyColorManifest(vector& buffer, string location) -> string; - auto gameBoyColorImport(vector& buffer, string location) -> bool; + auto gameBoyColorImport(vector& buffer, string location) -> string; //game-boy-advance.cpp auto gameBoyAdvanceManifest(string location) -> string; auto gameBoyAdvanceManifest(vector& buffer, string location) -> string; - auto gameBoyAdvanceImport(vector& buffer, string location) -> bool; + auto gameBoyAdvanceImport(vector& buffer, string location) -> string; //bs-memory.cpp auto bsMemoryManifest(string location) -> string; auto bsMemoryManifest(vector& buffer, string location) -> string; - auto bsMemoryImport(vector& buffer, string location) -> bool; + auto bsMemoryImport(vector& buffer, string location) -> string; //sufami-turbo.cpp auto sufamiTurboManifest(string location) -> string; auto sufamiTurboManifest(vector& buffer, string location) -> string; - auto sufamiTurboImport(vector& buffer, string location) -> bool; + auto sufamiTurboImport(vector& buffer, string location) -> string; private: string errorMessage; diff --git a/icarus/core/famicom.cpp b/icarus/core/famicom.cpp index 67a99450..80302d5e 100644 --- a/icarus/core/famicom.cpp +++ b/icarus/core/famicom.cpp @@ -37,7 +37,7 @@ auto Icarus::famicomManifest(vector& buffer, string location, uint* prgro return markup; } -auto Icarus::famicomImport(vector& buffer, string location) -> bool { +auto Icarus::famicomImport(vector& buffer, string location) -> string { auto name = prefixname(location); auto source = pathname(location); string target{settings["Library/Location"].text(), "Famicom/", name, ".fc/"}; @@ -52,7 +52,7 @@ auto Icarus::famicomImport(vector& buffer, string location) -> bool { if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup); file::write({target, "ines.rom"}, buffer.data(), 16); file::write({target, "program.rom"}, buffer.data() + 16, prgrom); - if(!chrrom) return success(); + if(!chrrom) return success(target); file::write({target, "character.rom"}, buffer.data() + 16 + prgrom, chrrom); - return success(); + return success(target); } diff --git a/icarus/core/game-boy-advance.cpp b/icarus/core/game-boy-advance.cpp index 48aa440f..833a29ab 100644 --- a/icarus/core/game-boy-advance.cpp +++ b/icarus/core/game-boy-advance.cpp @@ -31,7 +31,7 @@ auto Icarus::gameBoyAdvanceManifest(vector& buffer, string location) -> s return markup; } -auto Icarus::gameBoyAdvanceImport(vector& buffer, string location) -> bool { +auto Icarus::gameBoyAdvanceImport(vector& buffer, string location) -> string { auto name = prefixname(location); auto source = pathname(location); string target{settings["Library/Location"].text(), "Game Boy Advance/", name, ".gba/"}; @@ -43,5 +43,5 @@ auto Icarus::gameBoyAdvanceImport(vector& buffer, string location) -> boo if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup); file::write({target, "program.rom"}, buffer); - return success(); + return success(target); } diff --git a/icarus/core/game-boy-color.cpp b/icarus/core/game-boy-color.cpp index 8ce0f125..a6d4e6bb 100644 --- a/icarus/core/game-boy-color.cpp +++ b/icarus/core/game-boy-color.cpp @@ -31,7 +31,7 @@ auto Icarus::gameBoyColorManifest(vector& buffer, string location) -> str return markup; } -auto Icarus::gameBoyColorImport(vector& buffer, string location) -> bool { +auto Icarus::gameBoyColorImport(vector& buffer, string location) -> string { auto name = prefixname(location); auto source = pathname(location); string target{settings["Library/Location"].text(), "Game Boy Color/", name, ".gbc/"}; @@ -43,5 +43,5 @@ auto Icarus::gameBoyColorImport(vector& buffer, string location) -> bool if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup); file::write({target, "program.rom"}, buffer); - return success(); + return success(target); } diff --git a/icarus/core/game-boy.cpp b/icarus/core/game-boy.cpp index 20214455..b8a1b18c 100644 --- a/icarus/core/game-boy.cpp +++ b/icarus/core/game-boy.cpp @@ -31,7 +31,7 @@ auto Icarus::gameBoyManifest(vector& buffer, string location) -> string { return markup; } -auto Icarus::gameBoyImport(vector& buffer, string location) -> bool { +auto Icarus::gameBoyImport(vector& buffer, string location) -> string { auto name = prefixname(location); auto source = pathname(location); string target{settings["Library/Location"].text(), "Game Boy/", name, ".gb/"}; @@ -43,5 +43,5 @@ auto Icarus::gameBoyImport(vector& buffer, string location) -> bool { if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup); file::write({target, "program.rom"}, buffer); - return success(); + return success(target); } diff --git a/icarus/core/sufami-turbo.cpp b/icarus/core/sufami-turbo.cpp index cc44902b..b77accc1 100644 --- a/icarus/core/sufami-turbo.cpp +++ b/icarus/core/sufami-turbo.cpp @@ -31,7 +31,7 @@ auto Icarus::sufamiTurboManifest(vector& buffer, string location) -> stri return markup; } -auto Icarus::sufamiTurboImport(vector& buffer, string location) -> bool { +auto Icarus::sufamiTurboImport(vector& buffer, string location) -> string { auto name = prefixname(location); auto source = pathname(location); string target{settings["Library/Location"].text(), "Sufami Turbo/", name, ".st/"}; @@ -43,5 +43,5 @@ auto Icarus::sufamiTurboImport(vector& buffer, string location) -> bool { if(settings["icarus/CreateManifests"].boolean()) file::write({target, "manifest.bml"}, markup); file::write({target, "program.rom"}, buffer); - return success(); + return success(target); } diff --git a/icarus/core/super-famicom.cpp b/icarus/core/super-famicom.cpp index de479967..367d9020 100644 --- a/icarus/core/super-famicom.cpp +++ b/icarus/core/super-famicom.cpp @@ -45,7 +45,7 @@ auto Icarus::superFamicomManifestScan(vector& roms, Markup::Node n for(auto leaf : node) superFamicomManifestScan(roms, leaf); } -auto Icarus::superFamicomImport(vector& buffer, string location) -> bool { +auto Icarus::superFamicomImport(vector& buffer, string location) -> string { auto name = prefixname(location); auto source = pathname(location); string target{settings["Library/Location"].text(), "Super Famicom/", name, ".sfc/"}; @@ -81,5 +81,5 @@ auto Icarus::superFamicomImport(vector& buffer, string location) -> bool file::write({target, name}, firmware); } } - return success(); + return success(target); } diff --git a/icarus/icarus.cpp b/icarus/icarus.cpp index e15a9323..fbb5ae08 100644 --- a/icarus/icarus.cpp +++ b/icarus/icarus.cpp @@ -41,11 +41,35 @@ Icarus icarus; #include auto nall::main(lstring args) -> void { - if(args.size() == 3 && args[1] == "-m") { - if(!directory::exists(args[2])) return print("error: directory not found\n"); + if(args.size() == 2 && args[1] == "--name") { + return print("icarus"); + } + + if(args.size() == 3 && args[1] == "--manifest" && directory::exists(args[2])) { return print(icarus.manifest(args[2])); } + if(args.size() == 3 && args[1] == "--import" && file::exists(args[2])) { + if(string target = icarus.import(args[2])) { + return print(target, "\n"); + } + return; + } + + if(args.size() == 2 && args[1] == "--import") { + if(string source = BrowserDialog() + .setTitle("Load ROM Image") + .setPath(settings["icarus/Path"].text()) + .setFilters("ROM Files|*.fc:*.nes:*.sfc:*.smc:*.gb:*.gbc:*.gba:*.bs:*.st:*.zip") + .openFile()) { + if(string target = icarus.import(source)) { + settings["icarus/Path"].setValue(pathname(source)); + return print(target, "\n"); + } + } + return; + } + new ScanDialog; new SettingsDialog; new ImportDialog; diff --git a/icarus/icarus.plist b/icarus/icarus.plist index 6298f8d6..67833d77 100644 --- a/icarus/icarus.plist +++ b/icarus/icarus.plist @@ -2,6 +2,8 @@ + CFBundleIdentifier + org.byuu.icarus CFBundleDisplayName icarus CFBundleExecutable @@ -10,5 +12,9 @@ CFBundleIconFile icarus.icns --> + NSHighResolutionCapable + + NSSupportsAutomaticGraphicsSwitching +