From 3414c8c8df9ec21244006643ed8765ffd2b591f4 Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Wed, 13 Jan 2016 21:47:45 +1100 Subject: [PATCH] Update to v096r06 release. byuu says: This WIP finally achieves the vision I've had for icarus. I also fixed a mapping issue with Cx4 that, oddly enough, only caused the "2" from the Mega Man X2 title screen to disappear. [Editor's note - "the vision for icarus" was described in a separate, public forum post: http://board.byuu.org/phpbb3/viewtopic.php?p=20584 Quoting for posterity: icarus is now a full-fledged part of higan, and will be bundled with each higan WIP as well. This will ensure that in the future, the exact version of icarus you need to run higan will be included right along with it. As of this WIP, physical manifest files are now truly and entirely optional. From now on, you can associate your ROM image files with higan's main binary, or drop them directly on top of it, to load and play your games. Furthermore, there are two new menu options that appear under the library menu when icarus is present: - "Load ROM File ..." => gives you a single-file selection dialog to import (and if possible) run the game - "Import ROM Files ..." => gives you a multi-file import dialog with checkboxes to pull in multiple games at once Finally, as before, icarus can generate manifest.bml files for folders that lack them. For people who like the game folder and library system, nothing's changed. Keep using higan as you have been. For people who hate it, you can now use higan like your classic emulators. Treat the "Library->{System Name}" entries as your "favorites" list: the games you actually play. Treat the "Library->Load ROM" as your standard open file dialog in other emulators. And finally, treat "Advanced->Game Library" as your save data path for cheat codes, save states, save RAM, etc. ] --- higan/emulator/emulator.hpp | 2 +- higan/sfc/coprocessor/hitachidsp/memory.cpp | 20 ++++++++----- .../presentation/presentation.cpp | 13 +++++++++ .../presentation/presentation.hpp | 1 + higan/target-tomoko/program/interface.cpp | 2 +- higan/target-tomoko/program/program.cpp | 9 ++++-- icarus/GNUmakefile | 2 +- icarus/core/bs-memory.cpp | 4 +-- icarus/core/core.cpp | 10 +++---- icarus/core/core.hpp | 20 ++++++------- icarus/core/famicom.cpp | 6 ++-- icarus/core/game-boy-advance.cpp | 4 +-- icarus/core/game-boy-color.cpp | 4 +-- icarus/core/game-boy.cpp | 4 +-- icarus/core/sufami-turbo.cpp | 4 +-- icarus/core/super-famicom.cpp | 4 +-- icarus/icarus.cpp | 28 +++++++++++++++++-- icarus/icarus.plist | 6 ++++ 18 files changed, 99 insertions(+), 44 deletions(-) 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 +