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 { namespace Emulator {
static const string Name = "higan"; 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 Author = "byuu";
static const string License = "GPLv3"; static const string License = "GPLv3";
static const string Website = "http://byuu.org/"; static const string Website = "http://byuu.org/";

View File

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

View File

@@ -170,20 +170,22 @@ auto BrowserDialogWindow::setPath(string path) -> void {
for(auto content : contents) { for(auto content : contents) {
if(!content.endsWith("/")) continue; if(!content.endsWith("/")) continue;
if(folderMode && isMatch(content.rtrim("/"))) continue; content.rtrim("/");
if(folderMode && isMatch(content)) continue;
view.append(ListViewItem() 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))) .append(ListViewCell().setText(octal<3>(storage::mode({path, content}) & 0777)))
); );
} }
for(auto content : contents) { for(auto content : contents) {
if(content.endsWith("/") && !folderMode) continue; if(content.endsWith("/") != folderMode) continue; //file mode shows files; folder mode shows folders
if(!isMatch(content.rtrim("/"))) continue; content.rtrim("/");
if(!isMatch(content)) continue;
view.append(ListViewItem() 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))) .append(ListViewCell().setText(octal<3>(storage::mode({path, content}) & 0777)))
); );
} }

View File

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

View File

@@ -324,6 +324,13 @@ static auto CALLBACK Shared_windowProc(WindowProc windowProc, HWND hwnd, UINT ms
} }
#if defined(Hiro_ListView) #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: { case AppMessage::ListView_onActivate: {
if(auto listView = (mListView*)lparam) listView->doActivate(); if(auto listView = (mListView*)lparam) listView->doActivate();
break; break;

View File

@@ -18,6 +18,12 @@ auto pListViewCell::setIcon(const image& icon) -> void {
} }
auto pListViewCell::setText(const string& text) -> 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&> { auto pListViewCell::_parent() -> maybe<pListViewItem&> {

View File

@@ -28,9 +28,9 @@ auto SuperFX::enter() -> void {
continue; continue;
} }
unsigned opcode = (regs.sfr & 0x0300) + peekpipe(); unsigned opcode = regs.sfr.alt2 << 9 | regs.sfr.alt1 << 8 | peekpipe();
(this->*opcode_table[opcode])(); (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"); timing.append(timing.audio, "Audio");
append(timing, "Timing"); append(timing, "Timing");
load({configpath(), "tomoko/settings.bml"}); load(locate({configpath(), "tomoko/"}, "settings.bml"));
if(!library.location) library.location = {userpath(), "Emulation/"}; if(!library.location) library.location = {userpath(), "Emulation/"};
if(!video.driver) video.driver = ruby::Video::safestDriver(); if(!video.driver) video.driver = ruby::Video::safestDriver();
if(!audio.driver) audio.driver = ruby::Audio::safestDriver(); if(!audio.driver) audio.driver = ruby::Audio::safestDriver();
if(!input.driver) input.driver = ruby::Input::safestDriver(); if(!input.driver) input.driver = ruby::Input::safestDriver();
save({configpath(), "tomoko/settings.bml"}); save(locate({configpath(), "tomoko/"}, "settings.bml"));
} }
auto ConfigurationManager::quit() -> void { auto ConfigurationManager::quit() -> void {
save({configpath(), "tomoko/settings.bml"}); save(locate({configpath(), "tomoko/"}, "settings.bml"));
} }

View File

@@ -172,8 +172,8 @@ InputManager::InputManager() {
} }
appendHotkeys(); appendHotkeys();
config.load({configpath(), "tomoko/input.bml"}); config.load(locate({configpath(), "tomoko/"}, "input.bml"));
config.save({configpath(), "tomoko/input.bml"}); config.save(locate({configpath(), "tomoko/"}, "input.bml"));
} }
auto InputManager::bind() -> void { auto InputManager::bind() -> void {
@@ -217,7 +217,7 @@ auto InputManager::onChange(shared_pointer<HID::Device> device, unsigned group,
} }
auto InputManager::quit() -> void { auto InputManager::quit() -> void {
config.save({configpath(), "tomoko/input.bml"}); config.save(locate({configpath(), "tomoko/"}, "input.bml"));
emulators.reset(); emulators.reset();
hotkeys.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 { auto Program::loadMedia(Emulator::Interface& _emulator, Emulator::Interface::Media& media, const string& location) -> void {
unloadMedia(); unloadMedia();
mediaPaths(0) = {userpath(), "Emulation/System/", media.name, ".sys/"}; mediaPaths(0) = locate({userpath(), "Emulation/System/"}, {media.name, ".sys/"});
mediaPaths(media.id) = location; mediaPaths(media.id) = location;
folderPaths.append(location); folderPaths.append(location);

View File

@@ -4,6 +4,14 @@ Audio* audio = nullptr;
Input* input = nullptr; Input* input = nullptr;
Emulator::Interface* emulator = 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> #include <nall/main.hpp>
auto nall::main(lstring args) -> void { auto nall::main(lstring args) -> void {
Application::setName("tomoko"); Application::setName("tomoko");

View File

@@ -17,3 +17,5 @@ extern Emulator::Interface* emulator;
#include "settings/settings.hpp" #include "settings/settings.hpp"
#include "tools/tools.hpp" #include "tools/tools.hpp"
#include "presentation/presentation.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; if(!emulator) return;
auto sha256 = emulator->sha256(); 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); auto document = BML::unserialize(contents);
for(auto cartridge : document.find("cartridge")) { for(auto cartridge : document.find("cartridge")) {

View File

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