Fix up translations stuff with the rereleased version of quake.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6038 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
81d5091fac
commit
c2d3d3a41b
18 changed files with 424 additions and 40 deletions
|
@ -6348,7 +6348,10 @@ static void CL_PrintStandardMessage(char *msgtext, int printlevel)
|
|||
|
||||
// print final chunk
|
||||
Q_strncatz(fullmessage, msgtext, sizeof(fullmessage));
|
||||
Con_Printf("%s", fullmessage);
|
||||
if (scr_usekfont.ival)
|
||||
Con_PrintFlags(fullmessage, PFS_FORCEUTF8, 0);
|
||||
else
|
||||
Con_Printf("%s", fullmessage);
|
||||
}
|
||||
|
||||
static char printtext[4096];
|
||||
|
|
|
@ -403,8 +403,13 @@ for a few moments
|
|||
*/
|
||||
void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
||||
{
|
||||
unsigned int pfl = 0;
|
||||
size_t i;
|
||||
cprint_t *p;
|
||||
#ifdef HAVE_LEGACY
|
||||
if (scr_usekfont.ival)
|
||||
pfl |= PFS_FORCEUTF8;
|
||||
#endif
|
||||
if (!str)
|
||||
{
|
||||
if (cl.intermissionmode == IM_NONE)
|
||||
|
@ -545,7 +550,7 @@ void SCR_CenterPrint (int pnum, const char *str, qboolean skipgamecode)
|
|||
|
||||
for (;;)
|
||||
{
|
||||
p->charcount = COM_ParseFunString(CON_WHITEMASK, str, p->string, p->stringbytes, false) - p->string;
|
||||
p->charcount = COM_ParseFunString(CON_WHITEMASK, str, p->string, p->stringbytes, pfl) - p->string;
|
||||
|
||||
if ((p->charcount+1)*sizeof(*p->string) < p->stringbytes)
|
||||
break;
|
||||
|
|
|
@ -216,7 +216,8 @@ mpic_t *QBigFontWorks(void)
|
|||
if (p && R_GetShaderSizes(p, NULL, NULL, true))
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
return (mpic_t*)font_menu;
|
||||
}
|
||||
void Draw_BigFontString(int x, int y, const char *text)
|
||||
{
|
||||
|
@ -228,6 +229,11 @@ void Draw_BigFontString(int x, int y, const char *text)
|
|||
Draw_AltFunString(x, y + (20-8)/2, text);
|
||||
return;
|
||||
}
|
||||
if (p == (mpic_t*)font_menu)
|
||||
{
|
||||
Draw_FunStringWidthFont(font_menu, x, y, text, vid.width-x, false, false);
|
||||
return;
|
||||
}
|
||||
|
||||
{ //a hack for scaling
|
||||
p->width = 20*8;
|
||||
|
|
|
@ -4691,7 +4691,7 @@ static void QCBUILTIN PF_checkextension (pubprogfuncs_t *prinst, struct globalva
|
|||
{
|
||||
if (QSG_Extensions[i].extensioncheck)
|
||||
{
|
||||
extcheck_t ctx = {cls.fteprotocolextensions, cls.fteprotocolextensions2};
|
||||
extcheck_t ctx = {prinst->parms->user, cls.fteprotocolextensions, cls.fteprotocolextensions2};
|
||||
G_FLOAT(OFS_RETURN) = QSG_Extensions[i].extensioncheck(&ctx);
|
||||
}
|
||||
else
|
||||
|
@ -8552,7 +8552,7 @@ void PR_CSExtensionList_f(void)
|
|||
int j;
|
||||
const char *extname;
|
||||
|
||||
extcheck_t extcheck = {cls.fteprotocolextensions, cls.fteprotocolextensions2};
|
||||
extcheck_t extcheck = {&csqc_world, cls.fteprotocolextensions, cls.fteprotocolextensions2};
|
||||
|
||||
|
||||
#define SHOW_ACTIVEEXT 1
|
||||
|
|
|
@ -326,6 +326,7 @@ extern cvar_t com_protocolversion;
|
|||
extern cvar_t com_nogamedirnativecode;
|
||||
extern cvar_t com_parseutf8;
|
||||
#ifdef HAVE_LEGACY
|
||||
extern cvar_t scr_usekfont;
|
||||
extern cvar_t ezcompat_markup;
|
||||
#endif
|
||||
extern cvar_t sys_ticrate;
|
||||
|
|
|
@ -1231,6 +1231,8 @@ void R2D_Font_Changed(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
font_menu = Font_LoadFont("qfont?fmt=r", 20, 1, r_font_postprocess_outline.ival);
|
||||
|
||||
font_default = Font_LoadFont(gl_font.string, 8, 1, r_font_postprocess_outline.ival);
|
||||
if (!font_default && *gl_font.string)
|
||||
font_default = Font_LoadFont("", 8, 1, r_font_postprocess_outline.ival);
|
||||
|
|
|
@ -351,6 +351,7 @@ int Font_LineWidth(conchar_t *start, conchar_t *end);
|
|||
float Font_LineScaleWidth(conchar_t *start, conchar_t *end);
|
||||
void Font_LineDraw(int x, int y, conchar_t *start, conchar_t *end);
|
||||
conchar_t *Font_CharAt(int x, conchar_t *start, conchar_t *end);
|
||||
extern struct font_s *font_menu;
|
||||
extern struct font_s *font_default;
|
||||
extern struct font_s *font_console;
|
||||
extern struct font_s *font_tiny;
|
||||
|
|
|
@ -92,6 +92,7 @@ cvar_t host_mapname = CVARAFD("mapname", "", "host_mapname", 0, "Cvar that hol
|
|||
#ifdef HAVE_LEGACY
|
||||
cvar_t ezcompat_markup = CVARD("ezcompat_markup", "1", "Attempt compatibility with ezquake's text markup.0: disabled.\n1: Handle markup ampersand markup.\n2: Handle chevron markup (only in echo commands, for config compat, because its just too unreliable otherwise).");
|
||||
cvar_t pm_noround = CVARD("pm_noround", "0", "Disables player prediction snapping, in a way that cannot be reliably predicted but may be needed to avoid map bugs.");
|
||||
cvar_t scr_usekfont = CVARD("scr_usekfont"/*kex*/, "0", "Exists for compat with the quake rerelease, changing the behaviour of QC's sprint/bprint/centerprint builtins.");
|
||||
#endif
|
||||
|
||||
qboolean com_modified; // set true if using non-id files
|
||||
|
@ -6358,6 +6359,7 @@ void COM_Init (void)
|
|||
Cvar_Register (&com_nogamedirnativecode, "Gamecode");
|
||||
Cvar_Register (&com_parseutf8, "Internationalisation");
|
||||
#ifdef HAVE_LEGACY
|
||||
Cvar_Register (&scr_usekfont, NULL);
|
||||
Cvar_Register (&ezcompat_markup, NULL);
|
||||
Cvar_Register (&pm_noround, NULL);
|
||||
#endif
|
||||
|
|
|
@ -975,6 +975,7 @@ struct po_s *PO_Create(void);
|
|||
void PO_Merge(struct po_s *po, vfsfile_t *file);
|
||||
const char *PO_GetText(struct po_s *po, const char *msg);
|
||||
void PO_Close(struct po_s *po);
|
||||
void TL_Reformat(char *out, size_t outsize, size_t numargs, const char **arg);
|
||||
|
||||
//
|
||||
// log.c
|
||||
|
|
|
@ -3820,7 +3820,9 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
|
|||
/*quake requires a few settings for compatibility*/
|
||||
#define QRPCOMPAT "set cl_cursor_scale 0.2\nset cl_cursor_bias_x 7.5\nset cl_cursor_bias_y 0.8\n"
|
||||
#define QUAKESPASMSUCKS "set mod_h2holey_bugged 1\n"
|
||||
#define QCFG "//schemes quake qw\n" "set v_gammainverted 1\nset con_stayhidden 0\nset com_parseutf8 0\nset allow_download_pakcontents 1\nset allow_download_refpackages 0\nset r_meshpitch -1\nr_sprite_backfacing 1\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QRPCOMPAT QUAKESPASMSUCKS
|
||||
#define QUAKEOVERRIDES "set v_gammainverted 1\nset con_stayhidden 0\nset allow_download_pakcontents 1\nset allow_download_refpackages 0\nset r_meshpitch -1\nr_sprite_backfacing 1\nset sv_bigcoords \"\"\nmap_autoopenportals 1\n" "sv_port "STRINGIFY(PORT_QWSERVER)" "STRINGIFY(PORT_NQSERVER)"\n" ZFIXHACK EZQUAKECOMPETITIVE QUAKESPASMSUCKS
|
||||
#define QCFG "//schemes quake qw\n" QUAKEOVERRIDES "set com_parseutf8 0\n" QRPCOMPAT
|
||||
#define KEXCFG "//schemes quake_r2\n" QUAKEOVERRIDES "set com_parseutf8 1\nset campaign 0\n"
|
||||
/*NetQuake reconfiguration, to make certain people feel more at home...*/
|
||||
#define NQCFG "//disablehomedir 1\n//mainconfig ftenq\n" QCFG "cfg_save_auto 1\nset sv_nqplayerphysics 1\nset cl_loopbackprotocol auto\ncl_sbar 1\nset plug_sbar 0\nset sv_port "STRINGIFY(PORT_NQSERVER)"\ncl_defaultport "STRINGIFY(PORT_NQSERVER)"\nset m_preset_chosen 1\nset vid_wait 1\nset cl_demoreel 1\n"
|
||||
#define SPASMCFG NQCFG "fps_preset builtin_spasm\nset cl_demoreel 0\ncl_sbar 2\nset gl_load24bit 1\n"
|
||||
|
@ -3895,6 +3897,8 @@ static const gamemode_info_t gamemode_info[] = {
|
|||
//for quake, we also allow extracting all files from paks. some people think it loads faster that way or something.
|
||||
#ifdef HAVE_LEGACY
|
||||
//cmdline switch exename protocol name(dpmaster) identifying file exec dir1 dir2 dir3 dir(fte) full name
|
||||
//use rerelease behaviours if we seem to be running from that dir.
|
||||
{"-quake_rerel",NULL, "FTE-QuakeRerelease", {"QuakeEX.kpf"}, KEXCFG, {"id1", "*fte"}, "RerelQuake", UPDATEURL(Q1)},
|
||||
//standard quake
|
||||
{"-quake", "q1", QUAKEPROT, {"id1/pak0.pak","id1/quake.rc"},QCFG, {"id1", "qw", "*fte"}, "Quake", UPDATEURL(Q1)},
|
||||
//alternative name, because fmf file install names are messy when a single name is used for registry install path.
|
||||
|
@ -4468,6 +4472,19 @@ static void FS_ReloadPackFilesFlags(unsigned int reloadflags)
|
|||
com_base_searchpaths = NULL;
|
||||
gameonly_gamedir = gameonly_homedir = NULL;
|
||||
|
||||
#if defined(HAVE_LEGACY) && defined(PACKAGE_PK3)
|
||||
{
|
||||
searchpathfuncs_t *pak;
|
||||
vfsfile_t *vfs;
|
||||
char pakname[MAX_OSPATH];
|
||||
Q_snprintfz(pakname, sizeof(pakname), "%sQuakeEX.kpf", com_gamepath);
|
||||
vfs = VFSOS_Open(pakname, "rb");
|
||||
pak = FSZIP_LoadArchive(vfs, NULL, pakname, pakname, "");
|
||||
if (pak) //logically should have SPF_EXPLICIT set, but that would give it a worse gamedir depth
|
||||
FS_AddPathHandle(&oldpaths, "", pakname, pak, "", SPF_COPYPROTECTED, reloadflags);
|
||||
}
|
||||
#endif
|
||||
|
||||
i = COM_CheckParm ("-basepack");
|
||||
while (i && i < com_argc-1)
|
||||
{
|
||||
|
|
|
@ -7590,6 +7590,9 @@ static qboolean check_pext2_infoblobs (extcheck_t *extcheck) {return !!(extchec
|
|||
//static qboolean check_pext2_stunaware (extcheck_t *extcheck) {return !!(extcheck->pext2 & PEXT2_STUNAWARE);}
|
||||
static qboolean check_pext2_vrinputs (extcheck_t *extcheck) {return !!(extcheck->pext2 & PEXT2_VRINPUTS);}
|
||||
|
||||
//rerelease stomped on things. make sure our earlier extension reports correctly.
|
||||
static qboolean check_bouncemissile (extcheck_t *extcheck) {return !extcheck->world->remasterlogic/*became 'movetype_gib'*/;}
|
||||
|
||||
#define NOBI NULL, 0,{NULL},
|
||||
qc_extension_t QSG_Extensions[] = {
|
||||
//these don't have well-defined names...
|
||||
|
@ -7635,7 +7638,7 @@ qc_extension_t QSG_Extensions[] = {
|
|||
{"DP_LIGHTSTYLE_STATICVALUE"},
|
||||
{"DP_LITSUPPORT"},
|
||||
{"DP_MONSTERWALK", NULL, 0,{NULL}, "MOVETYPE_WALK is valid on non-player entities. Note that only players receive acceleration etc in line with none/bounce/fly/noclip movetypes on the player, thus you will have to provide your own accelerations (incluing gravity) yourself."},
|
||||
{"DP_MOVETYPEBOUNCEMISSILE"}, //I added the code for hexen2 support.
|
||||
{"DP_MOVETYPEBOUNCEMISSILE", check_bouncemissile}, //I added the code for hexen2 support.
|
||||
{"DP_MOVETYPEFOLLOW"},
|
||||
{"DP_QC_ASINACOSATANATAN2TAN", NULL, 5,{"asin", "acos", "atan", "atan2", "tan"}},
|
||||
{"DP_QC_CHANGEPITCH", NULL, 1,{"changepitch"}},
|
||||
|
|
|
@ -46,6 +46,7 @@ struct wedict_s
|
|||
//thus this system requires various builtins to exist at specific numbers.
|
||||
//this competes against checkbuiltin(funcreference).
|
||||
typedef struct {
|
||||
world_t *world;
|
||||
unsigned int pext1, pext2;
|
||||
} extcheck_t;
|
||||
typedef struct qc_extension_s {
|
||||
|
|
|
@ -15,9 +15,15 @@ int com_language;
|
|||
char sys_language[64] = "";
|
||||
static char langpath[MAX_OSPATH] = "";
|
||||
struct language_s languages[MAX_LANGUAGES];
|
||||
static struct po_s *com_translations;
|
||||
|
||||
static void QDECL TL_LanguageChanged(struct cvar_s *var, char *oldvalue)
|
||||
{
|
||||
if (com_translations)
|
||||
{
|
||||
PO_Close(com_translations);
|
||||
com_translations = NULL;
|
||||
}
|
||||
com_language = TL_FindLanguage(var->string);
|
||||
}
|
||||
|
||||
|
@ -495,3 +501,147 @@ const char *PO_GetText(struct po_s *po, const char *msg)
|
|||
return line->translated;
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
static void PO_Merge_Rerelease(struct po_s *po, const char *fmt)
|
||||
{
|
||||
//FOO <plat,plat> = "CString"
|
||||
char line[32768];
|
||||
char key[256];
|
||||
char val[32768];
|
||||
char *s;
|
||||
vfsfile_t *file = NULL;
|
||||
|
||||
if (!file && *language.string) //use system locale names
|
||||
file = FS_OpenVFS(va(fmt, language.string), "rb", FS_GAME);
|
||||
if (!file) //make a guess
|
||||
{
|
||||
s = NULL;
|
||||
if (language.string[0] && language.string[1] && (!language.string[2] || language.string[2] == '-' || language.string[2] == '_'))
|
||||
{ //try to map the user's formal locale to the rerelease's arbitrary names (at least from the perspective of anyone who doesn't speak english).
|
||||
if (!strncmp(language.string, "fr", 2))
|
||||
s = "french";
|
||||
else if (!strncmp(language.string, "de", 2))
|
||||
s = "german";
|
||||
else if (!strncmp(language.string, "it", 2))
|
||||
s = "italian";
|
||||
else if (!strncmp(language.string, "ru", 2))
|
||||
s = "russian";
|
||||
else if (!strncmp(language.string, "es", 2))
|
||||
s = "spanish";
|
||||
}
|
||||
if (s)
|
||||
file = FS_OpenVFS(va(fmt, s), "rb", FS_GAME);
|
||||
}
|
||||
if (!file) //fall back on misnamed american, for lack of a better default.
|
||||
file = FS_OpenVFS(va(fmt, "english"), "rb", FS_GAME);
|
||||
if (file)
|
||||
{
|
||||
*key = '$';
|
||||
while(VFS_GETS(file, line, sizeof(line)))
|
||||
{
|
||||
s = COM_ParseOut(line, key+1, sizeof(key)-1);
|
||||
s = COM_ParseOut(s, val, sizeof(val));
|
||||
if (strcmp(val,"="))
|
||||
continue;
|
||||
s = COM_ParseCString(s, val, sizeof(val), NULL);
|
||||
if (!s)
|
||||
continue;
|
||||
PO_AddText(po, key, val);
|
||||
}
|
||||
VFS_CLOSE(file);
|
||||
}
|
||||
}
|
||||
|
||||
void TL_Reformat(char *out, size_t outsize, size_t numargs, const char **arg)
|
||||
{
|
||||
const char *fmt;
|
||||
const char *a;
|
||||
size_t alen;
|
||||
|
||||
for (alen = 0; alen < numargs; alen++)
|
||||
{
|
||||
if (*arg[alen] == '$')
|
||||
{
|
||||
if (!com_translations)
|
||||
{
|
||||
char lang[64], *h;
|
||||
vfsfile_t *f = NULL;
|
||||
com_translations = PO_Create();
|
||||
PO_Merge_Rerelease(com_translations, "localization/loc_%s.txt");
|
||||
|
||||
Q_strncpyz(lang, language.string, sizeof(lang));
|
||||
while ((h = strchr(lang, '-')))
|
||||
*h = '_'; //standardise it
|
||||
if (*lang)
|
||||
f = FS_OpenVFS(va("localisation/%s.po", lang), "rb", FS_GAME); //long/specific form
|
||||
if (!f)
|
||||
{
|
||||
if ((h = strchr(lang, '_')))
|
||||
{
|
||||
*h = 0;
|
||||
if (*lang)
|
||||
f = FS_OpenVFS(va("localisation/%s.po", lang), "rb", FS_GAME); //short/general form
|
||||
}
|
||||
}
|
||||
if (f)
|
||||
PO_Merge(com_translations, f);
|
||||
}
|
||||
arg[alen] = PO_GetText(com_translations, arg[alen]);
|
||||
}
|
||||
}
|
||||
|
||||
fmt = (numargs>0&&arg[0])?arg[0]:"";
|
||||
|
||||
outsize--;
|
||||
while (outsize > 0)
|
||||
{
|
||||
if (!*fmt)
|
||||
break;
|
||||
else if (*fmt == '{')
|
||||
{
|
||||
unsigned int index = strtoul(fmt+1, (char**)&fmt, 10)+1;
|
||||
int size = 0;
|
||||
if (*fmt == ',')
|
||||
size = strtol(fmt+1, (char**)&fmt, 10);
|
||||
if (*fmt == ':')
|
||||
{ //formatting, which we don't support because its all strings.
|
||||
fmt = fmt+1;
|
||||
while (*fmt && *fmt != '}')
|
||||
fmt++;
|
||||
}
|
||||
if (*fmt == '}')
|
||||
fmt++;
|
||||
else
|
||||
break; //some formatting error
|
||||
|
||||
if (index >= numargs || !arg[index])
|
||||
a = "";
|
||||
else
|
||||
a = arg[index];
|
||||
|
||||
alen = strlen(a);
|
||||
if (alen > outsize)
|
||||
alen = outsize;
|
||||
if (size > 0)
|
||||
{ //right aligned
|
||||
if (alen > size)
|
||||
alen = size;
|
||||
memcpy(out, a, alen);
|
||||
}
|
||||
else if (size < 0)
|
||||
{ //left aligned
|
||||
if (alen > -size)
|
||||
alen = -size;
|
||||
memcpy(out, a, alen);
|
||||
}
|
||||
else //no alignment, no padding.
|
||||
memcpy(out, a, alen);
|
||||
out += alen;
|
||||
outsize -= alen;
|
||||
}
|
||||
else
|
||||
*out++ = *fmt++, outsize--;
|
||||
}
|
||||
*out = 0;
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ float Font_DrawScaleChar(float px, float py, unsigned int charflags, unsigned in
|
|||
|
||||
void Font_EndString(struct font_s *font);
|
||||
int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends);
|
||||
struct font_s *font_menu;
|
||||
struct font_s *font_default;
|
||||
struct font_s *font_console;
|
||||
struct font_s *font_tiny;
|
||||
|
@ -228,6 +229,7 @@ enum fontfmt_e
|
|||
FMT_WINDOWS1252,//variation of latin-1 with extra glyphs
|
||||
FMT_KOI8U, //image is 16*16 koi8-u codepage.
|
||||
FMT_HORIZONTAL, //unicode, charcount=width/(height-2). single strip of chars, like halflife.
|
||||
FMT_RERELEASE, //fonts/foo.kfont specifies a texture and a series of glyph positions within it.
|
||||
};
|
||||
|
||||
typedef struct fontface_s
|
||||
|
@ -1023,6 +1025,7 @@ static struct charcache_s *Font_TryLoadGlyphRaster(font_t *f, fontface_t *qface,
|
|||
{
|
||||
safedefault:
|
||||
case FMT_AUTO: //shouldn't happen.
|
||||
case FMT_RERELEASE: //shouldn't happen.
|
||||
case FMT_ISO88591: //all identity.
|
||||
case FMT_HORIZONTAL: //erk...
|
||||
c1tab = NULL;
|
||||
|
@ -1610,6 +1613,85 @@ qboolean Font_LoadHorizontalFont(struct font_s *f, int fheight, const char *font
|
|||
return false;
|
||||
}
|
||||
|
||||
qboolean Font_LoadKexFont(struct font_s *f, int fheight, const char *fontfilename)
|
||||
{
|
||||
vfsfile_t *kfont = FS_OpenVFS(va("fonts/%s.kfont", fontfilename), "rb", FS_GAME);
|
||||
char line[256];
|
||||
char val[256], *s;
|
||||
struct charcache_s *c;
|
||||
fontface_t *qface;
|
||||
if (!kfont)
|
||||
return false;
|
||||
while(VFS_GETS(kfont, line, sizeof(line)))
|
||||
{
|
||||
s = COM_ParseOut(line, val, sizeof(val));
|
||||
if (!s)
|
||||
continue;
|
||||
if (!strcmp(val, "texture") && (s=COM_ParseOut(s, val, sizeof(val))))
|
||||
{
|
||||
TEXDOWAIT(f->singletexture);
|
||||
if (!TEXLOADED(f->singletexture))
|
||||
f->singletexture = Image_GetTexture(val, NULL, IF_NOWORKER|IF_EXACTEXTENSION|IF_UIPIC|(r_font_linear.ival?IF_LINEAR:IF_NEAREST|IF_NOPURGE)|IF_NOPICMIP|IF_NOMIPMAP|IF_NOGAMMA|IF_NOPURGE, NULL, NULL, 0, 0, PTI_INVALID);
|
||||
}
|
||||
else if (*val >= '0' && *val <='9')
|
||||
{
|
||||
unsigned int codepoint = atoi(val);
|
||||
unsigned int x, y, w, h;//, u;
|
||||
if (!TEXLOADED(f->singletexture))
|
||||
break;
|
||||
|
||||
s=COM_ParseOut(s, val, sizeof(val));
|
||||
x = atoi(val);
|
||||
s=COM_ParseOut(s, val, sizeof(val));
|
||||
y = atoi(val);
|
||||
s=COM_ParseOut(s, val, sizeof(val));
|
||||
w = atoi(val);
|
||||
s=COM_ParseOut(s, val, sizeof(val));
|
||||
h = atoi(val);
|
||||
s=COM_ParseOut(s, val, sizeof(val));
|
||||
//u = atoi(val);
|
||||
if (!s)
|
||||
continue; //something truncated.
|
||||
if (codepoint >= FONT_MAXCHARS || h<=0)
|
||||
continue; //out of range.
|
||||
c = Font_GetCharStore(f, codepoint);
|
||||
if (codepoint != ' ')
|
||||
{
|
||||
y+=2;
|
||||
h-=4;
|
||||
}
|
||||
c->advance = max(1,(f->charheight * w)/h);
|
||||
|
||||
c->bmw = (w * PLANEWIDTH) / f->singletexture->width;
|
||||
c->bmh = (h * PLANEHEIGHT) / f->singletexture->height;
|
||||
c->bmx = (x * PLANEWIDTH) / f->singletexture->width;
|
||||
c->bmy = (y * PLANEHEIGHT) / f->singletexture->height;
|
||||
c->left = 0;
|
||||
c->nextchar = 0; //these chars are not linked in
|
||||
c->texplane = BITMAPPLANE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VFS_CLOSE(kfont);
|
||||
if (!TEXLOADED(f->singletexture))
|
||||
return false;
|
||||
|
||||
/*success!*/
|
||||
qface = Z_Malloc(sizeof(*qface));
|
||||
qface->flink = &faces;
|
||||
qface->fnext = *qface->flink;
|
||||
*qface->flink = qface;
|
||||
if (qface->fnext)
|
||||
qface->fnext->flink = &qface->fnext;
|
||||
qface->refs++;
|
||||
Q_snprintfz(qface->name, sizeof(qface->name), "fonts/%s.kfont", fontfilename);
|
||||
|
||||
f->face[f->faces++] = qface;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef AVAIL_FREETYPE
|
||||
extern cvar_t dpcompat_smallerfonts;
|
||||
int Font_ChangeFTSize(fontface_t *qface, int pixelheight)
|
||||
|
@ -2196,6 +2278,8 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
|
|||
fmt = FMT_KOI8U;
|
||||
else if (*t == 'h')
|
||||
fmt = FMT_HORIZONTAL;
|
||||
else if (*t == 'r')
|
||||
fmt = FMT_RERELEASE;
|
||||
}
|
||||
if (!strncmp(parms, "aspect=", 7))
|
||||
{
|
||||
|
@ -2388,6 +2472,8 @@ struct font_s *Font_LoadFont(const char *fontfilename, float vheight, float scal
|
|||
if (end)
|
||||
*end = 0;
|
||||
|
||||
if (fmt == FMT_RERELEASE)
|
||||
success = Font_LoadKexFont(f, height, start);
|
||||
if (fmt == FMT_HORIZONTAL)
|
||||
success = Font_LoadHorizontalFont(f, height, start);
|
||||
#ifdef AVAIL_FREETYPE
|
||||
|
@ -2673,6 +2759,8 @@ float Font_CharScaleHeight(void)
|
|||
int Font_TabWidth(int x)
|
||||
{
|
||||
int tabwidth = Font_CharWidth(CON_WHITEMASK, ' ');
|
||||
if (!tabwidth)
|
||||
tabwidth = curfont->charheight;
|
||||
tabwidth *= 8;
|
||||
|
||||
x++;
|
||||
|
|
|
@ -3558,10 +3558,19 @@ static void *X11VID_CreateCursor(const qbyte *imagedata, int width, int height,
|
|||
{
|
||||
int nw,nh;
|
||||
qbyte *nd;
|
||||
nw = width * scale;
|
||||
nh = height * scale;
|
||||
if (nw <= 0 || nh <= 0 || nw > 128 || nh > 128) //don't go crazy.
|
||||
return NULL;
|
||||
for(;;)
|
||||
{
|
||||
nw = width * scale;
|
||||
nh = height * scale;
|
||||
if (nw <= 0 || nh <= 0 || nw > 128 || nh > 128) //don't go crazy.
|
||||
return NULL;
|
||||
if (nw < 8)
|
||||
scale = 8/width;
|
||||
else if (nh < 8)
|
||||
scale = 8/height;
|
||||
else
|
||||
break;
|
||||
}
|
||||
nd = Image_ResampleTexture(format, imagedata, width, height, NULL, nw, nh);
|
||||
if (!nd)
|
||||
return NULL; //resampling of that format didn't work for some reason...
|
||||
|
|
|
@ -2313,16 +2313,6 @@ void Q_InitProgs(enum initprogs_e flags)
|
|||
#endif
|
||||
|
||||
World_RBE_Start(&sv.world);
|
||||
|
||||
if (sv.world.remasterlogic)
|
||||
{
|
||||
PR_EnableEBFSBuiltin("bprints", 23);
|
||||
PR_EnableEBFSBuiltin("sprints", 24);
|
||||
PR_EnableEBFSBuiltin("centerprints", 73);
|
||||
PR_EnableEBFSBuiltin("finaleFinished", 79);
|
||||
PR_EnableEBFSBuiltin("localsound_remaster", 80);
|
||||
Con_Printf(CON_WARNING "Remastered quakec detected (this is not fool-proof), compat workarounds have been enabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
qboolean PR_QCChat(char *text, int say_type)
|
||||
|
@ -7237,13 +7227,13 @@ static void QCBUILTIN PF_checkextension (pubprogfuncs_t *prinst, struct globalva
|
|||
if (ext->extensioncheck && clnum >= 1 && clnum <= sv.allocated_client_slots)
|
||||
{
|
||||
client_t *cl = &svs.clients[clnum-1];
|
||||
extcheck_t check = {cl->fteprotocolextensions, cl->fteprotocolextensions2};
|
||||
extcheck_t check = {prinst->parms->user, cl->fteprotocolextensions, cl->fteprotocolextensions2};
|
||||
if (!ext->extensioncheck(&check))
|
||||
return; //blocked by some setting somewhere, somehow.
|
||||
}
|
||||
else if (ext->extensioncheck)
|
||||
{
|
||||
extcheck_t check = {Net_PextMask(PROTOCOL_VERSION_FTE1, false), Net_PextMask(PROTOCOL_VERSION_FTE2, false)};
|
||||
extcheck_t check = {prinst->parms->user, Net_PextMask(PROTOCOL_VERSION_FTE1, false), Net_PextMask(PROTOCOL_VERSION_FTE2, false)};
|
||||
if (!ext->extensioncheck(&check))
|
||||
return; //blocked by some setting somewhere, somehow.
|
||||
}
|
||||
|
@ -10732,15 +10722,100 @@ void PF_localsound_remaster(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
}
|
||||
void PF_centerprints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{ //TODO: send the strings to the client for localisation+reordering
|
||||
PF_centerprint(prinst, pr_globals);
|
||||
const char *arg[8];
|
||||
int args;
|
||||
char s[1024];
|
||||
int entnum;
|
||||
|
||||
entnum = G_EDICTNUM(prinst, OFS_PARM0);
|
||||
for (args = 0; args+1 < prinst->callargc; args++)
|
||||
arg[args] = PR_GetStringOfs(prinst, OFS_PARM1+args*(OFS_PARM1-OFS_PARM0));
|
||||
TL_Reformat(s, sizeof(s), args, arg);
|
||||
|
||||
PF_centerprint_Internal(entnum, false, s);
|
||||
}
|
||||
void PF_sprints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{ //TODO: send the strings to the client for localisation+reordering.
|
||||
PF_sprint(prinst, pr_globals);
|
||||
{
|
||||
const char *arg[8];
|
||||
int args;
|
||||
char s[1024];
|
||||
client_t *client;
|
||||
int entnum;
|
||||
int level;
|
||||
|
||||
#ifdef SERVER_DEMO_PLAYBACK
|
||||
if (sv.demofile)
|
||||
return;
|
||||
#endif
|
||||
|
||||
entnum = G_EDICTNUM(prinst, OFS_PARM0);
|
||||
|
||||
if (progstype == PROG_NQ || progstype == PROG_H2)
|
||||
{
|
||||
level = PRINT_HIGH;
|
||||
for (args = 0; args+1 < prinst->callargc; args++)
|
||||
arg[args] = PR_GetStringOfs(prinst, OFS_PARM1+args*(OFS_PARM1-OFS_PARM0));
|
||||
}
|
||||
else
|
||||
{
|
||||
level = G_FLOAT(OFS_PARM1);
|
||||
for (args = 0; args+2 < prinst->callargc; args++)
|
||||
arg[args] = PR_GetStringOfs(prinst, OFS_PARM2+args*(OFS_PARM1-OFS_PARM0));
|
||||
}
|
||||
TL_Reformat(s, sizeof(s), args, arg);
|
||||
|
||||
if (entnum < 1 || entnum > sv.allocated_client_slots)
|
||||
{
|
||||
Con_TPrintf ("tried to sprint to a non-client\n");
|
||||
return;
|
||||
}
|
||||
|
||||
client = &svs.clients[entnum-1];
|
||||
|
||||
SV_ClientPrintf (client, level, "%s", s);
|
||||
|
||||
if (sv_specprint.ival & SPECPRINT_SPRINT)
|
||||
{
|
||||
client_t *spec;
|
||||
unsigned int i;
|
||||
for (i = 0, spec = svs.clients; i < sv.allocated_client_slots; i++, spec++)
|
||||
{
|
||||
if (spec->state != cs_spawned || !spec->spectator)
|
||||
continue;
|
||||
if (spec->spec_track == entnum && (spec->spec_print & SPECPRINT_SPRINT))
|
||||
{
|
||||
if (level < spec->messagelevel)
|
||||
continue;
|
||||
if (spec->controller)
|
||||
SV_PrintToClient(spec->controller, level, s);
|
||||
else
|
||||
SV_PrintToClient(spec, level, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void PF_bprints(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{ //TODO: send the strings to the client for localisation+reordering
|
||||
PF_bprint(prinst, pr_globals);
|
||||
const char *arg[8];
|
||||
int args;
|
||||
char formatted[1024];
|
||||
int level;
|
||||
|
||||
if (progstype == PROG_QW)
|
||||
{
|
||||
level = G_FLOAT(OFS_PARM0);
|
||||
for (args = 0; args+1 < prinst->callargc; args++)
|
||||
arg[args] = PR_GetStringOfs(prinst, OFS_PARM1+args*(OFS_PARM1-OFS_PARM0));
|
||||
}
|
||||
else
|
||||
{
|
||||
level = PRINT_HIGH;
|
||||
for (args = 0; args < prinst->callargc; args++)
|
||||
arg[args] = PR_GetStringOfs(prinst, OFS_PARM0+args*(OFS_PARM1-OFS_PARM0));
|
||||
}
|
||||
|
||||
TL_Reformat(formatted, sizeof(formatted), args, arg);
|
||||
SV_BroadcastPrintf (level, "%s", formatted);
|
||||
}
|
||||
|
||||
#define STUB ,NULL,true
|
||||
|
@ -12113,6 +12188,20 @@ void PR_ResetBuiltins(progstype_t type) //fix all nulls to PF_FIXME and add any
|
|||
Con_Printf("Be aware that MVDSV does not follow standards. Please encourage mod developers to not require pr_imitatemvdsv to be set.\n");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_LEGACY
|
||||
//when this cvar is set, we're assumed to be running a rerelease-compatible mod.
|
||||
//obviously this might still break mods that don't include their own quake.rc (most of them), but hey... compat, right?
|
||||
if (scr_usekfont.ival)
|
||||
{
|
||||
PR_EnableEBFSBuiltin("bprints", 23);
|
||||
PR_EnableEBFSBuiltin("sprints", 24);
|
||||
PR_EnableEBFSBuiltin("centerprints", 73);
|
||||
|
||||
PR_EnableEBFSBuiltin("finaleFinished", 79);
|
||||
PR_EnableEBFSBuiltin("localsound_remaster", 80);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void PR_SVExtensionList_f(void)
|
||||
|
@ -12126,7 +12215,7 @@ void PR_SVExtensionList_f(void)
|
|||
int num;
|
||||
char biissues[8192];
|
||||
|
||||
extcheck_t extcheck = {Net_PextMask(PROTOCOL_VERSION_FTE1, false), Net_PextMask(PROTOCOL_VERSION_FTE2, false)};
|
||||
extcheck_t extcheck = {&sv.world, Net_PextMask(PROTOCOL_VERSION_FTE1, false), Net_PextMask(PROTOCOL_VERSION_FTE2, false)};
|
||||
|
||||
#define SHOW_ACTIVEEXT 1
|
||||
#define SHOW_ACTIVEBI 2
|
||||
|
|
|
@ -5726,11 +5726,12 @@ void SV_InitLocal (void)
|
|||
}
|
||||
|
||||
#define iswhite(c) ((c) == ' ' || (unsigned char)(c) == (unsigned char)INVIS_CHAR1 || (unsigned char)(c) == (unsigned char)INVIS_CHAR2 || (unsigned char)(c) == (unsigned char)INVIS_CHAR3)
|
||||
#define isinvalid(c) ((c) == ':' || (c) == '\\' || (c) == '\r' || (c) == '\n' || (unsigned char)(c) == (unsigned char)0xff || (c) == '\"')
|
||||
//colon is so clients can't get confused while parsing chats
|
||||
//255 is so fuhquake/ezquake don't end up with nameless players
|
||||
#define isinvalid(c) ((c) == ':' || (c) == '\\' || (c) == '$' || (c) == '\r' || (c) == '\n' || (unsigned char)(c) == (unsigned char)0xff || (c) == '\"')
|
||||
//colon is so clients can't get confused while parsing chats (eg frag messages)
|
||||
//255 is so fuhquake/ezquake don't end up with nameless players (and general MSG_ReadString bugs)
|
||||
//" is so mods that use player names in tokenizing/frik_files don't mess up. mods are still expected to be able to cope with space.
|
||||
//\ is blocked because it messes up our ^[NAME\player\NUM^] links, and because vanilla would hate it.
|
||||
//$ is blocked because of potential internationalisation escapes.
|
||||
|
||||
//is allowed to shorten, out must be as long as in and min of "unnamed"+1
|
||||
void SV_FixupName(const char *in, char *out, unsigned int outlen)
|
||||
|
|
|
@ -1332,6 +1332,7 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
|
|||
|
||||
int fl;
|
||||
const float *gravitydir;
|
||||
int movetype;
|
||||
|
||||
WPhys_CheckVelocity (w, ent);
|
||||
|
||||
|
@ -1364,11 +1365,12 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
|
|||
}
|
||||
|
||||
// add gravity
|
||||
if (ent->v->movetype != MOVETYPE_FLY
|
||||
&& ent->v->movetype != MOVETYPE_FLY_WORLDONLY
|
||||
&& ent->v->movetype != MOVETYPE_FLYMISSILE
|
||||
&& (ent->v->movetype != MOVETYPE_BOUNCEMISSILE || w->remasterlogic/*gib*/)
|
||||
&& ent->v->movetype != MOVETYPE_H2SWIM)
|
||||
movetype = ent->v->movetype;
|
||||
if (movetype != MOVETYPE_FLY
|
||||
&& movetype != MOVETYPE_FLY_WORLDONLY
|
||||
&& movetype != MOVETYPE_FLYMISSILE
|
||||
&& (movetype != MOVETYPE_BOUNCEMISSILE || w->remasterlogic/*gib*/)
|
||||
&& movetype != MOVETYPE_H2SWIM)
|
||||
WPhys_AddGravity (w, ent, gravitydir);
|
||||
|
||||
// move angles
|
||||
|
@ -1407,14 +1409,17 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
|
|||
|
||||
VectorCopy(trace.endpos, move);
|
||||
|
||||
if (ent->v->movetype == MOVETYPE_BOUNCE)
|
||||
movetype = ent->v->movetype;
|
||||
if (movetype == MOVETYPE_BOUNCEMISSILE && w->remasterlogic)
|
||||
movetype = MOVETYPE_BOUNCE; //'gib'...
|
||||
if (movetype == MOVETYPE_BOUNCE)
|
||||
{
|
||||
if (ent->xv->bouncefactor)
|
||||
backoff = 1 + ent->xv->bouncefactor;
|
||||
else
|
||||
backoff = 1.5;
|
||||
}
|
||||
else if (ent->v->movetype == MOVETYPE_BOUNCEMISSILE)
|
||||
else if (movetype == MOVETYPE_BOUNCEMISSILE)
|
||||
{
|
||||
if (ent->xv->bouncefactor)
|
||||
backoff = 1 + ent->xv->bouncefactor;
|
||||
|
@ -1431,7 +1436,7 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
|
|||
|
||||
|
||||
// stop if on ground
|
||||
if ((-DotProduct(gravitydir, trace.plane.normal) > 0.7) && (ent->v->movetype != MOVETYPE_BOUNCEMISSILE))
|
||||
if ((-DotProduct(gravitydir, trace.plane.normal) > 0.7) && (movetype != MOVETYPE_BOUNCEMISSILE))
|
||||
{
|
||||
float bouncespeed;
|
||||
float bouncestop = ent->xv->bouncestop;
|
||||
|
@ -1443,7 +1448,7 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
|
|||
bouncespeed = DotProduct(trace.plane.normal, ent->v->velocity);
|
||||
else
|
||||
bouncespeed = -DotProduct(gravitydir, ent->v->velocity);
|
||||
if (bouncespeed < bouncestop || ent->v->movetype != MOVETYPE_BOUNCE )
|
||||
if (bouncespeed < bouncestop || movetype != MOVETYPE_BOUNCE )
|
||||
{
|
||||
ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
|
||||
ent->v->groundentity = EDICT_TO_PROG(w->progs, trace.ent);
|
||||
|
|
Loading…
Reference in a new issue