ConsoleLanguageForTag picks, among the rows of the tag's language whose script
and region are empty or equal to the tag's, the one that names the most
(script outranks region), so a regional row wins over the language's main row
and a language with no row for the tag's region falls back to its main row.
The first group of rows covers the Latin-script European languages that have
no regional split but a few: English (United Kingdom for GB, IE, AU and NZ,
English (United States) otherwise), French and French (Canada), German,
Italian, Dutch and Romanian.
ParseLocale normalises the text as a POSIX name first, which leaves a BCP-47
tag unchanged except for underscores, and then parses the result, so the
caller handles en-US and en_US.UTF-8 alike. C, POSIX and an empty text report
no locale and leave the output tag as it was.
POSIX hosts name their locale language[_territory][.codeset][@modifier], such
as en_GB.UTF-8@euro, and use C and POSIX for no locale at all. NormalizePosixLocale
drops the codeset and the modifier, turns underscores into hyphens, maps the
@latin and @cyrillic modifiers to the Latn and Cyrl scripts where the name has
no script, and returns an empty string for C, POSIX and an empty name so the
caller sees "no locale" instead of a language called C.
Adds a host-only test, system_service_language_locale, for ParseTag: case
normalisation of the language, script and region subtags, the three-digit
region of es-419, variants and extensions that are ignored, and the inputs it
must reject (empty and oversized subtags, one-letter and long languages, the
POSIX underscore and codeset forms) without touching the output tag.
ANYPS5_LANGUAGE can only name a console language number. Taking the language
from the host needs the host's locale, which arrives as a BCP-47 tag such as
en-US, pt-BR or zh-Hant-TW. ParseTag reads the language, script and region
subtags, normalises their case, ignores variants and extensions, and rejects
empty subtags, subtags over 8 characters and languages that are not 2 or 3
letters.
The sceSystemServiceUsbStorage* exports jump straight into the USB storage
module, so call the matching libSceUsbStorage export instead of throwing.
RequestMapWSB keeps its marker while its two declarations disagree on the
fourth argument and the output type.
BunnyFl ran firmware 13.42's libSceSystemService.sprx in an emulator and
recorded the checks these calls make before they pass a request on. A
null title ID or one whose length isn't 9 makes sceSystemServiceGetAppId
and sceLncUtilGetAppId return -1 and sceLncUtilIsAppLaunched return
0x80940005. A null output, list, count or user returns 0x80940005 from
the LncUtil and SystemService calls and 0x80e30003 from
sceShellCoreUtilGetUserFocus, before the app ID is looked at, and a null
sceLncUtilLoadExec path returns 0x80940005.
What the module passes on as a request still throws: another
9-character title ID, another app ID, a list capacity of 0 and an empty
sceLncUtilLoadExec path.
sceLncUtilLoadExec takes the same path and null-terminated argument
list, which the SystemService call passes on to it on the console. It
returns sceSystemServiceLoadExec's result: the same parameter errors,
the same refusals for paths it cannot start, and "exit" ends the title
in the same way.
sceLncUtilIsAppSuspended, sceSystemServiceIsAppSuspended and
sceLncUtilIsSpeculativeLaunch write false for the running title's app
ID. The title that calls them is running and has no shell to suspend
it. It was started from the host rather than by sceLncUtilLaunchApp,
so no LncLaunchParam asked for a speculative launch. Another app ID
and a null output still throw.
sceLncUtilGetAppLaunchedUser, sceSystemServiceGetAppLaunchedUser and
sceShellCoreUtilGetUserFocus write the initial user for the running
title's app ID. That is the user sceUserServiceGetInitialUser and
sceUserServiceGetForegroundUser report. Another app ID and a null user
pointer still throw.
sceLncUtilGetAppId and sceLncUtilIsAppLaunched accept the running
title's ID as sceSystemServiceGetAppId does, and
sceLncUtilGetAppIdOfRunningBigApp returns what
sceSystemServiceGetAppIdOfRunningBigApp returns. Both big-app lists
write the running title's app ID as their only entry, because AnyPS5
runs one title. Another title ID, a null pointer and a list capacity of
0 still throw.