aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremmauss <emmausssss@gmail.com>2018-08-15 21:53:23 +0300
committergdkchan <gab.dark.100@gmail.com>2018-08-15 15:53:23 -0300
commit76d95dee05e3c51c18e1799f54cc407e0f633b4e (patch)
tree805192d0c86b77a9f08443a89cc62eb7ff096eee
parent55374ebba0ed49bc4624e47cc971b1e63f644583 (diff)
Implement ITimeZone 201, 202 (#327)
* Implement ITimeZone 201, 202 * fix alignment * fix array count * fix mismatching datetime kind and timezone
-rw-r--r--Ryujinx.HLE/OsHle/Services/Time/ITimeZoneService.cs75
1 files changed, 74 insertions, 1 deletions
diff --git a/Ryujinx.HLE/OsHle/Services/Time/ITimeZoneService.cs b/Ryujinx.HLE/OsHle/Services/Time/ITimeZoneService.cs
index 38440eef..87ef02f9 100644
--- a/Ryujinx.HLE/OsHle/Services/Time/ITimeZoneService.cs
+++ b/Ryujinx.HLE/OsHle/Services/Time/ITimeZoneService.cs
@@ -26,7 +26,9 @@ namespace Ryujinx.HLE.OsHle.Services.Time
{ 3, LoadLocationNameList },
{ 4, LoadTimeZoneRule },
{ 100, ToCalendarTime },
- { 101, ToCalendarTimeWithMyRule }
+ { 101, ToCalendarTimeWithMyRule },
+ { 201, ToPosixTime },
+ { 202, ToPosixTimeWithMyRule }
};
}
@@ -190,5 +192,76 @@ namespace Ryujinx.HLE.OsHle.Services.Time
return ToCalendarTimeWithTz(Context, PosixTime, TimeZone);
}
+
+ public long ToPosixTime(ServiceCtx Context)
+ {
+ long BufferPosition = Context.Request.SendBuff[0].Position;
+ long BufferSize = Context.Request.SendBuff[0].Size;
+
+ ushort Year = Context.RequestData.ReadUInt16();
+ byte Month = Context.RequestData.ReadByte();
+ byte Day = Context.RequestData.ReadByte();
+ byte Hour = Context.RequestData.ReadByte();
+ byte Minute = Context.RequestData.ReadByte();
+ byte Second = Context.RequestData.ReadByte();
+
+ DateTime CalendarTime = new DateTime(Year, Month, Day, Hour, Minute, Second);
+
+ if (BufferSize != 0x4000)
+ {
+ Context.Ns.Log.PrintWarning(LogClass.ServiceTime, $"TimeZoneRule buffer size is 0x{BufferSize:x} (expected 0x4000)");
+ }
+
+ // TODO: Reverse the TZif2 conversion in PCV to make this match with real hardware.
+ byte[] TzData = Context.Memory.ReadBytes(BufferPosition, 0x24);
+ string TzID = Encoding.ASCII.GetString(TzData).TrimEnd('\0');
+
+ long ResultCode = 0;
+
+ // Check if the Time Zone exists, otherwise error out.
+ try
+ {
+ TimeZoneInfo Info = TimeZoneInfo.FindSystemTimeZoneById(TzID);
+
+ return ToPosixTimeWithTz(Context, CalendarTime, Info);
+ }
+ catch (TimeZoneNotFoundException e)
+ {
+ Context.Ns.Log.PrintWarning(LogClass.ServiceTime, $"Timezone not found for string: {TzID} (len: {TzID.Length})");
+ ResultCode = 0x7BA74;
+ }
+
+ return ResultCode;
+ }
+
+ public long ToPosixTimeWithMyRule(ServiceCtx Context)
+ {
+ ushort Year = Context.RequestData.ReadUInt16();
+ byte Month = Context.RequestData.ReadByte();
+ byte Day = Context.RequestData.ReadByte();
+ byte Hour = Context.RequestData.ReadByte();
+ byte Minute = Context.RequestData.ReadByte();
+ byte Second = Context.RequestData.ReadByte();
+
+ DateTime CalendarTime = new DateTime(Year, Month, Day, Hour, Minute, Second, DateTimeKind.Local);
+
+ return ToPosixTimeWithTz(Context, CalendarTime, TimeZone);
+ }
+
+ private long ToPosixTimeWithTz(ServiceCtx Context, DateTime CalendarTime, TimeZoneInfo Info)
+ {
+ DateTime CalenderTimeUTC = TimeZoneInfo.ConvertTimeToUtc(CalendarTime, Info);
+
+ long PosixTime = ((DateTimeOffset)CalenderTimeUTC).ToUnixTimeSeconds();
+
+ long Position = Context.Request.RecvListBuff[0].Position;
+ long Size = Context.Request.RecvListBuff[0].Size;
+
+ Context.Memory.WriteInt64(Position, PosixTime);
+
+ Context.ResponseData.Write(1);
+
+ return 0;
+ }
}
}