From e39987a3e32080f647fb57757f6d4ac82857d32b Mon Sep 17 00:00:00 2001 From: Tim Allen Date: Mon, 8 Aug 2016 20:04:15 +1000 Subject: [PATCH] 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? --- higan/emulator/emulator.hpp | 4 ++-- higan/emulator/scheduler.hpp | 4 +--- higan/emulator/thread.hpp | 12 ++++++------ .../configuration/configuration.cpp | 2 +- higan/target-tomoko/input/input.cpp | 4 ++-- higan/target-tomoko/input/input.hpp | 4 ++-- hiro/windows/widget/label.cpp | 19 +++++++++++++++---- nall/stdint.hpp | 11 +++++++++++ 8 files changed, 40 insertions(+), 20 deletions(-) diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index b54855d8..1e2ce5a8 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -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 { diff --git a/higan/emulator/scheduler.hpp b/higan/emulator/scheduler.hpp index d9e2ca48..b90fbc73 100644 --- a/higan/emulator/scheduler.hpp +++ b/higan/emulator/scheduler.hpp @@ -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; } diff --git a/higan/emulator/thread.hpp b/higan/emulator/thread.hpp index 88e0f66f..640cdc6b 100644 --- a/higan/emulator/thread.hpp +++ b/higan/emulator/thread.hpp @@ -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; }; diff --git a/higan/target-tomoko/configuration/configuration.cpp b/higan/target-tomoko/configuration/configuration.cpp index 95b6f18c..980d82a8 100644 --- a/higan/target-tomoko/configuration/configuration.cpp +++ b/higan/target-tomoko/configuration/configuration.cpp @@ -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); } diff --git a/higan/target-tomoko/input/input.cpp b/higan/target-tomoko/input/input.cpp index b0caee68..b8fcb68b 100644 --- a/higan/target-tomoko/input/input.cpp +++ b/higan/target-tomoko/input/input.cpp @@ -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(); diff --git a/higan/target-tomoko/input/input.hpp b/higan/target-tomoko/input/input.hpp index f27812fa..da44abd4 100644 --- a/higan/target-tomoko/input/input.hpp +++ b/higan/target-tomoko/input/input.hpp @@ -64,8 +64,8 @@ struct InputManager { vector 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; diff --git a/hiro/windows/widget/label.cpp b/hiro/windows/widget/label.cpp index 3fc883dd..0bd242e3 100644 --- a/hiro/windows/widget/label.cpp +++ b/hiro/windows/widget/label.cpp @@ -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; } diff --git a/nall/stdint.hpp b/nall/stdint.hpp index 67408f31..d667d285 100644 --- a/nall/stdint.hpp +++ b/nall/stdint.hpp @@ -26,11 +26,22 @@ #include #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