2016-03-27 11:49:47 +02:00
|
|
|
/*
|
|
|
|
===========================================================================
|
2025-01-08 21:07:13 +01:00
|
|
|
Copyright (C) 2025 the OpenMoHAA team
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
This file is part of OpenMoHAA source code.
|
|
|
|
|
|
|
|
OpenMoHAA source code is free software; you can redistribute it
|
|
|
|
and/or modify it under the terms of the GNU General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the License,
|
|
|
|
or (at your option) any later version.
|
|
|
|
|
|
|
|
OpenMoHAA source code is distributed in the hope that it will be
|
|
|
|
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with OpenMoHAA source code; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
===========================================================================
|
|
|
|
*/
|
|
|
|
|
|
|
|
// localization.cpp : Localization for different languages
|
|
|
|
|
2023-01-31 01:22:10 +01:00
|
|
|
#include "win_localization.h"
|
2023-01-30 00:23:47 +01:00
|
|
|
#include <tiki.h>
|
2016-03-27 11:49:47 +02:00
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
#define MAX_BUFFERS 6
|
2023-05-22 01:43:52 +02:00
|
|
|
#define MAX_LOCALIZATION_LENGTH 1024
|
|
|
|
|
2016-03-27 11:49:47 +02:00
|
|
|
cLocalization *g_localization;
|
2025-01-08 21:25:59 +01:00
|
|
|
static char global_buf[MAX_BUFFERS][MAX_LOCALIZATION_LENGTH];
|
|
|
|
static char szTemp[100];
|
|
|
|
static size_t buf_index = 0;
|
2016-03-27 11:49:47 +02:00
|
|
|
|
|
|
|
void Sys_InitLocalization()
|
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
g_localization = new cLocalization;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Sys_ShutLocalization()
|
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
delete g_localization;
|
|
|
|
g_localization = NULL;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
const char *Sys_LV_ConvertString(const char *var)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
//
|
|
|
|
// Since 2.0, don't localize messages from fgame.
|
|
|
|
// The client already localize messages it receives
|
|
|
|
//
|
|
|
|
return var;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
const char *Sys_LV_CL_ConvertString(const char *var)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
if (!g_localization) {
|
|
|
|
return var;
|
|
|
|
}
|
2024-11-12 23:00:47 +01:00
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
return g_localization->ConvertString(var);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
typedef char *charstar;
|
2025-01-08 21:25:59 +01:00
|
|
|
|
|
|
|
int compare_strings(const void *pe1, const void *pe2)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
const char *psz1 = (const char *)pe1;
|
|
|
|
const char *psz2 = (const char *)pe2;
|
|
|
|
return Q_stricmp(psz1, psz2);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cLocalization::cLocalization()
|
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
int i;
|
|
|
|
int iFileCount;
|
|
|
|
char **ppszFiles;
|
|
|
|
char szFilename[MAX_QPATH];
|
|
|
|
size_t iBasePos;
|
|
|
|
|
|
|
|
ppszFiles = FS_ListFilteredFiles("global", "txt", "localization*.txt", qfalse, &iFileCount, qtrue);
|
|
|
|
Q_strncpyz(szFilename, "global/", sizeof(szFilename));
|
|
|
|
memset(szFilename + 8, 0, sizeof(szFilename) - 8);
|
|
|
|
iBasePos = strlen(szFilename);
|
|
|
|
|
|
|
|
Com_Printf("-- Localization: I see %d localization files\n", iFileCount);
|
|
|
|
qsort(ppszFiles, iFileCount, sizeof(char *), compare_strings);
|
|
|
|
for (i = 0; i < iFileCount; i++) {
|
|
|
|
Q_strncpyz(szFilename + iBasePos, ppszFiles[i], sizeof(szFilename) - iBasePos);
|
|
|
|
Com_Printf("--- Localization: reading file %s\n", szFilename);
|
|
|
|
LoadFile(szFilename);
|
|
|
|
}
|
|
|
|
|
|
|
|
FS_FreeFileList(ppszFiles);
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
void cLocalization::LoadFile(const char *name)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
TikiScript tiki;
|
|
|
|
const char *token;
|
|
|
|
loc_entry_t new_entry;
|
|
|
|
const char *p, *p2;
|
|
|
|
size_t rl;
|
|
|
|
size_t ll;
|
2025-01-08 22:52:47 +01:00
|
|
|
size_t i;
|
2025-01-08 21:25:59 +01:00
|
|
|
|
|
|
|
Com_Printf("Loading Localization File %s\n", name);
|
|
|
|
|
|
|
|
if (!tiki.LoadFile(name, qtrue)) {
|
|
|
|
Com_Printf("--- Error: File Not Found\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (tiki.TokenAvailable(qtrue)) {
|
|
|
|
token = tiki.GetToken(qtrue);
|
|
|
|
|
|
|
|
if (!Q_stricmp(token, "{")) {
|
|
|
|
if (!tiki.TokenAvailable(qtrue)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
token = tiki.GetToken(qtrue);
|
|
|
|
new_entry.m_refName = token;
|
|
|
|
|
|
|
|
rl = strlen(token);
|
|
|
|
p = strstr(token, "&&&");
|
|
|
|
|
|
|
|
if (p) {
|
|
|
|
new_entry.m_r1_rep = p - token;
|
|
|
|
p2 = p + 3;
|
|
|
|
p = strstr(p2, "&&&");
|
|
|
|
|
|
|
|
if (p) {
|
|
|
|
new_entry.m_r2_rep = p - p2;
|
|
|
|
new_entry.m_r3_rep = strlen(p + 3);
|
|
|
|
} else {
|
|
|
|
new_entry.m_r2_rep = strlen(p2);
|
|
|
|
new_entry.m_r3_rep = -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
new_entry.m_r1_rep = rl;
|
|
|
|
new_entry.m_r2_rep = -1;
|
|
|
|
new_entry.m_r3_rep = -1;
|
|
|
|
new_entry.m_l1_rep = -1;
|
|
|
|
new_entry.m_l2_rep = -1;
|
|
|
|
new_entry.m_l3_rep = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!tiki.TokenAvailable(qtrue)) {
|
|
|
|
Com_Printf(
|
|
|
|
"--- Error: EOF Found without LocName. Last RefName was %s. (Misspelling/Unused)\n",
|
|
|
|
new_entry.m_refName.c_str()
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
token = tiki.GetToken(qtrue);
|
|
|
|
new_entry.m_locName = token;
|
|
|
|
|
|
|
|
ll = strlen(token);
|
|
|
|
p = strstr(token, "&&&");
|
|
|
|
|
|
|
|
if (p) {
|
|
|
|
new_entry.m_l1_rep = p - token;
|
|
|
|
p2 = p + 3;
|
|
|
|
p = strstr(p2, "&&&");
|
|
|
|
|
|
|
|
if (p) {
|
|
|
|
new_entry.m_l2_rep = p - p2;
|
|
|
|
new_entry.m_l3_rep = strlen(p + 3);
|
|
|
|
} else {
|
|
|
|
new_entry.m_l2_rep = strlen(p2);
|
|
|
|
new_entry.m_l3_rep = -1;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
new_entry.m_r1_rep = rl;
|
|
|
|
new_entry.m_r2_rep = -1;
|
|
|
|
new_entry.m_r3_rep = -1;
|
|
|
|
new_entry.m_l1_rep = ll;
|
|
|
|
new_entry.m_l2_rep = -1;
|
|
|
|
new_entry.m_l3_rep = -1;
|
|
|
|
}
|
|
|
|
|
2025-01-08 22:52:47 +01:00
|
|
|
for (i = 1; i <= m_entries.NumObjects(); i++) {
|
|
|
|
if (new_entry.m_refName == m_entries.ObjectAt(i).m_refName) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == m_entries.NumObjects() + 1) {
|
|
|
|
m_entries.AddObject(new_entry);
|
|
|
|
}
|
2025-01-08 21:25:59 +01:00
|
|
|
|
|
|
|
if (!tiki.TokenAvailable(qtrue)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
token = tiki.GetToken(qtrue);
|
|
|
|
|
|
|
|
if (Q_stricmp(token, "}")) {
|
|
|
|
Com_Printf(
|
|
|
|
"--- Error: Invalid Entry... RefName: %s\t\tLocName: %s Attempting to Recover.\n",
|
|
|
|
new_entry.m_refName.c_str(),
|
|
|
|
new_entry.m_locName.c_str()
|
|
|
|
);
|
|
|
|
do {
|
|
|
|
if (!tiki.TokenAvailable(qtrue)) {
|
|
|
|
Com_Printf("--- Error: EOF Found. Unable to Recover from Error. \n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
token = tiki.GetToken(qtrue);
|
|
|
|
} while (Q_stricmp(token, "}"));
|
|
|
|
|
|
|
|
Com_Printf("--- Warning: Recovered From Error, Data May have been lost.\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Com_Printf("Loaded %d localization entries\n", m_entries.NumObjects());
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
static int bjb_strnscmp(const char *a, const char *b, size_t n)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-08 22:52:47 +01:00
|
|
|
int i;
|
|
|
|
|
|
|
|
while (n > 0 && *a && *b) {
|
|
|
|
if (*a == *b) {
|
2025-01-08 21:25:59 +01:00
|
|
|
a++;
|
|
|
|
b++;
|
2025-01-08 22:52:47 +01:00
|
|
|
n--;
|
|
|
|
continue;
|
2025-01-08 21:25:59 +01:00
|
|
|
}
|
2025-01-08 22:52:47 +01:00
|
|
|
|
|
|
|
if (!isspace((unsigned char)*a) || !isspace((unsigned char)*b)) {
|
|
|
|
return *a - *b;
|
2025-01-08 21:25:59 +01:00
|
|
|
}
|
2025-01-08 22:52:47 +01:00
|
|
|
|
|
|
|
while (n > 0 && *a && isspace(*a)) {
|
|
|
|
a++;
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*b && isspace(*b)) {
|
|
|
|
b++;
|
2025-01-08 21:25:59 +01:00
|
|
|
}
|
|
|
|
}
|
2025-01-08 22:52:47 +01:00
|
|
|
|
|
|
|
while (n > 0 && *a && isspace(*a)) {
|
|
|
|
a++;
|
|
|
|
n--;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*b && isspace(*b)) {
|
|
|
|
b++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (n <= 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
return *a - *b;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
static void bjb_rebreak(const char *var, char *buf, size_t max)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-08 22:52:47 +01:00
|
|
|
#if 0
|
2025-01-08 21:25:59 +01:00
|
|
|
const char *nl;
|
|
|
|
char *rb, *rb1, *rb2;
|
|
|
|
|
|
|
|
nl = strchr(var, '\n');
|
|
|
|
if (!nl || nl >= &var[max]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
rb = &buf[nl - var];
|
|
|
|
rb1 = &buf[nl - var];
|
|
|
|
rb2 = &buf[nl - var];
|
|
|
|
|
|
|
|
if (strlen(buf) < nl - var) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (rb1 > var && !isspace(*rb1)) {
|
|
|
|
rb1--;
|
|
|
|
}
|
|
|
|
while (*rb2 && rb2 < &var[max] && !isspace(*rb2)) {
|
|
|
|
rb2++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rb1 < var) {
|
|
|
|
if (!*rb2 || !isspace(*rb2)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
goto _set_new_line;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*rb2 || !isspace(*rb1) || !isspace(*rb2)) {
|
|
|
|
if (rb1 >= var && isspace(*rb1)) {
|
|
|
|
*rb1 = '\n';
|
|
|
|
goto _new_line_set;
|
|
|
|
} else if (!*rb2 || !isspace(*rb2)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
goto _set_new_line;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rb - rb1 - 4 <= rb2 - rb) {
|
|
|
|
*rb1 = '\n';
|
|
|
|
goto _new_line_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
_set_new_line:
|
|
|
|
*rb2 = '\n';
|
|
|
|
_new_line_set:
|
|
|
|
nl = strchr(nl + 1, '\n');
|
|
|
|
if (!nl || nl >= &var[max]) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2025-01-08 22:52:47 +01:00
|
|
|
#endif
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
const char *cLocalization::ConvertString(const char *var)
|
2016-03-27 11:49:47 +02:00
|
|
|
{
|
2025-01-08 21:25:59 +01:00
|
|
|
size_t l;
|
|
|
|
intptr_t i, m, n, o;
|
|
|
|
intptr_t nArg1;
|
|
|
|
const char *pArg1, *pArg2;
|
|
|
|
const char *pRef;
|
|
|
|
const char *pVar;
|
|
|
|
const char *pAfter;
|
|
|
|
const char *pSrc;
|
|
|
|
intptr_t nAfter, nBefore;
|
|
|
|
intptr_t n1, n2;
|
|
|
|
loc_entry_t *entry;
|
|
|
|
str s1, s2;
|
|
|
|
|
2025-01-08 22:52:47 +01:00
|
|
|
if (!*var) {
|
|
|
|
return var;
|
|
|
|
}
|
|
|
|
|
2025-01-08 21:25:59 +01:00
|
|
|
l = strlen(var);
|
2025-01-08 22:52:47 +01:00
|
|
|
o = l;
|
2025-01-08 21:25:59 +01:00
|
|
|
|
2025-01-08 22:52:47 +01:00
|
|
|
while (o && var[o - 1] < ' ') {
|
|
|
|
o--;
|
2025-01-08 21:25:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
pRef = &var[o];
|
2025-01-08 22:52:47 +01:00
|
|
|
pVar = var;
|
2025-01-08 21:25:59 +01:00
|
|
|
m = l - o;
|
|
|
|
n = 0;
|
|
|
|
|
2025-01-08 22:52:47 +01:00
|
|
|
while (o && (unsigned char)*pVar < ' ') {
|
|
|
|
o--;
|
2025-01-08 21:25:59 +01:00
|
|
|
pVar++;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *buf = global_buf[(buf_index++) % MAX_BUFFERS];
|
|
|
|
for (i = 1; i <= m_entries.NumObjects(); i++) {
|
|
|
|
entry = &m_entries.ObjectAt(i);
|
|
|
|
|
|
|
|
if (entry->m_r2_rep < 0) {
|
|
|
|
if (entry->m_r1_rep != o || bjb_strnscmp(pVar, entry->m_refName.c_str(), o)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(m + n)) {
|
|
|
|
strncpy(buf, entry->m_locName, MAX_LOCALIZATION_LENGTH);
|
|
|
|
bjb_rebreak(var, buf, MAX_LOCALIZATION_LENGTH);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->m_l1_rep + m + n < MAX_LOCALIZATION_LENGTH) {
|
|
|
|
memcpy(buf, var, n);
|
|
|
|
memcpy(&buf[n], entry->m_locName.c_str(), entry->m_l1_rep);
|
|
|
|
memcpy(&buf[entry->m_l1_rep + n], pRef, m);
|
|
|
|
buf[entry->m_l1_rep + m + n] = 0;
|
|
|
|
bjb_rebreak(var, buf, entry->m_l1_rep);
|
|
|
|
return buf;
|
|
|
|
} else {
|
|
|
|
return var;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
nArg1 = entry->m_r1_rep + entry->m_r2_rep;
|
|
|
|
if (entry->m_r3_rep >= 0) {
|
|
|
|
nArg1 += entry->m_r3_rep;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nArg1 > o) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bjb_strnscmp(pVar, entry->m_refName.c_str(), entry->m_r1_rep)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pSrc = &pVar[entry->m_r1_rep];
|
|
|
|
|
|
|
|
if (entry->m_r3_rep >= 0) {
|
|
|
|
pAfter = &entry->m_refName[entry->m_r1_rep + 3];
|
|
|
|
|
|
|
|
if (entry->m_r2_rep > 100) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(szTemp, pAfter, entry->m_r2_rep);
|
|
|
|
szTemp[entry->m_r2_rep] = 0;
|
|
|
|
|
|
|
|
pArg1 = strstr(pSrc, szTemp);
|
|
|
|
|
|
|
|
if (!pArg1) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nAfter = pArg1 - pSrc;
|
|
|
|
pArg2 = &pArg1[entry->m_r2_rep];
|
|
|
|
|
|
|
|
if (entry->m_r3_rep > 0) {
|
|
|
|
if (strlen(pArg2) < entry->m_r3_rep) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bjb_strnscmp(&pVar[o - entry->m_r3_rep], &pAfter[entry->m_r2_rep + 3], entry->m_r3_rep)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nBefore = &pVar[o - entry->m_r3_rep] - pArg2;
|
|
|
|
} else {
|
|
|
|
nBefore = o - (pArg2 - pVar);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (entry->m_r2_rep > 0) {
|
|
|
|
if (bjb_strnscmp(&pVar[o - entry->m_r2_rep], &entry->m_refName[entry->m_r1_rep + 3], entry->m_r2_rep)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
nAfter = &pVar[o - entry->m_r2_rep] - pSrc;
|
|
|
|
} else {
|
|
|
|
nAfter = o - entry->m_r1_rep;
|
|
|
|
}
|
|
|
|
|
|
|
|
pArg2 = NULL;
|
|
|
|
nBefore = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
n1 = 0;
|
|
|
|
n2 = 0;
|
|
|
|
if (n > 0) {
|
|
|
|
if (n >= 1024) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
memcpy(buf, var, n);
|
|
|
|
n2 = n;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->m_l1_rep >= 0) {
|
|
|
|
if (entry->m_l1_rep + n2 >= 1024) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->m_l1_rep > 0) {
|
|
|
|
memcpy(&buf[n2], &entry->m_locName[0], entry->m_l1_rep);
|
|
|
|
}
|
|
|
|
|
|
|
|
n2 += entry->m_l1_rep;
|
|
|
|
n1 = entry->m_l1_rep + 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nAfter >= 0) {
|
|
|
|
if (nAfter + n2 >= 1024) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nAfter > 0) {
|
|
|
|
memcpy(&buf[n2], pSrc, nAfter);
|
|
|
|
}
|
|
|
|
|
|
|
|
n2 += nAfter;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->m_l2_rep >= 0) {
|
|
|
|
if (entry->m_l2_rep + n2 >= 1024) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->m_l2_rep > 0) {
|
|
|
|
memcpy(&buf[n2], &entry->m_locName[n1], entry->m_l2_rep);
|
|
|
|
}
|
|
|
|
|
|
|
|
n2 += entry->m_l2_rep;
|
|
|
|
n1 += entry->m_l2_rep + 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nBefore >= 0) {
|
|
|
|
if (nBefore + n2 >= 1024) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nBefore > 0) {
|
|
|
|
memcpy(&buf[n2], pArg2, nBefore);
|
|
|
|
}
|
|
|
|
|
|
|
|
n2 += nBefore;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->m_l3_rep >= 0) {
|
|
|
|
if (entry->m_l3_rep + n2 >= 1024) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (entry->m_l3_rep > 0) {
|
|
|
|
memcpy(&buf[n2], &entry->m_locName[n1], entry->m_l3_rep);
|
|
|
|
}
|
|
|
|
|
|
|
|
n2 += entry->m_l3_rep;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m <= 0 || m + n2 < 1024) {
|
|
|
|
if (m + n2 < 1024) {
|
|
|
|
memcpy(&buf[n2], pRef, m);
|
|
|
|
n2 += m;
|
|
|
|
}
|
|
|
|
|
|
|
|
buf[n2] = 0;
|
|
|
|
bjb_rebreak(var, buf, n2);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!developer->integer || !var[0] || !var[1]) {
|
|
|
|
return var;
|
|
|
|
}
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
while (var[i] < 0 || !isspace(var[i])) {
|
|
|
|
i++;
|
|
|
|
if (!var[i]) {
|
|
|
|
return var;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!missing.ObjectInList(var)) {
|
|
|
|
missing.AddUniqueObject(var);
|
|
|
|
Com_DPrintf("LOCALIZATION ERROR: '%s' does not have a localization entry\n", var);
|
|
|
|
}
|
|
|
|
|
|
|
|
return var;
|
2016-03-27 11:49:47 +02:00
|
|
|
}
|