mirror of
https://github.com/yquake2/yquake2remaster.git
synced 2024-11-10 07:12:07 +00:00
game: Add remaster translation support
This commit is contained in:
parent
51d092660b
commit
1f0e67621c
11 changed files with 254 additions and 7 deletions
1
Makefile
1
Makefile
|
@ -963,6 +963,7 @@ GAME_OBJS_ = \
|
||||||
src/game/g_sphere.o \
|
src/game/g_sphere.o \
|
||||||
src/game/g_svcmds.o \
|
src/game/g_svcmds.o \
|
||||||
src/game/g_target.o \
|
src/game/g_target.o \
|
||||||
|
src/game/g_translate.o \
|
||||||
src/game/g_trigger.o \
|
src/game/g_trigger.o \
|
||||||
src/game/g_turret.o \
|
src/game/g_turret.o \
|
||||||
src/game/g_utils.o \
|
src/game/g_utils.o \
|
||||||
|
|
|
@ -2618,7 +2618,7 @@ door_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */,
|
||||||
|
|
||||||
self->touch_debounce_time = level.time + 5.0;
|
self->touch_debounce_time = level.time + 5.0;
|
||||||
|
|
||||||
gi.centerprintf(other, "%s", self->message);
|
gi.centerprintf(other, "%s", LocalizationMessage(self->message));
|
||||||
gi.sound(other, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
gi.sound(other, CHAN_AUTO, gi.soundindex("misc/talk1.wav"), 1, ATTN_NORM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ secret_touch(edict_t *self, edict_t *other, cplane_t *plane /* unused */, csurfa
|
||||||
|
|
||||||
if (self->message)
|
if (self->message)
|
||||||
{
|
{
|
||||||
gi.centerprintf(other, self->message);
|
gi.centerprintf(other, LocalizationMessage(self->message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -865,8 +865,8 @@ SP_worldspawn(edict_t *ent)
|
||||||
/* make some data visible to the server */
|
/* make some data visible to the server */
|
||||||
if (ent->message && ent->message[0])
|
if (ent->message && ent->message[0])
|
||||||
{
|
{
|
||||||
gi.configstring(CS_NAME, ent->message);
|
Q_strlcpy(level.level_name, LocalizationMessage(ent->message), sizeof(level.level_name));
|
||||||
Q_strlcpy(level.level_name, ent->message, sizeof(level.level_name));
|
gi.configstring(CS_NAME, level.level_name);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
218
src/game/g_translate.c
Normal file
218
src/game/g_translate.c
Normal file
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 1997-2001 Id Software, Inc.
|
||||||
|
* Copyright (c) ZeniMax Media Inc.
|
||||||
|
*
|
||||||
|
* This program 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.
|
||||||
|
*
|
||||||
|
* This program 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 this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*
|
||||||
|
* Localization logic.
|
||||||
|
*
|
||||||
|
* =======================================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "header/local.h"
|
||||||
|
|
||||||
|
localmessages_t *localmessages = NULL;
|
||||||
|
int nlocalmessages = 0;
|
||||||
|
|
||||||
|
static int
|
||||||
|
LocalizationSort(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
localmessages_t *msg1, *msg2;
|
||||||
|
|
||||||
|
msg1 = (localmessages_t*)p1;
|
||||||
|
msg2 = (localmessages_t*)p2;
|
||||||
|
return Q_stricmp(msg1->key, msg2->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocalizationInit(void)
|
||||||
|
{
|
||||||
|
byte *raw = NULL;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
localmessages = NULL;
|
||||||
|
nlocalmessages = 0;
|
||||||
|
|
||||||
|
/* load the file */
|
||||||
|
len = gi.FS_LoadFile("localization/loc_english.txt", (void **)&raw);
|
||||||
|
if (len > 1)
|
||||||
|
{
|
||||||
|
char *buf, *curr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
buf = malloc(len + 1);
|
||||||
|
memcpy(buf, raw, len);
|
||||||
|
buf[len] = 0;
|
||||||
|
|
||||||
|
/* get lines count */
|
||||||
|
curr = buf;
|
||||||
|
while(*curr)
|
||||||
|
{
|
||||||
|
size_t linesize = 0;
|
||||||
|
|
||||||
|
linesize = strcspn(curr, "\n\r");
|
||||||
|
if (*curr && strncmp(curr, "//", 2) &&
|
||||||
|
*curr != '\n' && *curr != '\r')
|
||||||
|
{
|
||||||
|
nlocalmessages ++;
|
||||||
|
}
|
||||||
|
curr += linesize;
|
||||||
|
if (curr >= (buf + len))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* skip our endline */
|
||||||
|
curr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nlocalmessages)
|
||||||
|
{
|
||||||
|
localmessages = gi.TagMalloc(nlocalmessages * sizeof(*localmessages), TAG_GAME);
|
||||||
|
memset(localmessages, 0, nlocalmessages * sizeof(*localmessages));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse lines */
|
||||||
|
curr = buf;
|
||||||
|
i = 0;
|
||||||
|
while(*curr)
|
||||||
|
{
|
||||||
|
size_t linesize = 0;
|
||||||
|
|
||||||
|
if (i == nlocalmessages)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
linesize = strcspn(curr, "\n\r");
|
||||||
|
curr[linesize] = 0;
|
||||||
|
if (*curr && strncmp(curr, "//", 2) &&
|
||||||
|
*curr != '\n' && *curr != '\r')
|
||||||
|
{
|
||||||
|
char *sign;
|
||||||
|
|
||||||
|
sign = strchr(curr, '=');
|
||||||
|
/* clean up end of key */
|
||||||
|
if (sign)
|
||||||
|
{
|
||||||
|
char *signend;
|
||||||
|
|
||||||
|
signend = sign - 1;
|
||||||
|
while ((*signend == ' ' || *signend == '\t') &&
|
||||||
|
(signend > curr))
|
||||||
|
{
|
||||||
|
*signend = 0;
|
||||||
|
/* go back */
|
||||||
|
signend --;
|
||||||
|
}
|
||||||
|
*sign = 0;
|
||||||
|
sign ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip value prefix */
|
||||||
|
if (sign && *sign)
|
||||||
|
{
|
||||||
|
size_t valueskip;
|
||||||
|
|
||||||
|
valueskip = strcspn(sign, " \t");
|
||||||
|
sign += valueskip;
|
||||||
|
if (*sign)
|
||||||
|
{
|
||||||
|
sign++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* start real value */
|
||||||
|
if (sign && *sign == '"')
|
||||||
|
{
|
||||||
|
char *currend;
|
||||||
|
|
||||||
|
sign ++;
|
||||||
|
|
||||||
|
currend = sign;
|
||||||
|
while (*currend && *currend != '"')
|
||||||
|
{
|
||||||
|
if (*currend == '\\')
|
||||||
|
{
|
||||||
|
/* escaped */
|
||||||
|
*currend = ' ';
|
||||||
|
currend++;
|
||||||
|
if (*currend == 'n')
|
||||||
|
{
|
||||||
|
/* new line */
|
||||||
|
*currend = '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currend++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*currend == '"')
|
||||||
|
{
|
||||||
|
/* mark as end of string */
|
||||||
|
*currend = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
localmessages[i].key = gi.TagMalloc(strlen(curr) + 2, TAG_GAME);
|
||||||
|
localmessages[i].key[0] = '$';
|
||||||
|
strcpy(localmessages[i].key + 1, curr);
|
||||||
|
localmessages[i].value = gi.TagMalloc(strlen(sign) + 1, TAG_GAME);
|
||||||
|
strcpy(localmessages[i].value, sign);
|
||||||
|
i ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curr += linesize;
|
||||||
|
if (curr >= (buf + len))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* skip our endline */
|
||||||
|
curr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlocalmessages = i;
|
||||||
|
/* sort messages */
|
||||||
|
qsort(localmessages, nlocalmessages, sizeof(localmessages_t), LocalizationSort);
|
||||||
|
|
||||||
|
gi.FS_FreeFile(raw);
|
||||||
|
free(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char*
|
||||||
|
LocalizationMessage(const char *message)
|
||||||
|
{
|
||||||
|
if (!message || !localmessages || !nlocalmessages)
|
||||||
|
{
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message[0] == '$')
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < nlocalmessages; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp(localmessages[i].key, message))
|
||||||
|
{
|
||||||
|
return localmessages[i].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
|
@ -321,7 +321,7 @@ G_UseTargets(edict_t *ent, edict_t *activator)
|
||||||
/* print the message */
|
/* print the message */
|
||||||
if (activator && (ent->message) && !(activator->svflags & SVF_MONSTER))
|
if (activator && (ent->message) && !(activator->svflags & SVF_MONSTER))
|
||||||
{
|
{
|
||||||
gi.centerprintf(activator, "%s", ent->message);
|
gi.centerprintf(activator, "%s", LocalizationMessage(ent->message));
|
||||||
|
|
||||||
if (ent->noise_index)
|
if (ent->noise_index)
|
||||||
{
|
{
|
||||||
|
|
|
@ -189,6 +189,15 @@ typedef struct
|
||||||
void (*AddCommandString)(const char *text);
|
void (*AddCommandString)(const char *text);
|
||||||
|
|
||||||
void (*DebugGraph)(float value, int color);
|
void (*DebugGraph)(float value, int color);
|
||||||
|
|
||||||
|
/* Extended to classic Quake2 API.
|
||||||
|
files will be memory mapped read only
|
||||||
|
the returned buffer may be part of a larger pak file,
|
||||||
|
or a discrete file from anywhere in the quake search path
|
||||||
|
a -1 return means the file does not exist
|
||||||
|
NULL can be passed for buf to just determine existance */
|
||||||
|
int (*FS_LoadFile) (const char *name, void **buf);
|
||||||
|
void (*FS_FreeFile) (void *buf);
|
||||||
} game_import_t;
|
} game_import_t;
|
||||||
|
|
||||||
/* functions exported by the game subsystem */
|
/* functions exported by the game subsystem */
|
||||||
|
|
|
@ -994,6 +994,18 @@ void SV_AddGravity(edict_t *ent);
|
||||||
void SaveClientData(void);
|
void SaveClientData(void);
|
||||||
void EndDMLevel(void);
|
void EndDMLevel(void);
|
||||||
|
|
||||||
|
/* g_translate.c */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
char *key;
|
||||||
|
char *value;
|
||||||
|
} localmessages_t;
|
||||||
|
|
||||||
|
extern localmessages_t *localmessages;
|
||||||
|
extern int nlocalmessages;
|
||||||
|
void LocalizationInit(void);
|
||||||
|
const char* LocalizationMessage(const char *message);
|
||||||
|
|
||||||
/* g_chase.c */
|
/* g_chase.c */
|
||||||
void UpdateChaseCam(edict_t *ent);
|
void UpdateChaseCam(edict_t *ent);
|
||||||
void ChaseNext(edict_t *ent);
|
void ChaseNext(edict_t *ent);
|
||||||
|
|
|
@ -421,8 +421,8 @@ HelpComputerMessage(edict_t *ent)
|
||||||
"xv 50 yv 172 string2 \"%3i/%3i %i/%i %i/%i\" ",
|
"xv 50 yv 172 string2 \"%3i/%3i %i/%i %i/%i\" ",
|
||||||
sk,
|
sk,
|
||||||
level.level_name,
|
level.level_name,
|
||||||
game.helpmessage1,
|
LocalizationMessage(game.helpmessage1),
|
||||||
game.helpmessage2,
|
LocalizationMessage(game.helpmessage2),
|
||||||
level.killed_monsters, level.total_monsters,
|
level.killed_monsters, level.total_monsters,
|
||||||
level.found_goals, level.total_goals,
|
level.found_goals, level.total_goals,
|
||||||
level.found_secrets, level.total_secrets);
|
level.found_secrets, level.total_secrets);
|
||||||
|
|
|
@ -264,6 +264,9 @@ InitGame(void)
|
||||||
g_quick_weap = gi.cvar("g_quick_weap", "1", CVAR_ARCHIVE);
|
g_quick_weap = gi.cvar("g_quick_weap", "1", CVAR_ARCHIVE);
|
||||||
g_swap_speed = gi.cvar("g_swap_speed", "1", 0);
|
g_swap_speed = gi.cvar("g_swap_speed", "1", 0);
|
||||||
|
|
||||||
|
/* initilize localization */
|
||||||
|
LocalizationInit();
|
||||||
|
|
||||||
/* items */
|
/* items */
|
||||||
InitItems();
|
InitItems();
|
||||||
|
|
||||||
|
|
|
@ -453,6 +453,10 @@ SV_InitGameProgs(void)
|
||||||
import.SetAreaPortalState = CM_SetAreaPortalState;
|
import.SetAreaPortalState = CM_SetAreaPortalState;
|
||||||
import.AreasConnected = CM_AreasConnected;
|
import.AreasConnected = CM_AreasConnected;
|
||||||
|
|
||||||
|
/* Extension to classic Quake2 API */
|
||||||
|
import.FS_LoadFile = FS_LoadFile;
|
||||||
|
import.FS_FreeFile = FS_FreeFile;
|
||||||
|
|
||||||
ge = (game_export_t *)Sys_GetGameAPI(&import);
|
ge = (game_export_t *)Sys_GetGameAPI(&import);
|
||||||
|
|
||||||
if (!ge)
|
if (!ge)
|
||||||
|
|
Loading…
Reference in a new issue