mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-10 23:01:59 +00:00
- moved date code to its own file.
This commit is contained in:
parent
6336e0e168
commit
504f85e6d4
5 changed files with 249 additions and 208 deletions
|
@ -1104,6 +1104,7 @@ set (PCH_SOURCES
|
||||||
common/filesystem/resourcefile.cpp
|
common/filesystem/resourcefile.cpp
|
||||||
common/engine/cycler.cpp
|
common/engine/cycler.cpp
|
||||||
common/engine/d_event.cpp
|
common/engine/d_event.cpp
|
||||||
|
common/engine/date.cpp
|
||||||
common/engine/stats.cpp
|
common/engine/stats.cpp
|
||||||
common/engine/sc_man.cpp
|
common/engine/sc_man.cpp
|
||||||
common/engine/palettecontainer.cpp
|
common/engine/palettecontainer.cpp
|
||||||
|
|
248
src/common/engine/date.cpp
Normal file
248
src/common/engine/date.cpp
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
/*
|
||||||
|
** date.cpp
|
||||||
|
**
|
||||||
|
** VM exports for engine backend classes
|
||||||
|
**
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
** Redistribution and use in source and binary forms, with or without
|
||||||
|
** modification, are permitted provided that the following conditions
|
||||||
|
** are met:
|
||||||
|
**
|
||||||
|
** 1. Redistributions of source code must retain the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer.
|
||||||
|
** 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
** notice, this list of conditions and the following disclaimer in the
|
||||||
|
** documentation and/or other materials provided with the distribution.
|
||||||
|
** 3. The name of the author may not be used to endorse or promote products
|
||||||
|
** derived from this software without specific prior written permission.
|
||||||
|
**
|
||||||
|
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
**---------------------------------------------------------------------------
|
||||||
|
**
|
||||||
|
**
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include "c_dispatch.h"
|
||||||
|
#include "vm.h"
|
||||||
|
#include "zstring.h"
|
||||||
|
#include "printf.h"
|
||||||
|
|
||||||
|
time_t epochoffset = 0; // epoch start in seconds (0 = January 1st, 1970)
|
||||||
|
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// CCMD setdate
|
||||||
|
//
|
||||||
|
// Set the time to a specific value
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
UNSAFE_CCMD(setdate)
|
||||||
|
{
|
||||||
|
if (argv.argc() != 3)
|
||||||
|
{
|
||||||
|
Printf("setdate HH:MM:SS DD-MM-YYYY: Set the current date\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t today;
|
||||||
|
time(&today);
|
||||||
|
struct tm* timeinfo = localtime(&today);
|
||||||
|
if (timeinfo != nullptr)
|
||||||
|
{
|
||||||
|
auto clock = FString(argv[1]).Split(":");
|
||||||
|
auto date = FString(argv[2]).Split("-");
|
||||||
|
if(clock.Size() != 3 || date.Size() != 3)
|
||||||
|
{
|
||||||
|
Printf("setdate HH:MM:SS DD-MM-YYYY: Set the current date\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!clock[0].IsInt())
|
||||||
|
{
|
||||||
|
Printf("Invalid hour\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!clock[1].IsInt())
|
||||||
|
{
|
||||||
|
Printf("Invalid minutes\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!clock[2].IsInt())
|
||||||
|
{
|
||||||
|
Printf("Invalid seconds\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!date[0].IsInt())
|
||||||
|
{
|
||||||
|
Printf("Invalid day\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!date[1].IsInt())
|
||||||
|
{
|
||||||
|
Printf("Invalid month\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!date[2].IsInt())
|
||||||
|
{
|
||||||
|
Printf("Invalid year\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set Date
|
||||||
|
timeinfo->tm_hour = int( clock[0].ToLong() );
|
||||||
|
timeinfo->tm_min = int( clock[1].ToLong() );
|
||||||
|
timeinfo->tm_sec = int( clock[2].ToLong() );
|
||||||
|
timeinfo->tm_mday = int( date[0].ToLong() );
|
||||||
|
timeinfo->tm_mon = int( date[1].ToLong() - 1); // Month interally is 0 - 11
|
||||||
|
timeinfo->tm_year = int( date[2].ToLong() - 1900 ); // Year interally is 00 - 138
|
||||||
|
|
||||||
|
time_t newTime = mktime(timeinfo);
|
||||||
|
tm* t_old = localtime(&today);
|
||||||
|
time_t oldTime = mktime(t_old);
|
||||||
|
|
||||||
|
if (newTime == -1 || oldTime == -1)
|
||||||
|
{
|
||||||
|
Printf("Unable to set the date\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
epochoffset = newTime - oldTime;
|
||||||
|
|
||||||
|
// This deals with some inconsistent display behaviour for DST
|
||||||
|
// In this case, we want to emulate GCC's behaviour
|
||||||
|
today += epochoffset;
|
||||||
|
struct tm* t_new = localtime(&today);
|
||||||
|
if (t_new != nullptr)
|
||||||
|
{
|
||||||
|
char timeString[1024];
|
||||||
|
if (strftime(timeString, sizeof(timeString), "%H", t_new))
|
||||||
|
{
|
||||||
|
auto hour = FString(timeString).ToLong();
|
||||||
|
if (hour - clock[0].ToLong() == -1 || hour - clock[0].ToLong() == 23)
|
||||||
|
epochoffset += 3600;
|
||||||
|
else if (hour - clock[0].ToLong() == 1 || hour - clock[0].ToLong() == -23)
|
||||||
|
epochoffset -= 3600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Printf("Unable to set the date\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CCMD(getdate)
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
time(&now);
|
||||||
|
now += epochoffset;
|
||||||
|
struct tm* timeinfo = localtime(&now);
|
||||||
|
if (timeinfo != nullptr)
|
||||||
|
{
|
||||||
|
char timeString[1024];
|
||||||
|
if (strftime(timeString, sizeof(timeString), "%H:%M:%S %d-%m-%Y%n", timeinfo))
|
||||||
|
Printf("%s\n", timeString);
|
||||||
|
else
|
||||||
|
Printf("Error Retrieving Current Date\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Printf("Error Retrieving Current Date\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//=====================================================================================
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//=====================================================================================
|
||||||
|
|
||||||
|
extern time_t epochoffset;
|
||||||
|
|
||||||
|
static int GetEpochTime()
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
time(&now);
|
||||||
|
return now != (time_t)(-1) ? int(now + epochoffset) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Returns an empty string if the Strf tokens are valid, otherwise returns the problematic token
|
||||||
|
static FString CheckStrfString(FString timeForm)
|
||||||
|
{
|
||||||
|
// Valid Characters after %
|
||||||
|
const char validSingles[] = { 'a','A','b','B','c','C','d','D','e','F','g','G','h','H','I','j','m','M','n','p','r','R','S','t','T','u','U','V','w','W','x','X','y','Y','z','Z' };
|
||||||
|
|
||||||
|
timeForm.Substitute("%%", "%a"); //Prevent %% from causing tokenizing problems
|
||||||
|
timeForm = "a" + timeForm; //Prevent %* at the beginning from causing a false error from tokenizing
|
||||||
|
|
||||||
|
auto tokens = timeForm.Split("%");
|
||||||
|
for (auto t : tokens)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
// % at end
|
||||||
|
if (t.Len() == 0) return FString("%");
|
||||||
|
|
||||||
|
// Single Character
|
||||||
|
for (size_t i = 0; i < sizeof(validSingles) / sizeof(validSingles[0]); i++)
|
||||||
|
{
|
||||||
|
if (t[0] == validSingles[i])
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) continue;
|
||||||
|
return FString("%") + t[0];
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FormatTime(const FString& timeForm, int timeVal, FString* result)
|
||||||
|
{
|
||||||
|
FString error = CheckStrfString(timeForm);
|
||||||
|
if (!error.IsEmpty())
|
||||||
|
ThrowAbortException(X_FORMAT_ERROR, "'%s' is not a valid format specifier of SystemTime.Format()", error.GetChars());
|
||||||
|
|
||||||
|
time_t val = timeVal;
|
||||||
|
struct tm* timeinfo = localtime(&val);
|
||||||
|
if (timeinfo != nullptr)
|
||||||
|
{
|
||||||
|
char timeString[1024];
|
||||||
|
if (strftime(timeString, sizeof(timeString), timeForm, timeinfo))
|
||||||
|
*result = timeString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_SystemTime, Now, GetEpochTime)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
ACTION_RETURN_INT(GetEpochTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION_NATIVE(_SystemTime, Format, FormatTime)
|
||||||
|
{
|
||||||
|
PARAM_PROLOGUE;
|
||||||
|
PARAM_STRING(timeForm);
|
||||||
|
PARAM_INT(timeVal);
|
||||||
|
FString result;
|
||||||
|
FormatTime(timeForm, timeVal, &result);
|
||||||
|
ACTION_RETURN_STRING(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -573,134 +573,6 @@ CCMD (special)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==========================================================================
|
|
||||||
//
|
|
||||||
// CCMD setdate
|
|
||||||
//
|
|
||||||
// Set the time to a specific value
|
|
||||||
//
|
|
||||||
//==========================================================================
|
|
||||||
|
|
||||||
extern time_t epochoffset;
|
|
||||||
CCMD(setdate)
|
|
||||||
{
|
|
||||||
if (argv.argc() != 3)
|
|
||||||
{
|
|
||||||
Printf("setdate HH:MM:SS DD-MM-YYYY: Set the current date\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
time_t today;
|
|
||||||
time(&today);
|
|
||||||
struct tm* timeinfo = localtime(&today);
|
|
||||||
if (timeinfo != nullptr)
|
|
||||||
{
|
|
||||||
auto clock = FString(argv[1]).Split(":");
|
|
||||||
auto date = FString(argv[2]).Split("-");
|
|
||||||
if(clock.Size() != 3 || date.Size() != 3)
|
|
||||||
{
|
|
||||||
Printf("setdate HH:MM:SS DD-MM-YYYY: Set the current date\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!clock[0].IsInt())
|
|
||||||
{
|
|
||||||
Printf("Invalid hour\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!clock[1].IsInt())
|
|
||||||
{
|
|
||||||
Printf("Invalid minutes\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!clock[2].IsInt())
|
|
||||||
{
|
|
||||||
Printf("Invalid seconds\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!date[0].IsInt())
|
|
||||||
{
|
|
||||||
Printf("Invalid day\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!date[1].IsInt())
|
|
||||||
{
|
|
||||||
Printf("Invalid month\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!date[2].IsInt())
|
|
||||||
{
|
|
||||||
Printf("Invalid year\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set Date
|
|
||||||
timeinfo->tm_hour = int( clock[0].ToLong() );
|
|
||||||
timeinfo->tm_min = int( clock[1].ToLong() );
|
|
||||||
timeinfo->tm_sec = int( clock[2].ToLong() );
|
|
||||||
timeinfo->tm_mday = int( date[0].ToLong() );
|
|
||||||
timeinfo->tm_mon = int( date[1].ToLong() - 1); // Month interally is 0 - 11
|
|
||||||
timeinfo->tm_year = int( date[2].ToLong() - 1900 ); // Year interally is 00 - 138
|
|
||||||
|
|
||||||
time_t newTime = mktime(timeinfo);
|
|
||||||
tm* t_old = localtime(&today);
|
|
||||||
time_t oldTime = mktime(t_old);
|
|
||||||
|
|
||||||
if (newTime == -1 || oldTime == -1)
|
|
||||||
{
|
|
||||||
Printf("Unable to set the date\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
epochoffset = newTime - oldTime;
|
|
||||||
|
|
||||||
// This deals with some inconsistent display behaviour for DST
|
|
||||||
// In this case, we want to emulate GCC's behaviour
|
|
||||||
today += epochoffset;
|
|
||||||
struct tm* t_new = localtime(&today);
|
|
||||||
if (t_new != nullptr)
|
|
||||||
{
|
|
||||||
char timeString[1024];
|
|
||||||
if (strftime(timeString, sizeof(timeString), "%H", t_new))
|
|
||||||
{
|
|
||||||
auto hour = FString(timeString).ToLong();
|
|
||||||
if (hour - clock[0].ToLong() == -1 || hour - clock[0].ToLong() == 23)
|
|
||||||
epochoffset += 3600;
|
|
||||||
else if (hour - clock[0].ToLong() == 1 || hour - clock[0].ToLong() == -23)
|
|
||||||
epochoffset -= 3600;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Printf("Unable to set the date\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CCMD(getdate)
|
|
||||||
{
|
|
||||||
time_t now;
|
|
||||||
time(&now);
|
|
||||||
now += epochoffset;
|
|
||||||
struct tm* timeinfo = localtime(&now);
|
|
||||||
if (timeinfo != nullptr)
|
|
||||||
{
|
|
||||||
char timeString[1024];
|
|
||||||
if (strftime(timeString, sizeof(timeString), "%H:%M:%S %d-%m-%Y%n", timeinfo))
|
|
||||||
Printf("%s\n", timeString);
|
|
||||||
else
|
|
||||||
Printf("Error Retrieving Current Date\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Printf("Error Retrieving Current Date\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// CCMD warp
|
// CCMD warp
|
||||||
|
|
|
@ -161,8 +161,6 @@ bool playeringame[MAXPLAYERS];
|
||||||
|
|
||||||
int gametic;
|
int gametic;
|
||||||
|
|
||||||
time_t epochoffset = 0; // epoch start in seconds (0 = January 1st, 1970)
|
|
||||||
|
|
||||||
CVAR(Bool, demo_compress, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
CVAR(Bool, demo_compress, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||||
FString newdemoname;
|
FString newdemoname;
|
||||||
FString newdemomap;
|
FString newdemomap;
|
||||||
|
|
|
@ -2669,84 +2669,6 @@ DEFINE_ACTION_FUNCTION_NATIVE(FLevelLocals, setFrozen, setFrozen)
|
||||||
//
|
//
|
||||||
//=====================================================================================
|
//=====================================================================================
|
||||||
|
|
||||||
extern time_t epochoffset;
|
|
||||||
|
|
||||||
static int GetEpochTime()
|
|
||||||
{
|
|
||||||
time_t now;
|
|
||||||
time(&now);
|
|
||||||
return now != (time_t)(-1) ? int(now + epochoffset) : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Returns an empty string if the Strf tokens are valid, otherwise returns the problematic token
|
|
||||||
static FString CheckStrfString(FString timeForm)
|
|
||||||
{
|
|
||||||
// Valid Characters after %
|
|
||||||
const char validSingles[] = { 'a','A','b','B','c','C','d','D','e','F','g','G','h','H','I','j','m','M','n','p','r','R','S','t','T','u','U','V','w','W','x','X','y','Y','z','Z' };
|
|
||||||
|
|
||||||
timeForm.Substitute("%%", "%a"); //Prevent %% from causing tokenizing problems
|
|
||||||
timeForm = "a" + timeForm; //Prevent %* at the beginning from causing a false error from tokenizing
|
|
||||||
|
|
||||||
auto tokens = timeForm.Split("%");
|
|
||||||
for (auto t : tokens)
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
// % at end
|
|
||||||
if (t.Len() == 0) return FString("%");
|
|
||||||
|
|
||||||
// Single Character
|
|
||||||
for (size_t i = 0; i < sizeof(validSingles)/sizeof(validSingles[0]); i++)
|
|
||||||
{
|
|
||||||
if (t[0] == validSingles[i])
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (found) continue;
|
|
||||||
return FString("%") + t[0];
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FormatTime(const FString& timeForm, int timeVal, FString* result)
|
|
||||||
{
|
|
||||||
FString error = CheckStrfString(timeForm);
|
|
||||||
if (!error.IsEmpty())
|
|
||||||
ThrowAbortException(X_FORMAT_ERROR, "'%s' is not a valid format specifier of SystemTime.Format()", error.GetChars());
|
|
||||||
|
|
||||||
time_t val = timeVal;
|
|
||||||
struct tm* timeinfo = localtime(&val);
|
|
||||||
if (timeinfo != nullptr)
|
|
||||||
{
|
|
||||||
char timeString[1024];
|
|
||||||
if (strftime(timeString, sizeof(timeString), timeForm, timeinfo))
|
|
||||||
*result = timeString;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(_SystemTime, Now, GetEpochTime)
|
|
||||||
{
|
|
||||||
PARAM_PROLOGUE;
|
|
||||||
ACTION_RETURN_INT(GetEpochTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(_SystemTime, Format, FormatTime)
|
|
||||||
{
|
|
||||||
PARAM_PROLOGUE;
|
|
||||||
PARAM_STRING(timeForm);
|
|
||||||
PARAM_INT(timeVal);
|
|
||||||
FString result;
|
|
||||||
FormatTime(timeForm, timeVal, &result);
|
|
||||||
ACTION_RETURN_STRING(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
//=====================================================================================
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//
|
|
||||||
//=====================================================================================
|
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetLatency, Net_GetLatency)
|
DEFINE_ACTION_FUNCTION_NATIVE(_AltHUD, GetLatency, Net_GetLatency)
|
||||||
{
|
{
|
||||||
PARAM_PROLOGUE;
|
PARAM_PROLOGUE;
|
||||||
|
|
Loading…
Reference in a new issue