366 lines
13 KiB
C++
366 lines
13 KiB
C++
![]() |
/////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// FILE : TextConversion.cpp
|
||
|
// PURPOSE : class to hold any text conversion functions for the game
|
||
|
// AUTHOR : Derek Payne
|
||
|
// STARTED : 17/03/2009
|
||
|
// Copyright (C) 1999-2009 Rockstar Games. All Rights Reserved.
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////////
|
||
|
#include "Text/TextConversion.h"
|
||
|
|
||
|
// framework
|
||
|
#include "fwlocalisation/languagePack.h"
|
||
|
#include "fwlocalisation/templateString.h"
|
||
|
|
||
|
// game
|
||
|
#include "Text/TextFormat.h"
|
||
|
#include "frontend/PauseMenu.h"
|
||
|
#include "Frontend/hud_colour.h"
|
||
|
|
||
|
TEXT_OPTIMISATIONS();
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// name: TextToHtml
|
||
|
//
|
||
|
// purpose: converts a char to html text using the parser & returns as char
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
char* CTextConversion::TextToHtml(const char *pInString, char *pOutString, s32 iMaxLength)
|
||
|
{
|
||
|
if (pInString)
|
||
|
{
|
||
|
bool bHtmlUsed = false;
|
||
|
Color32 colour = CHudColour::GetRGBA(HUD_COLOUR_WHITE); // Set default colour to our white hud colour, rather than a hard-coded white
|
||
|
|
||
|
CTextFormat::ParseToken(&pInString[0], &pOutString[0], true, &colour, 18, &bHtmlUsed, iMaxLength); // go through, find and replace colour tokens with HTML tags
|
||
|
}
|
||
|
|
||
|
return (pOutString);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
// name: StripHtml
|
||
|
//
|
||
|
// purpose: strips all text that is wrapped inside ~nrt~ out the text
|
||
|
//////////////////////////////////////////////////////////////////////////////
|
||
|
char* CTextConversion::StripNonRenderableText(char *Dest, const char *Src)
|
||
|
{
|
||
|
char *dest = Dest;
|
||
|
char *src = (char*)Src;
|
||
|
bool bInsideNrt = false;
|
||
|
s32 iSrcStringSize = fwTextUtil::GetByteCount(Src);
|
||
|
s32 iCharCount = 0;
|
||
|
|
||
|
#define SIZE_OF_NRT_TOKEN (5) // ~nrt~
|
||
|
char TokenTest[SIZE_OF_NRT_TOKEN];
|
||
|
|
||
|
while(Src && *src && iCharCount < iSrcStringSize)
|
||
|
{
|
||
|
TokenTest[0] = *(src+1);
|
||
|
TokenTest[1] = *(src+2);
|
||
|
TokenTest[2] = *(src+3);
|
||
|
TokenTest[3] = '\0';
|
||
|
|
||
|
if (TokenTest[0] == FONT_CHAR_TOKEN_NON_RENDERABLE_TEXT[0] && TokenTest[1] == FONT_CHAR_TOKEN_NON_RENDERABLE_TEXT[1] && TokenTest[2] == FONT_CHAR_TOKEN_NON_RENDERABLE_TEXT[2])
|
||
|
{
|
||
|
bInsideNrt = !bInsideNrt;
|
||
|
|
||
|
src += SIZE_OF_NRT_TOKEN;
|
||
|
iCharCount += SIZE_OF_NRT_TOKEN;
|
||
|
}
|
||
|
|
||
|
if (!bInsideNrt)
|
||
|
{
|
||
|
*(dest++) = *src;
|
||
|
iCharCount ++;
|
||
|
}
|
||
|
|
||
|
src++;
|
||
|
}
|
||
|
|
||
|
*dest = rage::TEXT_CHAR_TERMINATOR;
|
||
|
|
||
|
return(Dest);
|
||
|
}
|
||
|
|
||
|
//////////////////////////////////////////////////////////////////////////
|
||
|
void CTextConversion::FormatIntForHumans(s64 iValue, char* pOutValue, int iLength, const char* const pszPrefix /* = "%s" */, bool bAddCurrencyDeliminator)
|
||
|
{
|
||
|
char const * const currencyDelimiter = ","; //CLocalisation::GetCurrentLanguageCurrencyDelimiter();
|
||
|
|
||
|
// handle negative numbers
|
||
|
bool bIsNegative = iValue < 0;
|
||
|
if(bIsNegative)
|
||
|
iValue *= -1;
|
||
|
|
||
|
s64 remainder = iValue % 1000;
|
||
|
char tempStr[64] = "";
|
||
|
pOutValue[0] = '\0';
|
||
|
|
||
|
const char* pAdjPrefix = pszPrefix;
|
||
|
char pTempPrefix[10] = {0};
|
||
|
if(bIsNegative)
|
||
|
{
|
||
|
pTempPrefix[0] = '-';
|
||
|
strncpy(pTempPrefix + 1, pszPrefix, 9);
|
||
|
pAdjPrefix = pTempPrefix;
|
||
|
}
|
||
|
|
||
|
if (bAddCurrencyDeliminator)
|
||
|
{
|
||
|
if(iValue < 1000)
|
||
|
{
|
||
|
formatf(tempStr, iLength, "%" I64FMT "d", remainder);
|
||
|
formatf(pOutValue, iLength, pAdjPrefix, tempStr);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
formatf(tempStr, iLength, "%03" I64FMT "d", remainder);
|
||
|
|
||
|
iValue /= 1000;
|
||
|
|
||
|
while(iValue > 0)
|
||
|
{
|
||
|
remainder = iValue % 1000;
|
||
|
if(iValue < 1000)
|
||
|
{
|
||
|
formatf(pOutValue, iLength, "%" I64FMT "d%s%s", remainder, currencyDelimiter, tempStr);
|
||
|
formatf(tempStr, iLength, "%s", pOutValue);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
formatf(pOutValue, iLength, "%03" I64FMT "d%s%s", remainder, currencyDelimiter, tempStr);
|
||
|
formatf(tempStr, iLength, "%s", pOutValue);
|
||
|
}
|
||
|
iValue /= 1000;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
formatf(tempStr, iLength, ("%" I64FMT "d"), iValue);
|
||
|
}
|
||
|
|
||
|
formatf(pOutValue, iLength, pAdjPrefix, tempStr);
|
||
|
}
|
||
|
|
||
|
void CTextConversion::FormatMsTimeAsString( char * out_buffer, size_t const bufferSize, u32 const timeMs, bool roundMs )
|
||
|
{
|
||
|
if( Verifyf( out_buffer, "CTextConversion::FormatMsTimeAsString - NULL destination buffer" ) &&
|
||
|
Verifyf( bufferSize > 0, "CTextConversion::FormatMsTimeAsString - Invalid buffer size" ) )
|
||
|
{
|
||
|
u32 const c_timeMilliseconds = timeMs;
|
||
|
u32 const c_timeMillisecondsPart = ( c_timeMilliseconds % 1000 ) / (roundMs ? 10 : 1);
|
||
|
u32 const c_timeSecondsPart = ( c_timeMilliseconds / 1000 ) % 60;
|
||
|
u32 const c_timeMinutesPart = ( c_timeMilliseconds / 1000 ) / 60;
|
||
|
|
||
|
char const * const c_formatString = roundMs ? "%02u:%02u.%02u" : "%02u:%02u.%03u";
|
||
|
formatf( out_buffer, bufferSize, c_formatString, c_timeMinutesPart, c_timeSecondsPart, c_timeMillisecondsPart );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CTextConversion::FormatMsTimeAsLongString( char * out_buffer, size_t const bufferSize, u32 const timeMs )
|
||
|
{
|
||
|
if( Verifyf( out_buffer, "CTextConversion::FormatMsTimeAsLongString - NULL destination buffer" ) &&
|
||
|
Verifyf( bufferSize > 0, "CTextConversion::FormatMsTimeAsLongString - Invalid buffer size" ) )
|
||
|
{
|
||
|
int offset = 0;
|
||
|
|
||
|
u32 const c_seconds = ( timeMs / 1000 );
|
||
|
u32 const c_secondsPart = c_seconds % 60;
|
||
|
|
||
|
u32 const c_minutes = c_seconds / 60;
|
||
|
u32 const c_minutesPart = c_minutes % 60;
|
||
|
|
||
|
u32 const c_hoursPart = c_minutes / 60;
|
||
|
|
||
|
if( c_hoursPart > 0 )
|
||
|
{
|
||
|
offset = formatf_n( out_buffer, bufferSize,
|
||
|
"%u %s", c_hoursPart, TheText.Get( c_hoursPart == 1 ? "TIMER_HOUR_L" : "TIMER_HOUR_LPL") );
|
||
|
}
|
||
|
|
||
|
if( c_minutesPart > 0 )
|
||
|
{
|
||
|
offset += formatf_n( out_buffer + offset, bufferSize - offset,
|
||
|
"%s%u %s", c_hoursPart > 0 ? " " : "",
|
||
|
c_minutesPart, TheText.Get( c_minutesPart == 1 ? "TIMER_MINUTE_L" : "TIMER_MINUTE_LPL" ) );
|
||
|
}
|
||
|
|
||
|
if( c_secondsPart > 0 )
|
||
|
{
|
||
|
formatf_n( out_buffer + offset, bufferSize - offset,
|
||
|
"%s%u %s", (c_minutesPart > 0 || c_hoursPart > 0) ? " " : "",
|
||
|
c_secondsPart, TheText.Get( c_secondsPart == 1 ? "TIMER_SEC_L" : "TIMER_SEC_LPL" ) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CTextConversion::ConvertFileTimeToLongString( char* out_buffer, size_t const bufferSize, u64 const fileTime )
|
||
|
{
|
||
|
fiDevice::SystemTime sysTime;
|
||
|
fiDevice::ConvertFileTimeToSystemTime( fileTime , sysTime );
|
||
|
ConvertSystemTimeToLongString( out_buffer, bufferSize, sysTime );
|
||
|
}
|
||
|
|
||
|
void CTextConversion::ConvertSystemTimeToLongString( char* out_buffer, size_t const bufferSize, fiDevice::SystemTime const & sysTime )
|
||
|
{
|
||
|
if( uiVerifyf( out_buffer && bufferSize > 0, "CTextConversion::ConvertSystemTimeToLongString - Invalid buffer!" ) )
|
||
|
{
|
||
|
sysLanguage const c_currentLanguage = (sysLanguage)CPauseMenu::GetMenuPreference( PREF_CURRENT_LANGUAGE );
|
||
|
|
||
|
char const * const c_dateDelimiter = fwLanguagePack::GetDateFormatDelimiter( c_currentLanguage );
|
||
|
|
||
|
fwLanguagePack::DATE_FORMAT const c_dateFormat = fwLanguagePack::GetDateFormatType( c_currentLanguage );
|
||
|
|
||
|
u32 const c_firstItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? sysTime.wDay :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? sysTime.wMonth : sysTime.wYear;
|
||
|
|
||
|
u32 const c_secondItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? sysTime.wMonth :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? sysTime.wDay : sysTime.wMonth;
|
||
|
|
||
|
u32 const c_thirdItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? sysTime.wYear :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? sysTime.wYear : sysTime.wDay;
|
||
|
|
||
|
formatf_n( out_buffer, bufferSize, "%u%s%u%s%02u - %02u:%02u",
|
||
|
|
||
|
c_firstItem,
|
||
|
c_dateDelimiter,
|
||
|
c_secondItem,
|
||
|
c_dateDelimiter,
|
||
|
c_thirdItem,
|
||
|
|
||
|
sysTime.wHour, sysTime.wMinute );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CTextConversion::ConvertFileTimeToString( char* out_buffer, size_t const bufferSize, bool const shorthandMonth, bool const shorthandDay, u64 const fileTime )
|
||
|
{
|
||
|
fiDevice::SystemTime sysTime;
|
||
|
fiDevice::ConvertFileTimeToSystemTime( fileTime , sysTime );
|
||
|
ConvertSystemTimeToString( out_buffer, bufferSize, shorthandMonth, shorthandDay, sysTime );
|
||
|
}
|
||
|
|
||
|
void CTextConversion::ConvertSystemTimeToString( char* out_buffer, size_t const bufferSize, bool const shorthandMonth, bool const shorthandDay,
|
||
|
fiDevice::SystemTime const & sysTime )
|
||
|
{
|
||
|
if( uiVerifyf( out_buffer && bufferSize > 0, "CTextConversion::ConvertSystemTimeToString - Invalid buffer!" ) )
|
||
|
{
|
||
|
sysLanguage const c_currentLanguage = (sysLanguage)CPauseMenu::GetMenuPreference( PREF_CURRENT_LANGUAGE );
|
||
|
char const * const c_dateDelimiter = fwLanguagePack::GetDateFormatDelimiter( c_currentLanguage );
|
||
|
|
||
|
fwLanguagePack::DATE_FORMAT const c_dateFormat = fwLanguagePack::GetDateFormatType( c_currentLanguage );
|
||
|
|
||
|
LocalizationKey c_monthLngKey;
|
||
|
fwLanguagePack::GetMonthString( c_monthLngKey.getBufferRef(), sysTime.wMonth, shorthandMonth, false );
|
||
|
|
||
|
LocalizationKey c_dayLngKey;
|
||
|
fwLanguagePack::GetDayString( c_monthLngKey.getBufferRef(), sysTime.wDayOfWeek, shorthandDay );
|
||
|
|
||
|
SimpleString_16 c_yearString;
|
||
|
c_yearString.sprintf( "%02u", sysTime.wYear );
|
||
|
|
||
|
char const * const c_firstItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? TheText.Get( c_dayLngKey.getBuffer() ) :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? TheText.Get( c_monthLngKey.getBuffer() ) : c_yearString.getBuffer();
|
||
|
|
||
|
char const * const c_secondItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? TheText.Get( c_monthLngKey.getBuffer() ) :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? TheText.Get( c_dayLngKey.getBuffer() ) : TheText.Get( c_monthLngKey.getBuffer() );
|
||
|
|
||
|
char const * const c_thirdItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? c_yearString.getBuffer() :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? c_yearString.getBuffer() : TheText.Get( c_dayLngKey.getBuffer() );
|
||
|
|
||
|
formatf_n( out_buffer, bufferSize, "%s%s%s%s%s",
|
||
|
|
||
|
c_firstItem,
|
||
|
c_dateDelimiter,
|
||
|
c_secondItem,
|
||
|
c_dateDelimiter,
|
||
|
c_thirdItem );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CTextConversion::ConvertFileTimeToFileNameString( char* out_buffer, size_t const bufferSize, u64 const fileTime )
|
||
|
{
|
||
|
fiDevice::SystemTime sysTime;
|
||
|
fiDevice::ConvertFileTimeToSystemTime( fileTime , sysTime );
|
||
|
ConvertSystemTimeToFileNameString( out_buffer, bufferSize, sysTime );
|
||
|
}
|
||
|
|
||
|
void CTextConversion::ConvertSystemTimeToFileNameString( char* out_buffer, size_t const bufferSize, fiDevice::SystemTime const & sysTime )
|
||
|
{
|
||
|
if( uiVerifyf( out_buffer && bufferSize > 0, "CTextConversion::ConvertSystemTimeToFileNameString - Invalid buffer!" ) )
|
||
|
{
|
||
|
sysLanguage const c_currentLanguage = (sysLanguage)CPauseMenu::GetMenuPreference( PREF_CURRENT_LANGUAGE );
|
||
|
fwLanguagePack::DATE_FORMAT const c_dateFormat = fwLanguagePack::GetDateFormatType( c_currentLanguage );
|
||
|
|
||
|
LocalizationKey c_monthLngKey;
|
||
|
fwLanguagePack::GetMonthString( c_monthLngKey.getBufferRef(), sysTime.wMonth, true, false );
|
||
|
|
||
|
SimpleString_16 c_dayString;
|
||
|
c_dayString.sprintf( "%u", sysTime.wDay );
|
||
|
SimpleString_16 c_yearString;
|
||
|
c_yearString.sprintf( "%02u", sysTime.wYear );
|
||
|
|
||
|
char const * const c_firstItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? c_dayString.getBuffer() :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? TheText.Get( c_monthLngKey.getBuffer() ) : c_yearString.getBuffer();
|
||
|
|
||
|
char const * const c_secondItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? TheText.Get( c_monthLngKey.getBuffer() ) :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? c_dayString.getBuffer() : TheText.Get( c_monthLngKey.getBuffer() );
|
||
|
|
||
|
char const * const c_thirdItem = c_dateFormat == fwLanguagePack::DATE_FORMAT_DMY ? c_yearString.getBuffer() :
|
||
|
c_dateFormat == fwLanguagePack::DATE_FORMAT_MDY ? c_yearString.getBuffer() : c_dayString.getBuffer();
|
||
|
|
||
|
formatf_n( out_buffer, bufferSize, "%s-%s-%s",
|
||
|
|
||
|
c_firstItem,
|
||
|
c_secondItem,
|
||
|
c_thirdItem );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
size_t CTextConversion::ConvertToWideChar( const char* szString, wchar_t* wszString, size_t length )
|
||
|
{
|
||
|
size_t returnSize = 0;
|
||
|
|
||
|
if( uiVerifyf( szString, "CTextConversion::ConvertToWideChar - Null source string!" )
|
||
|
&& uiVerifyf( wszString && length > 0, "CMontage::CTextConversion::ConvertToWideChar - Null buffer!" ) )
|
||
|
{
|
||
|
size_t lengthString = strlen(szString);
|
||
|
|
||
|
if( uiVerifyf( lengthString < length, "CMontage::GetNameW - Invalid buffer size %" SIZETFMT "u, needs %" SIZETFMT "u",
|
||
|
length, lengthString + 1 ) )
|
||
|
{
|
||
|
|
||
|
#if defined(__RUSSIAN_BUILD) && __RUSSIAN_BUILD
|
||
|
char szRussianName[RAGE_MAX_PATH];
|
||
|
|
||
|
// convert to Russian 1251 code page.
|
||
|
CFont::ConvertToRussian(szString, szRussianName, RAGE_MAX_PATH);
|
||
|
|
||
|
memset(wszString, 0, length*sizeof(wchar_t));
|
||
|
MultiByteToWideChar(1251, MB_PRECOMPOSED, szRussianName, lengthString, wszString, length);
|
||
|
#else
|
||
|
/*TODO4FIVE
|
||
|
if (!CLocalisation::IsCurrentLanguageRussian())*/
|
||
|
{
|
||
|
::mbstowcs_s(&returnSize, wszString, length, szString, lengthString);
|
||
|
}
|
||
|
/*TODO4FIVE
|
||
|
else
|
||
|
{
|
||
|
char szRussianName[RAGE_MAX_PATH];
|
||
|
|
||
|
// convert to Russian 1251 code page.
|
||
|
CFont::ConvertToRussian(szString, szRussianName, RAGE_MAX_PATH);
|
||
|
|
||
|
memset(wszString, 0, length*sizeof(WCHAR));
|
||
|
MultiByteToWideChar(1251, MB_PRECOMPOSED, szRussianName, lengthString, wszString, length);
|
||
|
}*/
|
||
|
#endif // __RUSSIAN_BUILD
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return returnSize;
|
||
|
}
|