Update to v101 release.

byuu says (in the public announcement):

Not a large changelog this time, sorry. This release is mostly to fix
the SA-1 issue, and to get some real-world testing of the new scheduler
model. Most of the work in the past month has gone into writing a 68000
CPU core; yet it's still only about half-way finished.

Changelog (since the previous release):

  - fixed SNES SA-1 IRQ regression (fixes Super Mario RPG level-up
    screen)
  - new scheduler for all emulator cores (precision of 2^-127)
  - icarus database adds nine new SNES games
  - added Input/Frequency to settings file (allows simulation of
    latency)

byuu says (in the WIP forum):

Changelog:

  - in 32-bit mode, Thread uses uint64\_t with 2^-63 time units (10^-7
    precision in the worst case)
      - nearly ten times the precision of an attosecond
  - in 64-bit mode, Thread uses uint128\_t with 2^-127 time units
    (10^-26 precision in the worst case)
      - far more accurate than yoctoseconds; almost closing in on planck
        time

Note: a quartz crystal is accurate to 10^-4 or 10^-5. A cesium fountain
atomic clock is accurate to 10^-15. So ... yeah. 2^-63 was perfectly
fine; but there was no speed penalty whatsoever for using uint128\_t in
64-bit mode, so why not?
This commit is contained in:
Tim Allen 2016-08-08 20:04:15 +10:00
parent f5e5bf1772
commit e39987a3e3
8 changed files with 40 additions and 20 deletions

View File

@ -11,13 +11,13 @@ using namespace nall;
namespace Emulator {
static const string Name = "higan";
static const string Version = "100.16";
static const string Version = "101";
static const string Author = "byuu";
static const string License = "GPLv3";
static const string Website = "http://byuu.org/";
//incremented only when serialization format changes
static const string SerializerVersion = "100.15";
static const string SerializerVersion = "101";
namespace Constants {
namespace Colorburst {

View File

@ -2,8 +2,6 @@
namespace Emulator {
struct Thread;
struct Scheduler {
enum class Mode : uint {
Run,
@ -51,7 +49,7 @@ struct Scheduler {
}
auto exit(Event event) -> void {
uint128_t minimum = -1;
uintmax minimum = -1;
for(auto thread : _threads) {
if(thread->_clock < minimum) minimum = thread->_clock;
}

View File

@ -15,14 +15,14 @@ struct Thread {
auto setFrequency(double frequency) -> void {
_frequency = frequency + 0.5;
_scalar = ((uint128_t)1 << 96) / _frequency;
_scalar = ((uintmax)1 << (8 * sizeof(uintmax) - 1)) / _frequency;
}
auto setScalar(uint128_t scalar) -> void {
auto setScalar(uintmax scalar) -> void {
_scalar = scalar;
}
auto setClock(uint128_t clock) -> void {
auto setClock(uintmax clock) -> void {
_clock = clock;
}
@ -44,9 +44,9 @@ struct Thread {
protected:
cothread_t _handle = nullptr;
uint32_t _frequency = 0;
uint128_t _scalar = 0;
uint128_t _clock = 0;
uintmax _frequency = 0;
uintmax _scalar = 0;
uintmax _clock = 0;
friend class Scheduler;
};

View File

@ -43,7 +43,7 @@ Settings::Settings() {
set("Audio/Resampler", "Sinc");
set("Input/Driver", ruby::Input::optimalDriver());
set("Input/Latency", 5);
set("Input/Frequency", 5);
set("Input/FocusLoss/Pause", false);
set("Input/FocusLoss/AllowInput", false);
}

View File

@ -144,7 +144,7 @@ auto InputMapping::deviceName() -> string {
InputManager::InputManager() {
inputManager = this;
latency = max(1u, settings["Input/Latency"].natural());
frequency = max(1u, settings["Input/Frequency"].natural());
for(auto& emulator : program->emulators) {
auto& inputEmulator = emulators(emulators.size());
@ -204,7 +204,7 @@ auto InputManager::bind() -> void {
auto InputManager::poll() -> void {
//polling actual hardware is very time-consuming: skip call if poll was called too recently
auto thisPoll = chrono::millisecond();
if(thisPoll - lastPoll < latency) return;
if(thisPoll - lastPoll < frequency) return;
lastPoll = thisPoll;
auto devices = input->poll();

View File

@ -64,8 +64,8 @@ struct InputManager {
vector<InputHotkey*> hotkeys;
InputEmulator* emulator = nullptr; //points to InputEmulator that represents the currently active emulator
uint64 lastPoll; //time in milliseconds since last call to poll()
uint64 latency; //minimum time in milliseconds before poll() can be called again
uint64 lastPoll; //time in milliseconds since last call to poll()
uint64 frequency; //minimum time in milliseconds before poll() can be called again
};
extern unique_pointer<InputManager> inputManager;

View File

@ -44,19 +44,30 @@ static auto CALLBACK Label_windowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
BeginPaint(hwnd, &ps);
RECT rc;
GetClientRect(hwnd, &rc);
DrawThemeParentBackground(hwnd, ps.hdc, &rc);
//todo: use DrawThemeParentBackground if Label is inside TabFrame
if(auto brush = window->self()->hbrush) {
FillRect(ps.hdc, &rc, brush);
} else {
DrawThemeParentBackground(hwnd, ps.hdc, &rc);
}
SetBkMode(ps.hdc, TRANSPARENT);
SelectObject(ps.hdc, label->self()->hfont);
unsigned length = GetWindowTextLength(hwnd);
uint length = GetWindowTextLength(hwnd);
wchar_t text[length + 1];
GetWindowText(hwnd, text, length + 1);
text[length] = 0;
DrawText(ps.hdc, text, -1, &rc, DT_CALCRECT | DT_END_ELLIPSIS);
unsigned height = rc.bottom;
uint height = rc.bottom;
GetClientRect(hwnd, &rc);
rc.top = (rc.bottom - height) / 2;
rc.bottom = rc.top + height;
DrawText(ps.hdc, text, -1, &rc, DT_LEFT | DT_END_ELLIPSIS);
uint horizontalAlignment = DT_CENTER;
if(label->alignment().horizontal() < 0.333) horizontalAlignment = DT_LEFT;
if(label->alignment().horizontal() > 0.666) horizontalAlignment = DT_RIGHT;
uint verticalAlignment = DT_VCENTER;
if(label->alignment().vertical() < 0.333) verticalAlignment = DT_TOP;
if(label->alignment().vertical() > 0.666) verticalAlignment = DT_BOTTOM;
DrawText(ps.hdc, text, -1, &rc, DT_END_ELLIPSIS | horizontalAlignment | verticalAlignment);
EndPaint(hwnd, &ps);
return false;
}

View File

@ -26,11 +26,22 @@
#include <stdint.h>
#endif
//note: (u)intmax actually mean it: use as many bits as is possible
#if defined(__SIZEOF_INT128__)
#define HAS_INT128
using int128_t = signed __int128;
using uint128_t = unsigned __int128;
using intmax = int128_t;
using uintmax = uint128_t;
#else
using intmax = intmax_t;
using uintmax = uintmax_t;
#endif
using intptr = intptr_t;
using uintptr = uintptr_t;
using float32_t = float;
using float64_t = double;
//note: long double size is not reliable across platforms