summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/vi/vi.cpp97
1 files changed, 58 insertions, 39 deletions
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 1bdf19e13..70c933934 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -32,6 +32,9 @@
namespace Service::VI {
+constexpr ResultCode ERR_OPERATION_FAILED{ErrorModule::VI, 1};
+constexpr ResultCode ERR_UNSUPPORTED{ErrorModule::VI, 6};
+
struct DisplayInfo {
/// The name of this particular display.
char display_name[0x40]{"Default"};
@@ -874,6 +877,22 @@ public:
~IApplicationDisplayService() = default;
private:
+ enum class ConvertedScaleMode : u64 {
+ Freeze = 0,
+ ScaleToWindow = 1,
+ ScaleAndCrop = 2,
+ None = 3,
+ PreserveAspectRatio = 4,
+ };
+
+ enum class NintendoScaleMode : u32 {
+ None = 0,
+ Freeze = 1,
+ ScaleToWindow = 2,
+ ScaleAndCrop = 3,
+ PreserveAspectRatio = 4,
+ };
+
void GetRelayService(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_VI, "(STUBBED) called");
@@ -974,13 +993,27 @@ private:
void SetLayerScalingMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- const u32 scaling_mode = rp.Pop<u32>();
+ const auto scaling_mode = rp.PopEnum<NintendoScaleMode>();
const u64 unknown = rp.Pop<u64>();
- LOG_WARNING(Service_VI, "(STUBBED) called. scaling_mode=0x{:08X}, unknown=0x{:016X}",
- scaling_mode, unknown);
+ LOG_DEBUG(Service_VI, "called. scaling_mode=0x{:08X}, unknown=0x{:016X}",
+ static_cast<u32>(scaling_mode), unknown);
IPC::ResponseBuilder rb{ctx, 2};
+
+ if (scaling_mode > NintendoScaleMode::PreserveAspectRatio) {
+ LOG_ERROR(Service_VI, "Invalid scaling mode provided.");
+ rb.Push(ERR_OPERATION_FAILED);
+ return;
+ }
+
+ if (scaling_mode != NintendoScaleMode::ScaleToWindow &&
+ scaling_mode != NintendoScaleMode::PreserveAspectRatio) {
+ LOG_ERROR(Service_VI, "Unsupported scaling mode supplied.");
+ rb.Push(ERR_UNSUPPORTED);
+ return;
+ }
+
rb.Push(RESULT_SUCCESS);
}
@@ -1061,51 +1094,37 @@ private:
rb.PushCopyObjects(vsync_event);
}
- enum class ConvertedScaleMode : u64 {
- None = 0, // VI seems to name this as "Unknown" but lots of games pass it, assume it's no
- // scaling/default
- Freeze = 1,
- ScaleToWindow = 2,
- Crop = 3,
- NoCrop = 4,
- };
-
- // This struct is different, currently it's 1:1 but this might change in the future.
- enum class NintendoScaleMode : u32 {
- None = 0,
- Freeze = 1,
- ScaleToWindow = 2,
- Crop = 3,
- NoCrop = 4,
- };
-
void ConvertScalingMode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
- auto mode = rp.PopEnum<NintendoScaleMode>();
+ const auto mode = rp.PopEnum<NintendoScaleMode>();
LOG_DEBUG(Service_VI, "called mode={}", static_cast<u32>(mode));
- IPC::ResponseBuilder rb{ctx, 4};
- rb.Push(RESULT_SUCCESS);
+ const auto converted_mode = ConvertScalingModeImpl(mode);
+
+ if (converted_mode.Succeeded()) {
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushEnum(*converted_mode);
+ } else {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(converted_mode.Code());
+ }
+ }
+
+ static ResultVal<ConvertedScaleMode> ConvertScalingModeImpl(NintendoScaleMode mode) {
switch (mode) {
case NintendoScaleMode::None:
- rb.PushEnum(ConvertedScaleMode::None);
- break;
+ return MakeResult(ConvertedScaleMode::None);
case NintendoScaleMode::Freeze:
- rb.PushEnum(ConvertedScaleMode::Freeze);
- break;
+ return MakeResult(ConvertedScaleMode::Freeze);
case NintendoScaleMode::ScaleToWindow:
- rb.PushEnum(ConvertedScaleMode::ScaleToWindow);
- break;
- case NintendoScaleMode::Crop:
- rb.PushEnum(ConvertedScaleMode::Crop);
- break;
- case NintendoScaleMode::NoCrop:
- rb.PushEnum(ConvertedScaleMode::NoCrop);
- break;
+ return MakeResult(ConvertedScaleMode::ScaleToWindow);
+ case NintendoScaleMode::ScaleAndCrop:
+ return MakeResult(ConvertedScaleMode::ScaleAndCrop);
+ case NintendoScaleMode::PreserveAspectRatio:
+ return MakeResult(ConvertedScaleMode::PreserveAspectRatio);
default:
- UNIMPLEMENTED_MSG("Unknown scaling mode {}", static_cast<u32>(mode));
- rb.PushEnum(ConvertedScaleMode::None);
- break;
+ return ERR_OPERATION_FAILED;
}
}