Ejemplo n.º 1
0
        public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
        {
            _normalSession   = normalSession;
            _commonArguments = IApplet.ReadStruct <CommonArguments>(_normalSession.Pop());

            Logger.Info?.PrintMsg(LogClass.ServiceAm, $"ErrorApplet version: 0x{_commonArguments.AppletVersion:x8}");

            _errorStorage      = _normalSession.Pop();
            _errorCommonHeader = IApplet.ReadStruct <ErrorCommonHeader>(_errorStorage);
            _errorStorage      = _errorStorage.Skip(Marshal.SizeOf(typeof(ErrorCommonHeader))).ToArray();

            switch (_errorCommonHeader.Type)
            {
            case ErrorType.ErrorCommonArg:
            {
                ParseErrorCommonArg();

                break;
            }

            case ErrorType.ApplicationErrorArg:
            {
                ParseApplicationErrorArg();

                break;
            }

            default: throw new NotImplementedException($"ErrorApplet type {_errorCommonHeader.Type} is not implemented.");
            }

            AppletStateChanged?.Invoke(this, null);

            return(ResultCode.Success);
        }
Ejemplo n.º 2
0
        public ResultCode Start(AppletSession normalSession,
                                AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            _interactiveSession.DataAvailable += OnInteractiveData;

            var launchParams   = _normalSession.Pop();
            var keyboardConfig = _normalSession.Pop();
            var transferMemory = _normalSession.Pop();

            _keyboardConfig = ReadStruct <SoftwareKeyboardConfig>(keyboardConfig);

            if (_keyboardConfig.UseUtf8)
            {
                _encoding = Encoding.UTF8;
            }

            _state = SoftwareKeyboardState.Ready;

            Execute();

            return(ResultCode.Success);
        }
Ejemplo n.º 3
0
        unsafe public ResultCode Start(AppletSession normalSession,
                                       AppletSession interactiveSession)
        {
            _normalSession = normalSession;

            byte[] launchParams = _normalSession.Pop();
            byte[] controllerSupportArgPrivate     = _normalSession.Pop();
            ControllerSupportArgPrivate privateArg = IApplet.ReadStruct <ControllerSupportArgPrivate>(controllerSupportArgPrivate);

            Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ArgPriv {privateArg.PrivateSize} {privateArg.ArgSize} {privateArg.Mode}" +
                             $"HoldType:{(NpadJoyHoldType)privateArg.NpadJoyHoldType} StyleSets:{(ControllerType)privateArg.NpadStyleSet}");

            if (privateArg.Mode != ControllerSupportMode.ShowControllerSupport)
            {
                _normalSession.Push(BuildResponse()); // Dummy response for other modes
                AppletStateChanged?.Invoke(this, null);

                return(ResultCode.Success);
            }

            byte[] controllerSupportArg = _normalSession.Pop();

            ControllerSupportArgHeader argHeader;

            if (privateArg.ArgSize == Marshal.SizeOf <ControllerSupportArg>())
            {
                ControllerSupportArg arg = IApplet.ReadStruct <ControllerSupportArg>(controllerSupportArg);
                argHeader = arg.Header;
                // Read enable text here?
            }
            else
            {
                Logger.PrintStub(LogClass.ServiceHid, $"Unknown revision of ControllerSupportArg.");

                argHeader = IApplet.ReadStruct <ControllerSupportArgHeader>(controllerSupportArg); // Read just the header
            }

            Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet Arg {argHeader.PlayerCountMin} {argHeader.PlayerCountMax} {argHeader.EnableTakeOverConnection} {argHeader.EnableSingleMode}");

            // Currently, the only purpose of this applet is to help
            // choose the primary input controller for the game
            // TODO: Ideally should hook back to HID.Controller. When applet is called, can choose appropriate controller and attach to appropriate id.
            if (argHeader.PlayerCountMin > 1)
            {
                Logger.PrintWarning(LogClass.ServiceHid, "More than one controller was requested.");
            }

            ControllerSupportResultInfo result = new ControllerSupportResultInfo
            {
                PlayerCount = 1,
                SelectedId  = (uint)GetNpadIdTypeFromIndex(_system.Device.Hid.Npads.PrimaryController)
            };

            Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ReturnResult {result.PlayerCount} {result.SelectedId}");

            _normalSession.Push(BuildResponse(result));
            AppletStateChanged?.Invoke(this, null);

            return(ResultCode.Success);
        }
Ejemplo n.º 4
0
        public ResultCode Start(AppletSession normalSession,
                                AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            _interactiveSession.DataAvailable += OnInteractiveData;

            _alreadyShown       = false;
            _useChangedStringV2 = false;

            var launchParams   = _normalSession.Pop();
            var keyboardConfig = _normalSession.Pop();

            if (keyboardConfig.Length == Marshal.SizeOf <SoftwareKeyboardInitialize>())
            {
                // Initialize the keyboard applet in background mode.

                _isBackground = true;

                _keyboardBackgroundInitialize = ReadStruct <SoftwareKeyboardInitialize>(keyboardConfig);
                _backgroundState = InlineKeyboardState.Uninitialized;

                return(ResultCode.Success);
            }
            else
            {
                // Initialize the keyboard applet in foreground mode.

                _isBackground = false;

                if (keyboardConfig.Length < Marshal.SizeOf <SoftwareKeyboardConfig>())
                {
                    Logger.Error?.Print(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
                }
                else
                {
                    _keyboardForegroundConfig = ReadStruct <SoftwareKeyboardConfig>(keyboardConfig);
                }

                if (!_normalSession.TryPop(out _transferMemory))
                {
                    Logger.Error?.Print(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
                }

                if (_keyboardForegroundConfig.UseUtf8)
                {
                    _encoding = Encoding.UTF8;
                }

                _foregroundState = SoftwareKeyboardState.Ready;

                ExecuteForegroundKeyboard();

                return(ResultCode.Success);
            }
        }
Ejemplo n.º 5
0
        public ResultCode Start(AppletSession normalSession,
                                AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            _interactiveSession.DataAvailable += OnInteractiveData;

            var launchParams   = _normalSession.Pop();
            var keyboardConfig = _normalSession.Pop();

            // TODO: A better way would be handling the background creation properly
            // in LibraryAppleCreator / Acessor instead of guessing by size.
            if (keyboardConfig.Length == Marshal.SizeOf <SoftwareKeyboardInitialize>())
            {
                _isBackground = true;

                _keyboardBgInitialize = ReadStruct <SoftwareKeyboardInitialize>(keyboardConfig);
                _state = SoftwareKeyboardState.Uninitialized;

                return(ResultCode.Success);
            }
            else
            {
                _isBackground = false;

                if (keyboardConfig.Length < Marshal.SizeOf <SoftwareKeyboardConfig>())
                {
                    Logger.Error?.Print(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
                }
                else
                {
                    _keyboardFgConfig = ReadStruct <SoftwareKeyboardConfig>(keyboardConfig);
                }

                if (!_normalSession.TryPop(out _transferMemory))
                {
                    Logger.Error?.Print(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
                }

                if (_keyboardFgConfig.UseUtf8)
                {
                    _encoding = Encoding.UTF8;
                }

                _state = SoftwareKeyboardState.Ready;

                ExecuteForegroundKeyboard();

                return(ResultCode.Success);
            }
        }
Ejemplo n.º 6
0
        public ResultCode Start(AppletSession normalSession,
                                AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            // TODO(jduncanator): Parse PlayerSelectConfig from input data
            _normalSession.Push(BuildResponse());

            AppletStateChanged?.Invoke(this, null);

            return(ResultCode.Success);
        }
Ejemplo n.º 7
0
        public ILibraryAppletAccessor(AppletId appletId, Horizon system)
        {
            _stateChangedEvent       = new KEvent(system.KernelContext);
            _normalOutDataEvent      = new KEvent(system.KernelContext);
            _interactiveOutDataEvent = new KEvent(system.KernelContext);

            _applet = AppletManager.Create(appletId, system);

            _normalSession      = new AppletSession();
            _interactiveSession = new AppletSession();

            _applet.AppletStateChanged        += OnAppletStateChanged;
            _normalSession.DataAvailable      += OnNormalOutData;
            _interactiveSession.DataAvailable += OnInteractiveOutData;

            Logger.PrintInfo(LogClass.ServiceAm, $"Applet '{appletId}' created.");
        }
Ejemplo n.º 8
0
        public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            _commonArguments = IApplet.ReadStruct <CommonArguments>(_normalSession.Pop());

            Logger.Stub?.PrintStub(LogClass.ServiceAm, $"WebApplet version: 0x{_commonArguments.AppletVersion:x8}");

            ReadOnlySpan <byte> webArguments = _normalSession.Pop();

            (_shimKind, _arguments) = BrowserArgument.ParseArguments(webArguments);

            Logger.Stub?.PrintStub(LogClass.ServiceAm, $"Web Arguments: {_arguments.Count}");

            foreach (BrowserArgument argument in _arguments)
            {
                Logger.Stub?.PrintStub(LogClass.ServiceAm, $"{argument.Type}: {argument.GetValue()}");
            }

            if ((_commonArguments.AppletVersion >= 0x80000 && _shimKind == ShimKind.Web) || (_commonArguments.AppletVersion >= 0x30000 && _shimKind == ShimKind.Share))
            {
                List <BrowserOutput> result = new List <BrowserOutput>();

                result.Add(new BrowserOutput(BrowserOutputType.ExitReason, (uint)WebExitReason.ExitButton));

                _normalSession.Push(BuildResponseNew(result));
            }
            else
            {
                WebCommonReturnValue result = new WebCommonReturnValue()
                {
                    ExitReason = WebExitReason.ExitButton,
                };

                _normalSession.Push(BuildResponseOld(result));
            }

            AppletStateChanged?.Invoke(this, null);

            return(ResultCode.Success);
        }
Ejemplo n.º 9
0
        public ResultCode Start(AppletSession normalSession,
                                AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            _interactiveSession.DataAvailable += OnInteractiveData;

            var launchParams   = _normalSession.Pop();
            var keyboardConfig = _normalSession.Pop();

            if (keyboardConfig.Length < Marshal.SizeOf <SoftwareKeyboardConfig>())
            {
                Logger.Error?.Print(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
            }
            else
            {
                _keyboardConfig = ReadStruct <SoftwareKeyboardConfig>(keyboardConfig);
            }

            if (!_normalSession.TryPop(out _transferMemory))
            {
                Logger.Error?.Print(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
            }

            if (_keyboardConfig.UseUtf8)
            {
                _encoding = Encoding.UTF8;
            }

            _state = SoftwareKeyboardState.Ready;

            Execute();

            return(ResultCode.Success);
        }
Ejemplo n.º 10
0
        unsafe public ResultCode Start(AppletSession normalSession,
                                       AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            var _ = _normalSession.Pop();   // unknown

            var controllerSupportArgPrivate = _normalSession.Pop();
            var c = ReadStruct <ControllerSupportArgPrivate>(controllerSupportArgPrivate);

            Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ArgPriv {c.PrivateSize} {c.ArgSize} {c.Mode}" +
                             $"HoldType:{(HidJoyHoldType)c.NpadJoyHoldType} StyleSets:{(ControllerType)c.NpadStyleSet}");

            if (c.Mode != ControllerSupportMode.ShowControllerSupport)
            {
                _normalSession.Push(BuildResponse());   // Dummy response for other modes
                AppletStateChanged?.Invoke(this, null);

                return(ResultCode.Success);
            }

            var controllerSupportArg = _normalSession.Pop();

            ControllerSupportArgHeader h;

            if (c.ArgSize == Marshal.SizeOf <ControllerSupportArg>())
            {
                var arg = ReadStruct <ControllerSupportArg>(controllerSupportArg);
                h = arg.Header;
                // Read enable text here?
            }
            else
            {
                Logger.PrintStub(LogClass.ServiceHid, $"Unknown revision of ControllerSupportArg.");
                h = ReadStruct <ControllerSupportArgHeader>(controllerSupportArg); // Read just the header
            }

            Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet Arg {h.PlayerCountMin} {h.PlayerCountMax} {h.EnableTakeOverConnection}");

            // Currently, the only purpose of this applet is to help
            // choose the primary input controller for the game
            // TODO: Ideally should hook back to HID.Controller. When applet is called, can choose appropriate controller and attach to appropriate id.
            if (h.PlayerCountMin > 1)
            {
                Logger.PrintWarning(LogClass.ServiceHid, "Game requested more than 1 controller!");
            }

            var result = new ControllerSupportResultInfo
            {
                PlayerCount = 1,
                SelectedId  = (uint)HLE.HOS.Services.Hid.HidServer.HidUtils.GetNpadIdTypeFromIndex(_system.Device.Hid.Npads.PrimaryControllerId)
            };

            Logger.PrintStub(LogClass.ServiceHid, $"ControllerApplet ReturnResult {result.PlayerCount} {result.SelectedId}");

            _normalSession.Push(BuildResponse(result));
            AppletStateChanged?.Invoke(this, null);

            return(ResultCode.Success);
        }
Ejemplo n.º 11
0
        unsafe public ResultCode Start(AppletSession normalSession,
                                       AppletSession interactiveSession)
        {
            _normalSession = normalSession;

            byte[] launchParams = _normalSession.Pop();
            byte[] controllerSupportArgPrivate     = _normalSession.Pop();
            ControllerSupportArgPrivate privateArg = IApplet.ReadStruct <ControllerSupportArgPrivate>(controllerSupportArgPrivate);

            Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerApplet ArgPriv {privateArg.PrivateSize} {privateArg.ArgSize} {privateArg.Mode} " +
                                   $"HoldType:{(NpadJoyHoldType)privateArg.NpadJoyHoldType} StyleSets:{(ControllerType)privateArg.NpadStyleSet}");

            if (privateArg.Mode != ControllerSupportMode.ShowControllerSupport)
            {
                _normalSession.Push(BuildResponse()); // Dummy response for other modes
                AppletStateChanged?.Invoke(this, null);

                return(ResultCode.Success);
            }

            byte[] controllerSupportArg = _normalSession.Pop();

            ControllerSupportArgHeader argHeader;

            if (privateArg.ArgSize == Marshal.SizeOf <ControllerSupportArgV7>())
            {
                ControllerSupportArgV7 arg = IApplet.ReadStruct <ControllerSupportArgV7>(controllerSupportArg);
                argHeader = arg.Header;

                Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerSupportArg Version 7 EnableExplainText={arg.EnableExplainText != 0}");
                // Read enable text here?
            }
            else if (privateArg.ArgSize == Marshal.SizeOf <ControllerSupportArgVPre7>())
            {
                ControllerSupportArgVPre7 arg = IApplet.ReadStruct <ControllerSupportArgVPre7>(controllerSupportArg);
                argHeader = arg.Header;

                Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerSupportArg Version Pre-7 EnableExplainText={arg.EnableExplainText != 0}");
                // Read enable text here?
            }
            else
            {
                Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerSupportArg Version Unknown");

                argHeader = IApplet.ReadStruct <ControllerSupportArgHeader>(controllerSupportArg); // Read just the header
            }

            int playerMin = argHeader.PlayerCountMin;
            int playerMax = argHeader.PlayerCountMax;

            Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerApplet Arg {playerMin} {playerMax} {argHeader.EnableTakeOverConnection} {argHeader.EnableSingleMode}");

            int         configuredCount = 0;
            PlayerIndex primaryIndex    = PlayerIndex.Unknown;

            while (!_system.Device.Hid.Npads.Validate(playerMin, playerMax, (ControllerType)privateArg.NpadStyleSet, out configuredCount, out primaryIndex))
            {
                ControllerAppletUiArgs uiArgs = new ControllerAppletUiArgs
                {
                    PlayerCountMin   = playerMin,
                    PlayerCountMax   = playerMax,
                    SupportedStyles  = (ControllerType)privateArg.NpadStyleSet,
                    SupportedPlayers = _system.Device.Hid.Npads.GetSupportedPlayers(),
                    IsDocked         = _system.State.DockedMode
                };

                if (!_system.Device.UiHandler.DisplayMessageDialog(uiArgs))
                {
                    break;
                }
            }

            ControllerSupportResultInfo result = new ControllerSupportResultInfo
            {
                PlayerCount = (sbyte)configuredCount,
                SelectedId  = (uint)GetNpadIdTypeFromIndex(primaryIndex)
            };

            Logger.Stub?.PrintStub(LogClass.ServiceHid, $"ControllerApplet ReturnResult {result.PlayerCount} {result.SelectedId}");

            _normalSession.Push(BuildResponse(result));
            AppletStateChanged?.Invoke(this, null);

            _system.ReturnFocus();

            return(ResultCode.Success);
        }
Ejemplo n.º 12
0
        public ResultCode Start(AppletSession normalSession,
                                AppletSession interactiveSession)
        {
            _normalSession      = normalSession;
            _interactiveSession = interactiveSession;

            _interactiveSession.DataAvailable += OnInteractiveData;

            var launchParams   = _normalSession.Pop();
            var keyboardConfig = _normalSession.Pop();

            if (keyboardConfig.Length == Marshal.SizeOf <SoftwareKeyboardInitialize>())
            {
                // Initialize the keyboard applet in background mode.

                _isBackground = true;

                _keyboardBackgroundInitialize = ReadStruct <SoftwareKeyboardInitialize>(keyboardConfig);
                InlineKeyboardState state = InlineKeyboardState.Uninitialized;
                SetInlineState(state);

                string acceptKeyName;
                string cancelKeyName;

                if (_device.UiHandler != null)
                {
                    _dynamicTextInputHandler              = _device.UiHandler.CreateDynamicTextInputHandler();
                    _dynamicTextInputHandler.TextChanged += DynamicTextChanged;

                    acceptKeyName = _dynamicTextInputHandler.AcceptKeyName;
                    cancelKeyName = _dynamicTextInputHandler.CancelKeyName;
                }
                else
                {
                    Logger.Error?.Print(LogClass.ServiceAm, "GUI Handler is not set, software keyboard applet will not work properly");

                    acceptKeyName = "";
                    cancelKeyName = "";
                }

                _keyboardRenderer = new SoftwareKeyboardRenderer(acceptKeyName, cancelKeyName);

                _interactiveSession.Push(InlineResponses.FinishedInitialize(state));

                return(ResultCode.Success);
            }
            else
            {
                // Initialize the keyboard applet in foreground mode.

                _isBackground = false;

                if (keyboardConfig.Length < Marshal.SizeOf <SoftwareKeyboardConfig>())
                {
                    Logger.Error?.Print(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
                }
                else
                {
                    _keyboardForegroundConfig = ReadStruct <SoftwareKeyboardConfig>(keyboardConfig);
                }

                if (!_normalSession.TryPop(out _transferMemory))
                {
                    Logger.Error?.Print(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
                }

                if (_keyboardForegroundConfig.UseUtf8)
                {
                    _encoding = Encoding.UTF8;
                }

                _foregroundState = SoftwareKeyboardState.Ready;

                ExecuteForegroundKeyboard();

                return(ResultCode.Success);
            }
        }
Ejemplo n.º 13
0
        public ResultCode Start(AppletSession normalSession, AppletSession interactiveSession)
        {
            lock (_lock)
            {
                _normalSession      = normalSession;
                _interactiveSession = interactiveSession;

                _interactiveSession.DataAvailable += OnInteractiveData;

                var launchParams   = _normalSession.Pop();
                var keyboardConfig = _normalSession.Pop();

                _isBackground = keyboardConfig.Length == Marshal.SizeOf <SoftwareKeyboardInitialize>();

                if (_isBackground)
                {
                    // Initialize the keyboard applet in background mode.

                    _keyboardBackgroundInitialize = ReadStruct <SoftwareKeyboardInitialize>(keyboardConfig);
                    _backgroundState = InlineKeyboardState.Uninitialized;

                    if (_device.UiHandler == null)
                    {
                        Logger.Error?.Print(LogClass.ServiceAm, "GUI Handler is not set, software keyboard applet will not work properly");
                    }
                    else
                    {
                        // Create a text handler that converts keyboard strokes to strings.
                        _dynamicTextInputHandler = _device.UiHandler.CreateDynamicTextInputHandler();
                        _dynamicTextInputHandler.TextChangedEvent += HandleTextChangedEvent;
                        _dynamicTextInputHandler.KeyPressedEvent  += HandleKeyPressedEvent;

                        _npads = new NpadReader(_device);
                        _npads.NpadButtonDownEvent += HandleNpadButtonDownEvent;
                        _npads.NpadButtonUpEvent   += HandleNpadButtonUpEvent;

                        _keyboardRenderer = new SoftwareKeyboardRenderer(_device.UiHandler.HostUiTheme);
                    }

                    return(ResultCode.Success);
                }
                else
                {
                    // Initialize the keyboard applet in foreground mode.

                    if (keyboardConfig.Length < Marshal.SizeOf <SoftwareKeyboardConfig>())
                    {
                        Logger.Error?.Print(LogClass.ServiceAm, $"SoftwareKeyboardConfig size mismatch. Expected {Marshal.SizeOf<SoftwareKeyboardConfig>():x}. Got {keyboardConfig.Length:x}");
                    }
                    else
                    {
                        _keyboardForegroundConfig = ReadStruct <SoftwareKeyboardConfig>(keyboardConfig);
                    }

                    if (!_normalSession.TryPop(out _transferMemory))
                    {
                        Logger.Error?.Print(LogClass.ServiceAm, "SwKbd Transfer Memory is null");
                    }

                    if (_keyboardForegroundConfig.UseUtf8)
                    {
                        _encoding = Encoding.UTF8;
                    }

                    _foregroundState = SoftwareKeyboardState.Ready;

                    ExecuteForegroundKeyboard();

                    return(ResultCode.Success);
                }
            }
        }