Some probs about translating commands & cvars

Discuss programming topics for the various GPL'd game engine sources.
Post Reply
ChOwW
Posts: 21
Joined: Sat Dec 03, 2011 1:20 pm

Some probs about translating commands & cvars

Post by ChOwW »

I've been trying to implement a basic translation system on my personnal engine since a few hours, and... Well, I think I'll need some help here.

But first of all, I'll explain what I've thought, and more specially what I've done:

To make that system, I'm going to base my code to the cvar system. We don't want to be disturbed later if someone tries to modify the text. So, After launching the game, we will allow to make modifications to the texts. Then, it will run a small function opening a file, replacing the words, and closes the ability to modify the translations.

Anyway, I also imagine the worst, like someone writing binds through this file when this shouldn't be allowed.

Bref...

____________________________________________

1) The translation system is simple, and is greatly based on cvar's system.

Code: Select all

typedef struct language_s {
	char *text;					// name of the basis word
	char *defaulttext;			// default meaning
	char *translation;			// translated word (if any)

	struct language_s *nextword;
} language_t;

extern language_t *game_nextword;
2) I'm making a CVAR called "language" (ARCHIVE CVAR), used for knowing the language file we'll use later.

3) After making my Init, I'll make a switch of the value obtained, and it'll run a function to open a .lng (language) file with the name of the language.

==> PROBLEM IS, IT DOESN'T OPEN ANY OF MY FILES.

Code: Select all

/*
===================
Cmd_OpenLanguageFile
Opens a language file.
===================
*/
void Cmd_OpenLanguageFile (char *lang)
{
	char	*f;
	char	cfgname[128];
	int		mark;

	mark = Hunk_LowMark ();

// Ch0wW - All .lng files are now bound to the resource folder.
	sprintf(cfgname,"resource/%s", lang);

	Con_Printf(cfgname);
	COM_DefaultExtension (cfgname, ".lng");
	f = (char *)COM_LoadHunkFile (cfgname);
//--- 09/02/2012

	if (!f)
	{
		Con_Printf ("No Language file found. Reverting to default.");
		return;
	}
	
	Cbuf_InsertText (f);
	Hunk_FreeToLowMark (mark);
	Con_Printf("loaded %s language file done\n",  lang);
}
4) Then, after doing the basis, maybe I should create the lang commands and being able to run commands?
(My idea : send the text name, and the variable. If there isn't any variable (like in TL_Add() ), just set the default value. Else, run the translated value.)

Code: Select all

/*
============
TL_FindText 
============
*/
language_t *TL_FindText (char *tl_name)
{
	language_t	*txt;
	
	for (txt=game_nextword ; txt ; txt=txt->nextword)
		if (!Q_strcmp (tl_name, txt->text))
			return txt;

	return NULL;
}

/*
============
TL_Translate

Translates the text according to the language file.
============
*/
void TL_Translate (char *text, char *value)
{
	language_t	*tl;

		tl = TL_FindText (text); 
	if (!tl) return;

	//Z_Free (tl->translation);	// free the old value string	
	//tl->translation = Z_Malloc (Q_strlen(value)+1);
	tl->translation = value;
}


/* 
===========
TL_Cmd
Checks if my text can be translated through console inputs.
===========
*/
qboolean TL_Cmd (void)
{
	language_t	*tl;

	tl = TL_FindText (Cmd_Argv(0)); 
	if (!tl) return false;

	if (Cmd_Argc() == 1)return false;

	TL_Translate (tl->text, Cmd_Argv(1));

	return true;
}
/*
============
TL_Add
Like as Cvar_RegisterVariable
============
*/
void TL_Add (language_t *tl_text)
{
	char	value[512];
	qboolean changed;
	
// link the variable in
	tl_text->nextword = game_nextword;
	game_nextword = tl_text;

// copy the value off, because future sets will Z_Free it
	strcpy (value, tl_text->defaulttext);
	tl_text->translation = Z_Malloc (1);	
	
	TL_Translate(tl_text->text, tl_text->defaulttext);
==> Another problem is, even if the following code works, that any modifications will change to a number or random things.

5) Well, Cvar-related, add a condition :

Code: Select all

// check cvars && translation commands
	if (!Cvar_Command () && !TL_Cmd () && cl_warncmd.value)
		Con_Printf ("Unknown command \"%s\"\n", Cmd_Argv(0));
(please note that cl_warncmd is QW-based)

yet, it does work, but only the steps 3 & 4 are slowing me down.

I had some ideas of how to fix that like adding a temporary char in language_t , but I just don't get it.

Or, if someone gets a better idea, please tell it.

Thanks in advance!

(btw, yeah, I thought of this while watching FTE code, just to get some fixes in QuakeC [which are hard to notice :P ]. But also, as it was a total mess, at least for me, I prefered to make my own system )
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: Some probs about translating commands & cvars

Post by revelator »

i think you could use the gpl gettext library to handle the bulk of the translation.
Productivity is a state of mind.
ChOwW
Posts: 21
Joined: Sat Dec 03, 2011 1:20 pm

Re: Some probs about translating commands & cvars

Post by ChOwW »

Thanks for the reply!

I tried to implant it, but I found it so hard to use that I prefer to remove it from my own project.

I then created an hard-coded "unreal-like" locale system with ini files corresponding to our language.

Also, I left too my cvar-like locale system to implant it to QuakeC, making translated mods easier. Anyway, I'm left with one another problem:

I noticed than G_STRING cannot return a variable at all (left operand must be l-value), while G_INT/FLOAT/VECTOR/--- can.

Is there a possible solution to return a string value?
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Some probs about translating commands & cvars

Post by Spike »

G_INT(OFS_RETURN) = "your char* here" - pr_string_table;

note that the above is not 64bit safe.
see PF_ftos for an existing example.
ChOwW
Posts: 21
Joined: Sat Dec 03, 2011 1:20 pm

Re: Some probs about translating commands & cvars

Post by ChOwW »

Oh, you're right about ftos, I haven't noticed it at all... I was being concentrated on G_STRING, and not about some other built-in string functions ...

Anyway, thanks Spike for this!
Post Reply