update native-menu things.

attempt to deal with misaligned bsp models.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5258 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2018-06-02 08:55:57 +00:00
parent b1b5fcf4fb
commit ac471dd03e
42 changed files with 581 additions and 227 deletions

View file

@ -25,9 +25,13 @@
struct vfsfile_s;
struct serverinfo_s;
struct searchpathfuncs_s;
struct model_s;
struct font_s;
struct shader_s;
enum slist_test_e;
enum hostcachekey_e; //obtained via calls to gethostcacheindexforkey
enum fs_relative;
enum com_tokentype_e;
#ifndef __QUAKEDEF_H__
#ifdef __cplusplus
typedef enum {qfalse, qtrue} qboolean;//false and true are forcivly defined.
@ -72,8 +76,39 @@ struct menu_inputevent_args_s
};
};
typedef enum
{
MI_INIT, //initial startup
MI_RENDERER, //renderer restarted, any models/shaders/textures handles are no longer valid
MI_RESOLUTION, //video mode changed (scale or physical size) but without any gpu resources getting destroyed. you'll want to reload fonts.
} mintreason_t;
typedef struct
{
struct model_s *model;
int frame[2];
float frametime[2];
float frameweight[2];
vec4_t matrix[3]; //axis/angles+origin
} menuentity_t;
typedef struct
{
//these are in virtual coords, thus they need to be floats so that they can be rounded to ints more cleanly... yeah, scaling sucks.
vec2_t pos;
vec2_t size;
float time; //affects shader effects
vec_t fov[2];
vec4_t viewmatrix[3];
struct model_s *worldmodel;
int numentities;
menuentity_t *entlist;
} menuscene_t;
typedef struct {
int api_version; //this may be higher than you expect.
const char *engine_version;
int (*checkextension) (const char *ext);
void (*error) (const char *err);
@ -81,9 +116,13 @@ typedef struct {
void (*dprintf) (const char *text, ...);
void (*localcmd) (const char *cmd);
float (*cvar_float) (const char *name);
const char *(*cvar_string) (const char *name); //return value lasts until cvar_set is called, etc, so don't cache.
const char *(*cvar_string) (const char *name, qboolean effective); //NULL if it doesn't exist. return value lasts until cvar_set is called, etc, so don't cache. effective=true reports its active value, not the value that the user wanted.
const char *(*cvar_default) (const char *name);
void (*cvar_set) (const char *name, const char *value);
void (*registercvar) (const char *name, const char *defaultvalue, unsigned int flags, const char *description);
void (*registercommand) (const char *name, const char *description);
char *(*parsetoken) (const char *data, char *out, int outlen, enum com_tokentype_e *toktype);
int (*isserver) (void);
int (*getclientstate) (void);
@ -94,21 +133,24 @@ typedef struct {
void (*fclose) (struct vfsfile_s *fhandle);
char *(*fgets) (struct vfsfile_s *fhandle, char *out, size_t outsize); //returns output buffer, or NULL
void (*fprintf) (struct vfsfile_s *fhandle, const char *s, ...);
void (*EnumerateFiles) (const char *match, int (QDECL *callback)(const char *fname, qofs_t fsize, time_t mtime, void *ctx, struct searchpathfuncs_s *package), void *ctx);
void (*enumeratefiles) (const char *match, int (QDECL *callback)(const char *fname, qofs_t fsize, time_t mtime, void *ctx, struct searchpathfuncs_s *package), void *ctx);
// Drawing stuff
// int (*iscachedpic) (const char *name);
void *(*precache_pic) (const char *name);
int (*drawgetimagesize) (void *pic, int *x, int *y);
void (*drawquad) (vec2_t position[4], vec2_t texcoords[4], void *pic, vec4_t rgba, unsigned int be_flags);
// void (*drawsubpic) (vec2_t pos, vec2_t sz, const char *pic, vec2_t srcpos, vec2_t srcsz, vec4_t rgba, unsigned int be_flags);
// void (*drawfill) (vec2_t position, vec2_t size, vec4_t rgba, unsigned int be_flags);
// float (*drawcharacter) (vec2_t position, int character, vec2_t scale, vec4_t rgba, unsigned int be_flags);
// float (*drawrawstring) (vec3_t position, char *text, vec3_t scale, vec4_t rgba, unsigned int be_flags);
float (*drawstring) (vec2_t position, const char *text, float height, vec4_t rgba, unsigned int be_flags);
float (*stringwidth) (const char *text, float height);
void (*drawsetcliparea) (float x, float y, float width, float height);
void (*drawresetcliparea) (void);
struct shader_s *(*cachepic)(const char *name);
qboolean (*drawgetimagesize)(struct shader_s *pic, int *x, int *y);
void (*drawquad) (const vec2_t position[4], const vec2_t texcoords[4], struct shader_s *pic, const vec4_t rgba, unsigned int be_flags);
float (*drawstring) (vec2_t position, const char *text, struct font_s *font, float height, const vec4_t rgba, unsigned int be_flags);
float (*stringwidth) (const char *text, struct font_s *font, float height);
struct font_s *(*loadfont) (const char *facename, float intendedheight); //with ttf fonts, you'll probably want one for each size.
void (*destroyfont) (struct font_s *font);
// 3D scene stuff
struct model_s *(*cachemodel)(const char *name);
void (*getmodelsize) (struct model_s *model, vec3_t out_mins, vec3_t out_maxs);
void (*renderscene) (menuscene_t *scene);
// Menu specific stuff
qboolean (*setkeydest) (qboolean focused); //returns whether it changed.
@ -119,39 +161,39 @@ typedef struct {
int (*findkeysforcommand) (int bindmap, const char *command, int *out_scancodes, int *out_modifiers, int keycount);
// Server browser stuff
int (*gethostcachevalue) (int type);
enum hostcachekey_e (*gethostcacheindexforkey) (const char *key);
struct serverinfo_s *(*getsortedhost) (int idx);
char *(*gethostcachestring) (struct serverinfo_s *host, enum hostcachekey_e fld);
float (*gethostcachenumber) (struct serverinfo_s *host, enum hostcachekey_e fld);
void (*resethostcachemasks) (void);
void (*sethostcachemaskstring) (qboolean or, enum hostcachekey_e fld, char *str, enum slist_test_e op);
void (*sethostcachemaskstring) (qboolean or, enum hostcachekey_e fld, const char *str, enum slist_test_e op);
void (*sethostcachemasknumber) (qboolean or, enum hostcachekey_e fld, int num, enum slist_test_e op);
void (*sethostcachesort) (enum hostcachekey_e fld, qboolean descending);
void (*resorthostcache) (void);
struct serverinfo_s *(*getsortedhost) (int idx);
int (*resorthostcache) (void);
void (*refreshhostcache) (qboolean fullreset);
enum hostcachekey_e (*gethostcacheindexforkey) (const char *key);
qboolean (*sendhostcachequeries) (void); //returns true while there are still waiting for servers. should be called each frame while you still care about the servers.
} menu_import_t;
typedef struct {
int api_version;
void (*Init) (void);
void (*Shutdown) (void);
void (*Draw) (int width, int height, float frametime);
void (*DrawLoading) (int width, int height, float frametime);
void (*Init) (mintreason_t reason, float vwidth, float vheight, int pwidth, int pheight);
void (*Shutdown) (mintreason_t reason);
void (*Draw) (double frametime);
void (*DrawLoading) (double frametime);
void (*Toggle) (int wantmode);
int (*InputEvent) (struct menu_inputevent_args_s ev);
void (*ConsoleCommand) (const char *cmd);
qboolean(*ConsoleCommand) (const char *cmdline, int argc, char const*const*argv);
} menu_export_t;
#ifndef NATIVEEXPORT
#ifdef _WIN32
#define NATIVEEXPORTPROTO QDECL
#define NATIVEEXPORT __declspec(dllexport) NATIVEEXPORTPROTO
#define NATIVEEXPORTPROTO __declspec(dllexport)
#define NATIVEEXPORT NATIVEEXPORTPROTO
#else
#define NATIVEEXPORTPROTO
#define NATIVEEXPORT __attribute__((visibility("default")))
#endif
#endif
menu_export_t *NATIVEEXPORTPROTO GetMenuAPI (menu_import_t *import);
NATIVEEXPORTPROTO menu_export_t *QDECL GetMenuAPI (menu_import_t *import);

View file

@ -4716,6 +4716,8 @@ unsigned int Host_GuessFileType(const char *mimetype, const char *filename)
{HRF_MODEL, "psk"},
{HRF_MODEL, "zym"},
{HRF_MODEL, "dpm"},
{HRF_MODEL, "gltf"},
{HRF_MODEL, "glb"},
//sprites
{HRF_MODEL, "spr"},
{HRF_MODEL, "spr2"},

View file

@ -1461,7 +1461,7 @@ static int CL_LoadSounds(int stage, qboolean dontactuallyload)
void Sound_CheckDownload(const char *s)
{
#ifndef QUAKETC
#if !defined(QUAKETC) && defined(AVAIL_OGGVORBIS)
char mangled[512];
#endif
if (*s == '*') //q2 sexed sound

View file

@ -1251,6 +1251,9 @@ qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, cons
#else
NULL,
#endif
NULL,
Image_GetTexture,
FS_OpenVFS
};
if (VM_LONG(arg[0]) >= sizeof(funcs))
return (qintptr_t)&funcs;

View file

@ -1899,7 +1899,7 @@ void SCR_DrawLoading (qboolean opaque)
#ifdef MENU_NATIVECODE
if (mn_entry && mn_entry->DrawLoading)
{
mn_entry->DrawLoading(vid.width, vid.height, host_frametime);
mn_entry->DrawLoading(host_frametime);
return;
}
#endif
@ -3397,7 +3397,7 @@ void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
#endif
#ifdef MENU_NATIVECODE
if (mn_entry)
mn_entry->Draw(vid.width, vid.height, host_frametime);
mn_entry->Draw(host_frametime);
#endif
M_Draw (uimenu);

View file

@ -1665,6 +1665,7 @@ const char *Media_Send_GetProperty(cin_t *cin, const char *key);
#define Media_StopFilm(a) (void)true
#endif
void Media_SaveTracks(vfsfile_t *outcfg);
void Media_Init(void);
qboolean Media_NamedTrack(const char *initialtrack, const char *looptrack); //new background music interface
void Media_NumberedTrack(unsigned int initialtrack, unsigned int looptrack); //legacy cd interface for protocols that only support numbered tracks.

View file

@ -1323,7 +1323,7 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
i = 0;
x = left;
if (con->commandcompletion && con_showcompletion.ival)
if (con->commandcompletion && con_showcompletion.ival && text[0] && !(text[0] == '/' && !text[1]))
{
if (cl_chatmode.ival && (text[0] == '/' || (cl_chatmode.ival == 2 && Cmd_IsCommand(text))))
{ //color the first token yellow, it's a valid command
@ -1337,7 +1337,7 @@ int Con_DrawInput (console_t *con, qboolean focused, int left, int right, int y,
{
int cmdstart;
cmdstart = text[0] == '/'?1:0;
fname = Cmd_CompleteCommand(text+cmdstart, true, true, con_commandmatch, NULL);
fname = Cmd_CompleteCommand(text+cmdstart, true, true, max(1, con_commandmatch), NULL);
if (fname && strlen(fname) < 256) //we can compleate it to:
{
for (p = min(strlen(fname), key_linepos-cmdstart); fname[p]>0; p++)

View file

@ -5355,6 +5355,8 @@ static void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int fla
#if 0//def DECOMPRESS_BPTC
case PTI_BC6_RGBFU:
case PTI_BC6_RGBFS:
rcoding = PTI_RGBA16F;
break;
case PTI_BC7_RGBA:
case PTI_BC7_RGBA_SRGB:
rcoding = PTI_ZOMGWTF;
@ -5412,6 +5414,10 @@ static void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int fla
return;
}
//Fixme: PTI_E5BGR9 -> PTI_RGBA32F
//Fixme: PTI_RGBA16F -> PTI_RGBA32F
//FIXME: PTI_RGBA32F -> PTI_RGBA8
if ((mips->encoding == PTI_RGBX8 && sh_config.texfmt[PTI_BGRX8]) ||
(mips->encoding == PTI_BGRX8 && sh_config.texfmt[PTI_RGBX8]) ||
(mips->encoding == PTI_RGBA8 && sh_config.texfmt[PTI_BGRA8]) ||
@ -6598,7 +6604,8 @@ static qboolean Image_LocateHighResTexture(image_t *tex, flocation_t *bestloc, c
int firstex = (tex->flags & IF_EXACTEXTENSION)?tex_extensions_count-1:0;
flocation_t loc;
if (strncmp(tex->ident, "http:", 5) && strncmp(tex->ident, "https:", 6))
for(altname = tex->ident;altname;altname = nextalt)
{
nextalt = strchr(altname, ':');
@ -6978,7 +6985,14 @@ static void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t
if (tex->fallbackdata)
{
if (Image_LoadRawTexture(tex, tex->flags, tex->fallbackdata, (char*)tex->fallbackdata+(tex->fallbackwidth*tex->fallbackheight), tex->fallbackwidth, tex->fallbackheight, tex->fallbackfmt))
if (tex->fallbackfmt == TF_INVALID)
{
void *data = tex->fallbackdata;
tex->fallbackdata = NULL;
if (Image_LoadTextureFromMemory(tex, tex->flags, tex->ident, fname, data, tex->fallbackwidth))
return;
}
else if (Image_LoadRawTexture(tex, tex->flags, tex->fallbackdata, (char*)tex->fallbackdata+(tex->fallbackwidth*tex->fallbackheight), tex->fallbackwidth, tex->fallbackheight, tex->fallbackfmt))
{
tex->fallbackdata = NULL;
return;
@ -7098,7 +7112,7 @@ static void Image_Downloaded(struct dl_download *dl)
#endif
//find a texture. will try to load it from disk, using the fallback if it would fail.
image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt)
image_t *QDECL Image_GetTexture(const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt)
{
image_t *tex;
@ -7135,6 +7149,10 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
int b = fallbackwidth*fallbackheight, pb = 0;
switch(fallbackfmt)
{
case TF_INVALID:
b = fallbackwidth;
pb = fallbackheight;
break;
case TF_8PAL24:
pb = 3*256;
b *= 1;
@ -7414,7 +7432,7 @@ void Image_List_f(void)
Q_strncpyz(defuck, loc.search->logicalpath, sizeof(defuck));
while((bullshit=strchr(defuck, '\\')))
*bullshit = '/';
Con_Printf("^[%s\\desc\\%s/%s^]: ", tex->ident, defuck, fname);
Con_Printf("^[%s\\tip\\%s/%s^]: ", tex->ident, defuck, fname);
}
else
Con_Printf("%s: ", tex->ident);

View file

@ -122,7 +122,7 @@ static cvar_t joy_exponent = CVARD("joyexponent", "3", "Scales joystick/controll
static cvar_t joy_radialdeadzone = CVARD("joyradialdeadzone", "1", "Treat controller dead zones as a pair, rather than per-axis.");
#define EVENTQUEUELENGTH 512
#define EVENTQUEUELENGTH 1024
struct eventlist_s
{
enum
@ -747,7 +747,7 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum, float frame
ev.mouse.delta[0] = mx;
ev.mouse.delta[1] = my;
ev.mouse.screen[0] = (mouse->oldpos[0] * vid.width) / vid.pixelwidth;
ev.mouse.screen[1] = (mouse->oldpos[1] * vid.width) / vid.pixelwidth;
ev.mouse.screen[1] = (mouse->oldpos[1] * vid.height) / vid.pixelheight;
if (mn_entry->InputEvent(ev))
{
mx = 0;
@ -1048,7 +1048,10 @@ z is height... generally its used as a mousewheel instead, but there are some '3
*/
void IN_MouseMove(unsigned int devid, int abs, float x, float y, float z, float size)
{
struct eventlist_s *ev = in_newevent();
struct eventlist_s *ev;
if (!abs && !x && !y && !z)
return; //ignore non-movements
ev = in_newevent();
if (!ev)
return;
ev->devid = devid;

View file

@ -554,6 +554,7 @@ static void INS_DeactivateMouse (void)
ClipCursor (NULL);
ReleaseCapture ();
SetCursorPos(window_rect.left+mousecursor_x, window_rect.top+mousecursor_y);
}
mouseactive = false;

View file

@ -2838,7 +2838,7 @@ void Key_Event (unsigned int devid, int key, unsigned int unicode, qboolean down
{
if (mn_entry)
{
struct menu_inputevent_args_s ev = {MIE_KEYDOWN, devid};
struct menu_inputevent_args_s ev = {down?MIE_KEYDOWN:MIE_KEYUP, devid};
ev.key.scancode = key;
ev.key.charcode = unicode;
if (mn_entry->InputEvent(ev))

View file

@ -244,6 +244,7 @@ K_MAX
#define K_ALT K_LALT
#define K_WIN K_LWIN
#ifdef __QUAKEDEF_H__
typedef enum //highest has priority
{
kdm_game = 1u<<0, //should always be set
@ -251,7 +252,7 @@ typedef enum //highest has priority
kdm_message = 1u<<2,
kdm_gmenu = 1u<<3, //menu.dat
#ifdef MENU_NATIVECODE
kdm_nmenu = 1u<<4,
kdm_nmenu = 1u<<4, //should probably reuse gmenu...
#else
kdm_nmenu = 0,
#endif
@ -315,6 +316,6 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode);
struct console_s;
qboolean Key_GetConsoleSelectionBox(struct console_s *con, int *sx, int *sy, int *ex, int *ey);
qboolean Key_MouseShouldBeFree(void);
#endif
#endif

View file

@ -2700,7 +2700,7 @@ void PM_Command_f(void)
Con_Printf("Applying package changes\n");
if (qrenderer != QR_NONE)
PM_PromptApplyChanges();
else
else if (Cmd_ExecLevel == RESTRICT_LOCAL)
PM_ApplyChanges();
}
else if (!strcmp(act, "changes"))

View file

@ -1945,6 +1945,8 @@ static int M_Main_AddExtraOptions(menu_t *mainm, int y)
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "IRC ", "irc\n"); y += 20;}
if (Cmd_Exists("qi"))
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Quake Injector", "qi\n"); y += 20;}
// else if (PM_CanInstall("qi"))
// {MC_AddConsoleCommandQBigFont(mainm, 72, y, "Quake Injector", "pkg reset; pkg add qi; pkg apply\n"); y += 20;}
if (Cmd_Exists("menu_download"))
{MC_AddConsoleCommandQBigFont(mainm, 72, y, "Updates ", "menu_download\n"); y += 20;}
@ -2141,7 +2143,7 @@ void M_Menu_Main_f (void)
}
else
{
int width, y;
int width;
Key_Dest_Add(kdm_emenu);
mainm = M_CreateMenu(0);

View file

@ -352,7 +352,7 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack)
{
"",
#if defined(AVAIL_OGGOPUS) || defined(FTE_TARGET_WEB)
".opus",
".opus", //opus might be the future, but ogg is the present
#endif
#if defined(AVAIL_OGGVORBIS) || defined(FTE_TARGET_WEB)
".ogg",
@ -364,8 +364,9 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack)
NULL
};
char trackname[MAX_QPATH];
char tryname[MAX_QPATH];
int bestdepth = 0x7fffffff, d;
int ie, ip;
qboolean found = false;
char *trackend;
if (!track || !*track) //ignore calls if the primary track is invalid. whatever is already playing will continue to play.
@ -394,11 +395,11 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack)
if (!tracknum) //might as well require exact file
{
Q_snprintfz(trackname, sizeof(trackname), "%s", track);
found = COM_FCheckExists(trackname);
d = COM_FCheckExists(trackname);
}
else
#endif
for(ip = 0; path[ip] && !found; ip++)
for(ip = 0; path[ip]; ip++)
{
if (tracknum)
{
@ -406,33 +407,49 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack)
{
if (tracknum <= 999)
{
for(ie = 0; ext[ie] && !found; ie++)
for(ie = 0; ext[ie]; ie++)
{
Q_snprintfz(trackname, sizeof(trackname), "%strack%03u%s", path[ip], tracknum, ext[ie]);
found = COM_FCheckExists(trackname);
Q_snprintfz(tryname, sizeof(tryname), "%strack%03u%s", path[ip], tracknum, ext[ie]);
d = COM_FDepthFile(tryname, false);
if (d < bestdepth)
{
bestdepth = d;
Q_strncpy(trackname, tryname, sizeof(trackname));
}
}
}
if (tracknum <= 99)
{
for(ie = 0; ext[ie] && !found; ie++)
for(ie = 0; ext[ie]; ie++)
{
Q_snprintfz(trackname, sizeof(trackname), "%strack%02u%s", path[ip], tracknum, ext[ie]);
found = COM_FCheckExists(trackname);
Q_snprintfz(tryname, sizeof(tryname), "%strack%02u%s", path[ip], tracknum, ext[ie]);
d = COM_FDepthFile(tryname, false);
if (d < bestdepth)
{
bestdepth = d;
Q_strncpy(trackname, tryname, sizeof(trackname));
}
}
}
}
}
else
{
for(ie = 0; ext[ie] && !found; ie++)
for(ie = 0; ext[ie]; ie++)
{
Q_snprintfz(trackname, sizeof(trackname), "%s%s%s", path[ip], track, ext[ie]);
found = COM_FCheckExists(trackname);
Q_snprintfz(tryname, sizeof(tryname), "%s%s%s", path[ip], track, ext[ie]);
d = COM_FDepthFile(tryname, false);
if (d < bestdepth)
{
bestdepth = d;
Q_strncpy(trackname, tryname, sizeof(trackname));
}
}
}
}
if (found)
//okay, do that faketrack thing if we got one.
if (bestdepth < 0x7fffffff)
{
#ifdef HAVE_CDPLAYER
cdplaytracknum = 0;
@ -444,11 +461,11 @@ qboolean Media_NamedTrack(const char *track, const char *looptrack)
}
#ifdef HAVE_CDPLAYER
//couldn't do a faketrack, resort to actual cd tracks, if we're allowed
if (tracknum && cdenabled)
{
Q_strncpyz(media_loopingtrack, looptrack, sizeof(media_loopingtrack));
//couldn't do a faketrack, resort to actual cd tracks, if we're allowed
if (!CDAudio_Startup())
return false;
if (cdnumtracks <= 0)
@ -526,6 +543,14 @@ void Media_SetPauseTrack(qboolean paused)
}
#ifdef HAVE_CDPLAYER
void Media_SaveTracks(vfsfile_t *outcfg)
{
unsigned int n;
char buf[MAX_QPATH*4];
for (n = 1; n < REMAPPED_TRACKS; n++)
if (*cdremap[n].fname)
Con_Printf("cd remap %u %s\n", n, COM_QuotedString(cdremap[n].fname, buf, sizeof(buf), false));
}
void CD_f (void)
{
char *command;

View file

@ -8,7 +8,7 @@ extern unsigned int r2d_be_flags;
#include "shader.h"
#include "cl_master.h"
static int MN_checkextension(const char *extname)
static int MN_CheckExtension(const char *extname)
{
unsigned int i;
for (i = 0; i < QSG_Extensions_count; i++)
@ -18,15 +18,41 @@ static int MN_checkextension(const char *extname)
}
return false;
}
static void MN_localcmd(const char *text)
static void MN_LocalCmd(const char *text)
{
Cbuf_AddText(text, RESTRICT_LOCAL); //menus are implicitly trusted. latching and other stuff would be a nightmare otherwise.
}
static void MN_registercvar(const char *cvarname, const char *defaulttext, unsigned int flags, const char *description)
static const char *MN_Cvar_String(const char *cvarname, qboolean effective)
{
cvar_t *cv = Cvar_FindVar(cvarname);
if (cv)
{ //some cvars don't change instantly, giving them (temporary) effective values that are different from their intended values.
if (cv->latched_string && !effective)
return cv->latched_string;
return cv->string;
}
else
return NULL;
}
static const char *MN_Cvar_GetDefault(const char *cvarname)
{
cvar_t *cv = Cvar_FindVar(cvarname);
if (cv)
return cv->defaultstr?cv->defaultstr:"";
else
return NULL;
}
static void MN_RegisterCvar(const char *cvarname, const char *defaulttext, unsigned int flags, const char *description)
{
Cvar_Get2(cvarname, defaulttext, flags, description, NULL);
}
static int MN_getserverstate(void)
void Cmd_DeleteAlias(const char *name);
static void MN_RegisterCommand(const char *commandname, const char *description)
{
Cmd_DeleteAlias(commandname); //menuqc has no real way to register commands, so it has a nasty habit of creating loads of weird awkward aliases.
Cmd_AddCommandD(commandname, NULL, description);
}
static int MN_GetServerState(void)
{
if (!sv.active)
return 0;
@ -34,7 +60,7 @@ static int MN_getserverstate(void)
return 1;
return 2;
}
static int MN_getclientstate(void)
static int MN_GetClientState(void)
{
if (cls.state >= ca_active)
return 2;
@ -46,50 +72,60 @@ static void MN_fclose(vfsfile_t *f)
{
VFS_CLOSE(f);
}
static void *MN_precache_pic(const char *picname)
static shader_t *MN_CachePic(const char *picname)
{
return R2D_SafeCachePic(picname);
}
static int MN_drawgetimagesize(void *pic, int *w, int *h)
static qboolean MN_DrawGetImageSize(void *pic, int *w, int *h)
{
return R_GetShaderSizes(pic, w, h, true);
return R_GetShaderSizes(pic, w, h, true)>0;
}
static void MN_drawquad(vec2_t position[4], vec2_t texcoords[4], void *pic, vec4_t rgba, unsigned int be_flags)
static void MN_DrawQuad(const vec2_t position[4], const vec2_t texcoords[4], shader_t *pic, const vec4_t rgba, unsigned int be_flags)
{
extern shader_t *shader_draw_fill, *shader_draw_fill_trans;
r2d_be_flags = be_flags;
if (!pic)
pic = rgba[3]==1?shader_draw_fill:shader_draw_fill_trans;
R2D_ImageColours(rgba[0], rgba[1], rgba[2], rgba[3]);
R2D_Image2dQuad(position, texcoords, pic);
r2d_be_flags = 0;
}
static float MN_drawstring(vec2_t position, const char *text, float height, vec4_t rgba, unsigned int be_flags)
static float MN_DrawString(const vec2_t position, const char *text, struct font_s *font, float height, const vec4_t rgba, unsigned int be_flags)
{
float px, py, ix;
unsigned int codeflags, codepoint;
conchar_t buffer[2048], *str = buffer;
if (!font)
font = font_default;
COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), false);
Font_BeginScaledString(font_default, position[0], position[1], height, height, &px, &py);
R2D_ImageColours(rgba[0], rgba[1], rgba[2], rgba[3]);
Font_BeginScaledString(font, position[0], position[1], height, height, &px, &py);
ix=px;
while(*str)
{
str = Font_Decode(str, &codeflags, &codepoint);
px = Font_DrawScaleChar(px, py, codeflags, codepoint);
}
Font_EndString(font_default);
Font_EndString(font);
return ((px-ix)*(float)vid.width)/(float)vid.rotpixelwidth;
}
static float MN_stringwidth(const char *text, float height)
static float MN_StringWidth(const char *text, struct font_s *font, float height)
{
float px, py;
conchar_t buffer[2048], *end;
if (!font)
font = font_default;
end = COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), false);
Font_BeginScaledString(font_default, 0, 0, height, height, &px, &py);
Font_BeginScaledString(font, 0, 0, height, height, &px, &py);
px = Font_LineScaleWidth(buffer, end);
Font_EndString(font_default);
Font_EndString(font);
return (px * (float)vid.width) / (float)vid.rotpixelwidth;
}
static void MN_drawsetcliparea(float x, float y, float width, float height)
static void MN_DrawSetClipArea(float x, float y, float width, float height)
{
srect_t srect;
if (R2D_Flush)
@ -104,13 +140,13 @@ static void MN_drawsetcliparea(float x, float y, float width, float height)
srect.y = (1-srect.y) - srect.height;
BE_Scissor(&srect);
}
static void MN_drawresetcliparea(void)
static void MN_DrawResetClipArea(void)
{
if (R2D_Flush)
R2D_Flush();
BE_Scissor(NULL);
}
static qboolean MN_setkeydest(qboolean focused)
static qboolean MN_SetKeyDest(qboolean focused)
{
qboolean ret = Key_Dest_Has(kdm_nmenu);
if (ret == focused)
@ -119,9 +155,10 @@ static qboolean MN_setkeydest(qboolean focused)
{
if (key_dest_absolutemouse & kdm_nmenu)
{ //we're activating the mouse cursor now... make sure the position is actually current.
//FIXME: we should probably get the input code to do this for us when switching cursor modes.
struct menu_inputevent_args_s ev = {MIE_MOUSEABS, -1};
ev.mouse.screen[0] = mousecursor_x;
ev.mouse.screen[1] = mousecursor_y;
ev.mouse.screen[0] = (mousecursor_x * vid.width) / vid.pixelwidth;
ev.mouse.screen[1] = (mousecursor_y * vid.height) / vid.pixelheight;
mn_entry->InputEvent(ev);
}
Key_Dest_Add(kdm_nmenu);
@ -130,7 +167,7 @@ static qboolean MN_setkeydest(qboolean focused)
Key_Dest_Remove(kdm_nmenu);
return true;
}
static int MN_getkeydest(void)
static int MN_GetKeyDest(void)
{
if (Key_Dest_Has(kdm_nmenu))
{
@ -140,7 +177,7 @@ static int MN_getkeydest(void)
}
return 0;
}
static int MN_setmousetarget(const char *cursorname, float hot_x, float hot_y, float scale)
static int MN_SetMouseTarget(const char *cursorname, float hot_x, float hot_y, float scale)
{
if (cursorname)
{
@ -162,12 +199,108 @@ static int MN_setmousetarget(const char *cursorname, float hot_x, float hot_y, f
return true;
}
static model_t *MN_CacheModel(const char *name)
{
return Mod_ForName(name, MLV_SILENT);
}
static qboolean MN_GetModelSize(model_t *model, vec3_t out_mins, vec3_t out_maxs)
{
if (model)
{
while(model->loadstate == MLS_LOADING)
COM_WorkerPartialSync(model, &model->loadstate, MLS_LOADING);
VectorCopy(model->mins, out_mins);
VectorCopy(model->maxs, out_maxs);
return model->loadstate == MLS_LOADED;
}
VectorClear(out_mins);
VectorClear(out_maxs);
return false;
}
static void MN_RenderScene(menuscene_t *scene)
{
int i;
entity_t ent;
menuentity_t *e;
if (R2D_Flush)
R2D_Flush();
CL_ClearEntityLists();
memset(&ent, 0, sizeof(ent));
for (i = 0; i < scene->numentities; i++)
{
e = &scene->entlist[i];
ent.keynum = i;
ent.model = scene->entlist[i].model;
VectorCopy(e->matrix[0], ent.axis[0]); ent.origin[0] = e->matrix[0][3];
VectorCopy(e->matrix[1], ent.axis[1]); ent.origin[1] = e->matrix[0][7];
VectorCopy(e->matrix[2], ent.axis[2]); ent.origin[2] = e->matrix[0][11];
ent.scale = 1;
ent.framestate.g[FS_REG].frame[0] = e->frame[0];
ent.framestate.g[FS_REG].frame[1] = e->frame[1];
ent.framestate.g[FS_REG].lerpweight[1] = e->frameweight[0];
ent.framestate.g[FS_REG].lerpweight[0] = e->frameweight[1];
ent.framestate.g[FS_REG].frametime[0] = e->frametime[0];
ent.framestate.g[FS_REG].frametime[1] = e->frametime[1];
ent.playerindex = -1;
ent.topcolour = TOP_DEFAULT;
ent.bottomcolour = BOTTOM_DEFAULT;
Vector4Set(ent.shaderRGBAf, 1, 1, 1, 1);
VectorSet(ent.glowmod, 1, 1, 1);
#ifdef HEXEN2
ent.drawflags = SCALE_ORIGIN_ORIGIN;
ent.abslight = 0;
#endif
ent.skinnum = 0;
ent.fatness = 0;
ent.forcedshader = NULL;
ent.customskin = 0;
V_AddAxisEntity(&ent);
}
VectorCopy(scene->viewmatrix[0], r_refdef.viewaxis[0]); r_refdef.vieworg[0] = scene->viewmatrix[0][3];
VectorCopy(scene->viewmatrix[1], r_refdef.viewaxis[1]); r_refdef.vieworg[1] = scene->viewmatrix[0][7];
VectorCopy(scene->viewmatrix[2], r_refdef.viewaxis[2]); r_refdef.vieworg[2] = scene->viewmatrix[0][11];
r_refdef.viewangles[0] = -(atan2(r_refdef.viewaxis[0][2], sqrt(r_refdef.viewaxis[0][1]*r_refdef.viewaxis[0][1]+r_refdef.viewaxis[0][0]*r_refdef.viewaxis[0][0])) * 180 / M_PI);
r_refdef.viewangles[1] = (atan2(r_refdef.viewaxis[0][1], r_refdef.viewaxis[0][0]) * 180 / M_PI);
r_refdef.viewangles[2] = 0;
r_refdef.flags = 0;
if (scene->worldmodel && scene->worldmodel == cl.worldmodel)
r_refdef.flags &= ~RDF_NOWORLDMODEL;
else
r_refdef.flags |= RDF_NOWORLDMODEL;
r_refdef.fovv_x = r_refdef.fov_x = scene->fov[0];
r_refdef.fovv_y = r_refdef.fov_y = scene->fov[1];
r_refdef.vrect.x = scene->pos[0];
r_refdef.vrect.y = scene->pos[1];
r_refdef.vrect.width = scene->size[0];
r_refdef.vrect.height = scene->size[1];
r_refdef.time = scene->time;
r_refdef.useperspective = true;
r_refdef.mindist = bound(0.1, gl_mindist.value, 4);
r_refdef.maxdist = gl_maxdist.value;
r_refdef.playerview = &cl.playerview[0];
memset(&r_refdef.globalfog, 0, sizeof(r_refdef.globalfog));
r_refdef.areabitsknown = false;
R_RenderView();
r_refdef.playerview = NULL;
r_refdef.time = 0;
}
void MN_Shutdown(void)
{
Key_Dest_Remove(kdm_nmenu);
if (mn_entry)
{
mn_entry->Shutdown();
mn_entry->Shutdown(MI_INIT);
mn_entry = NULL;
}
if (libmenu)
@ -182,19 +315,24 @@ qboolean MN_Init(void)
static menu_import_t imports =
{
NATIVEMENU_API_VERSION_MAX,
NULL,
MN_checkextension,
MN_CheckExtension,
Host_Error,
Con_Printf,
Con_DPrintf,
MN_localcmd,
MN_LocalCmd,
Cvar_VariableValue,
Cvar_VariableString,
MN_Cvar_String,
MN_Cvar_GetDefault,
Cvar_SetNamed,
MN_registercvar,
MN_RegisterCvar,
MN_RegisterCommand,
MN_getserverstate,
MN_getclientstate,
COM_ParseType,
MN_GetServerState,
MN_GetClientState,
S_LocalSound2,
// file input / search crap
@ -204,25 +342,37 @@ qboolean MN_Init(void)
VFS_PRINTF,
COM_EnumerateFiles,
// Drawing stuff
MN_precache_pic,
MN_drawgetimagesize,
MN_drawquad,
MN_drawstring,
MN_stringwidth,
MN_drawsetcliparea,
MN_drawresetcliparea,
// Drawing stuff
MN_DrawSetClipArea,
MN_DrawResetClipArea,
//pics
MN_CachePic,
MN_DrawGetImageSize,
MN_DrawQuad,
//strings
MN_DrawString,
MN_StringWidth,
Font_LoadFont,
Font_Free,
//3d stuff
MN_CacheModel,
MN_GetModelSize,
MN_RenderScene,
// Menu specific stuff
MN_setkeydest,
MN_getkeydest,
MN_setmousetarget,
MN_SetKeyDest,
MN_GetKeyDest,
MN_SetMouseTarget,
Key_KeynumToString,
Key_StringToKeynum,
M_FindKeysForBind,
// Server browser stuff
NULL,//MN_gethostcachevalue,
Master_KeyForName,
Master_SortedServer,
Master_ReadKeyString,
Master_ReadKeyFloat,
@ -231,10 +381,8 @@ qboolean MN_Init(void)
Master_SetMaskInteger,
Master_SetSortField,
Master_SortServers,
Master_SortedServer,
MasterInfo_Refresh,
Master_KeyForName,
CL_QueryServers,
};
dllfunction_t funcs[] =
{
@ -266,12 +414,14 @@ qboolean MN_Init(void)
if (libmenu)
{
imports.engine_version = version_string();
key_dest_absolutemouse |= kdm_nmenu;
mn_entry = pGetMenuAPI (&imports);
if (mn_entry && mn_entry->api_version >= NATIVEMENU_API_VERSION_MIN && mn_entry->api_version <= NATIVEMENU_API_VERSION_MAX)
{
mn_entry->Init();
mn_entry->Init(0, vid.width, vid.height, vid.pixelwidth, vid.pixelheight);
return true;
}
else

View file

@ -3041,6 +3041,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
shader_t *shader;
vec2_t fs = {8,8};
// float bones[12*MAX_BONES];
vec3_t lightpos = {0, 1, 0};
modelview_t *mods = c->dptr;
@ -3077,6 +3078,12 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
ent.scale = 1;
// ent.angles[1] = realtime*45;//mods->yaw;
// ent.angles[0] = realtime*23.4;//mods->pitch;
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorInverse(ent.axis[1]);
ent.model = Mod_ForName(mods->modelname, MLV_WARN);
if (!ent.model)
return; //panic!
@ -3104,15 +3111,35 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
ent.light_avg[0] = ent.light_avg[1] = ent.light_avg[2] = 0.66;
ent.light_range[0] = ent.light_range[1] = ent.light_range[2] = 0.33;
ent.light_dir[0] = 0; ent.light_dir[1] = 1; ent.light_dir[2] = 0;
V_ApplyRefdef();
/*
{
trace_t tr;
vec3_t worldmouse;
vec3_t mouse = {mousecursor_x/vid.width, 1-mousecursor_y/vid.height, 0.5};
float d;
Matrix4x4_CM_UnProject(mouse, worldmouse, r_refdef.viewangles, r_refdef.vieworg, r_refdef.fov_x, r_refdef.fov_y);
d = DotProduct(worldmouse, fwd);
VectorMA(worldmouse, -d, fwd, worldmouse);
if (ent.model->funcs.NativeTrace && ent.model->funcs.NativeTrace(ent.model, 0, &ent.framestate, ent.axis, r_refdef.vieworg, worldmouse, vec3_origin, vec3_origin, false, ~0, &tr))
;
else
VectorCopy(worldmouse, tr.endpos);
VectorCopy(tr.endpos, lightpos);
}
*/
VectorNormalize(lightpos);
ent.light_dir[0] = DotProduct(lightpos, ent.axis[0]);
ent.light_dir[1] = DotProduct(lightpos, ent.axis[1]);
ent.light_dir[2] = DotProduct(lightpos, ent.axis[2]);
ent.light_known = 2;
ent.angles[0]*=r_meshpitch.value;
AngleVectors(ent.angles, ent.axis[0], ent.axis[1], ent.axis[2]);
ent.angles[0]*=r_meshpitch.value;
VectorInverse(ent.axis[1]);
if (ent.model->type == mod_dummy)
{
Draw_FunString(0, 0, va("model \"%s\" not loaded", ent.model->name));
@ -3296,7 +3323,6 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
V_AddEntity(&ent);
V_ApplyRefdef();
R_RenderView();
y = 0;
@ -3477,8 +3503,8 @@ static qboolean M_ModelViewerKey(struct menucustom_s *c, struct menu_s *m, int k
if (key == 'w')
{
mods->dist *= 0.9;
if (mods->dist < 5)
mods->dist = 5;
if (mods->dist < 1)
mods->dist = 1;
}
else if (key == 's')
mods->dist /= 0.9;

View file

@ -484,7 +484,7 @@ qboolean MP_ConsoleCommand(const char *cmdtext);
#endif
#ifdef MENU_NATIVECODE
#include "../native/api_menu.h"
#include "api_menu.h"
extern menu_export_t *mn_entry;
void MN_Shutdown(void);
qboolean MN_Init(void);

View file

@ -104,7 +104,7 @@ void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque);
void R2D_EditorBackground (void);
void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic);
void R2D_Image2dQuad(vec2_t points[], vec2_t texcoords[], mpic_t *pic);
void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, mpic_t *pic);
void R2D_ImageColours(float r, float g, float b, float a);
void R2D_ImagePaletteColour(unsigned int i, float a);

View file

@ -67,9 +67,6 @@ extern cvar_t sv_listen_qw;
extern cvar_t sv_listen_nq;
extern cvar_t sv_listen_dp;
extern cvar_t sv_listen_q3;
#ifdef HAVE_DTLS
extern cvar_t sv_listen_dtls;
#endif
typedef struct {
enum masterprotocol_e protocol;

View file

@ -218,7 +218,7 @@ void PR_ReloadFonts(qboolean reload)
{ //otherwise load it.
for (j = 0; j < fontslot[i].sizes; j++)
{
fontslot[i].font[j] = Font_LoadFont(fontslot[i].size[j], fontslot[i].facename);
fontslot[i].font[j] = Font_LoadFont(fontslot[i].facename, fontslot[i].size[j]);
}
}
}
@ -285,7 +285,7 @@ void QCBUILTIN PF_CL_loadfont (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
if (qrenderer == QR_NONE)
fontslot[slotnum].font[i] = NULL;
else
fontslot[slotnum].font[i] = Font_LoadFont(fontslot[slotnum].size[i], facename);
fontslot[slotnum].font[i] = Font_LoadFont(facename, fontslot[slotnum].size[i]);
fontslot[slotnum].sizes++;
}
}
@ -395,7 +395,7 @@ void CL_LoadFont_f(void)
if (qrenderer == QR_NONE)
fontslot[slotnum].font[i] = NULL;
else
fontslot[slotnum].font[i] = Font_LoadFont(fontslot[slotnum].size[i], facename);
fontslot[slotnum].font[i] = Font_LoadFont(facename, fontslot[slotnum].size[i]);
fontslot[slotnum].sizes++;
}
}

View file

@ -662,7 +662,7 @@ void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2,
draw_mesh.numvertexes += 4;
draw_mesh.numindexes += 6;
}
void R2D_Image2dQuad(vec2_t points[], vec2_t texcoords[], mpic_t *pic)
void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, mpic_t *pic)
{
int i;
if (!pic)
@ -1061,9 +1061,9 @@ void R2D_Font_Changed(void)
LOGFONTW lf = {0};
CHOOSEFONTW cf = {sizeof(cf)};
extern HWND mainwindow;
font_default = Font_LoadFont(8, "");
font_default = Font_LoadFont("", 8);
if (tsize != 8)
font_console = Font_LoadFont(tsize, "");
font_console = Font_LoadFont("", tsize);
if (!font_console)
font_console = font_default;
@ -1102,18 +1102,27 @@ void R2D_Font_Changed(void)
}
#endif
font_default = Font_LoadFont(8, gl_font.string);
font_default = Font_LoadFont(gl_font.string, 8);
if (!font_default && *gl_font.string)
font_default = Font_LoadFont(8, "");
font_default = Font_LoadFont("", 8);
if (tsize != 8)
{
font_console = Font_LoadFont(tsize, gl_font.string);
font_console = Font_LoadFont(gl_font.string, tsize);
if (!font_console)
font_console = Font_LoadFont(tsize, "");
font_console = Font_LoadFont("", tsize);
}
if (!font_console)
font_console = font_default;
//these are here instead of R2D_Console_Resize because this is guarenteed to happen in a sane place, while R2D_Console_Resize can happen during waits.
#ifdef MENU_NATIVECODE
if (mn_entry)
mn_entry->Init(MI_RESOLUTION, vid.width, vid.height, vid.rotpixelwidth, vid.rotpixelheight);
#endif
#ifdef PLUGINS
Plug_ResChanged();
#endif
}
static void QDECL R2D_Font_Callback(struct cvar_s *var, char *oldvalue)
@ -1210,10 +1219,6 @@ void R2D_Console_Resize(void)
vid.height = cheight;
Cvar_ForceCallback(&gl_font);
#ifdef PLUGINS
Plug_ResChanged();
#endif
}
static void QDECL R2D_Conheight_Callback(struct cvar_s *var, char *oldvalue)

View file

@ -507,6 +507,7 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
rad = cl_dlights[lnum].radius;
VectorSubtract(cl_dlights[lnum].origin, currententity->origin, lightofs);
//FIXME: transform by forward/right/up
dist = DotProduct (lightofs, surf->plane->normal) - surf->plane->dist;
rad -= fabs(dist);
minlight = cl_dlights[lnum].minlight;

View file

@ -361,6 +361,7 @@ typedef struct {
qboolean modified;
qboolean external;
qboolean hasdeluxe;
uploadfmt_t fmt;
int width;
int height;
glRect_t rectchange;
@ -443,7 +444,7 @@ enum imageflags
image_t *Image_FindTexture (const char *identifier, const char *subpath, unsigned int flags);
image_t *Image_CreateTexture(const char *identifier, const char *subpath, unsigned int flags);
image_t *Image_GetTexture (const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt);
image_t *QDECL Image_GetTexture (const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt);
qboolean Image_UnloadTexture(image_t *tex); //true if it did something.
void Image_DestroyTexture (image_t *tex);
qboolean Image_LoadTextureFromMemory(texid_t tex, int flags, const char *iname, char *fname, qbyte *filedata, int filesize); //intended really for worker threads, but should be fine from the main thread too

View file

@ -1290,6 +1290,11 @@ void D3DSucks(void)
void R_ShutdownRenderer(qboolean devicetoo)
{
#ifdef MENU_NATIVECODE
if (mn_entry)
mn_entry->Shutdown(MI_RENDERER);
#endif
//make sure the worker isn't still loading stuff
COM_WorkerFullSync();

View file

@ -1222,7 +1222,7 @@ void Draw_TinyString (float x, float y, const qbyte *str)
if (!font_tiny)
{
font_tiny = Font_LoadFont(8, "gfx/tinyfont");
font_tiny = Font_LoadFont("gfx/tinyfont", 8);
if (!font_tiny)
return;
}

View file

@ -245,7 +245,7 @@ void Font_Init(void);
void Font_Shutdown(void);
int Font_RegisterTrackerImage(const char *image); //returns a unicode char value that can be used to embed the char within a line of text.
qboolean Font_TrackerValid(unsigned int imid);
struct font_s *Font_LoadFont(float height, const char *fontfilename);
struct font_s *Font_LoadFont(const char *fontfilename, float height);
void Font_Free(struct font_s *f);
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/

View file

@ -1922,10 +1922,7 @@ static void QDECL S_EnumeratedOutDevice(const char *driver, const char *deviceco
char nbuf[1024];
char dbuf[1024];
if (devicecode && ( strchr(devicecode, ' ') ||
strchr(devicecode, '\"')))
fullintname = va("\"%s:%s\"", driver, devicecode); //it'll all get escaped anyway. but yeah, needs to be a single token or our multi-device stuff won't work properly. yes, this is a bit of a hack.
else if (devicecode)
if (devicecode)
fullintname = va("%s:%s", driver, devicecode);
else
fullintname = driver;

View file

@ -1151,25 +1151,16 @@ static void Cmd_AliasEdit_f (void)
}
#endif
void Cmd_DeleteAlias(char *name)
void Cmd_DeleteAlias(const char *name)
{
cmdalias_t *a, *b;
if (!strcmp(cmd_alias->name, name))
cmdalias_t *a, **link;
for (link = &cmd_alias; (a = *link); link = &(*link)->next)
{
a = cmd_alias;
cmd_alias = cmd_alias->next;
Z_Free(a->value);
Z_Free(a);
return;
}
for (a = cmd_alias ; a ; a=a->next)
{
if (!strcmp(a->next->name, name))
if (!strcmp(a->name, name))
{
b = a->next;
a->next = b->next;
Z_Free(b->value);
Z_Free(b);
*link = a->next;
Z_Free(a->value);
Z_Free(a);
return;
}
}
@ -2732,6 +2723,10 @@ void Cmd_ExecuteString (const char *text, int level)
#if defined(MENU_DAT) && !defined(SERVERONLY)
if (MP_ConsoleCommand(text))
return; //let the csqc handle it if it wants.
#endif
#if defined(MENU_NATIVECODE)
if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, cmd_argv))
return;
#endif
Cmd_ForwardToServer ();
}
@ -2894,6 +2889,10 @@ void Cmd_ExecuteString (const char *text, int level)
if (MP_ConsoleCommand(text))
return; //let the csqc handle it if it wants.
#endif
#if defined(MENU_NATIVECODE)
if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, cmd_argv))
return;
#endif
#ifdef PLUGINS
if (Plugin_ExecuteString())
@ -3975,6 +3974,11 @@ void Cmd_WriteConfig_f(void)
Key_WriteBindings (f);
if (cfg_save_buttons.ival)
IN_WriteButtons(f, all);
#ifdef HAVE_CDPLAYER
// if (cfg_save_cdtracks.ival)
Media_SaveTracks(f);
#endif
if (cfg_save_infos.ival)
CL_SaveInfo(f);
#else

View file

@ -2027,7 +2027,12 @@ void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader)
continue;
#else
if (!mod->numanimations)
continue;
{
if (mod->ofs_skel_xyz)
posedata = mod->ofs_skel_xyz;
else
continue;
}
else
{
galiaspose_t *pose;

View file

@ -158,6 +158,7 @@ typedef struct galiasinfo_s
//#ifndef SERVERONLY
vec2_t *ofs_st_array;
vec2_t *ofs_lmst_array;
vec4_t *ofs_rgbaf;
byte_vec4_t *ofs_rgbaub;
//#endif
@ -227,9 +228,16 @@ typedef struct modplugfuncs_s
struct terrainfuncs_s *(QDECL *GetTerrainFuncs)(void);
void *reserved2;
image_t *(QDECL *GetTexture)(const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt);
vfsfile_t *(QDECL *OpenVFS)(const char *filename, const char *mode, enum fs_relative relativeto);
void *unused3;
void *unused4;
void *unused5;
void *unused6;
void *unused7;
void *unused8;
void *unused9;
void *unused10;
} modplugfuncs_t;
#define MODPLUGFUNCS_VERSION 2

View file

@ -365,8 +365,6 @@ extern char com_token[65536];
typedef enum {TTP_UNKNOWN, TTP_STRING, TTP_LINEENDING, TTP_RAWTOKEN, TTP_EOF, TTP_PUNCTUATION} com_tokentype_t;
extern com_tokentype_t com_tokentype;
extern qboolean com_eof;
//these cast away the const for the return value.
//char *COM_Parse (const char *data);
#define COM_Parse(d) COM_ParseOut(d,com_token, sizeof(com_token))
@ -587,7 +585,7 @@ qboolean FS_Copy(const char *source, const char *dest, enum fs_relative relative
qboolean FS_NativePath(const char *fname, enum fs_relative relativeto, char *out, int outlen); //if you really need to fopen yourself
qboolean FS_WriteFile (const char *filename, const void *data, int len, enum fs_relative relativeto);
void *FS_MallocFile(const char *filename, enum fs_relative relativeto, qofs_t *filesize);
vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto);
vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto);
vfsfile_t *FS_OpenTemp(void);
vfsfile_t *FS_OpenTCP(const char *name, int defaultport);

View file

@ -795,7 +795,7 @@ static int QDECL COM_Dir_List(const char *name, qofs_t size, time_t mtime, void
Q_snprintfz(link, sizeof(link), "\\tip\\Change Map\\map\\%s", name+5);
colour = "^4"; //disconnects
}
else if (!Q_strcasecmp(link, "bsp") || !Q_strcasecmp(link, "spr") || !Q_strcasecmp(link, "mdl") || !Q_strcasecmp(link, "md3") || !Q_strcasecmp(link, "iqm") || !Q_strcasecmp(link, "vvm") || !Q_strcasecmp(link, "psk") || !Q_strcasecmp(link, "dpm") || !Q_strcasecmp(link, "zym") || !Q_strcasecmp(link, "md5mesh") || !Q_strcasecmp(link, "md5anim"))
else if (!Q_strcasecmp(link, "bsp") || !Q_strcasecmp(link, "spr") || !Q_strcasecmp(link, "mdl") || !Q_strcasecmp(link, "md3") || !Q_strcasecmp(link, "iqm") || !Q_strcasecmp(link, "vvm") || !Q_strcasecmp(link, "psk") || !Q_strcasecmp(link, "dpm") || !Q_strcasecmp(link, "zym") || !Q_strcasecmp(link, "md5mesh") || !Q_strcasecmp(link, "md5anim") || !Q_strcasecmp(link, "gltf") || !Q_strcasecmp(link, "glb") || !Q_strcasecmp(link, "ase") || !Q_strcasecmp(link, "lwo"))
Q_snprintfz(link, sizeof(link), "\\tip\\Open in Model Viewer\\modelviewer\\%s", name);
else if (!Q_strcasecmp(link, "qc") || !Q_strcasecmp(link, "src") || !Q_strcasecmp(link, "qh") || !Q_strcasecmp(link, "h") || !Q_strcasecmp(link, "c")
|| !Q_strcasecmp(link, "cfg") || !Q_strcasecmp(link, "rc")
@ -804,7 +804,7 @@ static int QDECL COM_Dir_List(const char *name, qofs_t size, time_t mtime, void
|| !Q_strcasecmp(link, "glsl") || !Q_strcasecmp(link, "hlsl")
|| !Q_strcasecmp(link, "shader") || !Q_strcasecmp(link, "framegroups"))
Q_snprintfz(link, sizeof(link), "\\tip\\Open in Text Editor\\edit\\%s", name);
else if (!Q_strcasecmp(link, "tga") || !Q_strcasecmp(link, "png") || !Q_strcasecmp(link, "jpg") || !Q_strcasecmp(link, "jpeg") || !Q_strcasecmp(link, "lmp") || !Q_strcasecmp(link, "pcx") || !Q_strcasecmp(link, "bmp") || !Q_strcasecmp(link, "dds"))
else if (!Q_strcasecmp(link, "tga") || !Q_strcasecmp(link, "png") || !Q_strcasecmp(link, "jpg") || !Q_strcasecmp(link, "jpeg") || !Q_strcasecmp(link, "lmp") || !Q_strcasecmp(link, "pcx") || !Q_strcasecmp(link, "bmp") || !Q_strcasecmp(link, "dds") || !Q_strcasecmp(link, "ktx"))
{
//FIXME: image replacements are getting in the way here.
Q_snprintfz(link, sizeof(link), "\\tiprawimg\\%s\\tip\\(note: image replacement rules are context-dependant, including base path, sub path, extension, or complete replacement via a shader)", name);
@ -1882,7 +1882,7 @@ a = append
t = text mode (because windows sucks). binary is otherwise assumed.
p = persist (ie: saved games and configs, but not downloads or large content)
*/
vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto)
vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto)
{
char cleanname[MAX_QPATH];
char fullname[MAX_OSPATH];

View file

@ -98,9 +98,9 @@ cvar_t net_enabled = CVARD("net_enabled", "1", "If 0, disables all network
cvar_t net_enable_qizmo = CVARD("net_enable_qizmo", "1", "Enables compatibility with qizmo's tcp connections serverside. Frankly, using sv_port_tcp without this is a bit pointless.");
cvar_t net_enable_qtv = CVARD("net_enable_qtv", "1", "Listens for qtv proxies, or clients using the qtvplay command.");
cvar_t net_enable_tls = CVARD("net_enable_tls", "1", "If enabled, binary data sent to a non-tls tcp port will be interpretted as a tls handshake (enabling https or wss over the same tcp port.");
cvar_t net_enable_http = CVARD("net_enable_http", "1", "If enabled, tcp ports will accept http clients, potentially serving large files which could distrupt gameplay.");
cvar_t net_enable_http = CVARD("net_enable_http", "0", "If enabled, tcp ports will accept http clients, potentially serving large files which could distrupt gameplay.");
cvar_t net_enable_websockets = CVARD("net_enable_websockets", "1", "If enabled, tcp ports will accept websocket game clients.");
cvar_t net_enable_webrtcbroker = CVARD("net_enable_webrtcbroker", "1", "If 1, tcp ports will accept websocket connections from clients trying to broker direct webrtc connections. This should be low traffic, but might involve a lot of mostly-idle connections.");
cvar_t net_enable_webrtcbroker = CVARD("net_enable_webrtcbroker", "0", "If 1, tcp ports will accept websocket connections from clients trying to broker direct webrtc connections. This should be low traffic, but might involve a lot of mostly-idle connections.");
#endif
#if defined(HAVE_DTLS) && !defined(CLIENTONLY)
static void QDECL NET_Enable_DTLS_Changed(struct cvar_s *var, char *oldvalue)

View file

@ -450,14 +450,10 @@ void GLDraw_Init (void)
TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n"));
GL_InitSceneProcessingShaders();
// Cmd_AddCommandD ("r_imagelist", GLDraw_ImageList_f, "Debug command. Reveals current list of loaded images.");
}
void GLDraw_DeInit (void)
{
Cmd_RemoveCommand ("r_imagelist");
R2D_Shutdown();
R_GAliasFlushSkinCache(true);

View file

@ -15,7 +15,7 @@
void Font_Init(void);
void Font_Shutdown(void);
struct font_s *Font_LoadFont(float height, const char *fontfilename);
struct font_s *Font_LoadFont(const char *fontfilename, float height);
void Font_Free(struct font_s *f);
void Font_BeginString(struct font_s *font, float vx, float vy, int *px, int *py);
void Font_BeginScaledString(struct font_s *font, float vx, float vy, float szx, float szy, float *px, float *py); /*avoid using*/
@ -1769,7 +1769,7 @@ void Doom_ExpandPatch(doompatch_t *p, unsigned char *b, int stride)
//creates a new font object from the given file, with each text row with the given height.
//width is implicit and scales with height and choice of font.
struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
struct font_s *Font_LoadFont(const char *fontfilename, float vheight)
{
struct font_s *f;
int i = 0;
@ -1779,6 +1779,7 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
int height = ((vheight * vid.rotpixelheight)/vid.height) + 0.5;
char facename[MAX_QPATH];
struct charcache_s *c;
float aspect = 1;
enum
{
FMT_AUTO, //freetype, or quake
@ -1845,6 +1846,12 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
else if (*t == 'h')
fmt = FMT_HORIZONTAL;
}
if (!strncmp(parms, "aspect=", 7))
{
char *t = parms+7;
aspect = strtod(t, &t);
parms = t;
}
while(*parms && *parms != '&')
parms++;
@ -2011,7 +2018,7 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
}
else
{
f->alt = Font_LoadFont(vheight, aname);
f->alt = Font_LoadFont(aname, vheight);
if (f->alt)
{
VectorCopy(f->alt->tint, f->alttint);
@ -2158,7 +2165,7 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
else
c = Font_GetCharStore(f, i);
c->advance = f->charheight;
c->advance = f->charheight * aspect;
c->bmh = PLANEWIDTH/16;
c->bmw = PLANEWIDTH/16;
c->bmx = (i&15)*(PLANEWIDTH/16);
@ -2176,7 +2183,7 @@ struct font_s *Font_LoadFont(float vheight, const char *fontfilename)
for (i = 0xe000; i <= 0xe0ff; i++)
{
c = Font_GetCharStore(f, i);
c->advance = f->charheight;
c->advance = f->charheight * aspect;
c->bmh = PLANEWIDTH/16;
c->bmw = PLANEWIDTH/16;
c->bmx = ((i&15))*(PLANEWIDTH/16);
@ -2197,6 +2204,9 @@ void Font_Free(struct font_s *f)
size_t i;
struct charcache_s **link, *c, *valid;
if (!f)
return;
//kill the alt font first.
if (f->alt)
{
@ -2744,14 +2754,14 @@ int Font_DrawChar(int px, int py, unsigned int charflags, unsigned int codepoint
case DEFAULTPLANE:
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((font->charheight)*vid.width) / (float)vid.rotpixelwidth;
sw = ((c->advance)*vid.width) / (float)vid.rotpixelwidth;
sh = ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(fontplanes.defaultfont);
break;
case BITMAPPLANE:
sx = ((px+c->left + dxbias)*(int)vid.width) / (float)vid.rotpixelwidth;
sy = ((py+c->top + dxbias)*(int)vid.height) / (float)vid.rotpixelheight;
sw = ((font->charheight)*vid.width) / (float)vid.rotpixelwidth;
sw = ((c->advance)*vid.width) / (float)vid.rotpixelwidth;
sh = ((font->charheight)*vid.height) / (float)vid.rotpixelheight;
v = Font_BeginChar(font->singletexture);
break;

View file

@ -1346,12 +1346,22 @@ static void Mod_LoadModelWorker (void *ctx, void *data, size_t a, size_t b)
magic = 0;
else
magic = LittleLong(*(unsigned *)buf);
for(i = 0; i < sizeof(modelloaders) / sizeof(modelloaders[0]); i++)
//look for known extensions first, to try to avoid issues with specific formats
for(i = 0; i < countof(modelloaders); i++)
{
if (modelloaders[i].load && modelloaders[i].magic == magic && !modelloaders[i].ident)
if (modelloaders[i].load && modelloaders[i].ident && *modelloaders[i].ident == '.' && !Q_strcasecmp(modelloaders[i].ident+1, ext))
break;
}
if (i < sizeof(modelloaders) / sizeof(modelloaders[0]))
//now look to see if we can find one with the right magic header
if (i == countof(modelloaders))
{
for(i = 0; i < countof(modelloaders); i++)
{
if (modelloaders[i].load && modelloaders[i].magic == magic && !modelloaders[i].ident)
break;
}
}
if (i < countof(modelloaders))
{
if (!modelloaders[i].load(mod, buf, filesize))
{
@ -5037,7 +5047,7 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
{
struct vispatch_s vispatch;
int i, j;
dheader_t *header;
dheader_t header;
mmodel_t *bm;
model_t *submod;
unsigned int chksum;
@ -5048,11 +5058,22 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
qboolean hexen2map = false;
qboolean isnotmap;
qboolean using_rbe = true;
qboolean misaligned = false;
COM_FileBase (mod->name, loadname, sizeof(loadname));
mod->type = mod_brush;
header = (dheader_t *)buffer;
if (fsize < sizeof(header))
return false;
mod_base = (qbyte *)buffer;
memcpy(&header, mod_base, sizeof(header));
header.version = LittleLong(header.version);
for (i=0 ; i<countof(header.lumps)/4 ; i++)
{
header.lumps[i].filelen = LittleLong(header.lumps[i].filelen);
header.lumps[i].fileofs = LittleLong(header.lumps[i].fileofs);
}
#ifdef SERVERONLY
isnotmap = !!sv.world.worldmodel;
@ -5067,29 +5088,27 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
isnotmap = true;
#endif
i = LittleLong (header->version);
if (i == BSPVERSION || i == BSPVERSIONPREREL)
switch(header.version)
{
case BSPVERSION:
case BSPVERSIONPREREL:
mod->fromgame = fg_quake;
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
}
else if (i == BSPVERSION_LONG1)
{
break;
case BSPVERSION_LONG1:
longm = true;
mod->fromgame = fg_quake;
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
}
else if (i == BSPVERSION_LONG2)
{
break;
case BSPVERSION_LONG2:
longm = 2;
mod->fromgame = fg_quake;
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
}
else if (i == BSPVERSIONHL) //halflife support
break;
case BSPVERSIONHL: //halflife support
mod->fromgame = fg_halflife;
else
{
break;
default:
Con_Printf (CON_ERROR "Mod_LoadBrushModel: %s has wrong version number (%i should be %i)\n", mod->name, i, BSPVERSION);
return false;
}
@ -5097,28 +5116,23 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
mod->lightmaps.width = 128;//LMBLOCK_WIDTH;
mod->lightmaps.height = 128;//LMBLOCK_HEIGHT;
// swap all the lumps
mod_base = (qbyte *)header;
for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
Q1BSPX_Setup(mod, mod_base, fsize, header->lumps, HEADER_LUMPS);
// checksum all of the map, except for entities
mod->checksum = 0;
mod->checksum2 = 0;
for (i = 0; i < HEADER_LUMPS; i++)
{
if ((unsigned)header->lumps[i].fileofs + (unsigned)header->lumps[i].filelen > fsize)
if ((header.lumps[i].fileofs & 3) && header.lumps[i].filelen)
misaligned = true;
if ((unsigned)header.lumps[i].fileofs + (unsigned)header.lumps[i].filelen > fsize)
{
Con_Printf (CON_ERROR "Mod_LoadBrushModel: %s appears truncated\n", mod->name);
return false;
}
if (i == LUMP_ENTITIES)
continue;
chksum = Com_BlockChecksum(mod_base + header->lumps[i].fileofs, header->lumps[i].filelen);
chksum = Com_BlockChecksum(mod_base + header.lumps[i].fileofs, header.lumps[i].filelen);
mod->checksum ^= chksum;
if (i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES)
@ -5126,13 +5140,39 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
mod->checksum2 ^= chksum;
}
if (1)//mod_ebfs.value)
if (misaligned)
{ //pre-phong versions of tyrutils wrote misaligned lumps. These crash on arm/etc.
char *tmp;
int ofs = 0;
Con_Printf(CON_WARNING"%s: Misaligned lumps detected\n", mod->name);
tmp = BZ_Malloc(fsize);
memcpy(tmp, mod_base, fsize);
for (i = 0; i < HEADER_LUMPS; i++)
{
if (ofs + header.lumps[i].filelen > fsize)
{ //can happen if two lumps overlap... otherwise impossible.
Con_Printf(CON_ERROR"%s: Realignment failed\n", mod->name);
BZ_Free(tmp);
return false;
}
memcpy(mod_base + ofs, tmp+header.lumps[i].fileofs, header.lumps[i].filelen);
header.lumps[i].fileofs = ofs;
ofs += header.lumps[i].filelen;
}
BZ_Free(tmp);
}
else
{
char *id;
id = (char *)(header + 1);
if (id[0]=='P' && id[1]=='A' && id[2]=='C' && id[3]=='K')
{ //EBFS detected.
COM_LoadMapPackFile(mod->name, sizeof(dheader_t));
Q1BSPX_Setup(mod, mod_base, fsize, header.lumps, HEADER_LUMPS);
if (1)//mod_ebfs.value)
{
char *id;
id = (char *)mod_base + sizeof(dheader_t);
if (id[0]=='P' && id[1]=='A' && id[2]=='C' && id[3]=='K')
{ //EBFS detected.
COM_LoadMapPackFile(mod->name, sizeof(dheader_t));
}
}
}
@ -5140,56 +5180,56 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
crouchhullfile = NULL;
Mod_FindVisPatch(&vispatch, mod, header->lumps[LUMP_LEAFS].filelen);
Mod_FindVisPatch(&vispatch, mod, header.lumps[LUMP_LEAFS].filelen);
// load into heap
if (!isDedicated || using_rbe)
{
TRACE(("Loading verts\n"));
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header->lumps[LUMP_VERTEXES]);
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[LUMP_VERTEXES]);
TRACE(("Loading edges\n"));
noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header->lumps[LUMP_EDGES], longm);
noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[LUMP_EDGES], longm);
TRACE(("Loading Surfedges\n"));
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header->lumps[LUMP_SURFEDGES]);
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[LUMP_SURFEDGES]);
}
if (!isDedicated)
{
TRACE(("Loading Textures\n"));
noerrors = noerrors && Mod_LoadTextures (mod, mod_base, &header->lumps[LUMP_TEXTURES]);
noerrors = noerrors && Mod_LoadTextures (mod, mod_base, &header.lumps[LUMP_TEXTURES]);
}
TRACE(("Loading Submodels\n"));
noerrors = noerrors && Mod_LoadSubmodels (mod, mod_base, &header->lumps[LUMP_MODELS], &hexen2map);
noerrors = noerrors && Mod_LoadSubmodels (mod, mod_base, &header.lumps[LUMP_MODELS], &hexen2map);
if (noerrors)
{
TRACE(("Loading CH\n"));
Mod_LoadCrouchHull(mod);
}
TRACE(("Loading Planes\n"));
noerrors = noerrors && Mod_LoadPlanes (mod, mod_base, &header->lumps[LUMP_PLANES]);
noerrors = noerrors && Mod_LoadPlanes (mod, mod_base, &header.lumps[LUMP_PLANES]);
TRACE(("Loading Entities\n"));
Mod_LoadEntities (mod, mod_base, &header->lumps[LUMP_ENTITIES]);
Mod_LoadEntities (mod, mod_base, &header.lumps[LUMP_ENTITIES]);
if (!isDedicated || using_rbe)
{
TRACE(("Loading Texinfo\n"));
noerrors = noerrors && Mod_LoadTexinfo (mod, mod_base, &header->lumps[LUMP_TEXINFO]);
noerrors = noerrors && Mod_LoadTexinfo (mod, mod_base, &header.lumps[LUMP_TEXINFO]);
TRACE(("Loading Faces\n"));
noerrors = noerrors && Mod_LoadFaces (mod, mod_base, &header->lumps[LUMP_FACES], &header->lumps[LUMP_LIGHTING], longm);
noerrors = noerrors && Mod_LoadFaces (mod, mod_base, &header.lumps[LUMP_FACES], &header.lumps[LUMP_LIGHTING], longm);
}
if (!isDedicated)
{
TRACE(("Loading MarkSurfaces\n"));
noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header->lumps[LUMP_MARKSURFACES], longm);
noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[LUMP_MARKSURFACES], longm);
}
if (noerrors)
{
TRACE(("Loading Vis\n"));
Mod_LoadVisibility (mod, mod_base, &header->lumps[LUMP_VISIBILITY], vispatch.visptr, vispatch.vislen);
Mod_LoadVisibility (mod, mod_base, &header.lumps[LUMP_VISIBILITY], vispatch.visptr, vispatch.vislen);
}
noerrors = noerrors && Mod_LoadLeafs (mod, mod_base, &header->lumps[LUMP_LEAFS], longm, isnotmap, vispatch.leafptr, vispatch.leaflen);
noerrors = noerrors && Mod_LoadLeafs (mod, mod_base, &header.lumps[LUMP_LEAFS], longm, isnotmap, vispatch.leafptr, vispatch.leaflen);
TRACE(("Loading Nodes\n"));
noerrors = noerrors && Mod_LoadNodes (mod, mod_base, &header->lumps[LUMP_NODES], longm);
noerrors = noerrors && Mod_LoadNodes (mod, mod_base, &header.lumps[LUMP_NODES], longm);
TRACE(("Loading Clipnodes\n"));
noerrors = noerrors && Mod_LoadClipnodes (mod, mod_base, &header->lumps[LUMP_CLIPNODES], longm, hexen2map);
noerrors = noerrors && Mod_LoadClipnodes (mod, mod_base, &header.lumps[LUMP_CLIPNODES], longm, hexen2map);
if (noerrors)
{
TRACE(("Loading hull 0\n"));

View file

@ -1935,7 +1935,7 @@ void GLR_RenderView (void)
}
if (dofbo)
forcedfb = false;
else if (r_renderscale.value != 1)
else if (renderscale != 1)
forcedfb = true;
BE_Scissor(NULL);

View file

@ -68,7 +68,7 @@ vfsfile_t *IWebGenerateFile(const char *name, const char *content, int contentle
return NULL;
}
vfsfile_t *VFSSTDIO_Open(const char *osname, const char *mode, qboolean *needsflush);
vfsfile_t *FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto)
vfsfile_t *QDECL FS_OpenVFS(const char *filename, const char *mode, enum fs_relative relativeto)
{
return VFSSTDIO_Open(filename, mode, NULL);
}

View file

@ -45,6 +45,7 @@ extern cvar_t sv_csqcdebug;
extern cvar_t sv_csqc_progname;
extern cvar_t sv_calcphs;
extern cvar_t sv_playerslots, maxclients, maxspectators;
extern cvar_t sv_nqplayerphysics; //auto setting needs updating on map changes
/*
================
@ -1155,6 +1156,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
SV_UpdateMaxPlayers(0);
}
svs.gametype = newgametype;
Cvar_ForceCallback(&sv_nqplayerphysics);
sv.models[1] = sv.world.worldmodel;
#ifdef VM_Q1

View file

@ -34,6 +34,17 @@ edict_t *sv_player;
usercmd_t cmd;
void QDECL SV_NQPhysicsUpdate(cvar_t *var, char *oldvalue)
{
if (!strcmp(var->string, "auto"))
{ //prediction requires nq physics, so use it by default in multiplayer.
if (progstype == PROG_QW || (!isDedicated && sv.allocated_client_slots > 1))
var->ival = 1;
else
var->ival = 0;
}
}
extern cvar_t dpcompat_nopreparse;
#ifdef SERVERONLY
cvar_t cl_rollspeed = CVAR("cl_rollspeed", "200");
@ -65,7 +76,7 @@ cvar_t cmd_allowaccess = CVAR("cmd_allowaccess", "0"); //set to 1 to allow cmd t
cvar_t cmd_gamecodelevel = CVAR("cmd_gamecodelevel", STRINGIFY(RESTRICT_LOCAL)); //execution level which gamecode is told about (for unrecognised commands)
cvar_t sv_pure = CVARFD("sv_pure", "", CVAR_SERVERINFO, "The most evil cvar in the world, many clients will ignore this.\n0=standard quake rules.\n1=clients should prefer files within packages present on the server.\n2=clients should use *only* files within packages present on the server.\nDue to quake 1.01/1.06 differences, a setting of 2 only works in total conversions.");
cvar_t sv_nqplayerphysics = CVARAD("sv_nqplayerphysics", "0", "sv_nomsec", "Disable player prediction and run NQ-style player physics instead. This can be used for compatibility with mods that expect exact behaviour.");
cvar_t sv_nqplayerphysics = CVARAFCD("sv_nqplayerphysics", "0", "sv_nomsec", 0, SV_NQPhysicsUpdate, "Disable player prediction and run NQ-style player physics instead. This can be used for compatibility with mods that expect exact behaviour.");
cvar_t sv_edgefriction = CVARAF("sv_edgefriction", "2",
"edgefriction", 0);

View file

@ -148,7 +148,7 @@ void QI_DeHTML(const char *in, char *out, size_t outsize)
{ //italics
*out++ = '^';
outsize--;
*out++ = 'b';
*out++ = close?'7':'3';
outsize--;
}
}