summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar lat9nq2023-05-26 04:40:04 -0400
committerGravatar lat9nq2023-06-05 15:15:11 -0400
commit8d52dc163a0034596722ce2a50cfd9e645929a05 (patch)
treebbe6d51abf93bb6cacbfabe69d5ed53f059f0780 /src/core
parenttz_content_manager: Try the system time zone first (diff)
downloadyuzu-8d52dc163a0034596722ce2a50cfd9e645929a05.tar.gz
yuzu-8d52dc163a0034596722ce2a50cfd9e645929a05.tar.xz
yuzu-8d52dc163a0034596722ce2a50cfd9e645929a05.zip
time_zone_manager: Implement go_ahead/go_back
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/service/time/time_zone_manager.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/core/hle/service/time/time_zone_manager.cpp b/src/core/hle/service/time/time_zone_manager.cpp
index 973f7837a..805ffb902 100644
--- a/src/core/hle/service/time/time_zone_manager.cpp
+++ b/src/core/hle/service/time/time_zone_manager.cpp
@@ -2,6 +2,7 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <climits> 4#include <climits>
5#include <limits>
5 6
6#include "common/assert.h" 7#include "common/assert.h"
7#include "common/logging/log.h" 8#include "common/logging/log.h"
@@ -9,6 +10,7 @@
9#include "core/file_sys/nca_metadata.h" 10#include "core/file_sys/nca_metadata.h"
10#include "core/file_sys/registered_cache.h" 11#include "core/file_sys/registered_cache.h"
11#include "core/hle/service/time/time_zone_manager.h" 12#include "core/hle/service/time/time_zone_manager.h"
13#include "core/hle/service/time/time_zone_types.h"
12 14
13namespace Service::Time::TimeZone { 15namespace Service::Time::TimeZone {
14 16
@@ -629,11 +631,47 @@ static bool ParseTimeZoneBinary(TimeZoneRule& time_zone_rule, FileSys::VirtualFi
629 UNIMPLEMENTED(); 631 UNIMPLEMENTED();
630 } 632 }
631 } 633 }
634
635 const auto typesequiv = [](TimeZoneRule& rule, int a, int b) -> bool {
636 if (a < 0 || a >= rule.type_count || b < 0 || b >= rule.type_count) {
637 return {};
638 }
639
640 const struct TimeTypeInfo* ap = &rule.ttis[a];
641 const struct TimeTypeInfo* bp = &rule.ttis[b];
642
643 return (ap->gmt_offset == bp->gmt_offset && ap->is_dst == bp->is_dst &&
644 (std::strcmp(&rule.chars[ap->abbreviation_list_index],
645 &rule.chars[bp->abbreviation_list_index]) == 0));
646 };
647
632 if (time_zone_rule.type_count == 0) { 648 if (time_zone_rule.type_count == 0) {
633 return {}; 649 return {};
634 } 650 }
635 if (time_zone_rule.time_count > 1) { 651 if (time_zone_rule.time_count > 1) {
636 UNIMPLEMENTED(); 652 if (time_zone_rule.ats[0] <= std::numeric_limits<s64>::max() - seconds_per_repeat) {
653 s64 repeatat = time_zone_rule.ats[0] + seconds_per_repeat;
654 int repeatattype = time_zone_rule.types[0];
655 for (int i = 1; i < time_zone_rule.time_count; ++i) {
656 if (time_zone_rule.ats[i] == repeatat &&
657 typesequiv(time_zone_rule, time_zone_rule.types[i], repeatattype)) {
658 time_zone_rule.go_back = true;
659 break;
660 }
661 }
662 }
663 if (std::numeric_limits<s64>::min() + seconds_per_repeat <=
664 time_zone_rule.ats[time_zone_rule.time_count - 1]) {
665 s64 repeatat = time_zone_rule.ats[time_zone_rule.time_count - 1] - seconds_per_repeat;
666 int repeatattype = time_zone_rule.types[time_zone_rule.time_count - 1];
667 for (int i = time_zone_rule.time_count; i >= 0; --i) {
668 if (time_zone_rule.ats[i] == repeatat &&
669 typesequiv(time_zone_rule, time_zone_rule.types[i], repeatattype)) {
670 time_zone_rule.go_ahead = true;
671 break;
672 }
673 }
674 }
637 } 675 }
638 676
639 s32 default_type{}; 677 s32 default_type{};