@@ -37,6 +37,8 @@ cdvdStruct cdvd;
3737
3838s64 PSXCLK = 36864000 ;
3939
40+ static constexpr s32 GMT9_OFFSET_SECONDS = 9 * 60 * 60 ; // 32400
41+
4042static constexpr u8 monthmap[13 ] = { 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 };
4143
4244static constexpr u8 cdvdParamLength[16 ] = { 0 , 0 , 0 , 0 , 0 , 4 , 11 , 11 , 11 , 1 , 255 , 255 , 7 , 2 , 11 , 1 };
@@ -920,69 +922,88 @@ void cdvdReset()
920922 cdvd.ReadTime = cdvdBlockReadTime (MODE_DVDROM);
921923 cdvd.RotSpeed = cdvdRotationTime (MODE_DVDROM);
922924
925+ ReadOSDConfigParames ();
926+
927+ // Print time zone offset, DST, date format, time format, and system time basis.
928+ DevCon.WriteLn (Color_StrongGreen, configParams1.timezoneOffset < 0 ? " Time Zone Offset: GMT%03d:%02d" : " Time Zone Offset: GMT+%02d:%02d" ,
929+ configParams1.timezoneOffset / 60 , std::abs (configParams1.timezoneOffset % 60 ));
930+ DevCon.WriteLn (Color_StrongGreen, " DST: %s Time" , configParams2.daylightSavings ? " Summer" : " Winter" );
931+ DevCon.WriteLn (Color_StrongGreen, " Time Format: %s-Hour" , configParams2.timeFormat ? " 12" : " 24" );
932+ DevCon.WriteLn (Color_StrongGreen, " Date Format: %s" , configParams2.dateFormat ? (configParams2.dateFormat == 2 ? " DD/MM/YYYY" : " MM/DD/YYYY" ) : " YYYY/MM/DD" );
933+ DevCon.WriteLn (Color_StrongGreen, " System Time Basis: %s" ,
934+ EmuConfig.ManuallySetRealTimeClock ? " Manual RTC" : g_InputRecording.isActive () ? " Default Input Recording Time" : " Operating System Time" );
935+
936+ std::tm input_tm{};
937+ std::tm resulting_tm{};
938+
939+ const int bios_settings_offset_seconds = 60 * (configParams1.timezoneOffset + configParams2.daylightSavings * 60 );
940+
941+ // CDVD internally uses GMT+9, 1-indexed months, and year offset of 2000 instead of 1900.
923942 if (EmuConfig.ManuallySetRealTimeClock )
924943 {
925- // Convert to GMT+9 (assumes GMT+0)
926- std::tm tm{};
927- tm.tm_sec = EmuConfig.RtcSecond ;
928- tm.tm_min = EmuConfig.RtcMinute ;
929- tm.tm_hour = EmuConfig.RtcHour ;
930- tm.tm_mday = EmuConfig.RtcDay ;
931- tm.tm_mon = EmuConfig.RtcMonth - 1 ;
932- tm.tm_year = EmuConfig.RtcYear + 100 ; // 2000 - 1900
933- tm.tm_isdst = 1 ;
934-
935- // Need this instead of mktime for timezone independence
936- std::time_t t = 0 ;
937- #if defined(_WIN32)
938- t = _mkgmtime (&tm) + 32400 ; // 60 * 60 * 9 for GMT+9
939- gmtime_s (&tm, &t);
940- #else
941- t = timegm (&tm) + 32400 ;
942- gmtime_r (&t, &tm);
943- #endif
944-
945- cdvd.RTC .second = tm.tm_sec ;
946- cdvd.RTC .minute = tm.tm_min ;
947- cdvd.RTC .hour = tm.tm_hour ;
948- cdvd.RTC .day = tm.tm_mday ;
949- cdvd.RTC .month = tm.tm_mon + 1 ;
950- cdvd.RTC .year = tm.tm_year - 100 ;
951- }
952- // If we are recording, always use the same RTC setting
953- // for games that use the RTC to seed their RNG -- this is very important to be the same everytime!
944+ resulting_tm.tm_sec = EmuConfig.RtcSecond ;
945+ resulting_tm.tm_min = EmuConfig.RtcMinute ;
946+ resulting_tm.tm_hour = EmuConfig.RtcHour ;
947+ resulting_tm.tm_mday = EmuConfig.RtcDay ;
948+ resulting_tm.tm_mon = EmuConfig.RtcMonth - 1 ;
949+ resulting_tm.tm_year = EmuConfig.RtcYear + 100 ;
950+ resulting_tm.tm_isdst = 0 ;
951+
952+ // Work backwards to input time by accounting for BIOS settings and GMT+9 defaultism.
953+ #if defined(_WIN32)
954+ const std::time_t input_time = _mkgmtime (&resulting_tm) + GMT9_OFFSET_SECONDS - bios_settings_offset_seconds;
955+ gmtime_s (&input_tm, &input_time);
956+ #else
957+ const std::time_t input_time = timegm (&resulting_tm) + GMT9_OFFSET_SECONDS - bios_settings_offset_seconds;
958+ gmtime_r (&input_time, &input_tm);
959+ #endif
960+ }
954961 else if (g_InputRecording.isActive ())
955962 {
956- Console.WriteLn (" Input Recording Active - Using Constant RTC of 04-03-2020 (DD-MM-YYYY)" );
957- // Why not just 0 everything? Some games apparently require the date to be valid in terms of when
958- // the PS2 / Game actually came out. (MGS3). So set it to a value well beyond any PS2 game's release date.
959- cdvd.RTC .second = 0 ;
960- cdvd.RTC .minute = 0 ;
961- cdvd.RTC .hour = 0 ;
962- cdvd.RTC .day = 4 ;
963- cdvd.RTC .month = 3 ;
964- cdvd.RTC .year = 20 ;
963+ // Legacy default value if manual RTC is off to preserve compat with old input recordings (RNG seeding).
964+ // Well beyond any PS2 game's release date because some games require a valid date in terms of when the PS2 / Game actually came out (MGS3).
965+ input_tm.tm_sec = 0 ;
966+ input_tm.tm_min = 0 ;
967+ input_tm.tm_hour = 0 ;
968+ input_tm.tm_mday = 4 ;
969+ input_tm.tm_mon = 2 ;
970+ input_tm.tm_year = 120 ;
971+ input_tm.tm_isdst = 0 ;
972+
973+ #if defined(_WIN32)
974+ const std::time_t resulting_time = _mkgmtime (&input_tm) - GMT9_OFFSET_SECONDS + bios_settings_offset_seconds;
975+ gmtime_s (&resulting_tm, &resulting_time);
976+ #else
977+ const std::time_t resulting_time = timegm (&input_tm) - GMT9_OFFSET_SECONDS + bios_settings_offset_seconds;
978+ gmtime_r (&resulting_time, &resulting_tm);
979+ #endif
965980 }
966981 else
967982 {
968- // CDVD internally uses GMT+9. If you think the time's wrong, you're wrong.
969- // Set up your time zone and winter/summer in the BIOS. No PS2 BIOS I know of features automatic DST.
970- const std::time_t utc_time = std::time (nullptr );
971- const std::time_t gmt9_time = (utc_time + 32400 ); // 60 * 60 * 9
972- struct tm curtime = {};
983+ // User must set time zone and winter/summer DST in the BIOS for correct time.
984+ const std::time_t input_time = std::time (nullptr ) + GMT9_OFFSET_SECONDS;
985+ const std::time_t resulting_time = input_time - GMT9_OFFSET_SECONDS + bios_settings_offset_seconds;
986+
973987#ifdef _MSC_VER
974- gmtime_s (&curtime, &gmt9_time);
988+ gmtime_s (&input_tm, &input_time);
989+ gmtime_s (&resulting_tm, &resulting_time);
975990#else
976- gmtime_r (&gmt9_time, &curtime);
991+ gmtime_r (&input_time, &input_tm);
992+ gmtime_r (&resulting_time, &resulting_tm);
977993#endif
978- cdvd.RTC .second = static_cast <u8 >(curtime.tm_sec );
979- cdvd.RTC .minute = static_cast <u8 >(curtime.tm_min );
980- cdvd.RTC .hour = static_cast <u8 >(curtime.tm_hour );
981- cdvd.RTC .day = static_cast <u8 >(curtime.tm_mday );
982- cdvd.RTC .month = static_cast <u8 >(curtime.tm_mon + 1 ); // WX returns Jan as "0"
983- cdvd.RTC .year = static_cast <u8 >(curtime.tm_year - 100 ); // offset from 2000
984994 }
985995
996+ cdvd.RTC .second = static_cast <u8 >(input_tm.tm_sec );
997+ cdvd.RTC .minute = static_cast <u8 >(input_tm.tm_min );
998+ cdvd.RTC .hour = static_cast <u8 >(input_tm.tm_hour );
999+ cdvd.RTC .day = static_cast <u8 >(input_tm.tm_mday );
1000+ cdvd.RTC .month = static_cast <u8 >(input_tm.tm_mon + 1 );
1001+ cdvd.RTC .year = static_cast <u8 >(input_tm.tm_year - 100 ); // offset from 2000
1002+
1003+ DevCon.WriteLn (Color_StrongGreen, " Resulting System Time: 20%02u-%02u-%02u %02u:%02u:%02u" ,
1004+ resulting_tm.tm_year - 100 , resulting_tm.tm_mon + 1 , resulting_tm.tm_mday ,
1005+ resulting_tm.tm_hour , resulting_tm.tm_min , resulting_tm.tm_sec );
1006+
9861007 cdvdCtrlTrayClose ();
9871008}
9881009
0 commit comments