mirror of
https://github.com/TerryCavanagh/VVVVVV.git
synced 2024-12-22 17:49:43 +01:00
Simplify time formatting functions
Here's my notes on all the existing functions and what kind of time formats they output: - Game::giventimestring(int hrs, int min, int sec) H:MM:SS MM:SS - Game::timestring() // uses game.hours/minutes/seconds H:MM:SS MM:SS - Game::partimestring() // uses game.timetrialpar (seconds) MM:SS - Game::resulttimestring() // uses game.timetrialresulttime (sec) + timetrialresultframes (1/30s) MM:SS.CC - Game::timetstring(int t) // t = seconds MM:SS - Game::timestringcenti(char* buffer, const size_t buffer_size) // uses game.hours/minutes/seconds/frames H:MM:SS.CC MM:SS.CC - UtilityClass::timestring(int t) // t = frames, 30 frames = 1 second S:CC M:SS:CC This is kind of a mess, and there's a lot of functions that do the same thing except using different variables. For localization, I also want translators to be able to localize all these time formats - many languages use the decimal comma instead of the decimal point (12:34,56) maybe some languages really prefer something like 1時02分11秒44瞬... Which I don't know to be correct, but it's good to be prepared for it and not restrict translators arbitrarily to only changing ":" and "." when we can start making the system better in the first place. I added a new function, UtilityClass::format_time. This is the place where all time formats come together, given the number of seconds and optionally frames. I have simplified the above-mentioned functions somewhat, but I haven't given them a complete refactor or renaming - I mainly made sure that they all use the same backend so I can make the formats consistent and properly localizable. (And before we start shoving more temporary char buffers everywhere just to get rid of the std::string's, maybe we need to think of a globally used working buffer of size SCREEN_WIDTH_CHARS+1, as a register of sorts, for when any line of text needs to be made or processed, then printed, and then goes unused. Maybe help.textrow, or something like that.) As for this commit, the available time formats are now more consistent and changed a little in some places. Leading zeroes for the first unit are now no longer included, time trial results and the Super Gravitron can now display hours when they went to 60 minutes before, and we now always use .CC instead of :CC. These are the formats: - H:MM:SS - H:MM:SS.CC - M:SS - M:SS.CC - S.CC (only used when always_minutes=false, for the Gravitrons) Here's what changes to the current functions: - Game::partimestring() is removed - it was used in two places, and could be replaced by game.timetstring(game.timetrialpar) - Game::giventimestring(h,m,s) and Game::timestring() are now wrappers for the other functions - The four remaining functions (Game::resulttimestring(), Game::timetstring(t), Game::timestringcenti(buffer, buffer_size) and UtilityClass::timestring(t)) are now wrappers for the "central function", UtilityClass::format_time. - UtilityClass::twodigits(int t) is now unused so it's also removed. - I also added int UtilityClass::hms_to_seconds(int h, int m, int s)
This commit is contained in:
parent
dd24343141
commit
3e36bfd56f
5 changed files with 56 additions and 93 deletions
|
@ -1412,7 +1412,7 @@ void Game::updatestate(void)
|
|||
obj.removetrigger(82);
|
||||
hascontrol = false;
|
||||
|
||||
timetrialresulttime = seconds + (minutes * 60) + (hours * 60 * 60);
|
||||
timetrialresulttime = help.hms_to_seconds(hours, minutes, seconds);
|
||||
timetrialresultframes = frames;
|
||||
timetrialresulttrinkets = trinkets();
|
||||
timetrialresultshinytarget = timetrialshinytarget;
|
||||
|
@ -2605,13 +2605,16 @@ void Game::updatestate(void)
|
|||
graphics.textboxcenterx();
|
||||
break;
|
||||
case 3502:
|
||||
{
|
||||
state++;
|
||||
statedelay = 45+15;
|
||||
|
||||
graphics.createtextboxflipme(" All Crew Members Rescued! ", -1, 64, 0, 0, 0);
|
||||
savetime = timestring();
|
||||
savetime += "." + help.twodigits(frames*100 / 30);
|
||||
char buffer[SCREEN_WIDTH_CHARS + 1];
|
||||
timestringcenti(buffer, sizeof(buffer));
|
||||
savetime = buffer;
|
||||
break;
|
||||
}
|
||||
case 3503:
|
||||
{
|
||||
state++;
|
||||
|
@ -5748,86 +5751,33 @@ void Game::gameclock(void)
|
|||
|
||||
std::string Game::giventimestring( int hrs, int min, int sec )
|
||||
{
|
||||
std::string tempstring = "";
|
||||
if (hrs > 0)
|
||||
{
|
||||
tempstring += help.String(hrs) + ":";
|
||||
}
|
||||
tempstring += help.twodigits(min) + ":" + help.twodigits(sec);
|
||||
return tempstring;
|
||||
return timetstring(help.hms_to_seconds(hrs, min, sec));
|
||||
}
|
||||
|
||||
std::string Game::timestring(void)
|
||||
{
|
||||
std::string tempstring = "";
|
||||
if (hours > 0)
|
||||
{
|
||||
tempstring += help.String(hours) + ":";
|
||||
}
|
||||
tempstring += help.twodigits(minutes) + ":" + help.twodigits(seconds);
|
||||
return tempstring;
|
||||
}
|
||||
|
||||
std::string Game::partimestring(void)
|
||||
{
|
||||
//given par time in seconds:
|
||||
std::string tempstring = "";
|
||||
if (timetrialpar >= 60)
|
||||
{
|
||||
tempstring = help.twodigits(timetrialpar / 60) + ":" + help.twodigits(timetrialpar % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempstring = "00:" + help.twodigits(timetrialpar);
|
||||
}
|
||||
return tempstring;
|
||||
return giventimestring(hours, minutes, seconds);
|
||||
}
|
||||
|
||||
std::string Game::resulttimestring(void)
|
||||
{
|
||||
//given result time in seconds:
|
||||
std::string tempstring = "";
|
||||
if (timetrialresulttime >= 60)
|
||||
{
|
||||
tempstring = help.twodigits(timetrialresulttime / 60) + ":"
|
||||
+ help.twodigits(timetrialresulttime % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempstring = "00:" + help.twodigits(timetrialresulttime);
|
||||
}
|
||||
tempstring += "." + help.twodigits(timetrialresultframes*100 / 30);
|
||||
return tempstring;
|
||||
char output[SCREEN_WIDTH_CHARS + 1];
|
||||
help.format_time(output, sizeof(output), timetrialresulttime, timetrialresultframes, true);
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string Game::timetstring( int t )
|
||||
{
|
||||
//given par time in seconds:
|
||||
std::string tempstring = "";
|
||||
if (t >= 60)
|
||||
{
|
||||
tempstring = help.twodigits(t / 60) + ":" + help.twodigits(t % 60);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempstring = "00:" + help.twodigits(t);
|
||||
}
|
||||
return tempstring;
|
||||
char output[SCREEN_WIDTH_CHARS + 1];
|
||||
help.format_time(output, sizeof(output), t, -1, true);
|
||||
return output;
|
||||
}
|
||||
|
||||
void Game::timestringcenti(char* buffer, const size_t buffer_size)
|
||||
{
|
||||
/* 16 chars should be plenty for int32s */
|
||||
char hours_str[16] = {'\0'};
|
||||
if (hours > 0)
|
||||
{
|
||||
SDL_snprintf(hours_str, sizeof(hours_str), "%i:", hours);
|
||||
}
|
||||
SDL_snprintf(
|
||||
buffer, buffer_size,
|
||||
"%s%02i:%02i.%02i",
|
||||
hours_str, minutes, seconds, frames * 100 / 30
|
||||
);
|
||||
help.format_time(buffer, buffer_size, help.hms_to_seconds(hours, minutes, seconds), frames, true);
|
||||
}
|
||||
|
||||
void Game::returnmenu(void)
|
||||
|
|
|
@ -139,8 +139,6 @@ public:
|
|||
|
||||
std::string timestring(void);
|
||||
|
||||
std::string partimestring(void);
|
||||
|
||||
std::string resulttimestring(void);
|
||||
|
||||
std::string timetstring(int t);
|
||||
|
|
|
@ -1708,7 +1708,7 @@ void gamerender(void)
|
|||
|
||||
if (graphics.fademode==0 && !game.intimetrial && !game.isingamecompletescreen() && (!game.swnmode || game.swngame != 1) && game.showingametimer)
|
||||
{
|
||||
char buffer[SCREEN_WIDTH_TILES + 1]; /* ASCII only */
|
||||
char buffer[SCREEN_WIDTH_CHARS + 1];
|
||||
graphics.bprint(6, 6, "TIME:", 255,255,255);
|
||||
game.timestringcenti(buffer, sizeof(buffer));
|
||||
graphics.bprint(46, 6, buffer, 196, 196, 196);
|
||||
|
@ -1918,7 +1918,7 @@ void gamerender(void)
|
|||
}
|
||||
else
|
||||
{
|
||||
char buffer[SCREEN_WIDTH_TILES + 1]; /* ASCII only */
|
||||
char buffer[SCREEN_WIDTH_CHARS + 1];
|
||||
game.timestringcenti(buffer, sizeof(buffer));
|
||||
|
||||
//Draw OSD stuff
|
||||
|
@ -1954,12 +1954,12 @@ void gamerender(void)
|
|||
if(game.timetrialparlost)
|
||||
{
|
||||
graphics.bprint(195, 214, "PAR TIME:", 80, 80, 80);
|
||||
graphics.bprint(275, 214, game.partimestring(), 80, 80, 80);
|
||||
graphics.bprint(275, 214, game.timetstring(game.timetrialpar), 80, 80, 80);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.bprint(195, 214, "PAR TIME:", 255, 255, 255);
|
||||
graphics.bprint(275, 214, game.partimestring(), 196, 196, 196);
|
||||
graphics.bprint(275, 214, game.timetstring(game.timetrialpar), 196, 196, 196);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <SDL.h>
|
||||
#include <sstream>
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Maths.h"
|
||||
|
||||
static const char* GCChar(const SDL_GameControllerButton button)
|
||||
|
@ -168,37 +169,49 @@ std::string UtilityClass::GCString(const std::vector<SDL_GameControllerButton>&
|
|||
return retval;
|
||||
}
|
||||
|
||||
std::string UtilityClass::twodigits( int t )
|
||||
int UtilityClass::hms_to_seconds(int h, int m, int s)
|
||||
{
|
||||
if (t < 10)
|
||||
return h*3600 + m*60 + s;
|
||||
}
|
||||
|
||||
void UtilityClass::format_time(char* buffer, const size_t buffer_size, int seconds, int frames, bool always_minutes)
|
||||
{
|
||||
int s = seconds % 60;
|
||||
int m = (seconds / 60) % 60;
|
||||
int h = seconds / 3600;
|
||||
|
||||
if (h > 0)
|
||||
{
|
||||
return "0" + String(t);
|
||||
/* H:MM:SS / H:MM:SS.CC */
|
||||
SDL_snprintf(buffer, buffer_size,
|
||||
frames == -1 ? "%d:%02d:%02d" : "%d:%02d:%02d.%02d",
|
||||
h, m, s, frames * 100 / 30
|
||||
);
|
||||
}
|
||||
if (t >= 100)
|
||||
else if (m > 0 || always_minutes || frames == -1)
|
||||
{
|
||||
return "??";
|
||||
/* M:SS / M:SS.CC */
|
||||
SDL_snprintf(buffer, buffer_size,
|
||||
frames == -1 ? "%d:%02d" : "%d:%02d.%02d",
|
||||
m, s, frames * 100 / 30
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* S.CC */
|
||||
SDL_snprintf(buffer, buffer_size,
|
||||
"%d.%02d",
|
||||
s, frames * 100 / 30
|
||||
);
|
||||
}
|
||||
return String(t);
|
||||
}
|
||||
|
||||
std::string UtilityClass::timestring( int t )
|
||||
{
|
||||
//given a time t in frames, return a time in seconds
|
||||
std::string tempstring = "";
|
||||
int temp = t / 30;
|
||||
if (temp < 60) //less than one minute
|
||||
{
|
||||
t = t % 30;
|
||||
tempstring = String(temp) + ":" + twodigits(t * 100 / 30);
|
||||
}
|
||||
else
|
||||
{
|
||||
int temp2 = temp / 60;
|
||||
temp = temp % 60;
|
||||
t = t % 30;
|
||||
tempstring = String(temp2) + ":" + twodigits(temp) + ":" + twodigits(t * 100 / 30);
|
||||
}
|
||||
return tempstring;
|
||||
char output[SCREEN_WIDTH_CHARS + 1];
|
||||
format_time(output, sizeof(output), t / 30, t % 30, false);
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string UtilityClass::number_words( int _t )
|
||||
|
|
|
@ -95,7 +95,9 @@ public:
|
|||
|
||||
static std::string GCString(const std::vector<SDL_GameControllerButton>& buttons);
|
||||
|
||||
std::string twodigits(int t);
|
||||
int hms_to_seconds(int h, int m, int s);
|
||||
|
||||
void format_time(char* buffer, const size_t buffer_size, int seconds, int frames, bool always_minutes);
|
||||
|
||||
std::string timestring(int t);
|
||||
|
||||
|
|
Loading…
Reference in a new issue