Update to v094r36 release (open beta).

byuu says:

Changelog:
- GBA emulation accuracy has been substantially improved [Cydrak]
- GBA ldm bug fixed [jchadwick]
- SNES SuperFX timing has been improved [AWJ, ARM9, qwertymodo]
- SNES accuracy profile is now ~8% faster than before
- you no longer need to copy the .sys profile folders to
  ~/Emulation/System
    - you still need to put bios.rom (GBA BIOS) into Game Boy
      Advance.sys to use GBA emulation!!
- you no longer need to pre-configure inputs before first use
- loading games / changing window size won't recenter window
- checkboxes in cheat editor update correctly
- can't type into state manager description textbox on an empty slot
- typing in state manager description box works correctly; and updates
  list view correctly
- won't show files that match game extensions anymore (only game folders
  show up)
- libco Win64 port fixes with FPU^H^H^H XMM registers
- libco ARM port now available; so you too can play at 15fps on an RPi2!
  [jessedog3, Cydrak]
- controller selection will check the default item in the menu now on
  game load
- as usual, a whole lot of other stuff I'm forgetting

Known issues:
- type-ahead find does not work in list views (eg game selection
  dialog); I don't know how to fix this
- there's no game file importer yet
- there's no shader support yet
- there's no profiler available for the timing panel, you need to adjust
  values manually for now
This commit is contained in:
Tim Allen 2015-07-02 20:22:24 +10:00
parent 28a14198cb
commit ecb35cac33
14 changed files with 58 additions and 31 deletions

View File

@ -8,7 +8,7 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "094.35";
static const string Version = "094.36";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";

View File

@ -10,16 +10,16 @@ auto CPU::prefetch_step(unsigned clocks) -> void {
step(clocks);
if(!regs.wait.control.prefetch || active.dma) return;
prefetch.wait -= clocks;
while(!prefetch.full() && prefetch.wait <= 0) {
while(!prefetch.full() && clocks--) {
if(--prefetch.wait) continue;
prefetch.slot[prefetch.load >> 1 & 7] = cartridge.rom_read(Half, prefetch.load);
prefetch.load += 2;
prefetch.wait += bus_wait(Half | Sequential, prefetch.load);
prefetch.wait = bus_wait(Half | Sequential, prefetch.load);
}
}
auto CPU::prefetch_wait() -> void {
if(!regs.wait.control.prefetch || prefetch.full()) return;
if(!regs.wait.control.prefetch || active.dma || prefetch.full()) return;
prefetch_step(prefetch.wait);
prefetch.wait = bus_wait(Half | Nonsequential, prefetch.load);

View File

@ -170,20 +170,22 @@ auto BrowserDialogWindow::setPath(string path) -> void {
for(auto content : contents) {
if(!content.endsWith("/")) continue;
if(folderMode && isMatch(content.rtrim("/"))) continue;
content.rtrim("/");
if(folderMode && isMatch(content)) continue;
view.append(ListViewItem()
.append(ListViewCell().setText(content.rtrim("/")).setIcon(Icon::Emblem::Folder))
.append(ListViewCell().setText(content).setIcon(Icon::Emblem::Folder))
.append(ListViewCell().setText(octal<3>(storage::mode({path, content}) & 0777)))
);
}
for(auto content : contents) {
if(content.endsWith("/") && !folderMode) continue;
if(!isMatch(content.rtrim("/"))) continue;
if(content.endsWith("/") != folderMode) continue; //file mode shows files; folder mode shows folders
content.rtrim("/");
if(!isMatch(content)) continue;
view.append(ListViewItem()
.append(ListViewCell().setText(content.rtrim("/")).setIcon(folderMode ? Icon::Action::Open : Icon::Emblem::File))
.append(ListViewCell().setText(content).setIcon(folderMode ? Icon::Action::Open : Icon::Emblem::File))
.append(ListViewCell().setText(octal<3>(storage::mode({path, content}) & 0777)))
);
}

View File

@ -10,6 +10,7 @@ struct pWidget;
struct AppMessage {
enum : unsigned {
None = WM_APP,
ListView_doPaint,
ListView_onActivate,
ListView_onChange,
};

View File

@ -324,6 +324,13 @@ static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT ms
}
#if defined(Hiro_ListView)
case AppMessage::ListView_doPaint: {
if(auto listView = (mListView*)lparam) {
if(auto self = listView->self()) InvalidateRect(self->hwnd, nullptr, true);
}
break;
}
case AppMessage::ListView_onActivate: {
if(auto listView = (mListView*)lparam) listView->doActivate();
break;

View File

@ -18,6 +18,12 @@ auto pListViewCell::setIcon(const image& icon) -> void {
}
auto pListViewCell::setText(const string& text) -> void {
if(auto parent = _parent()) {
if(auto listView = parent->_parent()) {
//ListView uses a custom drawing routine; so we need to tell the control to repaint itself manually
PostMessageOnce(listView->_parentHandle(), AppMessage::ListView_doPaint, 0, (LPARAM)&listView->reference);
}
}
}
auto pListViewCell::_parent() -> maybe<pListViewItem&> {

View File

@ -28,9 +28,9 @@ auto SuperFX::enter() -> void {
continue;
}
unsigned opcode = (regs.sfr & 0x0300) + peekpipe();
unsigned opcode = regs.sfr.alt2 << 9 | regs.sfr.alt1 << 8 | peekpipe();
(this->*opcode_table[opcode])();
if(r15_modified == false) regs.r[15]++;
if(!r15_modified) regs.r[15]++;
}
}

View File

@ -42,14 +42,14 @@ ConfigurationManager::ConfigurationManager() {
timing.append(timing.audio, "Audio");
append(timing, "Timing");
load({configpath(), "tomoko/settings.bml"});
load(locate({configpath(), "tomoko/"}, "settings.bml"));
if(!library.location) library.location = {userpath(), "Emulation/"};
if(!video.driver) video.driver = ruby::Video::safestDriver();
if(!audio.driver) audio.driver = ruby::Audio::safestDriver();
if(!input.driver) input.driver = ruby::Input::safestDriver();
save({configpath(), "tomoko/settings.bml"});
save(locate({configpath(), "tomoko/"}, "settings.bml"));
}
auto ConfigurationManager::quit() -> void {
save({configpath(), "tomoko/settings.bml"});
save(locate({configpath(), "tomoko/"}, "settings.bml"));
}

View File

@ -172,8 +172,8 @@ InputManager::InputManager() {
}
appendHotkeys();
config.load({configpath(), "tomoko/input.bml"});
config.save({configpath(), "tomoko/input.bml"});
config.load(locate({configpath(), "tomoko/"}, "input.bml"));
config.save(locate({configpath(), "tomoko/"}, "input.bml"));
}
auto InputManager::bind() -> void {
@ -217,7 +217,7 @@ auto InputManager::onChange(shared_pointer<HID::Device> device, unsigned group,
}
auto InputManager::quit() -> void {
config.save({configpath(), "tomoko/input.bml"});
config.save(locate({configpath(), "tomoko/"}, "input.bml"));
emulators.reset();
hotkeys.reset();
}

View File

@ -16,7 +16,7 @@ auto Program::loadMedia(string location) -> void {
auto Program::loadMedia(Emulator::Interface& _emulator, Emulator::Interface::Media& media, const string& location) -> void {
unloadMedia();
mediaPaths(0) = {userpath(), "Emulation/System/", media.name, ".sys/"};
mediaPaths(0) = locate({userpath(), "Emulation/System/"}, {media.name, ".sys/"});
mediaPaths(media.id) = location;
folderPaths.append(location);

View File

@ -4,6 +4,14 @@ Audio* audio = nullptr;
Input* input = nullptr;
Emulator::Interface* emulator = nullptr;
//if file already exists in the same path as the binary; use it (portable mode)
//if not, use default requested path (*nix/user mode)
auto locate(string pathname, string filename) -> string {
string location = {programpath(), filename};
if(storage::exists(location)) return location;
return {pathname, filename};
}
#include <nall/main.hpp>
auto nall::main(lstring args) -> void {
Application::setName("tomoko");

View File

@ -17,3 +17,5 @@ extern Emulator::Interface* emulator;
#include "settings/settings.hpp"
#include "tools/tools.hpp"
#include "presentation/presentation.hpp"
auto locate(string pathname, string filename) -> string;

View File

@ -17,7 +17,7 @@ auto CheatDatabase::findCodes() -> void {
if(!emulator) return;
auto sha256 = emulator->sha256();
auto contents = string::read({localpath(), "tomoko/cheats.bml"});
auto contents = string::read(locate({localpath(), "tomoko/"}, "cheats.bml"));
auto document = BML::unserialize(contents);
for(auto cartridge : document.find("cartridge")) {

View File

@ -20,6 +20,8 @@ StateManager::StateManager(TabFrame* parent) : TabFrameItem(parent) {
loadButton.setText("Load").onActivate([&] { doLoad(); });
resetButton.setText("Reset").onActivate([&] { doReset(); });
eraseButton.setText("Erase").onActivate([&] { doErase(); });
doUpdateControls();
}
auto StateManager::doUpdateControls() -> void {
@ -33,7 +35,7 @@ auto StateManager::doUpdateControls() -> void {
loadButton.setEnabled(true);
eraseButton.setEnabled(true);
} else {
descriptionValue.setEnabled(false);
descriptionValue.setEnabled(false).setText("");
loadButton.setEnabled(false);
eraseButton.setEnabled(false);
}
@ -43,18 +45,17 @@ auto StateManager::doChangeSelected() -> void {
vector<uint8> buffer;
if(auto item = stateList.selected()) {
buffer = file::read(program->stateName(1 + item.offset(), true));
if(buffer.size() >= 584) {
string description;
description.reserve(512);
memory::copy(description.pointer(), buffer.data() + 72, 512);
description.resize(description.length());
descriptionValue.setEnabled(true).setText(description);
return doUpdateControls();
}
}
if(buffer.size() >= 584) {
string description;
description.reserve(512);
memory::copy(description.pointer(), buffer.data() + 72, 512);
description.resize(description.length());
descriptionValue.setText(description);
} else {
descriptionValue.setText("");
}
descriptionValue.setEnabled(false).setText("");
doUpdateControls();
}