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.

]
This commit is contained in:
Tim Allen 2016-01-13 21:47:45 +11:00
parent 82ec876302
commit 3414c8c8df
18 changed files with 99 additions and 44 deletions

View File

@ -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/";

View File

@ -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 {

View File

@ -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(); });

View File

@ -9,6 +9,7 @@ struct Presentation : Window {
MenuBar menuBar{this};
Menu libraryMenu{&menuBar};
vector<MenuItem*> loadBootableMedia;
MenuSeparator librarySeparator;
Menu systemMenu{&menuBar};
MenuItem powerSystem{&systemMenu};
MenuItem resetSystem{&systemMenu};

View File

@ -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);
}

View File

@ -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());
}
}
}
}
}

View File

@ -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:

View File

@ -31,7 +31,7 @@ auto Icarus::bsMemoryManifest(vector<uint8>& buffer, string location) -> string
return markup;
}
auto Icarus::bsMemoryImport(vector<uint8>& buffer, string location) -> bool {
auto Icarus::bsMemoryImport(vector<uint8>& 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<uint8>& 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);
}

View File

@ -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");

View File

@ -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<uint8>& output, string location) -> void;
//famicom.cpp
auto famicomManifest(string location) -> string;
auto famicomManifest(vector<uint8>& buffer, string location, uint* prgrom = nullptr, uint* chrrom = nullptr) -> string;
auto famicomImport(vector<uint8>& buffer, string location) -> bool;
auto famicomImport(vector<uint8>& buffer, string location) -> string;
//super-famicom.cpp
auto superFamicomManifest(string location) -> string;
auto superFamicomManifest(vector<uint8>& buffer, string location, bool* firmwareAppended = nullptr) -> string;
auto superFamicomManifestScan(vector<Markup::Node>& roms, Markup::Node node) -> void;
auto superFamicomImport(vector<uint8>& buffer, string location) -> bool;
auto superFamicomImport(vector<uint8>& buffer, string location) -> string;
//game-boy.cpp
auto gameBoyManifest(string location) -> string;
auto gameBoyManifest(vector<uint8>& buffer, string location) -> string;
auto gameBoyImport(vector<uint8>& buffer, string location) -> bool;
auto gameBoyImport(vector<uint8>& buffer, string location) -> string;
//game-boy-color.cpp
auto gameBoyColorManifest(string location) -> string;
auto gameBoyColorManifest(vector<uint8>& buffer, string location) -> string;
auto gameBoyColorImport(vector<uint8>& buffer, string location) -> bool;
auto gameBoyColorImport(vector<uint8>& buffer, string location) -> string;
//game-boy-advance.cpp
auto gameBoyAdvanceManifest(string location) -> string;
auto gameBoyAdvanceManifest(vector<uint8>& buffer, string location) -> string;
auto gameBoyAdvanceImport(vector<uint8>& buffer, string location) -> bool;
auto gameBoyAdvanceImport(vector<uint8>& buffer, string location) -> string;
//bs-memory.cpp
auto bsMemoryManifest(string location) -> string;
auto bsMemoryManifest(vector<uint8>& buffer, string location) -> string;
auto bsMemoryImport(vector<uint8>& buffer, string location) -> bool;
auto bsMemoryImport(vector<uint8>& buffer, string location) -> string;
//sufami-turbo.cpp
auto sufamiTurboManifest(string location) -> string;
auto sufamiTurboManifest(vector<uint8>& buffer, string location) -> string;
auto sufamiTurboImport(vector<uint8>& buffer, string location) -> bool;
auto sufamiTurboImport(vector<uint8>& buffer, string location) -> string;
private:
string errorMessage;

View File

@ -37,7 +37,7 @@ auto Icarus::famicomManifest(vector<uint8>& buffer, string location, uint* prgro
return markup;
}
auto Icarus::famicomImport(vector<uint8>& buffer, string location) -> bool {
auto Icarus::famicomImport(vector<uint8>& 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<uint8>& 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);
}

View File

@ -31,7 +31,7 @@ auto Icarus::gameBoyAdvanceManifest(vector<uint8>& buffer, string location) -> s
return markup;
}
auto Icarus::gameBoyAdvanceImport(vector<uint8>& buffer, string location) -> bool {
auto Icarus::gameBoyAdvanceImport(vector<uint8>& 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<uint8>& 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);
}

View File

@ -31,7 +31,7 @@ auto Icarus::gameBoyColorManifest(vector<uint8>& buffer, string location) -> str
return markup;
}
auto Icarus::gameBoyColorImport(vector<uint8>& buffer, string location) -> bool {
auto Icarus::gameBoyColorImport(vector<uint8>& 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<uint8>& 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);
}

View File

@ -31,7 +31,7 @@ auto Icarus::gameBoyManifest(vector<uint8>& buffer, string location) -> string {
return markup;
}
auto Icarus::gameBoyImport(vector<uint8>& buffer, string location) -> bool {
auto Icarus::gameBoyImport(vector<uint8>& 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<uint8>& 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);
}

View File

@ -31,7 +31,7 @@ auto Icarus::sufamiTurboManifest(vector<uint8>& buffer, string location) -> stri
return markup;
}
auto Icarus::sufamiTurboImport(vector<uint8>& buffer, string location) -> bool {
auto Icarus::sufamiTurboImport(vector<uint8>& 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<uint8>& 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);
}

View File

@ -45,7 +45,7 @@ auto Icarus::superFamicomManifestScan(vector<Markup::Node>& roms, Markup::Node n
for(auto leaf : node) superFamicomManifestScan(roms, leaf);
}
auto Icarus::superFamicomImport(vector<uint8>& buffer, string location) -> bool {
auto Icarus::superFamicomImport(vector<uint8>& 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<uint8>& buffer, string location) -> bool
file::write({target, name}, firmware);
}
}
return success();
return success(target);
}

View File

@ -41,11 +41,35 @@ Icarus icarus;
#include <nall/main.hpp>
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;

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>org.byuu.icarus</string>
<key>CFBundleDisplayName</key>
<string>icarus</string>
<key>CFBundleExecutable</key>
@ -10,5 +12,9 @@
<key>CFBundleIconFile</key>
<string>icarus.icns</string>
-->
<key>NSHighResolutionCapable</key>
<true/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>