Files
amxmodx/amxmodx/amxmod_compat.cpp
David Anderson 78956f3d89 merged bcompat changed into trunk
removed amxmod compat files for now
2006-09-01 03:29:27 +00:00

137 lines
2.7 KiB
C++

#include "amxmodx.h"
#include "amxmod_compat.h"
#include "format.h"
struct translate_result
{
int suki;
int dest;
int lang;
};
CVector<translate_result *> g_tr_results;
CStack<size_t> g_old_ids;
bool GetTranslation(int id, int &key, int &dest, int &lang)
{
if (id < 0 || (unsigned int)id > g_tr_results.size())
{
return false;
}
translate_result *pRes = g_tr_results[id];
key = pRes->suki;
dest = pRes->dest;
lang = pRes->lang;
g_old_ids.push((size_t)id);
return true;
}
void ClearTransCache()
{
for (size_t i=0; i<g_tr_results.size(); i++)
{
delete g_tr_results[i];
}
g_tr_results.clear();
while (!g_old_ids.empty())
{
g_old_ids.pop();
}
}
bool translate_bcompat(AMX *amx, cell *source, const char **_key, const char **_def)
{
unsigned int trans = static_cast<unsigned int>(*source);
trans &= ~BCOMPAT_TRANSLATE_BITS;
int key, _dest, lang;
if (!GetTranslation(trans, key, _dest, lang))
{
return false;
}
cell amx_addr, *phys_addr;
if (amx_Allot(amx, 3, &amx_addr, &phys_addr) != AMX_ERR_NONE)
{
return false;
}
if (_dest == -1)
{
*phys_addr = LANG_PLAYER;
} else if (_dest == 0) {
*phys_addr = LANG_SERVER;
} else if (lang >= 0 && lang < g_langMngr.GetLangsNum()) {
const char *name = g_langMngr.GetLangName(lang);
phys_addr[0] = static_cast<cell>(name[0]);
phys_addr[1] = static_cast<cell>(name[1]);
phys_addr[2] = static_cast<cell>('\0');
} else {
*phys_addr = LANG_SERVER;
}
//not optimized but it works, eh
//if someone cares they can make a translate() wrapper that takes the key # in directly
const char *r_key = g_langMngr.GetKey(key);
const char *def = translate(amx, amx_addr, r_key);
if (!def)
{
def = r_key;
}
amx_Release(amx, amx_addr);
*_key = g_langMngr.GetKey(key);
*_def = def;
return true;
}
static cell AMX_NATIVE_CALL amx_translate(AMX *amx, cell *params)
{
int len;
char *key = get_amxstring(amx, params[1], 0, len);
translate_result *pRes;
size_t id;
if (g_old_ids.empty())
{
pRes = new translate_result;
id = g_tr_results.size();
g_tr_results.push_back(pRes);
} else {
if (g_tr_results.size() >= BCOMPAT_TRANSLATE_MAX)
{
LogError(amx, AMX_ERR_NATIVE, "Exceeded bcompat translation limit of %d!", BCOMPAT_TRANSLATE_MAX);
return 0;
}
id = g_old_ids.front();
g_old_ids.pop();
pRes = g_tr_results[id];
}
pRes->suki = g_langMngr.GetKeyEntry(key);
//Some AMX Mod plugins do not register everything they need. Prevent a crash.
if (pRes->suki == -1)
{
pRes->suki = g_langMngr.AddKeyEntry(key);
}
pRes->dest = params[2];
pRes->lang = params[3];
return (cell)((unsigned int)BCOMPAT_TRANSLATE_BITS | (unsigned int)id);
}
AMX_NATIVE_INFO g_BcompatNatives[] =
{
{"translate", amx_translate},
{NULL, NULL},
};