mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
f5e5bf1772
commit
e39987a3e3
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue