mirror of
https://github.com/patchzyy/wiicompiled
synced 2026-09-26 07:01:08 -04:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 85f250155f | |||
| a9c9c0de26 | |||
| c92e45c2e7 | |||
| 583e702547 |
@@ -88,6 +88,7 @@ typedef enum _AuroraViewportPolicy {
|
|||||||
AURORA_VIEWPORT_FIT = 0, // Preserve logical aspect in the content framebuffer
|
AURORA_VIEWPORT_FIT = 0, // Preserve logical aspect in the content framebuffer
|
||||||
AURORA_VIEWPORT_STRETCH = 1, // Match content framebuffer aspect to the native surface
|
AURORA_VIEWPORT_STRETCH = 1, // Match content framebuffer aspect to the native surface
|
||||||
AURORA_VIEWPORT_NATIVE = 2, // Use active framebuffer pixels directly
|
AURORA_VIEWPORT_NATIVE = 2, // Use active framebuffer pixels directly
|
||||||
|
AURORA_VIEWPORT_16_9 = 3, // Fixed 16:9 content with bars on other surfaces
|
||||||
} AuroraViewportPolicy;
|
} AuroraViewportPolicy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ void AuroraSetViewportPolicy(AuroraViewportPolicy policy) {
|
|||||||
}
|
}
|
||||||
g_gxState.viewportPolicy = policy;
|
g_gxState.viewportPolicy = policy;
|
||||||
aurora::window::set_frame_buffer_aspect_fit(policy == AURORA_VIEWPORT_FIT);
|
aurora::window::set_frame_buffer_aspect_fit(policy == AURORA_VIEWPORT_FIT);
|
||||||
|
aurora::window::set_force_aspect_16_9(policy == AURORA_VIEWPORT_16_9);
|
||||||
aurora::window::set_present_surface_fill(policy == AURORA_VIEWPORT_STRETCH);
|
aurora::window::set_present_surface_fill(policy == AURORA_VIEWPORT_STRETCH);
|
||||||
if (changed) {
|
if (changed) {
|
||||||
// Reapply the guest viewport and scissor after a resize.
|
// Reapply the guest viewport and scissor after a resize.
|
||||||
|
|||||||
@@ -399,19 +399,20 @@ const char* PADGetNameForControllerIndex(const u32 idx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PADSetPortForIndex(const u32 idx, const u32 port) {
|
void PADSetPortForIndex(const u32 idx, const u32 port) {
|
||||||
|
if (port >= PAD_MAX_CONTROLLERS) return;
|
||||||
const auto* ctrl = __PADGetControllerForIndex(idx);
|
const auto* ctrl = __PADGetControllerForIndex(idx);
|
||||||
if (ctrl == nullptr) {
|
if (ctrl == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int32_t oldPort = SDL_GetGamepadPlayerIndex(ctrl->m_controller);
|
const int32_t oldPort = aurora::input::player_index(ctrl->m_index);
|
||||||
if (const auto* dest = aurora::input::get_controller_for_player(port); dest != nullptr && dest != ctrl) {
|
if (const auto* dest = aurora::input::get_controller_for_player(port); dest != nullptr && dest != ctrl) {
|
||||||
SDL_SetGamepadPlayerIndex(dest->m_controller, -1);
|
aurora::input::set_player_index(dest->m_index, -1);
|
||||||
}
|
}
|
||||||
if (oldPort >= 0 && oldPort != port) {
|
if (oldPort >= 0 && oldPort != port) {
|
||||||
aurora::input::persist_controller_for_player(oldPort, nullptr);
|
aurora::input::persist_controller_for_player(oldPort, nullptr);
|
||||||
}
|
}
|
||||||
SDL_SetGamepadPlayerIndex(ctrl->m_controller, static_cast<Sint32>(port));
|
aurora::input::set_player_index(ctrl->m_index, static_cast<Sint32>(port));
|
||||||
aurora::input::persist_controller_for_player(port, ctrl);
|
aurora::input::persist_controller_for_player(port, ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,7 +438,7 @@ void PADClearPort(const u32 port) {
|
|||||||
if (ctrl == nullptr) {
|
if (ctrl == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SDL_SetGamepadPlayerIndex(ctrl->m_controller, -1);
|
aurora::input::set_player_index(ctrl->m_index, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secondary bindings live only in memory; the runtime re-applies them from its
|
// Secondary bindings live only in memory; the runtime re-applies them from its
|
||||||
|
|||||||
@@ -214,7 +214,8 @@ Params make_params(wgpu::Extent3D sourceSize, const FrameMapping& mapping) noexc
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool stretch = mapping.viewportPolicy == AURORA_VIEWPORT_STRETCH;
|
const bool stretch = mapping.viewportPolicy == AURORA_VIEWPORT_STRETCH ||
|
||||||
|
mapping.viewportPolicy == AURORA_VIEWPORT_16_9;
|
||||||
const float scaleX = static_cast<float>(sourceSize.width) / static_cast<float>(logicalSize.x);
|
const float scaleX = static_cast<float>(sourceSize.width) / static_cast<float>(logicalSize.x);
|
||||||
const float scaleY = static_cast<float>(sourceSize.height) / static_cast<float>(logicalSize.y);
|
const float scaleY = static_cast<float>(sourceSize.height) / static_cast<float>(logicalSize.y);
|
||||||
const float scale = std::min(scaleX, scaleY);
|
const float scale = std::min(scaleX, scaleY);
|
||||||
|
|||||||
@@ -414,6 +414,29 @@ SDL_JoystickID add_controller(SDL_JoystickID which) noexcept {
|
|||||||
g_GameControllers[instance] = controller;
|
g_GameControllers[instance] = controller;
|
||||||
ensure_player_index(g_GameControllers[instance]);
|
ensure_player_index(g_GameControllers[instance]);
|
||||||
apply_port_preferences();
|
apply_port_preferences();
|
||||||
|
#if defined(SDL_PLATFORM_MACOS)
|
||||||
|
// First-use convenience only: never override a saved assignment or None.
|
||||||
|
if (g_portPreferences[0].state == PortPreferenceState::Unset) {
|
||||||
|
bool hasOtherPortPreference = false;
|
||||||
|
for (size_t port = 1; port < g_portPreferences.size(); ++port) {
|
||||||
|
if (g_portPreferences[port].state == PortPreferenceState::Controller &&
|
||||||
|
identity_match(g_portPreferences[port].identity, controller_identity(g_GameControllers[instance])) !=
|
||||||
|
IdentityMatch::None) {
|
||||||
|
hasOtherPortPreference = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasOtherPortPreference) {
|
||||||
|
const auto* p0 = get_controller_for_player(0);
|
||||||
|
if (p0 == nullptr) {
|
||||||
|
assign_player_index(g_GameControllers[instance], 0);
|
||||||
|
persist_controller_for_player(0, &g_GameControllers[instance]);
|
||||||
|
} else if (p0 == &g_GameControllers[instance]) {
|
||||||
|
persist_controller_for_player(0, &g_GameControllers[instance]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ SDL_Window* g_window;
|
|||||||
SDL_Renderer* g_renderer;
|
SDL_Renderer* g_renderer;
|
||||||
float g_frameBufferScale = 0.f;
|
float g_frameBufferScale = 0.f;
|
||||||
bool g_frameBufferAspectFit = true;
|
bool g_frameBufferAspectFit = true;
|
||||||
|
std::atomic_bool g_forceAspect169{false};
|
||||||
bool g_presentSurfaceFill = false;
|
bool g_presentSurfaceFill = false;
|
||||||
int g_presentAspectWidth = 0;
|
int g_presentAspectWidth = 0;
|
||||||
int g_presentAspectHeight = 0;
|
int g_presentAspectHeight = 0;
|
||||||
@@ -525,7 +526,20 @@ AuroraWindowSize get_window_size() {
|
|||||||
int fb_w = native_fb_w;
|
int fb_w = native_fb_w;
|
||||||
int fb_h = native_fb_h;
|
int fb_h = native_fb_h;
|
||||||
const auto [baseW, baseH] = vi::configured_fb_size();
|
const auto [baseW, baseH] = vi::configured_fb_size();
|
||||||
if (g_frameBufferAspectFit && baseW > 0 && baseH > 0) {
|
if (g_forceAspect169.load(std::memory_order_acquire) && native_fb_w > 0 && native_fb_h > 0) {
|
||||||
|
if (g_frameBufferScale > 0.f && baseW > 0 && baseH > 0) {
|
||||||
|
const auto [scaledW, scaledH] =
|
||||||
|
scale_frame_buffer_to_aspect(static_cast<int>(baseW), static_cast<int>(baseH),
|
||||||
|
g_frameBufferScale, 16.f / 9.f);
|
||||||
|
fb_w = scaledW;
|
||||||
|
fb_h = scaledH;
|
||||||
|
} else {
|
||||||
|
fb_w = std::min(native_fb_w,
|
||||||
|
std::max(1, static_cast<int>(std::lround(native_fb_h * (16.f / 9.f)))));
|
||||||
|
fb_h = std::min(native_fb_h,
|
||||||
|
std::max(1, static_cast<int>(std::lround(native_fb_w * (9.f / 16.f)))));
|
||||||
|
}
|
||||||
|
} else if (g_frameBufferAspectFit && baseW > 0 && baseH > 0) {
|
||||||
float renderScale = g_frameBufferScale > 0.f ? g_frameBufferScale : 1.f;
|
float renderScale = g_frameBufferScale > 0.f ? g_frameBufferScale : 1.f;
|
||||||
if (g_frameBufferScale <= 0.f) {
|
if (g_frameBufferScale <= 0.f) {
|
||||||
renderScale = std::min(static_cast<float>(native_fb_w) / static_cast<float>(baseW),
|
renderScale = std::min(static_cast<float>(native_fb_w) / static_cast<float>(baseW),
|
||||||
@@ -759,6 +773,14 @@ void set_frame_buffer_aspect_fit(bool fit) {
|
|||||||
request_frame_buffer_resize();
|
request_frame_buffer_resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_force_aspect_16_9(bool force) {
|
||||||
|
if (g_forceAspect169.load(std::memory_order_relaxed) == force) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_forceAspect169.store(force, std::memory_order_release);
|
||||||
|
request_frame_buffer_resize();
|
||||||
|
}
|
||||||
|
|
||||||
void set_present_surface_fill(bool fill) {
|
void set_present_surface_fill(bool fill) {
|
||||||
g_presentSurfaceFill = fill;
|
g_presentSurfaceFill = fill;
|
||||||
}
|
}
|
||||||
@@ -781,6 +803,10 @@ void unlock_present_aspect_ratio() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool get_present_aspect_ratio(float& aspect) noexcept {
|
bool get_present_aspect_ratio(float& aspect) noexcept {
|
||||||
|
if (g_forceAspect169.load(std::memory_order_acquire)) {
|
||||||
|
aspect = 16.f / 9.f;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (g_presentSurfaceFill && g_window != nullptr) {
|
if (g_presentSurfaceFill && g_window != nullptr) {
|
||||||
// Queried once per presentation snapshot; use the cached native client size
|
// Queried once per presentation snapshot; use the cached native client size
|
||||||
// instead of re-entering SDL for a value the window procedure already knows.
|
// instead of re-entering SDL for a value the window procedure already knows.
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ void sync_frame_buffer_size() noexcept;
|
|||||||
void request_frame_buffer_resize();
|
void request_frame_buffer_resize();
|
||||||
void set_frame_buffer_scale(float scale);
|
void set_frame_buffer_scale(float scale);
|
||||||
void set_frame_buffer_aspect_fit(bool fit);
|
void set_frame_buffer_aspect_fit(bool fit);
|
||||||
|
void set_force_aspect_16_9(bool force);
|
||||||
void set_present_surface_fill(bool fill);
|
void set_present_surface_fill(bool fill);
|
||||||
void lock_present_aspect_ratio(int width, int height);
|
void lock_present_aspect_ratio(int width, int height);
|
||||||
void unlock_present_aspect_ratio();
|
void unlock_present_aspect_ratio();
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern "C" bool g_dynamicAspectRatioEnabled;
|
extern "C" bool g_dynamicAspectRatioEnabled;
|
||||||
void ConfigureMkwDynamicAspect(bool widescreen, uint32_t surfaceWidth, uint32_t surfaceHeight);
|
void ConfigureMkwDynamicAspect(bool widescreen, bool forceAspect169, uint32_t surfaceWidth, uint32_t surfaceHeight);
|
||||||
|
void SetMkwForceAspect169(bool enabled);
|
||||||
|
bool MkwForceAspect169Requested();
|
||||||
void UpdateMkwDynamicAspectSurface(uint32_t surfaceWidth, uint32_t surfaceHeight);
|
void UpdateMkwDynamicAspectSurface(uint32_t surfaceWidth, uint32_t surfaceHeight);
|
||||||
// Arms the "keep EGG::Frustum's projection scale" flag on every screen that
|
// Arms the "keep EGG::Frustum's projection scale" flag on every screen that
|
||||||
// renders to a fixed-size offscreen target. Cheap and idempotent; called from
|
// renders to a fixed-size offscreen target. Cheap and idempotent; called from
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
struct RuntimeUserConfig {
|
struct RuntimeUserConfig {
|
||||||
std::optional<bool> widescreen;
|
std::optional<bool> widescreen;
|
||||||
|
std::optional<bool> forceAspect169;
|
||||||
std::optional<int32_t> windowPosX;
|
std::optional<int32_t> windowPosX;
|
||||||
std::optional<int32_t> windowPosY;
|
std::optional<int32_t> windowPosY;
|
||||||
std::optional<uint32_t> windowWidth;
|
std::optional<uint32_t> windowWidth;
|
||||||
@@ -298,6 +299,7 @@ inline void EnsureConfigFile() {
|
|||||||
"# Set paths.dvd_root to an extracted Mario Kart Wii DATA directory.\n\n"
|
"# Set paths.dvd_root to an extracted Mario Kart Wii DATA directory.\n\n"
|
||||||
"[video]\n"
|
"[video]\n"
|
||||||
"widescreen = true\n"
|
"widescreen = true\n"
|
||||||
|
"force_16_9 = false\n"
|
||||||
"resolution_multiplier = 1.0\n"
|
"resolution_multiplier = 1.0\n"
|
||||||
"frame_interpolation_fps = 0\n"
|
"frame_interpolation_fps = 0\n"
|
||||||
"display_mode = \"windowed\"\n"
|
"display_mode = \"windowed\"\n"
|
||||||
@@ -426,6 +428,7 @@ inline RuntimeUserConfig ParseConfigDocument(const toml::value& document) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.widescreen = FindConfigValue<bool>(document, "video", "widescreen");
|
config.widescreen = FindConfigValue<bool>(document, "video", "widescreen");
|
||||||
|
config.forceAspect169 = FindConfigValue<bool>(document, "video", "force_16_9");
|
||||||
config.windowPosX = FindConfigInt(document, "video", "window_x");
|
config.windowPosX = FindConfigInt(document, "video", "window_x");
|
||||||
config.windowPosY = FindConfigInt(document, "video", "window_y");
|
config.windowPosY = FindConfigInt(document, "video", "window_y");
|
||||||
if (auto value = FindConfigUint(document, "video", "window_width"); value && *value != 0) {
|
if (auto value = FindConfigUint(document, "video", "window_width"); value && *value != 0) {
|
||||||
@@ -782,6 +785,15 @@ inline bool WidescreenEnabled(bool fallback = false) {
|
|||||||
return Get().widescreen.value_or(fallback);
|
return Get().widescreen.value_or(fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool ForceAspect169Enabled(bool fallback = false) {
|
||||||
|
return Get().forceAspect169.value_or(fallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SetForceAspect169(bool value) {
|
||||||
|
Mutable().forceAspect169 = value;
|
||||||
|
return WriteSetting("video", "force_16_9", value ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
inline bool WindowPosition(int32_t& x, int32_t& y) {
|
inline bool WindowPosition(int32_t& x, int32_t& y) {
|
||||||
if (!Get().windowPosX || !Get().windowPosY) {
|
if (!Get().windowPosX || !Get().windowPosY) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <imgui.h>
|
#include <imgui.h>
|
||||||
#include <SDL3/SDL_gamepad.h>
|
#include <SDL3/SDL_gamepad.h>
|
||||||
#include <SDL3/SDL_joystick.h>
|
#include <SDL3/SDL_joystick.h>
|
||||||
|
#include <SDL3/SDL_platform.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
@@ -146,7 +147,7 @@ std::string BuildMappingString() {
|
|||||||
mapping += std::string(kSteps[i].mappingKey) + ":" + *g_wizard.bindings[i] + ",";
|
mapping += std::string(kSteps[i].mappingKey) + ":" + *g_wizard.bindings[i] + ",";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mapping += "platform:Windows,";
|
mapping += std::string("platform:") + SDL_GetPlatform() + ",";
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <atomic>
|
||||||
#include "aurora_events.h"
|
#include "aurora_events.h"
|
||||||
#include "hle/gx/gx_dynamic_aspect.h"
|
#include "hle/gx/gx_dynamic_aspect.h"
|
||||||
|
|
||||||
@@ -14,6 +15,10 @@ extern "C" int g_gxFrameCount;
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool g_widescreenConfigured = false;
|
bool g_widescreenConfigured = false;
|
||||||
|
bool g_widescreenSetting = false;
|
||||||
|
bool g_forceAspect169 = false;
|
||||||
|
std::atomic_bool g_requestedForceAspect169{false};
|
||||||
|
bool g_policyDirty = false;
|
||||||
uint32_t g_lastEggWidth43 = 0;
|
uint32_t g_lastEggWidth43 = 0;
|
||||||
uint32_t g_lastEggWidth169 = 0;
|
uint32_t g_lastEggWidth169 = 0;
|
||||||
|
|
||||||
@@ -167,21 +172,54 @@ void AssertMkwOffscreenScreenBypass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void UpdateMkwDynamicAspectSurface(uint32_t surfaceWidth, uint32_t surfaceHeight) {
|
void UpdateMkwDynamicAspectSurface(uint32_t surfaceWidth, uint32_t surfaceHeight) {
|
||||||
if (!g_widescreenConfigured || surfaceWidth == 0 || surfaceHeight == 0) {
|
const bool requestedForceAspect169 = g_requestedForceAspect169.load(std::memory_order_acquire);
|
||||||
|
if (g_forceAspect169 != requestedForceAspect169) {
|
||||||
|
g_forceAspect169 = requestedForceAspect169;
|
||||||
|
g_widescreenConfigured = g_widescreenSetting || g_forceAspect169;
|
||||||
|
g_dynamicAspectRatioEnabled = g_widescreenConfigured;
|
||||||
|
g_policyDirty = true;
|
||||||
|
}
|
||||||
|
if (surfaceWidth == 0 || surfaceHeight == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AuroraSetViewportPolicy(AURORA_VIEWPORT_STRETCH);
|
if (!g_widescreenConfigured) {
|
||||||
ApplyEggScreenRecords(surfaceWidth, surfaceHeight);
|
if (g_policyDirty) {
|
||||||
|
AuroraSetViewportPolicy(AURORA_VIEWPORT_FIT);
|
||||||
|
VILockAspectRatio(4, 3);
|
||||||
|
ApplyEggScreenRecords(surfaceWidth, surfaceHeight);
|
||||||
|
g_policyDirty = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (g_policyDirty) {
|
||||||
|
VIUnlockAspectRatio();
|
||||||
|
g_policyDirty = false;
|
||||||
|
}
|
||||||
|
AuroraSetViewportPolicy(g_forceAspect169 ? AURORA_VIEWPORT_16_9 : AURORA_VIEWPORT_STRETCH);
|
||||||
|
ApplyEggScreenRecords(g_forceAspect169 ? 16u : surfaceWidth,
|
||||||
|
g_forceAspect169 ? 9u : surfaceHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureMkwDynamicAspect(bool widescreen, uint32_t surfaceWidth, uint32_t surfaceHeight) {
|
void SetMkwForceAspect169(bool enabled) {
|
||||||
g_widescreenConfigured = widescreen;
|
g_requestedForceAspect169.store(enabled, std::memory_order_release);
|
||||||
g_dynamicAspectRatioEnabled = widescreen;
|
}
|
||||||
|
|
||||||
|
bool MkwForceAspect169Requested() {
|
||||||
|
return g_requestedForceAspect169.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureMkwDynamicAspect(bool widescreen, bool forceAspect169, uint32_t surfaceWidth, uint32_t surfaceHeight) {
|
||||||
|
g_widescreenSetting = widescreen;
|
||||||
|
g_widescreenConfigured = widescreen || forceAspect169;
|
||||||
|
g_forceAspect169 = forceAspect169;
|
||||||
|
g_requestedForceAspect169.store(forceAspect169, std::memory_order_relaxed);
|
||||||
|
g_dynamicAspectRatioEnabled = g_widescreenConfigured;
|
||||||
g_lastEggWidth43 = 0;
|
g_lastEggWidth43 = 0;
|
||||||
g_lastEggWidth169 = 0;
|
g_lastEggWidth169 = 0;
|
||||||
if (widescreen) {
|
if (g_widescreenConfigured) {
|
||||||
VIUnlockAspectRatio();
|
VIUnlockAspectRatio();
|
||||||
ApplyEggScreenRecords(surfaceWidth, surfaceHeight);
|
ApplyEggScreenRecords(forceAspect169 ? 16u : surfaceWidth,
|
||||||
|
forceAspect169 ? 9u : surfaceHeight);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -467,7 +467,8 @@ int32_t HandleIpTopIoctlv(uint32_t cmd, const std::vector<IoVector>& in, const s
|
|||||||
const int ret = sendto(s->native, reinterpret_cast<const char*>(sendData), static_cast<int>(sendSize),
|
const int ret = sendto(s->native, reinterpret_cast<const char*>(sendData), static_cast<int>(sendSize),
|
||||||
static_cast<int>(flags), destPtr, destLen);
|
static_cast<int>(flags), destPtr, destLen);
|
||||||
const int hostError = ret < 0 ? NativeLastError() : 0;
|
const int hostError = ret < 0 ? NativeLastError() : 0;
|
||||||
int32_t result = SocketResult(ret);
|
// Diagnostics may change the native error; use the send result captured above.
|
||||||
|
int32_t result = ret >= 0 ? SocketResult(ret) : SocketErrorResult(hostError);
|
||||||
if (patchedWrite && ret == static_cast<int>(sendSize)) {
|
if (patchedWrite && ret == static_cast<int>(sendSize)) {
|
||||||
result = static_cast<int32_t>(in[0].size);
|
result = static_cast<int32_t>(in[0].size);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "runtime_config.h"
|
#include "runtime_config.h"
|
||||||
|
#include "aurora_events.h"
|
||||||
#include "runtime_log.h"
|
#include "runtime_log.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -52,7 +53,7 @@ PPC_NATIVE_OVERRIDE(801B0220, SCCheckStatus_HLE, uint32_t, (), ());
|
|||||||
// Returns: 0 = 4:3, 1 = 16:9
|
// Returns: 0 = 4:3, 1 = 16:9
|
||||||
extern "C" uint32_t SCGetAspectRatio_HLE()
|
extern "C" uint32_t SCGetAspectRatio_HLE()
|
||||||
{
|
{
|
||||||
return RuntimeConfigFile::WidescreenEnabled(true) ? 1u : 0u;
|
return (RuntimeConfigFile::WidescreenEnabled(true) || MkwForceAspect169Requested()) ? 1u : 0u;
|
||||||
}
|
}
|
||||||
|
|
||||||
PPC_NATIVE_OVERRIDE(801B1BE4, SCGetAspectRatio_HLE, uint32_t, (), ());
|
PPC_NATIVE_OVERRIDE(801B1BE4, SCGetAspectRatio_HLE, uint32_t, (), ());
|
||||||
|
|||||||
@@ -1354,7 +1354,8 @@ int RuntimeMain(int argc, char** argv) {
|
|||||||
auroraConfig.logCallback = &RuntimeAuroraLogCallback;
|
auroraConfig.logCallback = &RuntimeAuroraLogCallback;
|
||||||
auroraConfig.logLevel = LOG_DEBUG;
|
auroraConfig.logLevel = LOG_DEBUG;
|
||||||
const bool configWidescreen = RuntimeConfigFile::WidescreenEnabled(true);
|
const bool configWidescreen = RuntimeConfigFile::WidescreenEnabled(true);
|
||||||
auroraConfig.windowWidth = configWidescreen ? 854 : 640;
|
const bool forceAspect169 = RuntimeConfigFile::ForceAspect169Enabled();
|
||||||
|
auroraConfig.windowWidth = (configWidescreen || forceAspect169) ? 854 : 640;
|
||||||
auroraConfig.windowHeight = 480;
|
auroraConfig.windowHeight = 480;
|
||||||
auroraConfig.windowWidth = RuntimeConfigFile::WindowWidth(auroraConfig.windowWidth);
|
auroraConfig.windowWidth = RuntimeConfigFile::WindowWidth(auroraConfig.windowWidth);
|
||||||
auroraConfig.windowHeight = RuntimeConfigFile::WindowHeight(auroraConfig.windowHeight);
|
auroraConfig.windowHeight = RuntimeConfigFile::WindowHeight(auroraConfig.windowHeight);
|
||||||
@@ -1372,7 +1373,8 @@ int RuntimeMain(int argc, char** argv) {
|
|||||||
// No vsync knob: aurora always configures a non-blocking present mode.
|
// No vsync knob: aurora always configures a non-blocking present mode.
|
||||||
auroraConfig.desiredBackend = BACKEND_AUTO;
|
auroraConfig.desiredBackend = BACKEND_AUTO;
|
||||||
const float resolutionMultiplier = RuntimeConfigFile::ResolutionMultiplier(1.0f);
|
const float resolutionMultiplier = RuntimeConfigFile::ResolutionMultiplier(1.0f);
|
||||||
ConfigureMkwDynamicAspect(configWidescreen, auroraConfig.windowWidth, auroraConfig.windowHeight);
|
ConfigureMkwDynamicAspect(configWidescreen, forceAspect169,
|
||||||
|
auroraConfig.windowWidth, auroraConfig.windowHeight);
|
||||||
VISetFrameBufferScale(resolutionMultiplier);
|
VISetFrameBufferScale(resolutionMultiplier);
|
||||||
// One table for both directions. RuntimeConfigFile::IsSupportedGraphicsApi
|
// One table for both directions. RuntimeConfigFile::IsSupportedGraphicsApi
|
||||||
// whitelists exactly these config names, so an unrecognised value has
|
// whitelists exactly these config names, so an unrecognised value has
|
||||||
@@ -1439,14 +1441,15 @@ int RuntimeMain(int argc, char** argv) {
|
|||||||
auroraInfo.windowSize.native_fb_height);
|
auroraInfo.windowSize.native_fb_height);
|
||||||
settings_overlay::InitializeRuntimeSettings();
|
settings_overlay::InitializeRuntimeSettings();
|
||||||
RT_LOG(RT_TAG_CONFIG) << "video.widescreen=" << (configWidescreen ? "true" : "false")
|
RT_LOG(RT_TAG_CONFIG) << "video.widescreen=" << (configWidescreen ? "true" : "false")
|
||||||
<< " SCGetAspectRatio=" << (configWidescreen ? 1 : 0)
|
<< " force_16_9=" << (forceAspect169 ? "true" : "false")
|
||||||
|
<< " SCGetAspectRatio=" << (configWidescreen || forceAspect169 ? 1 : 0)
|
||||||
<< " resolutionMultiplier=" << resolutionMultiplier
|
<< " resolutionMultiplier=" << resolutionMultiplier
|
||||||
<< " window=" << auroraInfo.windowSize.width << "x" << auroraInfo.windowSize.height
|
<< " window=" << auroraInfo.windowSize.width << "x" << auroraInfo.windowSize.height
|
||||||
<< " native=" << auroraInfo.windowSize.native_fb_width << "x"
|
<< " native=" << auroraInfo.windowSize.native_fb_width << "x"
|
||||||
<< auroraInfo.windowSize.native_fb_height
|
<< auroraInfo.windowSize.native_fb_height
|
||||||
<< " viewportPolicy=" << (g_dynamicAspectRatioEnabled ? "stretch" : "fit")
|
<< " viewportPolicy=" << (forceAspect169 ? "16:9" : (configWidescreen ? "stretch" : "fit"))
|
||||||
<< " presentAspect="
|
<< " presentAspect="
|
||||||
<< (g_dynamicAspectRatioEnabled ? "surface (dynamic EGG canvas)" : "4:3")
|
<< (forceAspect169 ? "16:9" : (configWidescreen ? "surface (dynamic EGG canvas)" : "4:3"))
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
g_auroraInitialized.store(true, std::memory_order_release);
|
g_auroraInitialized.store(true, std::memory_order_release);
|
||||||
|
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ int g_displayMode = [] {
|
|||||||
bool g_skipUnreadyPipelines = RuntimeConfigFile::SkipUnreadyPipelines(true);
|
bool g_skipUnreadyPipelines = RuntimeConfigFile::SkipUnreadyPipelines(true);
|
||||||
bool g_disableCopyFilter = RuntimeConfigFile::DisableCopyFilter(true);
|
bool g_disableCopyFilter = RuntimeConfigFile::DisableCopyFilter(true);
|
||||||
bool g_showFps = RuntimeConfigFile::ShowFps(true);
|
bool g_showFps = RuntimeConfigFile::ShowFps(true);
|
||||||
|
bool g_forceAspect169 = RuntimeConfigFile::ForceAspect169Enabled();
|
||||||
uint32_t g_disabledPostProcessingPaths = RuntimeConfigFile::DisabledPostProcessingPaths(0);
|
uint32_t g_disabledPostProcessingPaths = RuntimeConfigFile::DisabledPostProcessingPaths(0);
|
||||||
std::array<int32_t, PAD_MAX_CONTROLLERS> g_configuredControllerIndices = [] {
|
std::array<int32_t, PAD_MAX_CONTROLLERS> g_configuredControllerIndices = [] {
|
||||||
std::array<int32_t, PAD_MAX_CONTROLLERS> indices{};
|
std::array<int32_t, PAD_MAX_CONTROLLERS> indices{};
|
||||||
@@ -1006,6 +1007,12 @@ void DrawAudioSettings() {
|
|||||||
|
|
||||||
void DrawGraphicsSettings() {
|
void DrawGraphicsSettings() {
|
||||||
g_displayMode = static_cast<int>(aurora_get_display_mode());
|
g_displayMode = static_cast<int>(aurora_get_display_mode());
|
||||||
|
if (ImGui::Checkbox("Force 16:9", &g_forceAspect169)) {
|
||||||
|
SetMkwForceAspect169(g_forceAspect169);
|
||||||
|
RuntimeConfigFile::SetForceAspect169(g_forceAspect169);
|
||||||
|
}
|
||||||
|
ImGui::TextDisabled("Keep a 16:9 image with black bars when the window has another shape.");
|
||||||
|
ImGui::Separator();
|
||||||
struct EffectFlag {
|
struct EffectFlag {
|
||||||
const char* label;
|
const char* label;
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
|
|||||||
@@ -1942,6 +1942,22 @@ public sealed partial class PpcLifter
|
|||||||
new IrCall(string.Empty, TargetLabel(ins, validAddresses, preferFallthrough: false), blArgs)
|
new IrCall(string.Empty, TargetLabel(ins, validAddresses, preferFallthrough: false), blArgs)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case "bltl":
|
||||||
|
{
|
||||||
|
var crField = "cr0";
|
||||||
|
if (ops.Count > 0 && ops[0] is PpcConditionRegisterOperand crOp)
|
||||||
|
{
|
||||||
|
crField = NormalizeRegister(crOp.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new IrInstruction[]
|
||||||
|
{
|
||||||
|
new IrAssign("lr", IrValue.Imm((int)ins.EndAddress)),
|
||||||
|
new IrBranch("blt", TargetLabel(ins, validAddresses, preferFallthrough: false),
|
||||||
|
$"0x{ins.EndAddress:X8}", crField)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
case "bcl":
|
case "bcl":
|
||||||
{
|
{
|
||||||
var rawInstr = ReadRawInstruction(ins);
|
var rawInstr = ReadRawInstruction(ins);
|
||||||
|
|||||||
@@ -14,6 +14,23 @@ public class PpcLifterAdditionalCoverageTests
|
|||||||
private static PpcInstruction Instruction(uint raw, string mnemonic, params PpcOperand[] operands)
|
private static PpcInstruction Instruction(uint raw, string mnemonic, params PpcOperand[] operands)
|
||||||
=> PpcInstruction.Synthetic(0x80000000, raw, mnemonic, operands);
|
=> PpcInstruction.Synthetic(0x80000000, raw, mnemonic, operands);
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void LinkedConditionalBranchSetsLrBeforeEitherPath()
|
||||||
|
{
|
||||||
|
var branch = PpcDecoder.Decode(0x80004394, 0x41800029);
|
||||||
|
var ir = Assert.Single(new PpcLifter().Lift(new[] { branch })).Ir;
|
||||||
|
|
||||||
|
Assert.Equal("bltl", branch.Mnemonic);
|
||||||
|
var lr = Assert.IsType<IrAssign>(ir[0]);
|
||||||
|
Assert.Equal("lr", lr.Destination);
|
||||||
|
Assert.Equal(unchecked((int)0x80004398u), lr.Value.Constant);
|
||||||
|
|
||||||
|
var decision = Assert.IsType<IrBranch>(ir[1]);
|
||||||
|
Assert.Equal("blt", decision.Condition);
|
||||||
|
Assert.Equal("0x800043BC", decision.TrueLabel);
|
||||||
|
Assert.Equal("0x80004398", decision.FalseLabel);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void LiftsAdditionalNonDotArithmeticAndLogicalForms()
|
public void LiftsAdditionalNonDotArithmeticAndLogicalForms()
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user