#include "SDL_internal.h"
#ifdef SDL_TIME_N3DS
#include "../SDL_time_c.h"
#include <3ds.h>
#define DELTA_EPOCH_1900_OFFSET_MS 2208988800000LL
static void civil_from_days(int days, int *year, int *month, int *day)
{
days += 719468;
const int era = (days >= 0 ? days : days - 146096) / 146097;
const unsigned doe = (unsigned)(days - era * 146097); const unsigned yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365; const int y = (int)(yoe) + era * 400;
const unsigned doy = doe - (365 * yoe + yoe / 4 - yoe / 100); const unsigned mp = (5 * doy + 2) / 153; const unsigned d = doy - (153 * mp + 2) / 5 + 1; const unsigned m = mp < 10 ? mp + 3 : mp - 9;
*year = y + (m <= 2);
*month = (int)m;
*day = (int)d;
}
void SDL_GetSystemTimeLocalePreferences(SDL_DateFormat *df, SDL_TimeFormat *tf)
{
static const SDL_DateFormat LANG_TO_DATE_FORMAT[] = {
SDL_DATE_FORMAT_YYYYMMDD, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_YYYYMMDD, SDL_DATE_FORMAT_YYYYMMDD, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_DDMMYYYY, SDL_DATE_FORMAT_YYYYMMDD };
u8 system_language, is_north_america;
Result result, has_region;
if (R_FAILED(cfguInit())) {
return;
}
result = CFGU_GetSystemLanguage(&system_language);
has_region = CFGU_GetRegionCanadaUSA(&is_north_america);
cfguExit();
if (R_FAILED(result)) {
return;
}
if (df) {
*df = LANG_TO_DATE_FORMAT[system_language];
}
if (tf) {
*tf = SDL_TIME_FORMAT_24HR;
}
if (system_language == CFG_LANGUAGE_EN &&
R_SUCCEEDED(has_region) && is_north_america) {
if (df) {
*df = SDL_DATE_FORMAT_MMDDYYYY;
}
if (tf) {
*tf = SDL_TIME_FORMAT_12HR;
}
}
}
bool SDL_GetCurrentTime(SDL_Time *ticks)
{
CHECK_PARAM(!ticks) {
return SDL_InvalidParamError("ticks");
}
const Uint64 ndsTicksMax = (SDL_MAX_TIME / SDL_NS_PER_MS) + DELTA_EPOCH_1900_OFFSET_MS;
const Uint64 ndsTicks = SDL_min(osGetTime(), ndsTicksMax);
*ticks = SDL_MS_TO_NS(ndsTicks - DELTA_EPOCH_1900_OFFSET_MS);
return true;
}
bool SDL_TimeToDateTime(SDL_Time ticks, SDL_DateTime *dt, bool localTime)
{
CHECK_PARAM(!dt) {
return SDL_InvalidParamError("dt");
}
const int days = (int)(SDL_NS_TO_SECONDS(ticks) / SDL_SECONDS_PER_DAY);
civil_from_days(days, &dt->year, &dt->month, &dt->day);
int rem = (int)(SDL_NS_TO_SECONDS(ticks) - (days * SDL_SECONDS_PER_DAY));
dt->hour = rem / (60 * 60);
rem -= dt->hour * 60 * 60;
dt->minute = rem / 60;
rem -= dt->minute * 60;
dt->second = rem;
dt->nanosecond = ticks % SDL_NS_PER_SECOND;
dt->utc_offset = 0;
SDL_CivilToDays(dt->year, dt->month, dt->day, &dt->day_of_week, NULL);
return true;
}
#endif