aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.HLE/HOS/SystemState
diff options
context:
space:
mode:
authorgdkchan <gab.dark.100@gmail.com>2018-08-16 20:47:36 -0300
committerGitHub <noreply@github.com>2018-08-16 20:47:36 -0300
commit521751795a1c97c0d97f6f8904a3be69b13d3a9d (patch)
tree942a05899c40e2de6d92a38b93a494bd96ee64b8 /Ryujinx.HLE/HOS/SystemState
parent182d716867ae477c2b15a5332430dc2641fa1cc3 (diff)
Code style fixes and nits on the HLE project (#355)
* Some style fixes and nits on ITimeZoneService * Remove some unneeded usings * Remove the Ryujinx.HLE.OsHle.Handles namespace * Remove hbmenu automatic load on process exit * Rename Ns to Device, rename Os to System, rename SystemState to State * Move Exceptions and Utilities out of OsHle * Rename OsHle to HOS * Rename OsHle folder to HOS * IManagerDisplayService and ISystemDisplayService style fixes * BsdError shouldn't be public * Add a empty new line before using static * Remove unused file * Some style fixes on NPDM * Exit gracefully when the application is closed * Code style fixes on IGeneralService * Add 0x prefix on values printed as hex * Small improvements on finalization code * Move ProcessId and ThreadId out of AThreadState * Rename VFs to FileSystem * FsAccessHeader shouldn't be public. Also fix file names casing * More case changes on NPDM * Remove unused files * Move using to the correct place on NPDM * Use properties on KernelAccessControlMmio * Address PR feedback
Diffstat (limited to 'Ryujinx.HLE/HOS/SystemState')
-rw-r--r--Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs62
-rw-r--r--Ryujinx.HLE/HOS/SystemState/ColorSet.cs8
-rw-r--r--Ryujinx.HLE/HOS/SystemState/OpenCloseState.cs8
-rw-r--r--Ryujinx.HLE/HOS/SystemState/SystemLanguage.cs23
-rw-r--r--Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs145
-rw-r--r--Ryujinx.HLE/HOS/SystemState/UserId.cs76
-rw-r--r--Ryujinx.HLE/HOS/SystemState/UserProfile.cs36
7 files changed, 358 insertions, 0 deletions
diff --git a/Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs b/Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs
new file mode 100644
index 00000000..ee0e6fea
--- /dev/null
+++ b/Ryujinx.HLE/HOS/SystemState/AppletStateMgr.cs
@@ -0,0 +1,62 @@
+using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Services.Am;
+using System;
+using System.Collections.Concurrent;
+
+namespace Ryujinx.HLE.HOS.SystemState
+{
+ class AppletStateMgr : IDisposable
+ {
+ private ConcurrentQueue<MessageInfo> Messages;
+
+ public FocusState FocusState { get; private set; }
+
+ public KEvent MessageEvent { get; private set; }
+
+ public AppletStateMgr()
+ {
+ Messages = new ConcurrentQueue<MessageInfo>();
+
+ MessageEvent = new KEvent();
+ }
+
+ public void SetFocus(bool IsFocused)
+ {
+ FocusState = IsFocused
+ ? FocusState.InFocus
+ : FocusState.OutOfFocus;
+
+ EnqueueMessage(MessageInfo.FocusStateChanged);
+ }
+
+ public void EnqueueMessage(MessageInfo Message)
+ {
+ Messages.Enqueue(Message);
+
+ MessageEvent.WaitEvent.Set();
+ }
+
+ public bool TryDequeueMessage(out MessageInfo Message)
+ {
+ if (Messages.Count < 2)
+ {
+ MessageEvent.WaitEvent.Reset();
+ }
+
+ return Messages.TryDequeue(out Message);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+
+ protected virtual void Dispose(bool Disposing)
+ {
+ if (Disposing)
+ {
+ MessageEvent.Dispose();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/SystemState/ColorSet.cs b/Ryujinx.HLE/HOS/SystemState/ColorSet.cs
new file mode 100644
index 00000000..4d7a7e2f
--- /dev/null
+++ b/Ryujinx.HLE/HOS/SystemState/ColorSet.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.SystemState
+{
+ public enum ColorSet
+ {
+ BasicWhite = 0,
+ BasicBlack = 1
+ }
+}
diff --git a/Ryujinx.HLE/HOS/SystemState/OpenCloseState.cs b/Ryujinx.HLE/HOS/SystemState/OpenCloseState.cs
new file mode 100644
index 00000000..a2678b5c
--- /dev/null
+++ b/Ryujinx.HLE/HOS/SystemState/OpenCloseState.cs
@@ -0,0 +1,8 @@
+namespace Ryujinx.HLE.HOS.SystemState
+{
+ public enum OpenCloseState
+ {
+ Closed,
+ Open
+ }
+}
diff --git a/Ryujinx.HLE/HOS/SystemState/SystemLanguage.cs b/Ryujinx.HLE/HOS/SystemState/SystemLanguage.cs
new file mode 100644
index 00000000..2046ed62
--- /dev/null
+++ b/Ryujinx.HLE/HOS/SystemState/SystemLanguage.cs
@@ -0,0 +1,23 @@
+namespace Ryujinx.HLE.HOS.SystemState
+{
+ public enum SystemLanguage
+ {
+ Japanese,
+ AmericanEnglish,
+ French,
+ German,
+ Italian,
+ Spanish,
+ Chinese,
+ Korean,
+ Dutch,
+ Portuguese,
+ Russian,
+ Taiwanese,
+ BritishEnglish,
+ CanadianFrench,
+ LatinAmericanSpanish,
+ SimplifiedChinese,
+ TraditionalChinese
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs b/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs
new file mode 100644
index 00000000..bd1dbd78
--- /dev/null
+++ b/Ryujinx.HLE/HOS/SystemState/SystemStateMgr.cs
@@ -0,0 +1,145 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Ryujinx.HLE.HOS.SystemState
+{
+ public class SystemStateMgr
+ {
+ internal static string[] LanguageCodes = new string[]
+ {
+ "ja",
+ "en-US",
+ "fr",
+ "de",
+ "it",
+ "es",
+ "zh-CN",
+ "ko",
+ "nl",
+ "pt",
+ "ru",
+ "zh-TW",
+ "en-GB",
+ "fr-CA",
+ "es-419",
+ "zh-Hans",
+ "zh-Hant"
+ };
+
+ internal static string[] AudioOutputs = new string[]
+ {
+ "AudioTvOutput",
+ "AudioStereoJackOutput",
+ "AudioBuiltInSpeakerOutput"
+ };
+
+ internal long DesiredLanguageCode { get; private set; }
+
+ internal string ActiveAudioOutput { get; private set; }
+
+ public bool DockedMode { get; set; }
+
+ public ColorSet ThemeColor { get; set; }
+
+ private ConcurrentDictionary<string, UserProfile> Profiles;
+
+ internal UserProfile LastOpenUser { get; private set; }
+
+ public SystemStateMgr()
+ {
+ SetLanguage(SystemLanguage.AmericanEnglish);
+
+ SetAudioOutputAsBuiltInSpeaker();
+
+ Profiles = new ConcurrentDictionary<string, UserProfile>();
+
+ UserId DefaultUuid = new UserId("00000000000000000000000000000001");
+
+ AddUser(DefaultUuid, "Player");
+ OpenUser(DefaultUuid);
+ }
+
+ public void SetLanguage(SystemLanguage Language)
+ {
+ DesiredLanguageCode = GetLanguageCode((int)Language);
+ }
+
+ public void SetAudioOutputAsTv()
+ {
+ ActiveAudioOutput = AudioOutputs[0];
+ }
+
+ public void SetAudioOutputAsStereoJack()
+ {
+ ActiveAudioOutput = AudioOutputs[1];
+ }
+
+ public void SetAudioOutputAsBuiltInSpeaker()
+ {
+ ActiveAudioOutput = AudioOutputs[2];
+ }
+
+ public void AddUser(UserId Uuid, string Name)
+ {
+ UserProfile Profile = new UserProfile(Uuid, Name);
+
+ Profiles.AddOrUpdate(Uuid.UserIdHex, Profile, (Key, Old) => Profile);
+ }
+
+ public void OpenUser(UserId Uuid)
+ {
+ if (Profiles.TryGetValue(Uuid.UserIdHex, out UserProfile Profile))
+ {
+ (LastOpenUser = Profile).AccountState = OpenCloseState.Open;
+ }
+ }
+
+ public void CloseUser(UserId Uuid)
+ {
+ if (Profiles.TryGetValue(Uuid.UserIdHex, out UserProfile Profile))
+ {
+ Profile.AccountState = OpenCloseState.Closed;
+ }
+ }
+
+ public int GetUserCount()
+ {
+ return Profiles.Count;
+ }
+
+ internal bool TryGetUser(UserId Uuid, out UserProfile Profile)
+ {
+ return Profiles.TryGetValue(Uuid.UserIdHex, out Profile);
+ }
+
+ internal IEnumerable<UserProfile> GetAllUsers()
+ {
+ return Profiles.Values;
+ }
+
+ internal IEnumerable<UserProfile> GetOpenUsers()
+ {
+ return Profiles.Values.Where(x => x.AccountState == OpenCloseState.Open);
+ }
+
+ internal static long GetLanguageCode(int Index)
+ {
+ if ((uint)Index >= LanguageCodes.Length)
+ {
+ throw new ArgumentOutOfRangeException(nameof(Index));
+ }
+
+ long Code = 0;
+ int Shift = 0;
+
+ foreach (char Chr in LanguageCodes[Index])
+ {
+ Code |= (long)(byte)Chr << Shift++ * 8;
+ }
+
+ return Code;
+ }
+ }
+}
diff --git a/Ryujinx.HLE/HOS/SystemState/UserId.cs b/Ryujinx.HLE/HOS/SystemState/UserId.cs
new file mode 100644
index 00000000..1e7c53dd
--- /dev/null
+++ b/Ryujinx.HLE/HOS/SystemState/UserId.cs
@@ -0,0 +1,76 @@
+using Ryujinx.HLE.Utilities;
+using System;
+using System.IO;
+using System.Linq;
+
+namespace Ryujinx.HLE.HOS.SystemState
+{
+ public struct UserId
+ {
+ public string UserIdHex { get; private set; }
+
+ public byte[] Bytes { get; private set; }
+
+ public UserId(long Low, long High)
+ {
+ if ((Low | High) == 0)
+ {
+ throw new ArgumentException("Zero is not a valid user id!");
+ }
+
+ byte[] Bytes = new byte[16];
+
+ int Index = Bytes.Length;
+
+ void WriteBytes(long Value)
+ {
+ for (int Byte = 0; Byte < 8; Byte++)
+ {
+ Bytes[--Index] = (byte)(Value >> Byte * 8);
+ }
+ }
+
+ WriteBytes(Low);
+ WriteBytes(High);
+
+ UserIdHex = string.Empty;
+
+ foreach (byte Byte in Bytes)
+ {
+ UserIdHex += Byte.ToString("X2");
+ }
+
+ this.Bytes = Bytes;
+ }
+
+ public UserId(string UserIdHex)
+ {
+ if (UserIdHex == null || UserIdHex.Length != 32 || !UserIdHex.All("0123456789abcdefABCDEF".Contains))
+ {
+ throw new ArgumentException("Invalid user id!", nameof(UserIdHex));
+ }
+
+ if (UserIdHex == "00000000000000000000000000000000")
+ {
+ throw new ArgumentException("Zero is not a valid user id!", nameof(UserIdHex));
+ }
+
+ this.UserIdHex = UserIdHex.ToUpper();
+
+ Bytes = StringUtils.HexToBytes(UserIdHex);
+ }
+
+ internal void Write(BinaryWriter Writer)
+ {
+ for (int Index = Bytes.Length - 1; Index >= 0; Index--)
+ {
+ Writer.Write(Bytes[Index]);
+ }
+ }
+
+ public override string ToString()
+ {
+ return UserIdHex;
+ }
+ }
+} \ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/SystemState/UserProfile.cs b/Ryujinx.HLE/HOS/SystemState/UserProfile.cs
new file mode 100644
index 00000000..63852cdf
--- /dev/null
+++ b/Ryujinx.HLE/HOS/SystemState/UserProfile.cs
@@ -0,0 +1,36 @@
+using System;
+
+namespace Ryujinx.HLE.HOS.SystemState
+{
+ class UserProfile
+ {
+ private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+
+ public UserId Uuid { get; private set; }
+
+ public string Name { get; private set; }
+
+ public long LastModifiedTimestamp { get; private set; }
+
+ public OpenCloseState AccountState { get; set; }
+ public OpenCloseState OnlinePlayState { get; set; }
+
+ public UserProfile(UserId Uuid, string Name)
+ {
+ this.Uuid = Uuid;
+ this.Name = Name;
+
+ LastModifiedTimestamp = 0;
+
+ AccountState = OpenCloseState.Closed;
+ OnlinePlayState = OpenCloseState.Closed;
+
+ UpdateTimestamp();
+ }
+
+ private void UpdateTimestamp()
+ {
+ LastModifiedTimestamp = (long)(DateTime.Now - Epoch).TotalSeconds;
+ }
+ }
+}