Compare commits
58 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc89b7bfcb | ||
|
|
a155d3b7ff | ||
|
|
88f1fe79c6 | ||
|
|
177bdb94df | ||
|
|
4d1a2509df | ||
|
|
ac50d2cd60 | ||
|
|
2d2de1422e | ||
|
|
9e2f30ab4a | ||
|
|
be50a6ceef | ||
|
|
7788178f01 | ||
|
|
ae5e2d07c6 | ||
|
|
ee3ca32fa3 | ||
|
|
ed2da0ef70 | ||
|
|
c0011fdacd | ||
|
|
a886e3bc2a | ||
|
|
4cf4a5ecdc | ||
|
|
c79c9755b4 | ||
|
|
434cffa37d | ||
|
|
0cc2e7d81d | ||
|
|
84d39530cf | ||
|
|
227bc78cbe | ||
|
|
e0fb6a188c | ||
|
|
d79558a6f0 | ||
|
|
222ba939f2 | ||
|
|
f16eb90b8f | ||
|
|
0b855f1c21 | ||
|
|
dcc27d6dc1 | ||
|
|
b0ca330e14 | ||
|
|
cb3183212d | ||
|
|
65faeb9b2a | ||
|
|
b258403f0d | ||
|
|
65ea52394b | ||
|
|
73eaef9c05 | ||
|
|
b305646c44 | ||
|
|
c28ed85875 | ||
|
|
ca96b04a0c | ||
|
|
0171ec606b | ||
|
|
f73a280eeb | ||
|
|
ad1810e895 | ||
|
|
37041ea12c | ||
|
|
358050cfc6 | ||
|
|
68183e7b5a | ||
|
|
f9945f8a3b | ||
|
|
d1d7582a5b | ||
|
|
1f37dd02ce | ||
|
|
27dbbd8227 | ||
|
|
cfc28e0c1a | ||
|
|
ca17f581f5 | ||
|
|
20bd26dc7d | ||
|
|
40bccd74d3 | ||
|
|
4c0cf3d5ff | ||
|
|
3d4dfefaec | ||
|
|
910b02d74b | ||
|
|
9d08a11c1d | ||
|
|
99ae9dbf49 | ||
|
|
9eb485702f | ||
|
|
b87a588c37 | ||
|
|
bb9093ed57 |
2
externals/fmt
vendored
2
externals/fmt
vendored
Submodule externals/fmt updated: 4d35f94133...5859e58ba1
@@ -146,12 +146,13 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
|
||||
PrintColoredMessage(entry);
|
||||
}
|
||||
|
||||
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
|
||||
const char* function, const char* format, const fmt::ArgList& args) {
|
||||
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
|
||||
unsigned int line_num, const char* function, const char* format,
|
||||
const fmt::format_args& args) {
|
||||
if (filter && !filter->CheckMessage(log_class, log_level))
|
||||
return;
|
||||
Entry entry =
|
||||
CreateEntry(log_class, log_level, filename, line_num, function, fmt::format(format, args));
|
||||
CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args));
|
||||
|
||||
PrintColoredMessage(entry);
|
||||
}
|
||||
|
||||
@@ -104,9 +104,17 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
|
||||
#endif
|
||||
;
|
||||
|
||||
/// Logs a message to the global logger, using fmt
|
||||
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
|
||||
unsigned int line_num, const char* function, const char* format,
|
||||
const fmt::format_args& args);
|
||||
|
||||
template <typename... Args>
|
||||
void FmtLogMessage(Class log_class, Level log_level, const char* filename, unsigned int line_num,
|
||||
const char* function, const char* format, const fmt::ArgList& args);
|
||||
FMT_VARIADIC(void, FmtLogMessage, Class, Level, const char*, unsigned int, const char*, const char*)
|
||||
const char* function, const char* format, const Args&... args) {
|
||||
FmtLogMessageImpl(log_class, log_level, filename, line_num, function, format,
|
||||
fmt::make_args(args...));
|
||||
}
|
||||
|
||||
} // namespace Log
|
||||
|
||||
|
||||
@@ -130,6 +130,8 @@ add_library(core STATIC
|
||||
hle/service/friend/friend.h
|
||||
hle/service/friend/friend_a.cpp
|
||||
hle/service/friend/friend_a.h
|
||||
hle/service/friend/friend_u.cpp
|
||||
hle/service/friend/friend_u.h
|
||||
hle/service/hid/hid.cpp
|
||||
hle/service/hid/hid.h
|
||||
hle/service/lm/lm.cpp
|
||||
|
||||
@@ -92,6 +92,8 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
|
||||
return ResultStatus::ErrorLoader_ErrorEncrypted;
|
||||
case Loader::ResultStatus::ErrorInvalidFormat:
|
||||
return ResultStatus::ErrorLoader_ErrorInvalidFormat;
|
||||
case Loader::ResultStatus::ErrorUnsupportedArch:
|
||||
return ResultStatus::ErrorUnsupportedArch;
|
||||
default:
|
||||
return ResultStatus::ErrorSystemMode;
|
||||
}
|
||||
@@ -115,6 +117,8 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
|
||||
return ResultStatus::ErrorLoader_ErrorEncrypted;
|
||||
case Loader::ResultStatus::ErrorInvalidFormat:
|
||||
return ResultStatus::ErrorLoader_ErrorInvalidFormat;
|
||||
case Loader::ResultStatus::ErrorUnsupportedArch:
|
||||
return ResultStatus::ErrorUnsupportedArch;
|
||||
default:
|
||||
return ResultStatus::ErrorLoader;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
ErrorSystemFiles, ///< Error in finding system files
|
||||
ErrorSharedFont, ///< Error in finding shared font
|
||||
ErrorVideoCore, ///< Error in the video core
|
||||
ErrorUnsupportedArch, ///< Unsupported Architecture (32-Bit ROMs)
|
||||
ErrorUnknown ///< Any other error
|
||||
};
|
||||
|
||||
|
||||
@@ -120,18 +120,6 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
return ERR_WRONG_PERMISSION;
|
||||
}
|
||||
|
||||
// TODO(Subv): The same process that created a SharedMemory object
|
||||
// can not map it in its own address space unless it was created with addr=0, result 0xD900182C.
|
||||
|
||||
if (address != 0) {
|
||||
// TODO(shinyquagsire23): Check for virtual/mappable memory here too?
|
||||
if (address >= Memory::HEAP_VADDR && address < Memory::HEAP_VADDR_END) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%lx name=%s, invalid address",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
VAddr target_address = address;
|
||||
|
||||
if (base_address == 0 && target_address == 0) {
|
||||
|
||||
@@ -371,6 +371,18 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Sets the thread activity
|
||||
static ResultCode SetThreadActivity(Handle handle, u32 unknown) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, unknown=0x%08X", handle, unknown);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Gets the thread context
|
||||
static ResultCode GetThreadContext(Handle handle, VAddr addr) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called, handle=0x%08X, addr=0x%" PRIx64, handle, addr);
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Gets the priority for the specified thread
|
||||
static ResultCode GetThreadPriority(u32* priority, Handle handle) {
|
||||
const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle);
|
||||
@@ -853,8 +865,8 @@ static const FunctionDef SVC_Table[] = {
|
||||
{0x2F, nullptr, "GetLastThreadInfo"},
|
||||
{0x30, nullptr, "GetResourceLimitLimitValue"},
|
||||
{0x31, nullptr, "GetResourceLimitCurrentValue"},
|
||||
{0x32, nullptr, "SetThreadActivity"},
|
||||
{0x33, nullptr, "GetThreadContext"},
|
||||
{0x32, SvcWrap<SetThreadActivity>, "SetThreadActivity"},
|
||||
{0x33, SvcWrap<GetThreadContext>, "GetThreadContext"},
|
||||
{0x34, nullptr, "Unknown"},
|
||||
{0x35, nullptr, "Unknown"},
|
||||
{0x36, nullptr, "Unknown"},
|
||||
|
||||
@@ -70,6 +70,11 @@ void SvcWrap() {
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
template <ResultCode func(u32, u64)>
|
||||
void SvcWrap() {
|
||||
FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), PARAM(1)).raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(u32, u32, u64)>
|
||||
void SvcWrap() {
|
||||
FuncReturn(func((u32)(PARAM(0) & 0xFFFFFFFF), (u32)(PARAM(1) & 0xFFFFFFFF), PARAM(2)).raw);
|
||||
|
||||
@@ -19,8 +19,11 @@ namespace AM {
|
||||
|
||||
IWindowController::IWindowController() : ServiceFramework("IWindowController") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "CreateWindow"},
|
||||
{1, &IWindowController::GetAppletResourceUserId, "GetAppletResourceUserId"},
|
||||
{10, &IWindowController::AcquireForegroundRights, "AcquireForegroundRights"},
|
||||
{11, nullptr, "ReleaseForegroundRights"},
|
||||
{12, nullptr, "RejectToChangeIntoBackground"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -78,8 +81,11 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework("IDebugFunctions") {}
|
||||
ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger)
|
||||
: ServiceFramework("ISelfController"), nvflinger(std::move(nvflinger)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "Exit"},
|
||||
{1, &ISelfController::LockExit, "LockExit"},
|
||||
{2, &ISelfController::UnlockExit, "UnlockExit"},
|
||||
{3, nullptr, "EnterFatalSection"},
|
||||
{4, nullptr, "LeaveFatalSection"},
|
||||
{9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"},
|
||||
{10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"},
|
||||
{11, &ISelfController::SetOperationModeChangedNotification,
|
||||
@@ -88,8 +94,29 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
|
||||
"SetPerformanceModeChangedNotification"},
|
||||
{13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
|
||||
{14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
|
||||
{15, nullptr, "SetScreenShotAppletIdentityInfo"},
|
||||
{16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
|
||||
{17, nullptr, "SetControllerFirmwareUpdateSection"},
|
||||
{18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
|
||||
{19, nullptr, "SetScreenShotImageOrientation"},
|
||||
{20, nullptr, "SetDesirableKeyboardLayout"},
|
||||
{40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
|
||||
{41, nullptr, "IsSystemBufferSharingEnabled"},
|
||||
{42, nullptr, "GetSystemSharedLayerHandle"},
|
||||
{50, nullptr, "SetHandlesRequestToDisplay"},
|
||||
{51, nullptr, "ApproveToDisplay"},
|
||||
{60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
|
||||
{61, nullptr, "SetMediaPlaybackState"},
|
||||
{62, nullptr, "SetIdleTimeDetectionExtension"},
|
||||
{63, nullptr, "GetIdleTimeDetectionExtension"},
|
||||
{64, nullptr, "SetInputDetectionSourceSet"},
|
||||
{65, nullptr, "ReportUserIsActive"},
|
||||
{66, nullptr, "GetCurrentIlluminance"},
|
||||
{67, nullptr, "IsIlluminanceAvailable"},
|
||||
{68, nullptr, "SetAutoSleepDisabled"},
|
||||
{69, nullptr, "IsAutoSleepDisabled"},
|
||||
{70, nullptr, "ReportMultimediaError"},
|
||||
{80, nullptr, "SetWirelessPriorityMode"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -206,9 +233,30 @@ ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter"
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
|
||||
{1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
|
||||
{2, nullptr, "GetThisAppletKind"},
|
||||
{3, nullptr, "AllowToEnterSleep"},
|
||||
{4, nullptr, "DisallowToEnterSleep"},
|
||||
{5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
|
||||
{6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
|
||||
{7, nullptr, "GetCradleStatus"},
|
||||
{8, nullptr, "GetBootMode"},
|
||||
{9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
|
||||
{10, nullptr, "RequestToAcquireSleepLock"},
|
||||
{11, nullptr, "ReleaseSleepLock"},
|
||||
{12, nullptr, "ReleaseSleepLockTransiently"},
|
||||
{13, nullptr, "GetAcquiredSleepLockEvent"},
|
||||
{20, nullptr, "PushToGeneralChannel"},
|
||||
{30, nullptr, "GetHomeButtonReaderLockAccessor"},
|
||||
{31, nullptr, "GetReaderLockAccessorEx"},
|
||||
{40, nullptr, "GetCradleFwVersion"},
|
||||
{50, nullptr, "IsVrModeEnabled"},
|
||||
{51, nullptr, "SetVrModeEnabled"},
|
||||
{52, nullptr, "SwitchLcdBacklight"},
|
||||
{55, nullptr, "IsInControllerFirmwareUpdateSection"},
|
||||
{60, nullptr, "GetDefaultDisplayResolution"},
|
||||
{61, nullptr, "GetDefaultDisplayResolutionChangeEvent"},
|
||||
{62, nullptr, "GetHdcpAuthenticationState"},
|
||||
{63, nullptr, "GetHdcpAuthenticationStateChangeEvent"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -278,7 +326,7 @@ public:
|
||||
{104, nullptr, "PopInteractiveOutData"},
|
||||
{105, nullptr, "GetPopOutDataEvent"},
|
||||
{106, nullptr, "GetPopInteractiveOutDataEvent"},
|
||||
{120, nullptr, "NeedsToExitProcess"},
|
||||
{110, nullptr, "NeedsToExitProcess"},
|
||||
{120, nullptr, "GetLibraryAppletInfo"},
|
||||
{150, nullptr, "RequestForAppletToGetForeground"},
|
||||
{160, nullptr, "GetIndirectLayerConsumerHandle"},
|
||||
@@ -330,6 +378,7 @@ public:
|
||||
: ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorageAccessor::GetSize, "GetSize"},
|
||||
{10, nullptr, "Write"},
|
||||
{11, &IStorageAccessor::Read, "Read"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
@@ -372,6 +421,7 @@ public:
|
||||
: ServiceFramework("IStorage"), buffer(std::move(buffer)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorage::Open, "Open"},
|
||||
{1, nullptr, "OpenTransferStorage"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -392,12 +442,42 @@ private:
|
||||
IApplicationFunctions::IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
|
||||
{10, nullptr, "CreateApplicationAndPushAndRequestToStart"},
|
||||
{11, nullptr, "CreateApplicationAndPushAndRequestToStartForQuest"},
|
||||
{12, nullptr, "CreateApplicationAndRequestToStart"},
|
||||
{13, nullptr, "CreateApplicationAndRequestToStartForQuest"},
|
||||
{20, &IApplicationFunctions::EnsureSaveData, "EnsureSaveData"},
|
||||
{21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
|
||||
{22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
|
||||
{23, nullptr, "GetDisplayVersion"},
|
||||
{24, nullptr, "GetLaunchStorageInfoForDebug"},
|
||||
{25, nullptr, "ExtendSaveData"},
|
||||
{26, nullptr, "GetSaveDataSize"},
|
||||
{30, nullptr, "BeginBlockingHomeButtonShortAndLongPressed"},
|
||||
{31, nullptr, "EndBlockingHomeButtonShortAndLongPressed"},
|
||||
{32, nullptr, "BeginBlockingHomeButton"},
|
||||
{33, nullptr, "EndBlockingHomeButton"},
|
||||
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
|
||||
{50, nullptr, "GetPseudoDeviceId"},
|
||||
{60, nullptr, "SetMediaPlaybackStateForApplication"},
|
||||
{65, nullptr, "IsGamePlayRecordingSupported"},
|
||||
{66, &IApplicationFunctions::InitializeGamePlayRecording, "InitializeGamePlayRecording"},
|
||||
{67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
|
||||
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
|
||||
{68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
|
||||
{70, nullptr, "RequestToShutdown"},
|
||||
{71, nullptr, "RequestToReboot"},
|
||||
{80, nullptr, "ExitAndRequestToShowThanksMessage"},
|
||||
{90, nullptr, "EnableApplicationCrashReport"},
|
||||
{100, nullptr, "InitializeApplicationCopyrightFrameBuffer"},
|
||||
{101, nullptr, "SetApplicationCopyrightImage"},
|
||||
{102, nullptr, "SetApplicationCopyrightVisibility"},
|
||||
{110, nullptr, "QueryApplicationPlayStatistics"},
|
||||
{120, nullptr, "ExecuteProgram"},
|
||||
{121, nullptr, "ClearUserChannel"},
|
||||
{122, nullptr, "UnpopToUserChannel"},
|
||||
{500, nullptr, "StartContinuousRecordingFlushForDebug"},
|
||||
{1000, nullptr, "CreateMovieMaker"},
|
||||
{1001, nullptr, "PrepareForJit"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
{2, &ILibraryAppletProxy::GetWindowController, "GetWindowController"},
|
||||
{3, &ILibraryAppletProxy::GetAudioController, "GetAudioController"},
|
||||
{4, &ILibraryAppletProxy::GetDisplayController, "GetDisplayController"},
|
||||
{10, nullptr, "GetProcessWindingController"},
|
||||
{11, &ILibraryAppletProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
|
||||
{20, &ILibraryAppletProxy::GetApplicationFunctions, "GetApplicationFunctions"},
|
||||
{1000, &ILibraryAppletProxy::GetDebugFunctions, "GetDebugFunctions"},
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
{2, &IApplicationProxy::GetWindowController, "GetWindowController"},
|
||||
{3, &IApplicationProxy::GetAudioController, "GetAudioController"},
|
||||
{4, &IApplicationProxy::GetDisplayController, "GetDisplayController"},
|
||||
{10, nullptr, "GetProcessWindingController"},
|
||||
{11, &IApplicationProxy::GetLibraryAppletCreator, "GetLibraryAppletCreator"},
|
||||
{20, &IApplicationProxy::GetApplicationFunctions, "GetApplicationFunctions"},
|
||||
{1000, &IApplicationProxy::GetDebugFunctions, "GetDebugFunctions"},
|
||||
|
||||
@@ -19,6 +19,7 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u") {
|
||||
{5, nullptr, "GetAddOnContentBaseId"},
|
||||
{6, nullptr, "PrepareAddOnContentByApplicationId"},
|
||||
{7, nullptr, "PrepareAddOnContent"},
|
||||
{8, nullptr, "GetAddOnContentListChangedEvent"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -14,15 +14,20 @@ class IAudioIn final : public ServiceFramework<IAudioIn> {
|
||||
public:
|
||||
IAudioIn() : ServiceFramework("IAudioIn") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x0, nullptr, "GetAudioInState"},
|
||||
{0x1, nullptr, "StartAudioIn"},
|
||||
{0x2, nullptr, "StopAudioIn"},
|
||||
{0x3, nullptr, "AppendAudioInBuffer_1"},
|
||||
{0x4, nullptr, "RegisterBufferEvent"},
|
||||
{0x5, nullptr, "GetReleasedAudioInBuffer_1"},
|
||||
{0x6, nullptr, "ContainsAudioInBuffer"},
|
||||
{0x7, nullptr, "AppendAudioInBuffer_2"},
|
||||
{0x8, nullptr, "GetReleasedAudioInBuffer_2"},
|
||||
{0, nullptr, "GetAudioInState"},
|
||||
{1, nullptr, "StartAudioIn"},
|
||||
{2, nullptr, "StopAudioIn"},
|
||||
{3, nullptr, "AppendAudioInBuffer"},
|
||||
{4, nullptr, "RegisterBufferEvent"},
|
||||
{5, nullptr, "GetReleasedAudioInBuffer"},
|
||||
{6, nullptr, "ContainsAudioInBuffer"},
|
||||
{7, nullptr, "AppendAudioInBufferWithUserEvent"},
|
||||
{8, nullptr, "AppendAudioInBufferAuto"},
|
||||
{9, nullptr, "GetReleasedAudioInBufferAuto"},
|
||||
{10, nullptr, "AppendAudioInBufferWithUserEventAuto"},
|
||||
{11, nullptr, "GetAudioInBufferCount"},
|
||||
{12, nullptr, "SetAudioInDeviceGain"},
|
||||
{13, nullptr, "GetAudioInDeviceGain"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -31,8 +36,10 @@ public:
|
||||
|
||||
AudInU::AudInU() : ServiceFramework("audin:u") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, nullptr, "ListAudioIns"},
|
||||
{0x00000001, nullptr, "OpenAudioIn"},
|
||||
{0, nullptr, "ListAudioIns"},
|
||||
{1, nullptr, "OpenAudioIn"},
|
||||
{3, nullptr, "OpenAudioInAuto"},
|
||||
{4, nullptr, "ListAudioInsAuto"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -25,15 +25,18 @@ class IAudioOut final : public ServiceFramework<IAudioOut> {
|
||||
public:
|
||||
IAudioOut() : ServiceFramework("IAudioOut"), audio_out_state(AudioState::Stopped) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x0, nullptr, "GetAudioOutState"},
|
||||
{0x1, &IAudioOut::StartAudioOut, "StartAudioOut"},
|
||||
{0x2, &IAudioOut::StopAudioOut, "StopAudioOut"},
|
||||
{0x3, &IAudioOut::AppendAudioOutBuffer_1, "AppendAudioOutBuffer_1"},
|
||||
{0x4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
|
||||
{0x5, &IAudioOut::GetReleasedAudioOutBuffer_1, "GetReleasedAudioOutBuffer_1"},
|
||||
{0x6, nullptr, "ContainsAudioOutBuffer"},
|
||||
{0x7, nullptr, "AppendAudioOutBuffer_2"},
|
||||
{0x8, nullptr, "GetReleasedAudioOutBuffer_2"},
|
||||
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
|
||||
{1, &IAudioOut::StartAudioOut, "StartAudioOut"},
|
||||
{2, &IAudioOut::StopAudioOut, "StopAudioOut"},
|
||||
{3, &IAudioOut::AppendAudioOutBuffer, "AppendAudioOutBuffer"},
|
||||
{4, &IAudioOut::RegisterBufferEvent, "RegisterBufferEvent"},
|
||||
{5, &IAudioOut::GetReleasedAudioOutBuffer, "GetReleasedAudioOutBuffer"},
|
||||
{6, nullptr, "ContainsAudioOutBuffer"},
|
||||
{7, nullptr, "AppendAudioOutBufferAuto"},
|
||||
{8, nullptr, "GetReleasedAudioOutBufferAuto"},
|
||||
{9, nullptr, "GetAudioOutBufferCount"},
|
||||
{10, nullptr, "GetAudioOutPlayedSampleCount"},
|
||||
{11, nullptr, "FlushAudioOutBuffers"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -57,6 +60,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void GetAudioOutState(Kernel::HLERequestContext& ctx) {
|
||||
LOG_DEBUG(Service_Audio, "called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u32>(audio_out_state));
|
||||
}
|
||||
|
||||
void StartAudioOut(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
@@ -87,7 +97,7 @@ private:
|
||||
rb.PushCopyObjects(buffer_event);
|
||||
}
|
||||
|
||||
void AppendAudioOutBuffer_1(Kernel::HLERequestContext& ctx) {
|
||||
void AppendAudioOutBuffer(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
@@ -98,7 +108,7 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void GetReleasedAudioOutBuffer_1(Kernel::HLERequestContext& ctx) {
|
||||
void GetReleasedAudioOutBuffer(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
// TODO(st4rk): This is how libtransistor currently implements the
|
||||
@@ -189,8 +199,8 @@ void AudOutU::OpenAudioOut(Kernel::HLERequestContext& ctx) {
|
||||
AudOutU::AudOutU() : ServiceFramework("audout:u") {
|
||||
static const FunctionInfo functions[] = {{0x00000000, &AudOutU::ListAudioOuts, "ListAudioOuts"},
|
||||
{0x00000001, &AudOutU::OpenAudioOut, "OpenAudioOut"},
|
||||
{0x00000002, nullptr, "Unknown2"},
|
||||
{0x00000003, nullptr, "Unknown3"}};
|
||||
{0x00000002, nullptr, "ListAudioOutsAuto"},
|
||||
{0x00000003, nullptr, "OpenAudioOutAuto"}};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,13 +14,15 @@ class IFinalOutputRecorder final : public ServiceFramework<IFinalOutputRecorder>
|
||||
public:
|
||||
IFinalOutputRecorder() : ServiceFramework("IFinalOutputRecorder") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x0, nullptr, "GetFinalOutputRecorderState"},
|
||||
{0x1, nullptr, "StartFinalOutputRecorder"},
|
||||
{0x2, nullptr, "StopFinalOutputRecorder"},
|
||||
{0x3, nullptr, "AppendFinalOutputRecorderBuffer"},
|
||||
{0x4, nullptr, "RegisterBufferEvent"},
|
||||
{0x5, nullptr, "GetReleasedFinalOutputRecorderBuffer"},
|
||||
{0x6, nullptr, "ContainsFinalOutputRecorderBuffer"},
|
||||
{0, nullptr, "GetFinalOutputRecorderState"},
|
||||
{1, nullptr, "StartFinalOutputRecorder"},
|
||||
{2, nullptr, "StopFinalOutputRecorder"},
|
||||
{3, nullptr, "AppendFinalOutputRecorderBuffer"},
|
||||
{4, nullptr, "RegisterBufferEvent"},
|
||||
{5, nullptr, "GetReleasedFinalOutputRecorderBuffer"},
|
||||
{6, nullptr, "ContainsFinalOutputRecorderBuffer"},
|
||||
{8, nullptr, "AppendFinalOutputRecorderBufferAuto"},
|
||||
{9, nullptr, "GetReleasedFinalOutputRecorderBufferAuto"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -19,16 +19,18 @@ class IAudioRenderer final : public ServiceFramework<IAudioRenderer> {
|
||||
public:
|
||||
IAudioRenderer() : ServiceFramework("IAudioRenderer") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x0, nullptr, "GetAudioRendererSampleRate"},
|
||||
{0x1, nullptr, "GetAudioRendererSampleCount"},
|
||||
{0x2, nullptr, "GetAudioRendererMixBufferCount"},
|
||||
{0x3, nullptr, "GetAudioRendererState"},
|
||||
{0x4, &IAudioRenderer::RequestUpdateAudioRenderer, "RequestUpdateAudioRenderer"},
|
||||
{0x5, &IAudioRenderer::StartAudioRenderer, "StartAudioRenderer"},
|
||||
{0x6, &IAudioRenderer::StopAudioRenderer, "StopAudioRenderer"},
|
||||
{0x7, &IAudioRenderer::QuerySystemEvent, "QuerySystemEvent"},
|
||||
{0x8, nullptr, "SetAudioRendererRenderingTimeLimit"},
|
||||
{0x9, nullptr, "GetAudioRendererRenderingTimeLimit"},
|
||||
{0, nullptr, "GetAudioRendererSampleRate"},
|
||||
{1, nullptr, "GetAudioRendererSampleCount"},
|
||||
{2, nullptr, "GetAudioRendererMixBufferCount"},
|
||||
{3, nullptr, "GetAudioRendererState"},
|
||||
{4, &IAudioRenderer::RequestUpdateAudioRenderer, "RequestUpdateAudioRenderer"},
|
||||
{5, &IAudioRenderer::StartAudioRenderer, "StartAudioRenderer"},
|
||||
{6, &IAudioRenderer::StopAudioRenderer, "StopAudioRenderer"},
|
||||
{7, &IAudioRenderer::QuerySystemEvent, "QuerySystemEvent"},
|
||||
{8, nullptr, "SetAudioRendererRenderingTimeLimit"},
|
||||
{9, nullptr, "GetAudioRendererRenderingTimeLimit"},
|
||||
{10, nullptr, "RequestUpdateAudioRendererAuto"},
|
||||
{11, nullptr, "ExecuteAudioRendererRendering"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -158,7 +160,7 @@ public:
|
||||
{0x0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
|
||||
{0x1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"},
|
||||
{0x2, nullptr, "GetAudioDeviceOutputVolume"},
|
||||
{0x3, nullptr, "GetActiveAudioDeviceName"},
|
||||
{0x3, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceName"},
|
||||
{0x4, &IAudioDevice::QueryAudioDeviceSystemEvent, "QueryAudioDeviceSystemEvent"},
|
||||
{0x5, &IAudioDevice::GetActiveChannelCount, "GetActiveChannelCount"},
|
||||
{0x6, nullptr, "ListAudioDeviceNameAuto"},
|
||||
@@ -199,6 +201,18 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void GetActiveAudioDeviceName(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
const std::string audio_interface = "AudioDevice";
|
||||
ctx.WriteBuffer(audio_interface.c_str(), audio_interface.size());
|
||||
|
||||
IPC::ResponseBuilder rb = rp.MakeBuilder(3, 0, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(1);
|
||||
}
|
||||
|
||||
void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_Audio, "(STUBBED) called");
|
||||
|
||||
@@ -225,6 +239,8 @@ AudRenU::AudRenU() : ServiceFramework("audren:u") {
|
||||
{0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"},
|
||||
{1, &AudRenU::GetAudioRendererWorkBufferSize, "GetAudioRendererWorkBufferSize"},
|
||||
{2, &AudRenU::GetAudioDevice, "GetAudioDevice"},
|
||||
{3, nullptr, "OpenAudioRendererAuto"},
|
||||
{4, nullptr, "GetAudioDeviceServiceWithRevisionInfo"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -22,9 +22,9 @@ CodecCtl::CodecCtl() : ServiceFramework("codecctl") {
|
||||
{0x00000007, nullptr, "SetCodecActiveTarget"},
|
||||
{0x00000008, nullptr, "Unknown"},
|
||||
{0x00000009, nullptr, "BindCodecHeadphoneMicJackInterrupt"},
|
||||
{0x0000000A, nullptr, "IsCodecHeadphoneMicJackInserted"},
|
||||
{0x0000000B, nullptr, "ClearCodecHeadphoneMicJackInterrupt"},
|
||||
{0x0000000C, nullptr, "IsCodecDeviceRequested"},
|
||||
{0x00000010, nullptr, "IsCodecHeadphoneMicJackInserted"},
|
||||
{0x00000011, nullptr, "ClearCodecHeadphoneMicJackInterrupt"},
|
||||
{0x00000012, nullptr, "IsCodecDeviceRequested"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
: ServiceFramework("IStorage"), backend(std::move(backend)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorage::Read, "Read"}, {1, nullptr, "Write"}, {2, nullptr, "Flush"},
|
||||
{3, nullptr, "SetSize"}, {4, nullptr, "GetSize"},
|
||||
{3, nullptr, "SetSize"}, {4, nullptr, "GetSize"}, {5, nullptr, "OperateRange"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -72,8 +72,9 @@ public:
|
||||
explicit IFile(std::unique_ptr<FileSys::StorageBackend>&& backend)
|
||||
: ServiceFramework("IFile"), backend(std::move(backend)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"}, {2, nullptr, "Flush"},
|
||||
{3, &IFile::SetSize, "SetSize"}, {4, &IFile::GetSize, "GetSize"},
|
||||
{0, &IFile::Read, "Read"}, {1, &IFile::Write, "Write"},
|
||||
{2, nullptr, "Flush"}, {3, &IFile::SetSize, "SetSize"},
|
||||
{4, &IFile::GetSize, "GetSize"}, {5, nullptr, "OperateRange"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -227,11 +228,21 @@ public:
|
||||
: ServiceFramework("IFileSystem"), backend(std::move(backend)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IFileSystem::CreateFile, "CreateFile"},
|
||||
{1, nullptr, "DeleteFile"},
|
||||
{2, &IFileSystem::CreateDirectory, "CreateDirectory"},
|
||||
{3, nullptr, "DeleteDirectory"},
|
||||
{4, nullptr, "DeleteDirectoryRecursively"},
|
||||
{5, nullptr, "RenameFile"},
|
||||
{6, nullptr, "RenameDirectory"},
|
||||
{7, &IFileSystem::GetEntryType, "GetEntryType"},
|
||||
{8, &IFileSystem::OpenFile, "OpenFile"},
|
||||
{9, &IFileSystem::OpenDirectory, "OpenDirectory"},
|
||||
{10, &IFileSystem::Commit, "Commit"},
|
||||
{11, nullptr, "GetFreeSpaceSize"},
|
||||
{12, nullptr, "GetTotalSpaceSize"},
|
||||
{13, nullptr, "CleanDirectoryRecursively"},
|
||||
{14, nullptr, "GetFileTimeStampRaw"},
|
||||
{15, nullptr, "QueryEntry"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -356,14 +367,94 @@ private:
|
||||
|
||||
FSP_SRV::FSP_SRV() : ServiceFramework("fsp-srv") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &FSP_SRV::Initalize, "Initalize"},
|
||||
{0, nullptr, "MountContent"},
|
||||
{1, &FSP_SRV::Initialize, "Initialize"},
|
||||
{2, nullptr, "OpenDataFileSystemByCurrentProcess"},
|
||||
{7, nullptr, "OpenFileSystemWithPatch"},
|
||||
{8, nullptr, "OpenFileSystemWithId"},
|
||||
{9, nullptr, "OpenDataFileSystemByApplicationId"},
|
||||
{11, nullptr, "OpenBisFileSystem"},
|
||||
{12, nullptr, "OpenBisStorage"},
|
||||
{13, nullptr, "InvalidateBisCache"},
|
||||
{17, nullptr, "OpenHostFileSystem"},
|
||||
{18, &FSP_SRV::MountSdCard, "MountSdCard"},
|
||||
{19, nullptr, "FormatSdCardFileSystem"},
|
||||
{21, nullptr, "DeleteSaveDataFileSystem"},
|
||||
{22, &FSP_SRV::CreateSaveData, "CreateSaveData"},
|
||||
{23, nullptr, "CreateSaveDataFileSystemBySystemSaveDataId"},
|
||||
{24, nullptr, "RegisterSaveDataFileSystemAtomicDeletion"},
|
||||
{25, nullptr, "DeleteSaveDataFileSystemBySaveDataSpaceId"},
|
||||
{26, nullptr, "FormatSdCardDryRun"},
|
||||
{27, nullptr, "IsExFatSupported"},
|
||||
{28, nullptr, "DeleteSaveDataFileSystemBySaveDataAttribute"},
|
||||
{30, nullptr, "OpenGameCardStorage"},
|
||||
{31, nullptr, "OpenGameCardFileSystem"},
|
||||
{32, nullptr, "ExtendSaveDataFileSystem"},
|
||||
{33, nullptr, "DeleteCacheStorage"},
|
||||
{34, nullptr, "GetCacheStorageSize"},
|
||||
{51, &FSP_SRV::MountSaveData, "MountSaveData"},
|
||||
{52, nullptr, "OpenSaveDataFileSystemBySystemSaveDataId"},
|
||||
{53, nullptr, "OpenReadOnlySaveDataFileSystem"},
|
||||
{57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"},
|
||||
{58, nullptr, "ReadSaveDataFileSystemExtraData"},
|
||||
{59, nullptr, "WriteSaveDataFileSystemExtraData"},
|
||||
{60, nullptr, "OpenSaveDataInfoReader"},
|
||||
{61, nullptr, "OpenSaveDataInfoReaderBySaveDataSpaceId"},
|
||||
{62, nullptr, "OpenCacheStorageList"},
|
||||
{64, nullptr, "OpenSaveDataInternalStorageFileSystem"},
|
||||
{65, nullptr, "UpdateSaveDataMacForDebug"},
|
||||
{66, nullptr, "WriteSaveDataFileSystemExtraData2"},
|
||||
{80, nullptr, "OpenSaveDataMetaFile"},
|
||||
{81, nullptr, "OpenSaveDataTransferManager"},
|
||||
{82, nullptr, "OpenSaveDataTransferManagerVersion2"},
|
||||
{100, nullptr, "OpenImageDirectoryFileSystem"},
|
||||
{110, nullptr, "OpenContentStorageFileSystem"},
|
||||
{200, &FSP_SRV::OpenDataStorageByCurrentProcess, "OpenDataStorageByCurrentProcess"},
|
||||
{201, nullptr, "OpenDataStorageByProgramId"},
|
||||
{202, nullptr, "OpenDataStorageByDataId"},
|
||||
{203, &FSP_SRV::OpenRomStorage, "OpenRomStorage"},
|
||||
{400, nullptr, "OpenDeviceOperator"},
|
||||
{500, nullptr, "OpenSdCardDetectionEventNotifier"},
|
||||
{501, nullptr, "OpenGameCardDetectionEventNotifier"},
|
||||
{510, nullptr, "OpenSystemDataUpdateEventNotifier"},
|
||||
{511, nullptr, "NotifySystemDataUpdateEvent"},
|
||||
{600, nullptr, "SetCurrentPosixTime"},
|
||||
{601, nullptr, "QuerySaveDataTotalSize"},
|
||||
{602, nullptr, "VerifySaveDataFileSystem"},
|
||||
{603, nullptr, "CorruptSaveDataFileSystem"},
|
||||
{604, nullptr, "CreatePaddingFile"},
|
||||
{605, nullptr, "DeleteAllPaddingFiles"},
|
||||
{606, nullptr, "GetRightsId"},
|
||||
{607, nullptr, "RegisterExternalKey"},
|
||||
{608, nullptr, "UnregisterAllExternalKey"},
|
||||
{609, nullptr, "GetRightsIdByPath"},
|
||||
{610, nullptr, "GetRightsIdAndKeyGenerationByPath"},
|
||||
{611, nullptr, "SetCurrentPosixTimeWithTimeDifference"},
|
||||
{612, nullptr, "GetFreeSpaceSizeForSaveData"},
|
||||
{613, nullptr, "VerifySaveDataFileSystemBySaveDataSpaceId"},
|
||||
{614, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId"},
|
||||
{615, nullptr, "QuerySaveDataInternalStorageTotalSize"},
|
||||
{620, nullptr, "SetSdCardEncryptionSeed"},
|
||||
{630, nullptr, "SetSdCardAccessibility"},
|
||||
{631, nullptr, "IsSdCardAccessible"},
|
||||
{640, nullptr, "IsSignedSystemPartitionOnSdCardValid"},
|
||||
{700, nullptr, "OpenAccessFailureResolver"},
|
||||
{701, nullptr, "GetAccessFailureDetectionEvent"},
|
||||
{702, nullptr, "IsAccessFailureDetected"},
|
||||
{710, nullptr, "ResolveAccessFailure"},
|
||||
{720, nullptr, "AbandonAccessFailure"},
|
||||
{800, nullptr, "GetAndClearFileSystemProxyErrorInfo"},
|
||||
{1000, nullptr, "SetBisRootForHost"},
|
||||
{1001, nullptr, "SetSaveDataSize"},
|
||||
{1002, nullptr, "SetSaveDataRootPath"},
|
||||
{1003, nullptr, "DisableAutoSaveDataCreation"},
|
||||
{1004, nullptr, "SetGlobalAccessLogMode"},
|
||||
{1005, &FSP_SRV::GetGlobalAccessLogMode, "GetGlobalAccessLogMode"},
|
||||
{1006, nullptr, "OutputAccessLogToSdCard"},
|
||||
{1007, nullptr, "RegisterUpdatePartition"},
|
||||
{1008, nullptr, "OpenRegisteredUpdatePartition"},
|
||||
{1009, nullptr, "GetAndClearMemoryReportInfo"},
|
||||
{1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
@@ -379,7 +470,7 @@ void FSP_SRV::TryLoadRomFS() {
|
||||
}
|
||||
}
|
||||
|
||||
void FSP_SRV::Initalize(Kernel::HLERequestContext& ctx) {
|
||||
void FSP_SRV::Initialize(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_FS, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
private:
|
||||
void TryLoadRomFS();
|
||||
|
||||
void Initalize(Kernel::HLERequestContext& ctx);
|
||||
void Initialize(Kernel::HLERequestContext& ctx);
|
||||
void MountSdCard(Kernel::HLERequestContext& ctx);
|
||||
void CreateSaveData(Kernel::HLERequestContext& ctx);
|
||||
void MountSaveData(Kernel::HLERequestContext& ctx);
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/friend/friend.h"
|
||||
#include "core/hle/service/friend/friend_a.h"
|
||||
#include "core/hle/service/friend/friend_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Friend {
|
||||
|
||||
void Module::Interface::Unknown(Kernel::HLERequestContext& ctx) {
|
||||
void Module::Interface::CreateFriendService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
LOG_WARNING(Service_Friend, "(STUBBED) called");
|
||||
@@ -22,6 +23,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
auto module = std::make_shared<Module>();
|
||||
std::make_shared<Friend_A>(module)->InstallAsService(service_manager);
|
||||
std::make_shared<Friend_U>(module)->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Friend
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
public:
|
||||
Interface(std::shared_ptr<Module> module, const char* name);
|
||||
|
||||
void Unknown(Kernel::HLERequestContext& ctx);
|
||||
void CreateFriendService(Kernel::HLERequestContext& ctx);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Module> module;
|
||||
|
||||
@@ -10,7 +10,8 @@ namespace Friend {
|
||||
Friend_A::Friend_A(std::shared_ptr<Module> module)
|
||||
: Module::Interface(std::move(module), "friend:a") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &Friend_A::Unknown, "Unknown"},
|
||||
{0, &Friend_A::CreateFriendService, "CreateFriendService"},
|
||||
{1, nullptr, "CreateNotificationService"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
20
src/core/hle/service/friend/friend_u.cpp
Normal file
20
src/core/hle/service/friend/friend_u.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/friend/friend_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Friend {
|
||||
|
||||
Friend_U::Friend_U(std::shared_ptr<Module> module)
|
||||
: Module::Interface(std::move(module), "friend:u") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &Friend_U::CreateFriendService, "CreateFriendService"},
|
||||
{1, nullptr, "CreateNotificationService"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Friend
|
||||
} // namespace Service
|
||||
18
src/core/hle/service/friend/friend_u.h
Normal file
18
src/core/hle/service/friend/friend_u.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/friend/friend.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Friend {
|
||||
|
||||
class Friend_U final : public Module::Interface {
|
||||
public:
|
||||
explicit Friend_U(std::shared_ptr<Module> module);
|
||||
};
|
||||
|
||||
} // namespace Friend
|
||||
} // namespace Service
|
||||
@@ -198,25 +198,75 @@ public:
|
||||
{11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
|
||||
{21, &Hid::ActivateMouse, "ActivateMouse"},
|
||||
{31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
|
||||
{40, nullptr, "AcquireXpadIdEventHandle"},
|
||||
{41, nullptr, "ReleaseXpadIdEventHandle"},
|
||||
{51, nullptr, "ActivateXpad"},
|
||||
{55, nullptr, "GetXpadIds"},
|
||||
{56, nullptr, "ActivateJoyXpad"},
|
||||
{58, nullptr, "GetJoyXpadLifoHandle"},
|
||||
{59, nullptr, "GetJoyXpadIds"},
|
||||
{60, nullptr, "ActivateSixAxisSensor"},
|
||||
{61, nullptr, "DeactivateSixAxisSensor"},
|
||||
{62, nullptr, "GetSixAxisSensorLifoHandle"},
|
||||
{63, nullptr, "ActivateJoySixAxisSensor"},
|
||||
{64, nullptr, "DeactivateJoySixAxisSensor"},
|
||||
{65, nullptr, "GetJoySixAxisSensorLifoHandle"},
|
||||
{66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
|
||||
{67, nullptr, "StopSixAxisSensor"},
|
||||
{68, nullptr, "IsSixAxisSensorFusionEnabled"},
|
||||
{69, nullptr, "EnableSixAxisSensorFusion"},
|
||||
{70, nullptr, "SetSixAxisSensorFusionParameters"},
|
||||
{71, nullptr, "GetSixAxisSensorFusionParameters"},
|
||||
{72, nullptr, "ResetSixAxisSensorFusionParameters"},
|
||||
{73, nullptr, "SetAccelerometerParameters"},
|
||||
{74, nullptr, "GetAccelerometerParameters"},
|
||||
{75, nullptr, "ResetAccelerometerParameters"},
|
||||
{76, nullptr, "SetAccelerometerPlayMode"},
|
||||
{77, nullptr, "GetAccelerometerPlayMode"},
|
||||
{78, nullptr, "ResetAccelerometerPlayMode"},
|
||||
{79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
|
||||
{80, nullptr, "GetGyroscopeZeroDriftMode"},
|
||||
{81, nullptr, "ResetGyroscopeZeroDriftMode"},
|
||||
{82, nullptr, "IsSixAxisSensorAtRest"},
|
||||
{91, nullptr, "ActivateGesture"},
|
||||
{100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
|
||||
{101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
|
||||
{102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
|
||||
{103, &Hid::ActivateNpad, "ActivateNpad"},
|
||||
{104, nullptr, "DeactivateNpad"},
|
||||
{106, &Hid::AcquireNpadStyleSetUpdateEventHandle,
|
||||
"AcquireNpadStyleSetUpdateEventHandle"},
|
||||
{107, nullptr, "DisconnectNpad"},
|
||||
{108, nullptr, "GetPlayerLedPattern"},
|
||||
{120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
|
||||
{121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
|
||||
{122, &Hid::SetNpadJoyAssignmentModeSingleByDefault,
|
||||
"SetNpadJoyAssignmentModeSingleByDefault"},
|
||||
{123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
|
||||
{124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
|
||||
{125, nullptr, "MergeSingleJoyAsDualJoy"},
|
||||
{126, nullptr, "StartLrAssignmentMode"},
|
||||
{127, nullptr, "StopLrAssignmentMode"},
|
||||
{128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
|
||||
{129, nullptr, "GetNpadHandheldActivationMode"},
|
||||
{130, nullptr, "SwapNpadAssignment"},
|
||||
{131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
|
||||
{132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
|
||||
{200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
|
||||
{201, &Hid::SendVibrationValue, "SendVibrationValue"},
|
||||
{202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
|
||||
{203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
|
||||
{204, nullptr, "PermitVibration"},
|
||||
{205, nullptr, "IsVibrationPermitted"},
|
||||
{206, &Hid::SendVibrationValues, "SendVibrationValues"},
|
||||
{300, nullptr, "ActivateConsoleSixAxisSensor"},
|
||||
{301, nullptr, "StartConsoleSixAxisSensor"},
|
||||
{302, nullptr, "StopConsoleSixAxisSensor"},
|
||||
{400, nullptr, "IsUsbFullKeyControllerEnabled"},
|
||||
{401, nullptr, "EnableUsbFullKeyController"},
|
||||
{402, nullptr, "IsUsbFullKeyControllerConnected"},
|
||||
{1000, nullptr, "SetNpadCommunicationMode"},
|
||||
{1001, nullptr, "GetNpadCommunicationMode"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
|
||||
@@ -70,9 +70,8 @@ private:
|
||||
}
|
||||
void GetResult(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0);
|
||||
}
|
||||
void GetSystemEventReadableHandles(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_NIFM, "(STUBBED) called");
|
||||
|
||||
@@ -37,7 +37,9 @@ PL_U::PL_U() : ServiceFramework("pl:u") {
|
||||
{1, &PL_U::GetLoadState, "GetLoadState"},
|
||||
{2, &PL_U::GetSize, "GetSize"},
|
||||
{3, &PL_U::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"},
|
||||
{4, &PL_U::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"}};
|
||||
{4, &PL_U::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"},
|
||||
{5, nullptr, "GetSharedFontInOrderOfPriority"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
// Attempt to load shared font data from disk
|
||||
|
||||
@@ -96,7 +96,14 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
|
||||
{2, &NVDRV::Close, "Close"},
|
||||
{3, &NVDRV::Initialize, "Initialize"},
|
||||
{4, &NVDRV::QueryEvent, "QueryEvent"},
|
||||
{5, nullptr, "MapSharedMem"},
|
||||
{6, nullptr, "GetStatus"},
|
||||
{7, nullptr, "ForceSetClientPID"},
|
||||
{8, &NVDRV::SetClientPID, "SetClientPID"},
|
||||
{9, nullptr, "DumpGraphicsMemoryInfo"},
|
||||
{10, nullptr, "InitializeDevtools"},
|
||||
{11, nullptr, "Ioctl2"},
|
||||
{12, nullptr, "Ioctl3"},
|
||||
{13, &NVDRV::FinishInitialize, "FinishInitialize"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -13,17 +13,17 @@ namespace Nvidia {
|
||||
|
||||
NVMEMP::NVMEMP() : ServiceFramework("nvmemp") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &NVMEMP::Unknown0, "Unknown0"},
|
||||
{1, &NVMEMP::Unknown1, "Unknown1"},
|
||||
{0, &NVMEMP::Cmd0, "Cmd0"},
|
||||
{1, &NVMEMP::Cmd1, "Cmd1"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
void NVMEMP::Unknown0(Kernel::HLERequestContext& ctx) {
|
||||
void NVMEMP::Cmd0(Kernel::HLERequestContext& ctx) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void NVMEMP::Unknown1(Kernel::HLERequestContext& ctx) {
|
||||
void NVMEMP::Cmd1(Kernel::HLERequestContext& ctx) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ public:
|
||||
~NVMEMP() = default;
|
||||
|
||||
private:
|
||||
void Unknown0(Kernel::HLERequestContext& ctx);
|
||||
void Unknown1(Kernel::HLERequestContext& ctx);
|
||||
void Cmd0(Kernel::HLERequestContext& ctx);
|
||||
void Cmd1(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Nvidia
|
||||
|
||||
@@ -11,10 +11,106 @@ namespace PCTL {
|
||||
|
||||
class IParentalControlService final : public ServiceFramework<IParentalControlService> {
|
||||
public:
|
||||
IParentalControlService() : ServiceFramework("IParentalControlService") {}
|
||||
IParentalControlService() : ServiceFramework("IParentalControlService") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, nullptr, "Initialize"},
|
||||
{1001, nullptr, "CheckFreeCommunicationPermission"},
|
||||
{1002, nullptr, "ConfirmLaunchApplicationPermission"},
|
||||
{1003, nullptr, "ConfirmResumeApplicationPermission"},
|
||||
{1004, nullptr, "ConfirmSnsPostPermission"},
|
||||
{1005, nullptr, "ConfirmSystemSettingsPermission"},
|
||||
{1006, nullptr, "IsRestrictionTemporaryUnlocked"},
|
||||
{1007, nullptr, "RevertRestrictionTemporaryUnlocked"},
|
||||
{1008, nullptr, "EnterRestrictedSystemSettings"},
|
||||
{1009, nullptr, "LeaveRestrictedSystemSettings"},
|
||||
{1010, nullptr, "IsRestrictedSystemSettingsEntered"},
|
||||
{1011, nullptr, "RevertRestrictedSystemSettingsEntered"},
|
||||
{1012, nullptr, "GetRestrictedFeatures"},
|
||||
{1013, nullptr, "ConfirmStereoVisionPermission"},
|
||||
{1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
|
||||
{1015, nullptr, "ConfirmPlayableApplicationVideo"},
|
||||
{1031, nullptr, "IsRestrictionEnabled"},
|
||||
{1032, nullptr, "GetSafetyLevel"},
|
||||
{1033, nullptr, "SetSafetyLevel"},
|
||||
{1034, nullptr, "GetSafetyLevelSettings"},
|
||||
{1035, nullptr, "GetCurrentSettings"},
|
||||
{1036, nullptr, "SetCustomSafetyLevelSettings"},
|
||||
{1037, nullptr, "GetDefaultRatingOrganization"},
|
||||
{1038, nullptr, "SetDefaultRatingOrganization"},
|
||||
{1039, nullptr, "GetFreeCommunicationApplicationListCount"},
|
||||
{1042, nullptr, "AddToFreeCommunicationApplicationList"},
|
||||
{1043, nullptr, "DeleteSettings"},
|
||||
{1044, nullptr, "GetFreeCommunicationApplicationList"},
|
||||
{1045, nullptr, "UpdateFreeCommunicationApplicationList"},
|
||||
{1046, nullptr, "DisableFeaturesForReset"},
|
||||
{1047, nullptr, "NotifyApplicationDownloadStarted"},
|
||||
{1061, nullptr, "ConfirmStereoVisionRestrictionConfigurable"},
|
||||
{1062, nullptr, "GetStereoVisionRestriction"},
|
||||
{1063, nullptr, "SetStereoVisionRestriction"},
|
||||
{1064, nullptr, "ResetConfirmedStereoVisionPermission"},
|
||||
{1065, nullptr, "IsStereoVisionPermitted"},
|
||||
{1201, nullptr, "UnlockRestrictionTemporarily"},
|
||||
{1202, nullptr, "UnlockSystemSettingsRestriction"},
|
||||
{1203, nullptr, "SetPinCode"},
|
||||
{1204, nullptr, "GenerateInquiryCode"},
|
||||
{1205, nullptr, "CheckMasterKey"},
|
||||
{1206, nullptr, "GetPinCodeLength"},
|
||||
{1207, nullptr, "GetPinCodeChangedEvent"},
|
||||
{1208, nullptr, "GetPinCode"},
|
||||
{1403, nullptr, "IsPairingActive"},
|
||||
{1406, nullptr, "GetSettingsLastUpdated"},
|
||||
{1411, nullptr, "GetPairingAccountInfo"},
|
||||
{1421, nullptr, "GetAccountNickname"},
|
||||
{1424, nullptr, "GetAccountState"},
|
||||
{1432, nullptr, "GetSynchronizationEvent"},
|
||||
{1451, nullptr, "StartPlayTimer"},
|
||||
{1452, nullptr, "StopPlayTimer"},
|
||||
{1453, nullptr, "IsPlayTimerEnabled"},
|
||||
{1454, nullptr, "GetPlayTimerRemainingTime"},
|
||||
{1455, nullptr, "IsRestrictedByPlayTimer"},
|
||||
{1456, nullptr, "GetPlayTimerSettings"},
|
||||
{1457, nullptr, "GetPlayTimerEventToRequestSuspension"},
|
||||
{1458, nullptr, "IsPlayTimerAlarmDisabled"},
|
||||
{1471, nullptr, "NotifyWrongPinCodeInputManyTimes"},
|
||||
{1472, nullptr, "CancelNetworkRequest"},
|
||||
{1473, nullptr, "GetUnlinkedEvent"},
|
||||
{1474, nullptr, "ClearUnlinkedEvent"},
|
||||
{1601, nullptr, "DisableAllFeatures"},
|
||||
{1602, nullptr, "PostEnableAllFeatures"},
|
||||
{1603, nullptr, "IsAllFeaturesDisabled"},
|
||||
{1901, nullptr, "DeleteFromFreeCommunicationApplicationListForDebug"},
|
||||
{1902, nullptr, "ClearFreeCommunicationApplicationListForDebug"},
|
||||
{1903, nullptr, "GetExemptApplicationListCountForDebug"},
|
||||
{1904, nullptr, "GetExemptApplicationListForDebug"},
|
||||
{1905, nullptr, "UpdateExemptApplicationListForDebug"},
|
||||
{1906, nullptr, "AddToExemptApplicationListForDebug"},
|
||||
{1907, nullptr, "DeleteFromExemptApplicationListForDebug"},
|
||||
{1908, nullptr, "ClearExemptApplicationListForDebug"},
|
||||
{1941, nullptr, "DeletePairing"},
|
||||
{1951, nullptr, "SetPlayTimerSettingsForDebug"},
|
||||
{1952, nullptr, "GetPlayTimerSpentTimeForTest"},
|
||||
{1953, nullptr, "SetPlayTimerAlarmDisabledForDebug"},
|
||||
{2001, nullptr, "RequestPairingAsync"},
|
||||
{2002, nullptr, "FinishRequestPairing"},
|
||||
{2003, nullptr, "AuthorizePairingAsync"},
|
||||
{2004, nullptr, "FinishAuthorizePairing"},
|
||||
{2005, nullptr, "RetrievePairingInfoAsync"},
|
||||
{2006, nullptr, "FinishRetrievePairingInfo"},
|
||||
{2007, nullptr, "UnlinkPairingAsync"},
|
||||
{2008, nullptr, "FinishUnlinkPairing"},
|
||||
{2009, nullptr, "GetAccountMiiImageAsync"},
|
||||
{2010, nullptr, "FinishGetAccountMiiImage"},
|
||||
{2011, nullptr, "GetAccountMiiImageContentTypeAsync"},
|
||||
{2012, nullptr, "FinishGetAccountMiiImageContentType"},
|
||||
{2013, nullptr, "SynchronizeParentalControlSettingsAsync"},
|
||||
{2014, nullptr, "FinishSynchronizeParentalControlSettings"},
|
||||
{2015, nullptr, "FinishSynchronizeParentalControlSettingsWithLastUpdated"},
|
||||
{2016, nullptr, "RequestUpdateExemptionListAsync"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
};
|
||||
|
||||
void PCTL_A::GetService(Kernel::HLERequestContext& ctx) {
|
||||
void PCTL_A::CreateService(Kernel::HLERequestContext& ctx) {
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IParentalControlService>();
|
||||
@@ -23,7 +119,8 @@ void PCTL_A::GetService(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
PCTL_A::PCTL_A() : ServiceFramework("pctl:a") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &PCTL_A::GetService, "GetService"},
|
||||
{0, &PCTL_A::CreateService, "CreateService"},
|
||||
{1, nullptr, "CreateServiceWithoutInitialize"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ public:
|
||||
~PCTL_A() = default;
|
||||
|
||||
private:
|
||||
void GetService(Kernel::HLERequestContext& ctx);
|
||||
void CreateService(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace PCTL
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "core/hle/service/vi/vi_m.h"
|
||||
#include "core/hle/service/vi/vi_s.h"
|
||||
#include "core/hle/service/vi/vi_u.h"
|
||||
#include "core/settings.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
@@ -711,6 +712,23 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void GetDisplayResolution(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_VI, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
u64 display_id = rp.Pop<u64>();
|
||||
|
||||
IPC::ResponseBuilder rb = rp.MakeBuilder(6, 0, 0);
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
if (Settings::values.use_docked_mode) {
|
||||
rb.Push(static_cast<u32>(DisplayResolution::DockedWidth));
|
||||
rb.Push(static_cast<u32>(DisplayResolution::DockedHeight));
|
||||
} else {
|
||||
rb.Push(static_cast<u32>(DisplayResolution::UndockedWidth));
|
||||
rb.Push(static_cast<u32>(DisplayResolution::UndockedHeight));
|
||||
}
|
||||
}
|
||||
|
||||
void SetLayerScalingMode(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service_VI, "(STUBBED) called");
|
||||
IPC::RequestParser rp{ctx};
|
||||
@@ -808,6 +826,7 @@ IApplicationDisplayService::IApplicationDisplayService(
|
||||
{1000, &IApplicationDisplayService::ListDisplays, "ListDisplays"},
|
||||
{1010, &IApplicationDisplayService::OpenDisplay, "OpenDisplay"},
|
||||
{1020, &IApplicationDisplayService::CloseDisplay, "CloseDisplay"},
|
||||
{1102, &IApplicationDisplayService::GetDisplayResolution, "GetDisplayResolution"},
|
||||
{2101, &IApplicationDisplayService::SetLayerScalingMode, "SetLayerScalingMode"},
|
||||
{2020, &IApplicationDisplayService::OpenLayer, "OpenLayer"},
|
||||
{2030, &IApplicationDisplayService::CreateStrayLayer, "CreateStrayLayer"},
|
||||
|
||||
@@ -14,6 +14,13 @@ struct EventType;
|
||||
namespace Service {
|
||||
namespace VI {
|
||||
|
||||
enum class DisplayResolution : u32 {
|
||||
DockedWidth = 1920,
|
||||
DockedHeight = 1080,
|
||||
UndockedWidth = 1280,
|
||||
UndockedHeight = 720,
|
||||
};
|
||||
|
||||
class Module final {
|
||||
public:
|
||||
class Interface : public ServiceFramework<Interface> {
|
||||
|
||||
@@ -119,6 +119,11 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
|
||||
}
|
||||
metadata.Print();
|
||||
|
||||
const FileSys::ProgramAddressSpaceType arch_bits{metadata.GetAddressSpaceType()};
|
||||
if (arch_bits == FileSys::ProgramAddressSpaceType::Is32Bit) {
|
||||
return ResultStatus::ErrorUnsupportedArch;
|
||||
}
|
||||
|
||||
// Load NSO modules
|
||||
VAddr next_load_addr{Memory::PROCESS_IMAGE_VADDR};
|
||||
for (const auto& module : {"rtld", "main", "subsdk0", "subsdk1", "subsdk2", "subsdk3",
|
||||
|
||||
@@ -72,6 +72,7 @@ enum class ResultStatus {
|
||||
ErrorAlreadyLoaded,
|
||||
ErrorMemoryAllocationFailed,
|
||||
ErrorEncrypted,
|
||||
ErrorUnsupportedArch,
|
||||
};
|
||||
|
||||
/// Interface for loading an application
|
||||
|
||||
@@ -231,6 +231,8 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
|
||||
|
||||
// TODO(Subv): Different data types for separate components are not supported
|
||||
ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
|
||||
// TODO(Subv): Only UNORM formats are supported for now.
|
||||
ASSERT(r_type == Texture::ComponentType::UNORM);
|
||||
|
||||
return tic_entry;
|
||||
}
|
||||
|
||||
@@ -21,16 +21,16 @@ public:
|
||||
/// Notify rasterizer that the specified Maxwell register has been changed
|
||||
virtual void NotifyMaxwellRegisterChanged(u32 id) = 0;
|
||||
|
||||
/// Notify rasterizer that all caches should be flushed to 3DS memory
|
||||
/// Notify rasterizer that all caches should be flushed to Switch memory
|
||||
virtual void FlushAll() = 0;
|
||||
|
||||
/// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory
|
||||
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
|
||||
virtual void FlushRegion(VAddr addr, u64 size) = 0;
|
||||
|
||||
/// Notify rasterizer that any caches of the specified region should be invalidated
|
||||
virtual void InvalidateRegion(VAddr addr, u64 size) = 0;
|
||||
|
||||
/// Notify rasterizer that any caches of the specified region should be flushed to 3DS memory
|
||||
/// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
|
||||
/// and invalidated
|
||||
virtual void FlushAndInvalidateRegion(VAddr addr, u64 size) = 0;
|
||||
|
||||
|
||||
@@ -66,6 +66,12 @@ RasterizerOpenGL::RasterizerOpenGL() {
|
||||
has_ARB_separate_shader_objects = false;
|
||||
has_ARB_vertex_attrib_binding = false;
|
||||
|
||||
// Create sampler objects
|
||||
for (size_t i = 0; i < texture_samplers.size(); ++i) {
|
||||
texture_samplers[i].Create();
|
||||
state.texture_units[i].sampler = texture_samplers[i].sampler.handle;
|
||||
}
|
||||
|
||||
GLint ext_num;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &ext_num);
|
||||
for (GLint i = 0; i < ext_num; i++) {
|
||||
@@ -270,7 +276,9 @@ void RasterizerOpenGL::DrawArrays() {
|
||||
|
||||
// TODO(bunnei): Sync framebuffer_scale uniform here
|
||||
// TODO(bunnei): Sync scissorbox uniform(s) here
|
||||
// TODO(bunnei): Sync and bind the texture surfaces
|
||||
|
||||
// Sync and bind the texture surfaces
|
||||
BindTextures();
|
||||
|
||||
// Sync and bind the shader
|
||||
if (shader_dirty) {
|
||||
@@ -374,6 +382,39 @@ void RasterizerOpenGL::DrawArrays() {
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::BindTextures() {
|
||||
using Regs = Tegra::Engines::Maxwell3D::Regs;
|
||||
auto maxwell3d = Core::System::GetInstance().GPU().Get3DEngine();
|
||||
|
||||
// Each Maxwell shader stage can have an arbitrary number of textures, but we're limited to a
|
||||
// certain number in OpenGL. We try to only use the minimum amount of host textures by not
|
||||
// keeping a 1:1 relation between guest texture ids and host texture ids, ie, guest texture id 8
|
||||
// can be host texture id 0 if it's the only texture used in the guest shader program.
|
||||
u32 host_texture_index = 0;
|
||||
for (u32 stage = 0; stage < Regs::MaxShaderStage; ++stage) {
|
||||
ASSERT(host_texture_index < texture_samplers.size());
|
||||
const auto textures = maxwell3d.GetStageTextures(static_cast<Regs::ShaderStage>(stage));
|
||||
for (unsigned texture_index = 0; texture_index < textures.size(); ++texture_index) {
|
||||
const auto& texture = textures[texture_index];
|
||||
|
||||
if (texture.enabled) {
|
||||
texture_samplers[host_texture_index].SyncWithConfig(texture.tsc);
|
||||
Surface surface = res_cache.GetTextureSurface(texture);
|
||||
if (surface != nullptr) {
|
||||
state.texture_units[host_texture_index].texture_2d = surface->texture.handle;
|
||||
} else {
|
||||
// Can occur when texture addr is null or its memory is unmapped/invalid
|
||||
state.texture_units[texture_index].texture_2d = 0;
|
||||
}
|
||||
|
||||
++host_texture_index;
|
||||
} else {
|
||||
state.texture_units[texture_index].texture_2d = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::NotifyMaxwellRegisterChanged(u32 id) {}
|
||||
|
||||
void RasterizerOpenGL::FlushAll() {
|
||||
@@ -452,6 +493,44 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& framebu
|
||||
return true;
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SamplerInfo::Create() {
|
||||
sampler.Create();
|
||||
mag_filter = min_filter = Tegra::Texture::TextureFilter::Linear;
|
||||
wrap_u = wrap_v = Tegra::Texture::WrapMode::Wrap;
|
||||
border_color_r = border_color_g = border_color_b = border_color_a = 0;
|
||||
|
||||
// default is GL_LINEAR_MIPMAP_LINEAR
|
||||
glSamplerParameteri(sampler.handle, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
// Other attributes have correct defaults
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntry& config) {
|
||||
GLuint s = sampler.handle;
|
||||
|
||||
if (mag_filter != config.mag_filter) {
|
||||
mag_filter = config.mag_filter;
|
||||
glSamplerParameteri(s, GL_TEXTURE_MAG_FILTER, MaxwellToGL::TextureFilterMode(mag_filter));
|
||||
}
|
||||
if (min_filter != config.min_filter) {
|
||||
min_filter = config.min_filter;
|
||||
glSamplerParameteri(s, GL_TEXTURE_MIN_FILTER, MaxwellToGL::TextureFilterMode(min_filter));
|
||||
}
|
||||
|
||||
if (wrap_u != config.wrap_u) {
|
||||
wrap_u = config.wrap_u;
|
||||
glSamplerParameteri(s, GL_TEXTURE_WRAP_S, MaxwellToGL::WrapMode(wrap_u));
|
||||
}
|
||||
if (wrap_v != config.wrap_v) {
|
||||
wrap_v = config.wrap_v;
|
||||
glSamplerParameteri(s, GL_TEXTURE_WRAP_T, MaxwellToGL::WrapMode(wrap_v));
|
||||
}
|
||||
|
||||
if (wrap_u == Tegra::Texture::WrapMode::Border || wrap_v == Tegra::Texture::WrapMode::Border) {
|
||||
// TODO(Subv): Implement border color
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
|
||||
void RasterizerOpenGL::SetShader() {
|
||||
// TODO(bunnei): The below sets up a static test shader for passing untransformed vertices to
|
||||
// OpenGL for rendering. This should be removed/replaced when we start emulating Maxwell
|
||||
@@ -479,10 +558,10 @@ void main() {
|
||||
in vec2 frag_tex_coord;
|
||||
out vec4 color;
|
||||
|
||||
uniform sampler2D color_texture;
|
||||
uniform sampler2D tex[32];
|
||||
|
||||
void main() {
|
||||
color = vec4(1.0, 0.0, 1.0, 0.0);
|
||||
color = texture(tex[0], frag_tex_coord);
|
||||
}
|
||||
)";
|
||||
|
||||
@@ -503,6 +582,15 @@ void main() {
|
||||
state.draw.shader_program = test_shader.shader.handle;
|
||||
state.Apply();
|
||||
|
||||
for (u32 texture = 0; texture < texture_samplers.size(); ++texture) {
|
||||
// Set the texture samplers to correspond to different texture units
|
||||
std::string uniform_name = "tex[" + std::to_string(texture) + "]";
|
||||
GLint uniform_tex = glGetUniformLocation(test_shader.shader.handle, uniform_name.c_str());
|
||||
if (uniform_tex != -1) {
|
||||
glUniform1i(uniform_tex, TextureUnits::MaxwellTexture(texture).id);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_ARB_separate_shader_objects) {
|
||||
state.draw.shader_program = 0;
|
||||
state.Apply();
|
||||
|
||||
@@ -85,12 +85,34 @@ public:
|
||||
"FSUniformData structure must be less than 16kb as per the OpenGL spec");
|
||||
|
||||
private:
|
||||
struct SamplerInfo {};
|
||||
class SamplerInfo {
|
||||
public:
|
||||
OGLSampler sampler;
|
||||
|
||||
/// Creates the sampler object, initializing its state so that it's in sync with the
|
||||
/// SamplerInfo struct.
|
||||
void Create();
|
||||
/// Syncs the sampler object with the config, updating any necessary state.
|
||||
void SyncWithConfig(const Tegra::Texture::TSCEntry& config);
|
||||
|
||||
private:
|
||||
Tegra::Texture::TextureFilter mag_filter;
|
||||
Tegra::Texture::TextureFilter min_filter;
|
||||
Tegra::Texture::WrapMode wrap_u;
|
||||
Tegra::Texture::WrapMode wrap_v;
|
||||
u32 border_color_r;
|
||||
u32 border_color_g;
|
||||
u32 border_color_b;
|
||||
u32 border_color_a;
|
||||
};
|
||||
|
||||
/// Binds the framebuffer color and depth surface
|
||||
void BindFramebufferSurfaces(const Surface& color_surface, const Surface& depth_surface,
|
||||
bool has_stencil);
|
||||
|
||||
/// Binds the required textures to OpenGL before drawing a batch.
|
||||
void BindTextures();
|
||||
|
||||
/// Syncs the viewport to match the guest state
|
||||
void SyncViewport(const MathUtil::Rectangle<u32>& surfaces_rect, u16 res_scale);
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "video_core/engines/maxwell_3d.h"
|
||||
#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
|
||||
#include "video_core/renderer_opengl/gl_state.h"
|
||||
#include "video_core/textures/decoders.h"
|
||||
#include "video_core/utils.h"
|
||||
#include "video_core/video_core.h"
|
||||
|
||||
@@ -40,36 +41,36 @@ struct FormatTuple {
|
||||
GLint internal_format;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
bool compressed;
|
||||
// How many pixels in the original texture are equivalent to one pixel in the compressed
|
||||
// texture.
|
||||
u32 compression_factor;
|
||||
};
|
||||
|
||||
static constexpr std::array<FormatTuple, 5> fb_format_tuples = {{
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8}, // RGBA8
|
||||
{GL_RGB8, GL_BGR, GL_UNSIGNED_BYTE}, // RGB8
|
||||
{GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // RGB5A1
|
||||
{GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5}, // RGB565
|
||||
{GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4}, // RGBA4
|
||||
static constexpr std::array<FormatTuple, 1> fb_format_tuples = {{
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, false, 1}, // RGBA8
|
||||
}};
|
||||
|
||||
static constexpr std::array<FormatTuple, 4> depth_format_tuples = {{
|
||||
{GL_DEPTH_COMPONENT16, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}, // D16
|
||||
{},
|
||||
{GL_DEPTH_COMPONENT24, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT}, // D24
|
||||
{GL_DEPTH24_STENCIL8, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8}, // D24S8
|
||||
static constexpr std::array<FormatTuple, 2> tex_format_tuples = {{
|
||||
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, false, 1}, // RGBA8
|
||||
{GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_INT_8_8_8_8, true, 16}, // DXT1
|
||||
}};
|
||||
|
||||
static constexpr FormatTuple tex_tuple = {GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE};
|
||||
|
||||
static const FormatTuple& GetFormatTuple(PixelFormat pixel_format) {
|
||||
const SurfaceType type = SurfaceParams::GetFormatType(pixel_format);
|
||||
if (type == SurfaceType::Color) {
|
||||
ASSERT(static_cast<size_t>(pixel_format) < fb_format_tuples.size());
|
||||
return fb_format_tuples[static_cast<unsigned int>(pixel_format)];
|
||||
} else if (type == SurfaceType::Depth || type == SurfaceType::DepthStencil) {
|
||||
size_t tuple_idx = static_cast<size_t>(pixel_format) - 14;
|
||||
ASSERT(tuple_idx < depth_format_tuples.size());
|
||||
return depth_format_tuples[tuple_idx];
|
||||
// TODO(Subv): Implement depth formats
|
||||
ASSERT_MSG(false, "Unimplemented");
|
||||
} else if (type == SurfaceType::Texture) {
|
||||
ASSERT(static_cast<size_t>(pixel_format) < tex_format_tuples.size());
|
||||
return tex_format_tuples[static_cast<unsigned int>(pixel_format)];
|
||||
}
|
||||
return tex_tuple;
|
||||
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename Map, typename Interval>
|
||||
@@ -92,26 +93,16 @@ static void MortonCopyTile(u32 stride, u8* tile_buffer, u8* gl_buffer) {
|
||||
u8* tile_ptr = tile_buffer + VideoCore::MortonInterleave(x, y) * bytes_per_pixel;
|
||||
u8* gl_ptr = gl_buffer + ((7 - y) * stride + x) * gl_bytes_per_pixel;
|
||||
if (morton_to_gl) {
|
||||
if (format == PixelFormat::D24S8) {
|
||||
gl_ptr[0] = tile_ptr[3];
|
||||
std::memcpy(gl_ptr + 1, tile_ptr, 3);
|
||||
} else {
|
||||
std::memcpy(gl_ptr, tile_ptr, bytes_per_pixel);
|
||||
}
|
||||
std::memcpy(gl_ptr, tile_ptr, bytes_per_pixel);
|
||||
} else {
|
||||
if (format == PixelFormat::D24S8) {
|
||||
std::memcpy(tile_ptr, gl_ptr + 1, 3);
|
||||
tile_ptr[3] = gl_ptr[0];
|
||||
} else {
|
||||
std::memcpy(tile_ptr, gl_ptr, bytes_per_pixel);
|
||||
}
|
||||
std::memcpy(tile_ptr, gl_ptr, bytes_per_pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <bool morton_to_gl, PixelFormat format>
|
||||
static void MortonCopy(u32 stride, u32 height, u8* gl_buffer, VAddr base, VAddr start, VAddr end) {
|
||||
void MortonCopy(u32 stride, u32 height, u8* gl_buffer, VAddr base, VAddr start, VAddr end) {
|
||||
constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(format) / 8;
|
||||
constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(format);
|
||||
|
||||
@@ -122,46 +113,28 @@ static void MortonCopy(u32 stride, u32 height, u8* gl_buffer, VAddr base, VAddr
|
||||
Memory::GetPointer(base), gl_buffer, morton_to_gl);
|
||||
}
|
||||
|
||||
static constexpr std::array<void (*)(u32, u32, u8*, VAddr, VAddr, VAddr), 18> morton_to_gl_fns = {
|
||||
template <>
|
||||
void MortonCopy<true, PixelFormat::DXT1>(u32 stride, u32 height, u8* gl_buffer, VAddr base,
|
||||
VAddr start, VAddr end) {
|
||||
constexpr u32 bytes_per_pixel = SurfaceParams::GetFormatBpp(PixelFormat::DXT1) / 8;
|
||||
constexpr u32 gl_bytes_per_pixel = CachedSurface::GetGLBytesPerPixel(PixelFormat::DXT1);
|
||||
|
||||
// TODO(bunnei): Assumes the default rendering GOB size of 16 (128 lines). We should check the
|
||||
// configuration for this and perform more generic un/swizzle
|
||||
LOG_WARNING(Render_OpenGL, "need to use correct swizzle/GOB parameters!");
|
||||
auto data =
|
||||
Tegra::Texture::UnswizzleTexture(base, Tegra::Texture::TextureFormat::DXT1, stride, height);
|
||||
std::memcpy(gl_buffer, data.data(), data.size());
|
||||
}
|
||||
|
||||
static constexpr std::array<void (*)(u32, u32, u8*, VAddr, VAddr, VAddr), 2> morton_to_gl_fns = {
|
||||
MortonCopy<true, PixelFormat::RGBA8>,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
MortonCopy<true, PixelFormat::DXT1>,
|
||||
};
|
||||
|
||||
static constexpr std::array<void (*)(u32, u32, u8*, VAddr, VAddr, VAddr), 18> gl_to_morton_fns = {
|
||||
static constexpr std::array<void (*)(u32, u32, u8*, VAddr, VAddr, VAddr), 2> gl_to_morton_fns = {
|
||||
MortonCopy<false, PixelFormat::RGBA8>,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
nullptr,
|
||||
MortonCopy<false, PixelFormat::DXT1>,
|
||||
};
|
||||
|
||||
// Allocate an uninitialized texture of appropriate size and format for the surface
|
||||
@@ -175,8 +148,11 @@ static void AllocateSurfaceTexture(GLuint texture, const FormatTuple& format_tup
|
||||
cur_state.Apply();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, width, height, 0,
|
||||
format_tuple.format, format_tuple.type, nullptr);
|
||||
if (!format_tuple.compressed) {
|
||||
// Only pre-create the texture for non-compressed textures.
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format_tuple.internal_format, width, height, 0,
|
||||
format_tuple.format, format_tuple.type, nullptr);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@@ -606,9 +582,18 @@ void CachedSurface::UploadGLTexture(const MathUtil::Rectangle<u32>& rect, GLuint
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(stride));
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
|
||||
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
|
||||
&gl_buffer[buffer_offset]);
|
||||
if (tuple.compressed) {
|
||||
glCompressedTexImage2D(GL_TEXTURE_2D, 0, tuple.internal_format,
|
||||
static_cast<GLsizei>(rect.GetWidth()),
|
||||
static_cast<GLsizei>(rect.GetHeight()), 0,
|
||||
rect.GetWidth() * rect.GetHeight() *
|
||||
GetGLBytesPerPixel(pixel_format) / tuple.compression_factor,
|
||||
&gl_buffer[buffer_offset]);
|
||||
} else {
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, x0, y0, static_cast<GLsizei>(rect.GetWidth()),
|
||||
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
|
||||
&gl_buffer[buffer_offset]);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
|
||||
|
||||
@@ -954,15 +939,6 @@ Surface RasterizerCacheOpenGL::GetSurface(const SurfaceParams& params, ScaleMatc
|
||||
if (expandable != nullptr && expandable->res_scale > target_res_scale) {
|
||||
target_res_scale = expandable->res_scale;
|
||||
}
|
||||
// Keep res_scale when reinterpreting d24s8 -> rgba8
|
||||
if (params.pixel_format == PixelFormat::RGBA8) {
|
||||
find_params.pixel_format = PixelFormat::D24S8;
|
||||
expandable = FindMatch<MatchFlags::Expand | MatchFlags::Invalid>(
|
||||
surface_cache, find_params, match_res_scale);
|
||||
if (expandable != nullptr && expandable->res_scale > target_res_scale) {
|
||||
target_res_scale = expandable->res_scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
SurfaceParams new_params = params;
|
||||
new_params.res_scale = target_res_scale;
|
||||
@@ -1056,9 +1032,34 @@ SurfaceRect_Tuple RasterizerCacheOpenGL::GetSurfaceSubRect(const SurfaceParams&
|
||||
return std::make_tuple(surface, surface->GetScaledSubRect(params));
|
||||
}
|
||||
|
||||
Surface RasterizerCacheOpenGL::GetTextureSurface(const void* config) {
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
Surface RasterizerCacheOpenGL::GetTextureSurface(const Tegra::Texture::FullTextureInfo& config) {
|
||||
auto& gpu = Core::System::GetInstance().GPU();
|
||||
|
||||
SurfaceParams params;
|
||||
params.addr = gpu.memory_manager->PhysicalToVirtualAddress(config.tic.Address());
|
||||
params.width = config.tic.Width();
|
||||
params.height = config.tic.Height();
|
||||
params.is_tiled = config.tic.IsTiled();
|
||||
params.pixel_format = SurfaceParams::PixelFormatFromTextureFormat(config.tic.format);
|
||||
params.UpdateParams();
|
||||
|
||||
if (config.tic.Width() % 8 != 0 || config.tic.Height() % 8 != 0) {
|
||||
Surface src_surface;
|
||||
MathUtil::Rectangle<u32> rect;
|
||||
std::tie(src_surface, rect) = GetSurfaceSubRect(params, ScaleMatch::Ignore, true);
|
||||
|
||||
params.res_scale = src_surface->res_scale;
|
||||
Surface tmp_surface = CreateSurface(params);
|
||||
BlitTextures(src_surface->texture.handle, rect, tmp_surface->texture.handle,
|
||||
tmp_surface->GetScaledRect(),
|
||||
SurfaceParams::GetFormatType(params.pixel_format), read_framebuffer.handle,
|
||||
draw_framebuffer.handle);
|
||||
|
||||
remove_surfaces.emplace(tmp_surface);
|
||||
return tmp_surface;
|
||||
}
|
||||
|
||||
return GetSurface(params, ScaleMatch::Ignore, true);
|
||||
}
|
||||
|
||||
SurfaceSurfaceRect_Tuple RasterizerCacheOpenGL::GetFramebufferSurfaces(
|
||||
@@ -1240,28 +1241,7 @@ void RasterizerCacheOpenGL::ValidateSurface(const Surface& surface, VAddr addr,
|
||||
continue;
|
||||
}
|
||||
|
||||
// D24S8 to RGBA8
|
||||
if (surface->pixel_format == PixelFormat::RGBA8) {
|
||||
params.pixel_format = PixelFormat::D24S8;
|
||||
Surface reinterpret_surface =
|
||||
FindMatch<MatchFlags::Copy>(surface_cache, params, ScaleMatch::Ignore, interval);
|
||||
if (reinterpret_surface != nullptr) {
|
||||
ASSERT(reinterpret_surface->pixel_format == PixelFormat::D24S8);
|
||||
|
||||
SurfaceInterval convert_interval = params.GetCopyableInterval(reinterpret_surface);
|
||||
SurfaceParams convert_params = surface->FromInterval(convert_interval);
|
||||
auto src_rect = reinterpret_surface->GetScaledSubRect(convert_params);
|
||||
auto dest_rect = surface->GetScaledSubRect(convert_params);
|
||||
|
||||
ConvertD24S8toABGR(reinterpret_surface->texture.handle, src_rect,
|
||||
surface->texture.handle, dest_rect);
|
||||
|
||||
surface->invalid_regions.erase(convert_interval);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Load data from 3DS memory
|
||||
// Load data from Switch memory
|
||||
FlushRegion(params.addr, params.size);
|
||||
surface->LoadGLBuffer(params.addr, params.end);
|
||||
surface->UploadGLTexture(surface->GetSubRect(params), read_framebuffer.handle,
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "common/math_util.h"
|
||||
#include "video_core/gpu.h"
|
||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||
#include "video_core/textures/texture.h"
|
||||
|
||||
struct CachedSurface;
|
||||
using Surface = std::shared_ptr<CachedSurface>;
|
||||
@@ -51,30 +52,8 @@ enum class ScaleMatch {
|
||||
|
||||
struct SurfaceParams {
|
||||
enum class PixelFormat {
|
||||
// First 5 formats are shared between textures and color buffers
|
||||
RGBA8 = 0,
|
||||
RGB8 = 1,
|
||||
RGB5A1 = 2,
|
||||
RGB565 = 3,
|
||||
RGBA4 = 4,
|
||||
|
||||
// Texture-only formats
|
||||
IA8 = 5,
|
||||
RG8 = 6,
|
||||
I8 = 7,
|
||||
A8 = 8,
|
||||
IA4 = 9,
|
||||
I4 = 10,
|
||||
A4 = 11,
|
||||
ETC1 = 12,
|
||||
ETC1A4 = 13,
|
||||
|
||||
// Depth buffer-only formats
|
||||
D16 = 14,
|
||||
// gap
|
||||
D24 = 16,
|
||||
D24S8 = 17,
|
||||
|
||||
DXT1 = 1,
|
||||
Invalid = 255,
|
||||
};
|
||||
|
||||
@@ -88,28 +67,15 @@ struct SurfaceParams {
|
||||
};
|
||||
|
||||
static constexpr unsigned int GetFormatBpp(PixelFormat format) {
|
||||
constexpr std::array<unsigned int, 18> bpp_table = {
|
||||
if (format == PixelFormat::Invalid)
|
||||
return 0;
|
||||
|
||||
constexpr std::array<unsigned int, 2> bpp_table = {
|
||||
32, // RGBA8
|
||||
24, // RGB8
|
||||
16, // RGB5A1
|
||||
16, // RGB565
|
||||
16, // RGBA4
|
||||
16, // IA8
|
||||
16, // RG8
|
||||
8, // I8
|
||||
8, // A8
|
||||
8, // IA4
|
||||
4, // I4
|
||||
4, // A4
|
||||
4, // ETC1
|
||||
8, // ETC1A4
|
||||
16, // D16
|
||||
0,
|
||||
24, // D24
|
||||
32, // D24S8
|
||||
64, // DXT1
|
||||
};
|
||||
|
||||
assert(static_cast<size_t>(format) < bpp_table.size());
|
||||
ASSERT(static_cast<size_t>(format) < bpp_table.size());
|
||||
return bpp_table[static_cast<size_t>(format)];
|
||||
}
|
||||
unsigned int GetFormatBpp() const {
|
||||
@@ -134,6 +100,18 @@ struct SurfaceParams {
|
||||
}
|
||||
}
|
||||
|
||||
static PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format) {
|
||||
// TODO(Subv): Properly implement this
|
||||
switch (format) {
|
||||
case Tegra::Texture::TextureFormat::A8R8G8B8:
|
||||
return PixelFormat::RGBA8;
|
||||
case Tegra::Texture::TextureFormat::DXT1:
|
||||
return PixelFormat::DXT1;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
static bool CheckFormatsBlittable(PixelFormat pixel_format_a, PixelFormat pixel_format_b) {
|
||||
SurfaceType a_type = GetFormatType(pixel_format_a);
|
||||
SurfaceType b_type = GetFormatType(pixel_format_b);
|
||||
@@ -154,22 +132,17 @@ struct SurfaceParams {
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr SurfaceType GetFormatType(PixelFormat pixel_format) {
|
||||
if ((unsigned int)pixel_format < 5) {
|
||||
static SurfaceType GetFormatType(PixelFormat pixel_format) {
|
||||
if ((unsigned int)pixel_format <= static_cast<unsigned int>(PixelFormat::RGBA8)) {
|
||||
return SurfaceType::Color;
|
||||
}
|
||||
|
||||
if ((unsigned int)pixel_format < 14) {
|
||||
if ((unsigned int)pixel_format <= static_cast<unsigned int>(PixelFormat::DXT1)) {
|
||||
return SurfaceType::Texture;
|
||||
}
|
||||
|
||||
if (pixel_format == PixelFormat::D16 || pixel_format == PixelFormat::D24) {
|
||||
return SurfaceType::Depth;
|
||||
}
|
||||
|
||||
if (pixel_format == PixelFormat::D24S8) {
|
||||
return SurfaceType::DepthStencil;
|
||||
}
|
||||
// TODO(Subv): Implement the other formats
|
||||
ASSERT(false);
|
||||
|
||||
return SurfaceType::Invalid;
|
||||
}
|
||||
@@ -265,12 +238,10 @@ struct CachedSurface : SurfaceParams {
|
||||
OGLTexture texture;
|
||||
|
||||
static constexpr unsigned int GetGLBytesPerPixel(PixelFormat format) {
|
||||
// OpenGL needs 4 bpp alignment for D24 since using GL_UNSIGNED_INT as type
|
||||
return format == PixelFormat::Invalid
|
||||
? 0
|
||||
: (format == PixelFormat::D24 || GetFormatType(format) == SurfaceType::Texture)
|
||||
? 4
|
||||
: SurfaceParams::GetFormatBpp(format) / 8;
|
||||
if (format == PixelFormat::Invalid)
|
||||
return 0;
|
||||
|
||||
return SurfaceParams::GetFormatBpp(format) / 8;
|
||||
}
|
||||
|
||||
std::unique_ptr<u8[]> gl_buffer;
|
||||
@@ -303,17 +274,17 @@ public:
|
||||
void CopySurface(const Surface& src_surface, const Surface& dst_surface,
|
||||
SurfaceInterval copy_interval);
|
||||
|
||||
/// Load a texture from 3DS memory to OpenGL and cache it (if not already cached)
|
||||
/// Load a texture from Switch memory to OpenGL and cache it (if not already cached)
|
||||
Surface GetSurface(const SurfaceParams& params, ScaleMatch match_res_scale,
|
||||
bool load_if_create);
|
||||
|
||||
/// Attempt to find a subrect (resolution scaled) of a surface, otherwise loads a texture from
|
||||
/// 3DS memory to OpenGL and caches it (if not already cached)
|
||||
/// Switch memory to OpenGL and caches it (if not already cached)
|
||||
SurfaceRect_Tuple GetSurfaceSubRect(const SurfaceParams& params, ScaleMatch match_res_scale,
|
||||
bool load_if_create);
|
||||
|
||||
/// Get a surface based on the texture configuration
|
||||
Surface GetTextureSurface(const void* config);
|
||||
Surface GetTextureSurface(const Tegra::Texture::FullTextureInfo& config);
|
||||
|
||||
/// Get the color and depth surfaces based on the framebuffer configuration
|
||||
SurfaceSurfaceRect_Tuple GetFramebufferSurfaces(bool using_color_fb, bool using_depth_fb,
|
||||
@@ -328,7 +299,7 @@ public:
|
||||
/// Write any cached resources overlapping the region back to memory (if dirty)
|
||||
void FlushRegion(VAddr addr, u64 size, Surface flush_surface = nullptr);
|
||||
|
||||
/// Mark region as being invalidated by region_owner (nullptr if 3DS memory)
|
||||
/// Mark region as being invalidated by region_owner (nullptr if Switch memory)
|
||||
void InvalidateRegion(VAddr addr, u64 size, const Surface& region_owner);
|
||||
|
||||
/// Flush all cached resources tracked by this cache manager
|
||||
|
||||
@@ -194,7 +194,7 @@ void OpenGLState::Apply() const {
|
||||
// Textures
|
||||
for (unsigned i = 0; i < ARRAY_SIZE(texture_units); ++i) {
|
||||
if (texture_units[i].texture_2d != cur_state.texture_units[i].texture_2d) {
|
||||
glActiveTexture(TextureUnits::PicaTexture(i).Enum());
|
||||
glActiveTexture(TextureUnits::MaxwellTexture(i).Enum());
|
||||
glBindTexture(GL_TEXTURE_2D, texture_units[i].texture_2d);
|
||||
}
|
||||
if (texture_units[i].sampler != cur_state.texture_units[i].sampler) {
|
||||
|
||||
@@ -16,7 +16,7 @@ struct TextureUnit {
|
||||
}
|
||||
};
|
||||
|
||||
constexpr TextureUnit PicaTexture(int unit) {
|
||||
constexpr TextureUnit MaxwellTexture(int unit) {
|
||||
return TextureUnit{unit};
|
||||
}
|
||||
|
||||
|
||||
@@ -47,4 +47,27 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) {
|
||||
return {};
|
||||
}
|
||||
|
||||
inline GLenum TextureFilterMode(Tegra::Texture::TextureFilter filter_mode) {
|
||||
switch (filter_mode) {
|
||||
case Tegra::Texture::TextureFilter::Linear:
|
||||
return GL_LINEAR;
|
||||
case Tegra::Texture::TextureFilter::Nearest:
|
||||
return GL_NEAREST;
|
||||
}
|
||||
LOG_CRITICAL(Render_OpenGL, "Unimplemented texture filter mode=%u",
|
||||
static_cast<u32>(filter_mode));
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
||||
inline GLenum WrapMode(Tegra::Texture::WrapMode wrap_mode) {
|
||||
switch (wrap_mode) {
|
||||
case Tegra::Texture::WrapMode::ClampToEdge:
|
||||
return GL_CLAMP_TO_EDGE;
|
||||
}
|
||||
LOG_CRITICAL(Render_OpenGL, "Unimplemented texture wrap mode=%u", static_cast<u32>(wrap_mode));
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace MaxwellToGL
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
class EmuWindow;
|
||||
|
||||
/// Structure used for storing information about the textures for each 3DS screen
|
||||
/// Structure used for storing information about the textures for the Switch screen
|
||||
struct TextureInfo {
|
||||
OGLTexture resource;
|
||||
GLsizei width;
|
||||
@@ -24,7 +24,7 @@ struct TextureInfo {
|
||||
Tegra::FramebufferConfig::PixelFormat pixel_format;
|
||||
};
|
||||
|
||||
/// Structure used for storing information about the display target for each 3DS screen
|
||||
/// Structure used for storing information about the display target for the Switch screen
|
||||
struct ScreenInfo {
|
||||
GLuint display_texture;
|
||||
MathUtil::Rectangle<float> display_texcoords;
|
||||
|
||||
@@ -37,6 +37,16 @@ enum class TICHeaderVersion : u32 {
|
||||
BlockLinearColorKey = 4,
|
||||
};
|
||||
|
||||
enum class ComponentType : u32 {
|
||||
SNORM = 1,
|
||||
UNORM = 2,
|
||||
SINT = 3,
|
||||
UINT = 4,
|
||||
SNORM_FORCE_FP16 = 5,
|
||||
UNORM_FORCE_FP16 = 6,
|
||||
FLOAT = 7
|
||||
};
|
||||
|
||||
union TextureHandle {
|
||||
u32 raw;
|
||||
BitField<0, 20, u32> tic_id;
|
||||
@@ -48,10 +58,10 @@ struct TICEntry {
|
||||
union {
|
||||
u32 raw;
|
||||
BitField<0, 7, TextureFormat> format;
|
||||
BitField<7, 3, u32> r_type;
|
||||
BitField<10, 3, u32> g_type;
|
||||
BitField<13, 3, u32> b_type;
|
||||
BitField<16, 3, u32> a_type;
|
||||
BitField<7, 3, ComponentType> r_type;
|
||||
BitField<10, 3, ComponentType> g_type;
|
||||
BitField<13, 3, ComponentType> b_type;
|
||||
BitField<16, 3, ComponentType> a_type;
|
||||
};
|
||||
u32 address_low;
|
||||
union {
|
||||
@@ -77,6 +87,11 @@ struct TICEntry {
|
||||
u32 Height() const {
|
||||
return height_minus_1 + 1;
|
||||
}
|
||||
|
||||
bool IsTiled() const {
|
||||
return header_version == TICHeaderVersion::BlockLinear ||
|
||||
header_version == TICHeaderVersion::BlockLinearColorKey;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(TICEntry) == 0x20, "TICEntry has wrong size");
|
||||
|
||||
|
||||
@@ -347,8 +347,6 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
|
||||
const Core::System::ResultStatus result{system.Load(render_window, filename.toStdString())};
|
||||
|
||||
Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "Qt");
|
||||
|
||||
if (result != Core::System::ResultStatus::Success) {
|
||||
switch (result) {
|
||||
case Core::System::ResultStatus::ErrorGetLoader:
|
||||
@@ -357,7 +355,12 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
QMessageBox::critical(this, tr("Error while loading ROM!"),
|
||||
tr("The ROM format is not supported."));
|
||||
break;
|
||||
|
||||
case Core::System::ResultStatus::ErrorUnsupportedArch:
|
||||
LOG_CRITICAL(Frontend, "Unsupported architecture detected!",
|
||||
filename.toStdString().c_str());
|
||||
QMessageBox::critical(this, tr("Error while loading ROM!"),
|
||||
tr("The ROM uses currently unusable 32-bit architecture"));
|
||||
break;
|
||||
case Core::System::ResultStatus::ErrorSystemMode:
|
||||
LOG_CRITICAL(Frontend, "Failed to load ROM!");
|
||||
QMessageBox::critical(this, tr("Error while loading ROM!"),
|
||||
@@ -404,6 +407,7 @@ bool GMainWindow::LoadROM(const QString& filename) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "Qt");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace DefaultINI {
|
||||
|
||||
const char* sdl2_config_file = R"(
|
||||
[Controls]
|
||||
# The input devices and parameters for each 3DS native input
|
||||
# The input devices and parameters for each Switch native input
|
||||
# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..."
|
||||
# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values
|
||||
|
||||
|
||||
Reference in New Issue
Block a user