Skip to content

Commit 60ae1e6

Browse files
committed
RtlTimeToTimeFields Impl
Fixes last save time. Don’t ask me about this code, it works. Signed-off-by: Isaac Marovitz <isaacryu@icloud.com>
1 parent e0cc8be commit 60ae1e6

1 file changed

Lines changed: 88 additions & 2 deletions

File tree

MarathonRecomp/kernel/imports.cpp

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1448,9 +1448,95 @@ void KeQuerySystemTime(be<uint64_t>* time)
14481448
*time = currentTime100ns;
14491449
}
14501450

1451-
void RtlTimeToTimeFields()
1451+
struct TIME_FIELDS {
1452+
be<uint16_t> Year;
1453+
be<uint16_t> Month;
1454+
be<uint16_t> Day;
1455+
be<uint16_t> Hour;
1456+
be<uint16_t> Minute;
1457+
be<uint16_t> Second;
1458+
be<uint16_t> Milliseconds;
1459+
be<uint16_t> Weekday;
1460+
};
1461+
1462+
void RtlTimeToTimeFields(const be<uint64_t>* time, TIME_FIELDS* timeFields)
14521463
{
1453-
LOG_UTILITY("!!! STUB !!!");
1464+
constexpr uint64_t TICKS_PER_MILLISECOND = 10000;
1465+
constexpr uint64_t TICKS_PER_SECOND = 10000000;
1466+
constexpr uint64_t TICKS_PER_MINUTE = 600000000;
1467+
constexpr uint64_t TICKS_PER_HOUR = 36000000000;
1468+
constexpr uint64_t TICKS_PER_DAY = 864000000000;
1469+
1470+
static const int DaysInMonth[2][12] = {
1471+
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // Non-leap
1472+
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // Leap
1473+
};
1474+
1475+
// Calculate total days since January 1, 1601
1476+
uint64_t days = *time / TICKS_PER_DAY;
1477+
uint64_t remainingTicks = *time % TICKS_PER_DAY;
1478+
1479+
timeFields->Hour = static_cast<uint16_t>(remainingTicks / TICKS_PER_HOUR);
1480+
remainingTicks %= TICKS_PER_HOUR;
1481+
1482+
timeFields->Minute = static_cast<uint16_t>(remainingTicks / TICKS_PER_MINUTE);
1483+
remainingTicks %= TICKS_PER_MINUTE;
1484+
1485+
timeFields->Second = static_cast<uint16_t>(remainingTicks / TICKS_PER_SECOND);
1486+
remainingTicks %= TICKS_PER_SECOND;
1487+
1488+
timeFields->Milliseconds = static_cast<uint16_t>(remainingTicks / TICKS_PER_MILLISECOND);
1489+
1490+
// Calculate day of week (January 1, 1601 was a Monday = 1)
1491+
timeFields->Weekday = static_cast<uint16_t>((days + 1) % 7);
1492+
1493+
// Calculate year
1494+
uint32_t year = 1601;
1495+
1496+
// Each 400-year cycle has 146097 days
1497+
uint32_t cycles400 = static_cast<uint32_t>(days / 146097);
1498+
days %= 146097;
1499+
year += cycles400 * 400;
1500+
1501+
// Handle 100-year cycles (24 leap years + 76 normal years = 36524 days)
1502+
// Except the 4th century which has 36525 days
1503+
uint32_t cycles100 = static_cast<uint32_t>(days / 36524);
1504+
if (cycles100 == 4) cycles100 = 3; // Last day of 400-year cycle
1505+
days -= cycles100 * 36524;
1506+
year += cycles100 * 100;
1507+
1508+
// Handle 4-year cycles (1 leap year + 3 normal years = 1461 days)
1509+
uint32_t cycles4 = static_cast<uint32_t>(days / 1461);
1510+
days %= 1461;
1511+
year += cycles4 * 4;
1512+
1513+
// Handle individual years within 4-year cycle
1514+
uint32_t yearInCycle = static_cast<uint32_t>(days / 365);
1515+
if (yearInCycle == 4) yearInCycle = 3; // Last day of leap cycle
1516+
days -= yearInCycle * 365;
1517+
if (yearInCycle > 0) {
1518+
// Account for leap days in previous years of this cycle
1519+
days -= (yearInCycle - 1) / 4;
1520+
}
1521+
year += yearInCycle;
1522+
1523+
timeFields->Year = static_cast<uint16_t>(year);
1524+
1525+
// Determine if current year is a leap year
1526+
bool isLeapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
1527+
1528+
// Calculate month and day
1529+
const int* monthDays = DaysInMonth[isLeapYear ? 1 : 0];
1530+
uint32_t dayOfYear = static_cast<uint32_t>(days) + 1; // Convert to 1-based
1531+
1532+
uint16_t month = 1;
1533+
while (dayOfYear > static_cast<uint32_t>(monthDays[month - 1])) {
1534+
dayOfYear -= monthDays[month - 1];
1535+
month++;
1536+
}
1537+
1538+
timeFields->Month = month;
1539+
timeFields->Day = static_cast<uint16_t>(dayOfYear);
14541540
}
14551541

14561542
void RtlFreeAnsiString()

0 commit comments

Comments
 (0)