92 lines
3.3 KiB
C++
92 lines
3.3 KiB
C++
#include "Conversion.h"
|
|
#include "../Utility/Collection.hpp"
|
|
#include "Unicode.h"
|
|
#include <cstdlib>
|
|
#include <string>
|
|
|
|
namespace openloco::localisation
|
|
{
|
|
struct EncodingConvertEntry
|
|
{
|
|
utf32_t unicode;
|
|
uint8_t loco_code;
|
|
};
|
|
|
|
static const EncodingConvertEntry UnicodeToLocoTable[] = {
|
|
{ unicode_char::a_ogonek_uc, loco_char::a_ogonek_uc },
|
|
{ unicode_char::a_ogonek, loco_char::a_ogonek },
|
|
{ unicode_char::c_acute_uc, loco_char::c_acute_uc },
|
|
{ unicode_char::c_acute, loco_char::c_acute },
|
|
{ unicode_char::e_ogonek_uc, loco_char::e_ogonek_uc },
|
|
{ unicode_char::e_ogonek, loco_char::e_ogonek },
|
|
{ unicode_char::l_stroke_uc, loco_char::l_stroke_uc },
|
|
{ unicode_char::l_stroke, loco_char::l_stroke },
|
|
{ unicode_char::n_acute_uc, loco_char::n_acute_uc },
|
|
{ unicode_char::n_acute, loco_char::n_acute },
|
|
{ unicode_char::s_acute_uc, loco_char::s_acute_uc },
|
|
{ unicode_char::s_acute, loco_char::s_acute },
|
|
{ unicode_char::z_acute_uc, loco_char::z_acute_uc },
|
|
{ unicode_char::z_acute, loco_char::z_acute },
|
|
{ unicode_char::z_dot_uc, loco_char::z_dot_uc },
|
|
{ unicode_char::z_dot, loco_char::z_dot },
|
|
{ unicode_char::quote_open, loco_char::quote_open },
|
|
{ unicode_char::quote_close, loco_char::quote_close },
|
|
{ unicode_char::up, loco_char::up },
|
|
{ unicode_char::small_up, loco_char::small_up },
|
|
{ unicode_char::right, loco_char::right },
|
|
{ unicode_char::down, loco_char::down },
|
|
{ unicode_char::small_down, loco_char::small_down },
|
|
{ unicode_char::air, loco_char::air },
|
|
{ unicode_char::tick, loco_char::tick },
|
|
{ unicode_char::cross, loco_char::cross },
|
|
{ unicode_char::water, loco_char::water },
|
|
{ unicode_char::road, loco_char::road },
|
|
{ unicode_char::railway, loco_char::railway },
|
|
};
|
|
|
|
static int32_t searchCompare(const void* pKey, const void* pEntry)
|
|
{
|
|
utf32_t key = *((utf32_t*)pKey);
|
|
EncodingConvertEntry* entry = (EncodingConvertEntry*)pEntry;
|
|
if (key < entry->unicode)
|
|
return -1;
|
|
if (key > entry->unicode)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
utf32_t convertLocoToUnicode(uint8_t loco_code)
|
|
{
|
|
// We can't do a binary search here, as the table is sorted by Unicode point, not Loco's internal encoding.
|
|
for (const auto& entry : UnicodeToLocoTable)
|
|
{
|
|
if (entry.loco_code == loco_code)
|
|
return entry.unicode;
|
|
}
|
|
return loco_code;
|
|
}
|
|
|
|
uint8_t convertUnicodeToLoco(utf32_t unicode)
|
|
{
|
|
EncodingConvertEntry* entry = (EncodingConvertEntry*)std::bsearch(&unicode, UnicodeToLocoTable, utility::length(UnicodeToLocoTable), sizeof(EncodingConvertEntry), searchCompare);
|
|
if (entry != nullptr)
|
|
return entry->loco_code;
|
|
else if (unicode < 256)
|
|
return unicode;
|
|
else
|
|
return '?';
|
|
}
|
|
|
|
std::string convertUnicodeToLoco(std::string unicode_string)
|
|
{
|
|
std::string out;
|
|
uint8_t* input = (uint8_t*)unicode_string.c_str();
|
|
while (utf32_t unicode_point = readCodePoint(&input))
|
|
{
|
|
out += convertUnicodeToLoco(unicode_point);
|
|
}
|
|
|
|
return out;
|
|
}
|
|
}
|