Fixed crash from too many csqc entities (reported by shpuld)

Added .psd, .pbm/.pgm/.ppm, .pfm, and .hdr image formats. Extensions NOT added to r_imageextensions.
png (and the above formats) can now be loaded as RGBA16, instead of being truncated to RGBA8 (8bit pngs not affected).
r_imagelist will now show images from memory, instead of potentially loading new/different ones from disk.
Fix serverbrowser bug being too eager to join the server (eg from alt+tab).
Don't send ipv6 packets to qw/q2 masters. They won't be able to report ipv6 addresses anyway, and this reduces warnings when a host STILL has no ipv6 (my ISP sucks). this does not affect q3/dpmasters, for people without ipv4 addresses.
Tried to improve compat with Bloodshot's particle effects.
Fixed a couple of issues with R_AddTrisoup.
Fixed string tokenizing bug where it was using the wrong buffer size values.
Don't show link-local/localhost addresses in eg the status command (unless developer).
qtv-rel is now an easier target, for new qtv releases.
qtv warning fixes.
added a nailtrail effect to 'high' particles.
fixed terrain shaders.
fixed fogged water issue (on one of bal's maps).
first attempt at gltf2 format support



git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5400 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-02-16 19:09:07 +00:00
parent 9548e23535
commit fa0c73d33b
82 changed files with 5801 additions and 1059 deletions

View file

@ -133,7 +133,7 @@ IF(CMAKE_C_COMPILER_ID MATCHES "GNU")
#might as well do this, public builds use the regular Makefile.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")
IF(CMAKE_BUILD_TYPE MATCHES "Debug")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wno-pointer-sign -Wno-unknown-pragmas -Wno-format-zero-length -Wno-strict-aliasing")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wcast-align -Werror -Wno-pointer-sign -Wno-unknown-pragmas -Wno-format-zero-length -Wno-strict-aliasing -Wno-error=cpp")
ELSE()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
ENDIF()
@ -740,6 +740,31 @@ ELSE()
)
SET_TARGET_PROPERTIES(iqmtool PROPERTIES COMPILE_DEFINITIONS "${FTE_REVISON}")
ADD_EXECUTABLE(qtv
fteqtv/netchan.c
fteqtv/parse.c
fteqtv/msg.c
fteqtv/qw.c
fteqtv/source.c
fteqtv/bsp.c
fteqtv/rcon.c
fteqtv/mdfour.c
fteqtv/crc.c
fteqtv/control.c
fteqtv/forward.c
fteqtv/pmove.c
fteqtv/menu.c
fteqtv/httpsv.c
fteqtv/libqtvc/glibc_sucks.c
engine/common/sha1.c
)
SET_TARGET_PROPERTIES(qtv PROPERTIES COMPILE_DEFINITIONS "${FTE_REVISON};stricmp=strcasecmp;strnicmp=strncasecmp")
IF(WIN32)
TARGET_LINK_LIBRARIES(qtv ${ZLIB_LIBRARIES} ws2_32 winmm)
ELSE()
TARGET_LINK_LIBRARIES(qtv m)
ENDIF()
IF(NOT WIN32)
ADD_EXECUTABLE(ftemaster
${FTESV_ARCH_FILES}
@ -785,7 +810,6 @@ ELSE()
SET_TARGET_PROPERTIES(fteqcc PROPERTIES COMPILE_DEFINITIONS "${FTE_LIB_DEFINES};${FTE_REVISON}")
TARGET_LINK_LIBRARIES(fteqcc ${ZLIB_LIBRARIES} m)
IF(${WIN32})
ADD_EXECUTABLE(fteqccgui WIN32
engine/qclib/qccgui.c
@ -882,6 +906,32 @@ SET_TARGET_PROPERTIES(irc PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(irc PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(irc m)
#model formats plugin
ADD_LIBRARY(models MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/models/models.c
plugins/models/gltf.c
)
SET_TARGET_PROPERTIES(models PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(models PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(models PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(models m)
#x11 formats plugin
ADD_LIBRARY(x11 MODULE
plugins/qvm_api.c
plugins/plugin.c
plugins/xsv/m_x.c
plugins/xsv/x_reqs.c
plugins/xsv/x_res.c
engine/qclib/hash.c
)
SET_TARGET_PROPERTIES(x11 PROPERTIES COMPILE_DEFINITIONS "FTEPLUGIN;${FTE_LIB_DEFINES}")
SET_TARGET_PROPERTIES(x11 PROPERTIES PREFIX "fteplug_")
SET_TARGET_PROPERTIES(x11 PROPERTIES LINK_FLAGS "-Wl,--no-undefined")
TARGET_LINK_LIBRARIES(x11 m)
#ffmpeg client plugin. no proper way to detect dependancies right now, so I've gotta try the manual way.
FIND_PATH(AVCODEC_INCLUDE_DIR libavcodec/avcodec.h)
FIND_PATH(AVFORMAT_INCLUDE_DIR libavformat/avformat.h)

View file

@ -569,13 +569,14 @@ ifeq ($(FTE_TARGET),vc)
WARNINGFLAGS=-W3 -D_CRT_SECURE_NO_WARNINGS
GNUC_FUNCS=
else
WARNINGFLAGS=-Wall -Wno-pointer-sign -Wno-unknown-pragmas -Wno-format-zero-length -Wno-strict-aliasing
WARNINGFLAGS=-Wall -Wno-pointer-sign -Wno-unknown-pragmas -Wno-format-zero-length -Wno-strict-aliasing -Wcast-align
GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp
endif
SDL_INCLUDES=
#-I$(LIBS_DIR)/sdl/include -I/usr/include/SDL -I$(LIBS_DIR)/sdl/include/SDL
BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) -I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I. -I$(LIBS_DIR) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) -I./libs/freetype2/include -I./libs/freetype2/include/freetype $(BOTLIB_CFLAGS) $(SVNREVISION)
BASE_INCLUDES=-I$(CLIENT_DIR) -I$(SERVER_DIR) -I$(COMMON_DIR) -I$(GL_DIR) -I$(D3D_DIR) -I$(PROGS_DIR) -I. -I$(LIBS_DIR)
BASE_CFLAGS=$(WARNINGFLAGS) $(GNUC_FUNCS) $(BASE_INCLUDES) -I$(LIBS_DIR)/dxsdk9/include -I$(LIBS_DIR)/dxsdk7/include $(SDL_INCLUDES) -I./libs/freetype2/include -I./libs/freetype2/include/freetype $(BOTLIB_CFLAGS) $(SVNREVISION)
CLIENT_ONLY_CFLAGS=-DCLIENTONLY
SERVER_ONLY_CFLAGS=-DSERVERONLY
JOINT_CFLAGS=
@ -1263,6 +1264,8 @@ ifeq (win,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET)))
BASELDFLAGS+=-lcomctl32
EXEPOSTFIX=.exe
QTV_LDFLAGS=-lws2_32 -lwinmm
LIBS_DIR = $(BASE_DIR)/libs
SV_EXE_NAME=../$(EXE_NAME)sv$(BITS)$(EXEPOSTFIX)
SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lws2_32 -lwinmm
@ -2233,21 +2236,46 @@ libs-$(ARCH)/libBulletDynamics.a:
makelibs: libs-$(ARCH)/libjpeg.a libs-$(ARCH)/libz.a libs-$(ARCH)/libpng.a libs-$(ARCH)/libogg.a libs-$(ARCH)/libvorbis.a libs-$(ARCH)/libopus.a libs-$(ARCH)/libspeex.a libs-$(ARCH)/libspeexdsp.a libs-$(ARCH)/libfreetype.a $(MAKELIBS)
HTTP_OBJECTS=http/httpserver.c http/iwebiface.c common/fs_stdio.c http/ftpserver.c
$(RELEASE_DIR)/httpserver$(BITS): $(HTTP_OBJECTS)
$(CC) -o $(RELEASE_DIR)/httpserver$(BITS) -Icommon -Iclient -Iqclib -Igl -Iserver -DWEBSERVER -DWEBSVONLY -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DNO_PNG $(HTTP_OBJECTS)
httpserver: $(RELEASE_DIR)/httpserver$(BITS)
$(RELEASE_DIR)/httpserver$(BITS)$(EXEPOSTFIX): $(HTTP_OBJECTS)
$(CC) -o $@ -Icommon -Iclient -Iqclib -Igl -Iserver -DWEBSERVER -DWEBSVONLY -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -DNO_PNG $(HTTP_OBJECTS)
httpserver: $(RELEASE_DIR)/httpserver$(BITS)$(EXEPOSTFIX)
IQM_OBJECTS=../iqm/iqm.cpp
$(RELEASE_DIR)/iqm$(BITS): $(IQM_OBJECTS)
$(CC) -o $(RELEASE_DIR)/iqm$(BITS) $(IQM_OBJECTS) -lstdc++ -lm
iqm: $(RELEASE_DIR)/iqm$(BITS)
$(RELEASE_DIR)/iqm$(BITS)$(EXEPOSTFIX): $(IQM_OBJECTS)
$(CC) -o $@ $(IQM_OBJECTS) -lstdc++ -lm
iqm-rel: $(RELEASE_DIR)/iqm$(BITS)$(EXEPOSTFIX)
iqm: iqm-rel
MASTER_OBJECTS=server/sv_sys_unix.c common/sys_linux_threads.c common/net_ssl_gnutls.c server/sv_master.c common/net_wins.c common/cvar.c common/cmd.c common/sha1.c http/httpclient.c common/log.c common/fs.c common/fs_stdio.c common/common.c common/translate.c common/zone.c qclib/hash.c
$(RELEASE_DIR)/ftemaster$(BITS): $(MASTER_OBJECTS)
$(CC) -o $(RELEASE_DIR)/master$(BITS) $(MASTER_OBJECTS) -Icommon -Iclient -Iqclib -Igl -Iserver -DMASTERONLY -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -lm -ldl
master: $(RELEASE_DIR)/ftemaster$(BITS)
$(RELEASE_DIR)/ftemaster$(BITS)$(EXEPOSTFIX): $(MASTER_OBJECTS)
$(CC) -o $@ $(MASTER_OBJECTS) -Icommon -Iclient -Iqclib -Igl -Iserver -DMASTERONLY -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -lm -ldl
master-rel: $(RELEASE_DIR)/ftemaster$(BITS)$(EXEPOSTFIX)
master: master-rel
utils: httpserver iqm master
QTV_OBJECTS= \
netchan.c \
parse.c \
msg.c \
qw.c \
source.c \
bsp.c \
rcon.c \
mdfour.c \
crc.c \
control.c \
forward.c \
pmove.c \
menu.c \
httpsv.c \
sha1.c \
libqtvc/glibc_sucks.c
$(RELEASE_DIR)/qtv$(BITS)$(EXEPOSTFIX): $(QTV_OBJECTS)
$(CC) -o $@ $? -lstdc++ -lm $(BASE_INCLUDES) $(QTV_LDFLAGS)
qtv-rel:
$(MAKE) $(RELEASE_DIR)/qtv$(BITS)$(EXEPOSTFIX) VPATH="$(BASE_DIR)/../fteqtv:$(VPATH)"
qtv: qtv-rel
utils: httpserver iqm master qtv-rel
prefix ?= /usr/local
exec_prefix ?= $(prefix)

View file

@ -3894,7 +3894,9 @@ void CL_LinkPacketEntities (void)
int trailef, trailidx;
int modelflags;
struct itemtimer_s *timer, **timerlink;
float timestep = host_frametime;
float timestep = cl.time-cl.lastlinktime;
cl.lastlinktime = cl.time;
timestep = bound(0, timestep, 0.1);
pack = cl.currentpackentities;
if (!pack)

View file

@ -8304,7 +8304,7 @@ struct sortedsvcs_s
const char *name;
size_t bytes;
};
static QDECL int sorttraffic(const void *l, const void *r)
static int QDECL sorttraffic(const void *l, const void *r)
{
const struct sortedsvcs_s *a=l, *b=r;

View file

@ -809,6 +809,7 @@ typedef struct
double time; // this is the time value that the client
// is rendering at. always <= realtime
double lasttime; //cl.time from last frame.
double lastlinktime; //cl.time from last frame.
float servertime; //current server time, bound between gametime and gametimemark
float mtime; //server time as on the server when we last received a packet. not allowed to decrease.

View file

@ -2862,6 +2862,15 @@ void Con_DrawConsole (int lines, qboolean noback)
if ((buf = FS_LoadMallocFile (key, &fsize)))
Image_LoadTextureFromMemory(shader->defaulttextures->base, shader->defaulttextures->base->flags|IF_NOWORKER, key, key, buf, fsize);
}
}
key = Info_ValueForKey(info, "tipimgptr");
if (*key)
{
shader = R2D_SafeCachePic("tiprawimg");
shader->defaulttextures->base = Image_TextureIsValid(strtoull(key, NULL, 0));
}
if (shader && shader->defaulttextures->base)
{
shader->width = shader->defaulttextures->base->width;
shader->height = shader->defaulttextures->base->height;
if (shader->width > 320)

File diff suppressed because it is too large Load diff

View file

@ -1023,26 +1023,45 @@ static void PM_WriteInstalledPackages(void);
static package_t *PM_FindPackage(const char *packagename);
static int QDECL PM_EnumeratedPlugin (const char *name, qofs_t size, time_t mtime, void *param, searchpathfuncs_t *spath)
{
static const char *knownarch[] =
{
"x32", "x64", "amd64", "x86", //various x86 ABIs
"arm", "arm64", "armhf", //various arm ABIs
"ppc", "unk", //various misc ABIs
};
package_t *p;
struct packagedep_s *dep;
char vmname[MAX_QPATH];
int len;
int len, l, a;
char *dot;
if (!strncmp(name, "fteplug_", 8))
Q_strncpyz(vmname, name+8, sizeof(vmname));
else
Q_strncpyz(vmname, name, sizeof(vmname));
len = strlen(vmname);
len -= strlen(ARCH_CPU_POSTFIX ARCH_DL_POSTFIX);
if (!strcmp(vmname+len, ARCH_CPU_POSTFIX ARCH_DL_POSTFIX))
l = strlen(ARCH_CPU_POSTFIX ARCH_DL_POSTFIX);
if (len > l && !strcmp(vmname+len-l, ARCH_CPU_POSTFIX ARCH_DL_POSTFIX))
{
len -= l;
vmname[len] = 0;
}
else
{
dot = strchr(vmname, '.');
if (dot)
{
*dot = 0;
len = strlen(vmname);
//if we can find a known cpu arch there then ignore it - its a different cpu arch
for (a = 0; a < countof(knownarch); a++)
{
l = strlen(knownarch[a]);
if (len > l && !Q_strcasecmp(vmname + len-l, knownarch[a]))
return true; //wrong arch! ignore it.
}
}
}
len = strlen(vmname);
if (len > 0 && vmname[len-1] == '_')
vmname[len-1] = 0;
@ -1112,7 +1131,7 @@ static void PM_PreparePackageList(void)
char nat[MAX_OSPATH];
FS_NativePath("", FS_BINARYPATH, nat, sizeof(nat));
Con_DPrintf("Loading plugins from \"%s\"\n", nat);
Sys_EnumerateFiles(nat, "fteplug_*" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, PM_EnumeratedPlugin, &foundone, NULL);
Sys_EnumerateFiles(nat, "fteplug_*" ARCH_DL_POSTFIX, PM_EnumeratedPlugin, &foundone, NULL);
if (foundone && !pluginpromptshown)
{
pluginpromptshown = true;

View file

@ -790,7 +790,7 @@ static qboolean SL_Key (int key, menu_t *menu)
Master_FindRoute(server->adr);
serverpreview = 4;
}
else if (key == 'b' || key == 'o' || key == 'j' || key == K_ENTER || key == K_KP_ENTER || key != K_GP_START) //join
else if (key == 'b' || key == 'o' || key == 'j' || key == K_ENTER || key == K_KP_ENTER || key == K_GP_START) //join
{
if (key == 's' || key == 'o')
{

View file

@ -2322,7 +2322,7 @@ static cin_t *Media_Static_TryLoad(char *name)
(staticfilmimage = ReadJPEGFile(file, fsize, &imagewidth, &imageheight)) ||
#endif
#ifdef AVAIL_PNGLIB
(staticfilmimage = ReadPNGFile(file, fsize, &imagewidth, &imageheight, fullname)) ||
(staticfilmimage = ReadPNGFile(fullname, file, fsize, &imagewidth, &imageheight, &format)) ||
#endif
0)
{

View file

@ -307,9 +307,7 @@ void M_Menu_Options_f (void)
MB_CONSOLECMD("FPS Options", "menu_fps\n", "Set model filtering and graphical profile options."),
MB_CONSOLECMD("Rendering Options", "menu_render\n", "Set rendering options such as water warp and tinting effects."),
MB_CONSOLECMD("Lighting Options", "menu_lighting\n", "Set options for level lighting and dynamic lights."),
#ifdef GLQUAKE
MB_CONSOLECMD("Texture Options", "menu_textures\n", "Set options for texture detail and effects."),
#endif
#ifndef MINIMAL
MB_CONSOLECMD("Particle Options", "menu_particles\n", "Set particle effect options."),
#endif
@ -1068,8 +1066,10 @@ void FPS_Preset_f (void)
if (!stricmp("dp", arg))
{
#ifdef HAVE_SERVER
if (sv.state)
Cbuf_InsertText("echo Be sure to restart your server\n", RESTRICT_LOCAL, false);
#endif
Cbuf_InsertText(
//these are for smc+derived mods
"sv_listen_dp 1\n" //awkward, but forces the server to load the effectinfo.txt in advance.
@ -1078,6 +1078,9 @@ void FPS_Preset_f (void)
"dpcompat_noretouchground 1\n" //don't call touch functions on entities that already appear onground. this also changes the order that the onground flag is set relative to touch functions.
"cl_nopred 1\n" //DP doesn't predict by default, and DP mods have a nasty habit of clearing .solid values during prethinks, which screws up prediction. so play safe.
"r_dynamic 0\nr_shadow_realtime_dlight 1\n" //fte has separate cvars for everything. which kinda surprises people and makes stuff twice as bright as it should be.
"r_coronas_intensity 0.25\n"
"con_logcenterprint 0\n" //kinda annoying....
"scr_fov_mode 4\n" //for fairer framerate comparisons
//general compat stuff
"dpcompat_console 1\n" //
@ -1305,7 +1308,6 @@ void M_Menu_Render_f (void)
MC_AddFrameEnd(menu, y);
}
#ifdef GLQUAKE
void M_Menu_Textures_f (void)
{
static const char *texturefilternames[] =
@ -1384,7 +1386,9 @@ void M_Menu_Textures_f (void)
MB_COMBOCVAR("2D Filter Mode", gl_texturemode2d, texture2dfilternames, texture2dfiltervalues, "Chooses the texture filtering method used for HUD, menus, and other 2D assets."),
MB_COMBOCVAR("Anisotropy", gl_texture_anisotropic_filtering, anisotropylevels, anisotropyvalues, NULL),
MB_SPACING(4),
#ifdef GLQUAKE
MB_CHECKBOXCVAR("Software-style Rendering", r_softwarebanding_cvar, 0),
#endif
MB_CHECKBOXCVAR("Specular Highlights", gl_specular, 0),
// MB_CHECKBOXCVAR("Detail Textures", gl_detail, 0),
MB_CHECKBOXCVAR("offsetmapping", r_glsl_offsetmapping, 0),
@ -1402,7 +1406,6 @@ void M_Menu_Textures_f (void)
MC_AddBulk(menu, &resel, bulk, 16, 216, y);
MC_AddFrameEnd(menu, y);
}
#endif
typedef struct {
menucombo_t *lightcombo;
@ -3088,11 +3091,13 @@ typedef struct
MV_TEXTURE,
MV_COLLISION,
MV_EVENTS,
MV_NORMALS,
} mode;
int surfaceidx;
int skingroup;
int framegroup;
int boneidx;
int textype;
double framechangetime;
double skinchangetime;
float pitch;
@ -3337,6 +3342,25 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
#endif
if (mods->mode == MV_NORMALS)
{
shader_t *s;
if (1)
{
s = R_RegisterShader("hitbox_nodepth", SUF_NONE,
"{\n"
"polygonoffset\n"
"{\n"
"map $whiteimage\n"
"blendfunc gl_src_alpha gl_one\n"
"rgbgen vertex\n"
"alphagen vertex\n"
"nodepthtest\n"
"}\n"
"}\n");
Mod_AddSingleSurface(&ent, mods->surfaceidx, s, true);
}
}
if (mods->mode == MV_COLLISION)
{
shader_t *s;
@ -3359,7 +3383,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
"nodepthtest\n"
"}\n"
"}\n");
Mod_AddSingleSurface(&ent, mods->surfaceidx, s);
Mod_AddSingleSurface(&ent, mods->surfaceidx, s, false);
}
else
{
@ -3497,7 +3521,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
else
{
shader = Mod_ShaderForSkin(ent.model, mods->surfaceidx, mods->skingroup);
Draw_FunString(0, y, va("Skin %i: \"%s\", shader \"%s\"", mods->skingroup, fname, shader?shader->name:"NO SHADER"));
Draw_FunString(0, y, va("Skin %i: \"%s\", material \"%s\"", mods->skingroup, fname, shader?shader->name:"NO SHADER"));
}
y+=8;
}
@ -3508,7 +3532,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
qboolean loop = false;
if (!Mod_FrameInfoForNum(ent.model, mods->surfaceidx, mods->framegroup, &fname, &numframes, &duration, &loop))
fname = "Unknown Frame";
Draw_FunString(0, y, va("Frame%i: %s (%i poses, %f/%f secs, %s)", mods->framegroup, fname, numframes, ent.framestate.g[FS_REG].frametime[0], duration, loop?"looped":"unlooped"));
Draw_FunString(0, y, va("Frame%i: %s (%i poses, %f of %f secs, %s)", mods->framegroup, fname, numframes, ent.framestate.g[FS_REG].frametime[0], duration, loop?"looped":"unlooped"));
y+=8;
}
@ -3593,6 +3617,8 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, fs);
}
break;
case MV_NORMALS:
break;
case MV_BONES:
#ifdef SKELETALMODELS
{
@ -3645,10 +3671,62 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
shader_t *shader = Mod_ShaderForSkin(ent.model, mods->surfaceidx, mods->skingroup);
if (shader)
{
char *t;
texnums_t *skin = shader->defaulttextures;
shader = R_RegisterShader("modelviewertexturepreview", SUF_2D, "{\nprogram default2d\n{\nmap $diffuse\n}\n}\n");
shader->defaulttextures->base = skin->base;
R2D_Image(0, y, shader->defaulttextures->base->width, shader->defaulttextures->base->height, 0, 0, 1, 1, shader);
switch(mods->textype)
{
case 1:
t = "Normalmap";
shader->defaulttextures->base = skin->bump;
break;
case 2:
t = "SpecularMap";
shader->defaulttextures->base = skin->specular; //specular lighting values.
break;
case 3:
t = "UpperMap";
shader->defaulttextures->base = skin->upperoverlay; //diffuse texture for the upper body(shirt colour). no alpha channel. added to base.rgb
break;
case 4:
t = "LopwerMap";
shader->defaulttextures->base = skin->loweroverlay; //diffuse texture for the lower body(trouser colour). no alpha channel. added to base.rgb
break;
case 5:
t = "PalettedMap";
shader->defaulttextures->base = skin->paletted; //8bit paletted data, just because.
break;
case 6:
t = "FullbrightMap";
shader->defaulttextures->base = skin->fullbright;
break;
case 7:
t = "ReflectCube";
shader->defaulttextures->base = skin->reflectcube;
break;
case 8:
t = "ReflectMask";
shader->defaulttextures->base = skin->reflectmask;
break;
case 9:
t = "DisplacementMap";
shader->defaulttextures->base = skin->displacement;
break;
default:
mods->textype = 0;
t = "Diffusemap";
shader->defaulttextures->base = skin->base;
break;
}
if (shader->defaulttextures->base)
{
Draw_FunString(0, y, va("%s: %s (%s)", t, shader->defaulttextures->base->ident, shader->defaulttextures->base->subpath));
y+=8;
R2D_Image(0, y, shader->defaulttextures->base->width, shader->defaulttextures->base->height, 0, 0, 1, 1, shader);
}
else
Draw_FunString(0, y, va("%s: <NO TEXTURE>", t));
}
}
break;
@ -3677,7 +3755,8 @@ static qboolean M_ModelViewerKey(struct menucustom_s *c, struct menu_s *m, int k
case MV_SHADER: mods->mode = MV_TEXTURE; break;
case MV_TEXTURE: mods->mode = MV_COLLISION; break;
case MV_COLLISION: mods->mode = MV_EVENTS; break;
case MV_EVENTS: mods->mode = MV_NONE; break;
case MV_EVENTS: mods->mode = MV_NORMALS; break;
case MV_NORMALS: mods->mode = MV_NONE; break;
}
}
else if (key == 'r')
@ -3694,7 +3773,11 @@ static qboolean M_ModelViewerKey(struct menucustom_s *c, struct menu_s *m, int k
}
#endif
else if (key == '[')
{
mods->boneidx--;
if (mods->boneidx < 0)
mods->boneidx = 0;
}
else if (key == ']')
mods->boneidx++;
else if (key == K_UPARROW || key == K_KP_UPARROW || key == K_GP_DPAD_UP)
@ -3705,6 +3788,14 @@ static qboolean M_ModelViewerKey(struct menucustom_s *c, struct menu_s *m, int k
mods->yaw -= 5;
else if (key == K_RIGHTARROW || key == K_KP_RIGHTARROW || key == K_GP_DPAD_RIGHT)
mods->yaw += 5;
else if (key == 't')
{
if (mods->mode == MV_TEXTURE)
mods->textype += 1;
else
mods->textype = 0;
mods->mode = MV_TEXTURE;
}
else if (key == K_END)
{
mods->skingroup = max(0, mods->skingroup-1);
@ -3821,7 +3912,8 @@ static int QDECL CompleteModelViewerList (const char *name, qofs_t flags, time_t
|| !strcmp(ext, ".iqm") || !strcmp(ext, ".dpm") || !strcmp(ext, ".zym")
|| !strcmp(ext, ".psk") || !strcmp(ext, ".md5mesh") || !strcmp(ext, ".md5anim")
|| !strcmp(ext, ".bsp") || !strcmp(ext, ".map") || !strcmp(ext, ".hmp")
|| !strcmp(ext, ".spr") || !strcmp(ext, ".sp2") || !strcmp(ext, ".spr32"))
|| !strcmp(ext, ".spr") || !strcmp(ext, ".sp2") || !strcmp(ext, ".spr32")
|| !strcmp(ext, ".gltf") || !strcmp(ext, ".glb") || !strcmp(ext, ".ase") || !strcmp(ext, ".lwo") || !strcmp(ext, ".obj"))
{
ctx->cb(name, NULL, NULL, ctx);
}

View file

@ -1260,9 +1260,7 @@ void M_Init_Internal (void)
Cmd_AddCommand ("menu_fps", M_Menu_FPS_f);
Cmd_AddCommand ("menu_render" , M_Menu_Render_f);
Cmd_AddCommand ("menu_lighting", M_Menu_Lighting_f);
#ifdef GLQUAKE
Cmd_AddCommand ("menu_textures", M_Menu_Textures_f);
#endif
Cmd_AddCommand ("menu_teamplay", M_Menu_Teamplay_f);
Cmd_AddCommand ("menu_teamplay_locations", M_Menu_Teamplay_Locations_f);
Cmd_AddCommand ("menu_teamplay_needs", M_Menu_Teamplay_Needs_f);

View file

@ -198,7 +198,7 @@ extern int Mod_GetFrameCount (struct model_s *model);
extern qboolean Mod_GetTag (struct model_s *model, int tagnum, framestate_t *framestate, float *transforms);
extern int Mod_TagNumForName (struct model_s *model, const char *name);
void Mod_AddSingleSurface(struct entity_s *ent, int surfaceidx, shader_t *shader);
void Mod_AddSingleSurface(struct entity_s *ent, int surfaceidx, shader_t *shader, qboolean normals);
int Mod_GetNumBones(struct model_s *model, qboolean allowtags);
int Mod_GetBoneRelations(struct model_s *model, int firstbone, int lastbone, framestate_t *fstate, float *result);
int Mod_GetBoneParent(struct model_s *model, int bonenum);

View file

@ -73,7 +73,7 @@ qboolean Master_MasterProtocolIsEnabled(enum masterprotocol_e protocol)
#define MAX_MASTER_ADDRESSES 4 //each master might have multiple dns addresses, typically both ipv4+ipv6. we want to report to both address families so we work with remote single-stack hosts.
#ifndef CLIENTONLY
#ifdef HAVE_SERVER
static void QDECL Net_Masterlist_Callback(struct cvar_s *var, char *oldvalue);
static void SV_SetMaster_f (void);
#else
@ -247,7 +247,11 @@ void SV_Master_SingleHeartbeat(net_masterlist_t *master)
switch(master->protocol)
{
case MP_QUAKEWORLD:
if (sv_listen_qw.value)
if ((svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM
#ifdef VM_LUA
|| svs.gametype == GT_LUA
#endif
) && sv_listen_qw.value && na->type == NA_IP)
{
if (!madeqwstring)
{
@ -271,7 +275,7 @@ void SV_Master_SingleHeartbeat(net_masterlist_t *master)
break;
#ifdef Q2SERVER
case MP_QUAKE2:
if (svs.gametype == GT_QUAKE2 && sv_listen_qw.value) //sv_listen==sv_listen_qw, yes, weird.
if (svs.gametype == GT_QUAKE2 && sv_listen_qw.value && na->type == NA_IP) //sv_listen==sv_listen_qw, yes, weird.
{
char *str = "\377\377\377\377heartbeat\n%s\n%s";
char info[8192];
@ -363,6 +367,7 @@ struct thr_res
};
void SV_Master_Worker_Resolved(void *ctx, void *data, size_t a, size_t b)
{
char adr[256];
int i;
struct thr_res *work = data;
netadr_t *na;
@ -380,10 +385,29 @@ void SV_Master_Worker_Resolved(void *ctx, void *data, size_t a, size_t b)
*na = work->na[i];
master->needsresolve = false;
switch (master->protocol)
{
#ifdef Q2SERVER
case MP_QUAKE2:
#endif
case MP_QUAKEWORLD:
//these masters have no ipv6 results query, so don't sent ipv6 heartbeats
//(its possible that a router will convert to ipv4, but such a router is probably natted and its not really worth it)
if (na->type != NA_IP)
na->type = NA_INVALID;
break;
default:
//these masters should do ipv4+ipv6, but not others.
if (na->type != NA_IP && na->type != NA_IPV6)
na->type = NA_INVALID;
break; //protocol
}
if (na->type == NA_INVALID)
memset(na, 0, sizeof(*na));
else
{
Con_DPrintf ("Resolved master \"%s\" to %s\n", master->cv.string, NET_AdrToString(adr, sizeof(adr), na));
//fix up default ports if not specified
if (!na->port)
{
@ -395,7 +419,7 @@ void SV_Master_Worker_Resolved(void *ctx, void *data, size_t a, size_t b)
#endif
case MP_DPMASTER: na->port = BigShort (27950); break;
#ifdef Q2SERVER
case MP_QUAKE2: na->port = BigShort (27000); break; //FIXME: verify
case MP_QUAKE2: na->port = BigShort (27900); break; //FIXME: verify
#endif
#ifdef Q3SERVER
case MP_QUAKE3: na->port = BigShort (27950); break;
@ -541,6 +565,7 @@ void SV_Master_ClearAll(void)
}
}
#ifndef NOLEGACY
/*
====================
SV_SetMaster_f
@ -580,6 +605,7 @@ static void SV_SetMaster_f (void)
svs.last_heartbeat = -99999;
}
#endif
void SV_Master_ReResolve(void)
{
@ -2543,18 +2569,23 @@ void MasterInfo_Request(master_t *mast)
case MP_QUAKE3:
{
char *str;
str = va("%c%c%c%cgetservers %u empty full\n", 255, 255, 255, 255, 68);
if (mast->adr.type == NA_IPV6)
str = va("%c%c%c%cgetserversExt %u empty full ipv6\n", 255, 255, 255, 255, 68);
else
str = va("%c%c%c%cgetservers %u empty full\n", 255, 255, 255, 255, 68);
NET_SendPollPacket (strlen(str), str, mast->adr);
}
break;
#endif
#ifdef Q2CLIENT
case MP_QUAKE2:
NET_SendPollPacket (6, "query", mast->adr);
if (mast->adr.type == NA_IP) //qw masters have no ipx/ipv6 reporting, so its a bit pointless
NET_SendPollPacket (6, "query", mast->adr);
break;
#endif
case MP_QUAKEWORLD:
NET_SendPollPacket (3, "c\n", mast->adr);
if (mast->adr.type == NA_IP) //qw masters have no ipx/ipv6 reporting, so its a bit pointless
NET_SendPollPacket (3, "c\n", mast->adr);
break;
#ifdef NQPROT
case MP_NETQUAKE:
@ -2573,9 +2604,9 @@ void MasterInfo_Request(master_t *mast)
//for compat with dp, we use the nq netchan version. which is stupid, but whatever
//we ask for ipv6 addresses from ipv6 masters (assuming it resolved okay)
if (mast->adr.type == NA_IPV6)
str = va("%c%c%c%cgetserversExt %s %u empty full ipv6"/*\x0A\n"*/, 255, 255, 255, 255, game, com_protocolversion.ival);
str = va("%c%c%c%cgetserversExt %s %u empty full ipv6", 255, 255, 255, 255, game, com_protocolversion.ival);
else
str = va("%c%c%c%cgetservers %s %u empty full"/*\x0A\n"*/, 255, 255, 255, 255, game, com_protocolversion.ival);
str = va("%c%c%c%cgetservers %s %u empty full", 255, 255, 255, 255, game, com_protocolversion.ival);
NET_SendPollPacket (strlen(str), str, mast->adr);
}
}
@ -3619,7 +3650,7 @@ void Net_Master_Init(void)
int i;
for (i = 0; net_masterlist[i].cv.name; i++)
Cvar_Register(&net_masterlist[i].cv, "master servers");
#ifdef HAVE_SERVER
#if defined(HAVE_SERVER) && !defined(NOLEGACY)
Cmd_AddCommand ("setmaster", SV_SetMaster_f);
#endif

View file

@ -261,7 +261,7 @@ typedef struct part_type_s {
float rotationmin, rotationrand;
float scaledelta;
int countextra;
float countextra;
float count;
float countrand;
float countspacing; //for trails.
@ -2406,7 +2406,7 @@ qboolean PScript_Query(int typenum, int body, char *outstr, int outstrlen)
}
if (ptype->count || ptype->countrand || ptype->countextra || all)
Q_strncatz(outstr, va("count %g %g %i\n", ptype->count, ptype->countrand, ptype->countextra), outstrlen);
Q_strncatz(outstr, va("count %g %g %g\n", ptype->count, ptype->countrand, ptype->countextra), outstrlen);
if (ptype->rainfrequency != 1 || all)
Q_strncatz(outstr, va("rainfrequency %g\n", ptype->rainfrequency), outstrlen);
@ -2829,6 +2829,7 @@ static void FinishEffectinfoParticleType(part_type_t *ptype, qboolean blooddecal
{
//fte's textured particles are *0.25 for some reason.
//but fte also uses radiuses, while dp uses total size so we only need to double it here..
ptype->looks.stretch = 1;//affects billboarding in dp
ptype->scale *= 2*ptype->looks.stretch;
ptype->scalerand *= 2*ptype->looks.stretch;
ptype->scaledelta *= 2*2*ptype->looks.stretch; //fixme: this feels wrong, the results look correct though. hrmph.
@ -2838,9 +2839,12 @@ static void FinishEffectinfoParticleType(part_type_t *ptype, qboolean blooddecal
ptype->clipbounce = -2;
if (ptype->looks.type == PT_TEXTUREDSPARK)
{
ptype->scale *= 2;
ptype->scalerand *= 2;
ptype->scaledelta *= 2;
ptype->looks.stretch *= 0.04;
if (ptype->looks.stretch < 0)
ptype->looks.stretch = 0.000001;
// if (ptype->looks.stretch < 0)
// ptype->looks.stretch = 0.000001;
}
if (ptype->die == 9999) //internal: means unspecified.
@ -5572,31 +5576,18 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
len = VectorNormalize (vec);
// use ptype step to calc step vector and step size
if (ptype->countspacing)
{
step = ptype->countspacing; //particles per qu
step /= r_part_density.value; //scaled...
if (ptype->countextra)
{
count = ptype->countextra;
if (step>0)
count += len/step;
step = len/count;
}
}
else
{
step = ptype->count * r_part_density.value * timeinterval;
step += ptype->countextra; //particles per frame
step += ptype->countoverflow;
count = (int)step;
ptype->countoverflow = step-count; //the part that we're forgetting, to add to the next frame...
if (count<=0)
return;
else
step = len/count; //particles per second
}
//(fractional) extra count
step = (cl.paused&&(ptype->die||ptype->randdie))?0:ptype->countextra;
step += ptype->count * r_part_density.value * timeinterval;
//round it with overflow tracking
step += ptype->countoverflow;
count = step;
ptype->countoverflow = step-count;
step = ptype->countspacing; //particles per qu
step /= r_part_density.value; //scaled...
if (ptype->flags & PT_AVERAGETRAIL)
{
@ -5610,7 +5601,36 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
VectorScale(vec, step, vstep);
// add offset
// store last stop here for lack of a better solution besides vectors
if (ts)
{
ts->state2.laststop = stop = ts->state2.laststop + len; //when to stop
len = ts->state1.lastdist;
}
else
{
stop = len;
len = 0;
}
if (step && len < stop)
{
if (count && len)
{
//recalculate step to cover the entire distance.
count += (stop-len) / step;
step = (stop-len)/count;
}
else
count += (stop-len) / step;
}
else
{
step = 0;
VectorClear(vstep);
}
// add offset
// VectorAdd(start, ptype->orgbias, start);
// spawn mode precalculations
@ -5628,22 +5648,6 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
VectorVectors(vec, right, up);
}
// store last stop here for lack of a better solution besides vectors
if (ts)
{
ts->state2.laststop = stop = ts->state2.laststop + len; //when to stop
len = ts->state1.lastdist;
}
else
{
stop = len;
len = 0;
}
// len = ts->lastdist/step;
// len = (len - (int)len)*step;
// VectorMA (start, -len, vec, start);
if (ptype->flags & PT_NOSPREADFIRST)
nrfirst = len + step*1.5;
else
@ -5656,16 +5660,6 @@ static void P_ParticleTrailSpawn (vec3_t startpos, vec3_t end, part_type_t *ptyp
b = bfirst = NULL;
if (len < stop)
count = (stop-len) / step;
else
{
count = 0;
step = 0;
VectorClear(vstep);
}
// count += ptype->countextra;
while (count-->0)//len < stop)
{
len += step;
@ -6316,8 +6310,10 @@ static void R_AddTSparkParticle(scenetris_t *t, particle_t *p, plooks_t *type)
VectorSubtract(r_refdef.vieworg, o2, v);
CrossProduct(v, p->vel, cr);
VectorNormalize(cr);
VectorMA(o2, -p->scale/2, cr, cl_strisvertv[cl_numstrisvert+0]);
VectorMA(o2, p->scale/2, cr, cl_strisvertv[cl_numstrisvert+1]);
halfscale = fabs(p->scale); //gah, I hate dp.
VectorMA(o2, -halfscale/2, cr, cl_strisvertv[cl_numstrisvert+0]);
VectorMA(o2, halfscale/2, cr, cl_strisvertv[cl_numstrisvert+1]);
VectorMA(p->org, length, movedir, o2);
}
@ -6802,11 +6798,21 @@ static void PScript_DrawParticleTypes (void)
if (r_plooksdirty)
{
int i, j;
{
particleengine_t *tmp = fallback; fallback = NULL;
pe_default = PScript_FindParticleType("PE_DEFAULT");
pe_size2 = PScript_FindParticleType("PE_SIZE2");
pe_size3 = PScript_FindParticleType("PE_SIZE3");
pe_defaulttrail = PScript_FindParticleType("PE_DEFAULTTRAIL");
pe_default = PScript_FindParticleType("PE_DEFAULT");
pe_size2 = PScript_FindParticleType("PE_SIZE2");
pe_size3 = PScript_FindParticleType("PE_SIZE3");
pe_defaulttrail = PScript_FindParticleType("PE_DEFAULTTRAIL");
if (pe_default == P_INVALID)
{
//pe_default = PScript_FindParticleType("SVC_PARTICLE");
}
fallback = tmp;
}
for (i = 0; i < numparticletypes; i++)
{

View file

@ -1713,8 +1713,8 @@ void QCBUILTIN PF_R_AddTrisoup_Simple(pubprogfuncs_t *prinst, struct globalvars_
qboolean twod = qcflags & DRAWFLAG_2D;
unsigned int beflags;
unsigned int numverts;
qcvertex_t *vert;
unsigned int *idx;
const qcvertex_t *fte_restrict vert;
const unsigned int *fte_restrict idx;
unsigned int i, j, first;
if ((qcflags & 3) == DRAWFLAG_ADD)
@ -1728,10 +1728,14 @@ void QCBUILTIN PF_R_AddTrisoup_Simple(pubprogfuncs_t *prinst, struct globalvars_
if (qcflags & DRAWFLAG_LINES)
beflags |= BEF_LINES;
if (twod)
if (1)//twod)
shader = R_RegisterPic(PR_GetStringOfs(prinst, OFS_PARM0), NULL);
else
{
shader = R_RegisterSkin(PR_GetStringOfs(prinst, OFS_PARM0), NULL);
if (!shader->defaulttextures->base && (shader->flags & SHADER_HASDIFFUSE))
R_BuildDefaultTexnums(NULL, shader, 0);
}
if (R2D_Flush && (R2D_Flush != CSQC_PolyFlush || csqc_poly_shader != shader || csqc_poly_flags != beflags || csqc_poly_2d != twod))
R2D_Flush();
@ -1748,13 +1752,13 @@ void QCBUILTIN PF_R_AddTrisoup_Simple(pubprogfuncs_t *prinst, struct globalvars_
PR_BIError(prinst, "PF_R_AddTrisoup: invalid vertexes pointer\n");
return;
}
vert = (qcvertex_t*)(prinst->stringtable + vertsptr);
vert = (const qcvertex_t*)(prinst->stringtable + vertsptr);
if (indexesptr <= 0 || indexesptr+numindexes*sizeof(int) > prinst->stringtablesize)
{
PR_BIError(prinst, "PF_R_AddTrisoup: invalid indexes pointer\n");
return;
}
idx = (int*)(prinst->stringtable + indexesptr);
idx = (const int*)(prinst->stringtable + indexesptr);
first = cl_numstrisvert - csqc_poly_origvert;
if (first + numindexes > MAX_INDICIES)

View file

@ -1522,6 +1522,22 @@ char *particle_set_high =
"assoc gunshotsmoke\n"
"}\n"
//simple slight trail, to show movement more than anything else.
"r_part tr_spike\n"
"{\n"
"texture \"particles/fteparticlefont.tga\"\n"
"step 1.1\n"
"scale 4\n"
"die .4\n"
"rgb 20 20 20\n"
"alpha 1\n"
"blend add\n"
"spawnmode spiral 512\n"
"spawnvel 10\n"
"}\n"
"r_trail \"progs/spike.mdl\" tr_spike\n"
"r_trail \"progs/s_spike.mdl\" tr_spike\n"
////////////////////////////////////////////////
//explosion

View file

@ -443,6 +443,7 @@ enum imageflags
#define R_LoadTextureFB(id,w,h,d,f) Image_GetTexture(id, NULL, f, d, NULL, w, h, TF_TRANS8_FULLBRIGHT)
#define R_LoadTexture(id,w,h,fmt,d,fl) Image_GetTexture(id, NULL, fl, d, NULL, w, h, fmt)
image_t *Image_TextureIsValid(qintptr_t address);
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 *QDECL Image_GetTexture (const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt);
@ -583,7 +584,7 @@ void WritePCXfile (const char *filename, enum fs_relative fsroot, qbyte *data, i
qbyte *ReadPCXFile(qbyte *buf, int length, int *width, int *height);
qbyte *ReadTargaFile(qbyte *buf, int length, int *width, int *height, uploadfmt_t *format, qboolean greyonly, uploadfmt_t forceformat);
qbyte *ReadJPEGFile(qbyte *infile, int length, int *width, int *height);
qbyte *ReadPNGFile(qbyte *buf, int length, int *width, int *height, const char *name);
qbyte *ReadPNGFile(const char *fname, qbyte *buf, int length, int *width, int *height, uploadfmt_t *format);
qbyte *ReadPCXPalette(qbyte *buf, int len, qbyte *out);
void Image_ResampleTexture (unsigned *in, int inwidth, int inheight, unsigned *out, int outwidth, int outheight);
void Image_ResampleTexture8 (unsigned char *in, int inwidth, int inheight, unsigned char *out, int outwidth, int outheight);
@ -646,7 +647,7 @@ extern cvar_t gl_poly;
extern cvar_t gl_affinemodels;
extern cvar_t r_renderscale;
extern cvar_t gl_nohwblend;
extern cvar_t r_coronas, r_coronas_occlusion, r_coronas_mindist, r_coronas_fadedist, r_flashblend, r_flashblendscale;
extern cvar_t r_coronas, r_coronas_intensity, r_coronas_occlusion, r_coronas_mindist, r_coronas_fadedist, r_flashblend, r_flashblendscale;
extern cvar_t r_lightstylesmooth;
extern cvar_t r_lightstylesmooth_limit;
extern cvar_t r_lightstylespeed;

View file

@ -143,6 +143,7 @@ cvar_t r_skin_overlays = CVARF ("r_skin_overlays", "1",
cvar_t r_globalskin_first = CVARFD ("r_globalskin_first", "100", CVAR_RENDERERLATCH, "Specifies the first .skin value that is a global skin. Entities within this range will use the shader/image called 'gfx/skinSKIN.lmp' instead of their regular skin. See also: r_globalskin_count.");
cvar_t r_globalskin_count = CVARFD ("r_globalskin_count", "10", CVAR_RENDERERLATCH, "Specifies how many globalskins there are.");
cvar_t r_coronas = CVARFD ("r_coronas", "0", CVAR_ARCHIVE, "Draw coronas on realtime lights. Overrides glquake-esque flashblends.");
cvar_t r_coronas_intensity = CVARFD ("r_coronas_intensity", "1", CVAR_ARCHIVE, "Alternative intensity multiplier for coronas.");
cvar_t r_coronas_occlusion = CVARFD ("r_coronas_occlusion", "", CVAR_ARCHIVE, "Specifies that coronas should be occluded more carefully.\n0: No occlusion, at all.\n1: BSP occlusion only (simple tracelines).\n2: non-bsp occlusion also (complex tracelines).\n3: Depthbuffer reads (forces synchronisation).\n4: occlusion queries.");
cvar_t r_coronas_mindist = CVARFD ("r_coronas_mindist", "128", CVAR_ARCHIVE, "Coronas closer than this will be invisible, preventing near clip plane issues.");
cvar_t r_coronas_fadedist = CVARFD ("r_coronas_fadedist", "256", CVAR_ARCHIVE, "Coronas will fade out over this distance.");
@ -230,7 +231,7 @@ cvar_t scr_conalpha = CVARC ("scr_conalpha", "0.7",
Cvar_Limiter_ZeroToOne_Callback);
cvar_t scr_consize = CVAR ("scr_consize", "0.5");
cvar_t scr_conspeed = CVAR ("scr_conspeed", "2000");
cvar_t scr_fov_mode = CVARFD ("scr_fov_mode", "0", CVAR_ARCHIVE, "Controls what the fov cvar actually controls:\n0: largest axis (ultra-wide monitors means less height will be visible).\n1: smallest axis (ultra-wide monitors will distort at the edges).\n2: horizontal axis.\n3: vertical axis.");
cvar_t scr_fov_mode = CVARFD ("scr_fov_mode", "0", CVAR_ARCHIVE, "Controls what the fov cvar actually controls:\n0: largest axis (ultra-wide monitors means less height will be visible).\n1: smallest axis (ultra-wide monitors will distort at the edges).\n2: horizontal axis.\n3: vertical axis.\n4: horizontally-padded 4:3");
cvar_t scr_fov = CVARFCD("fov", "90", CVAR_ARCHIVE, SCR_Fov_Callback,
"field of vision, 1-170 degrees, standard fov is 90, nquake defaults to 108.");
cvar_t scr_fov_viewmodel = CVARFD("r_viewmodel_fov", "", CVAR_ARCHIVE,
@ -870,6 +871,7 @@ void Renderer_Init(void)
Cvar_Register(&r_stainfadeammount, GRAPHICALNICETIES);
Cvar_Register(&r_lightprepass_cvar, GLRENDEREROPTIONS);
Cvar_Register (&r_coronas, GRAPHICALNICETIES);
Cvar_Register (&r_coronas_intensity, GRAPHICALNICETIES);
Cvar_Register (&r_coronas_occlusion, GRAPHICALNICETIES);
Cvar_Register (&r_coronas_mindist, GRAPHICALNICETIES);
Cvar_Register (&r_coronas_fadedist, GRAPHICALNICETIES);

View file

@ -104,10 +104,14 @@ typedef enum uploadfmt
PTI_L8_SRGB, //8bit format. luminance gets flooded to all RGB channels. might be supported using swizzles.
PTI_L8A8_SRGB, //16bit format. L=luminance. note: this cannot be implemented as a swizzle as there's no way to get srgb on red without it on green.
//small formats.
PTI_R8, //used for paletted data
PTI_P8, //used for paletted data. Loaded as R8, but separate purely due to mipmap generation. should probably make a mipgen enum.
PTI_R8, //used for greyscale data (that doesn't need to get expanded to rgb).
PTI_RG8, //might be useful for normalmaps
PTI_R8_SNORM,
PTI_RG8_SNORM, //might be useful for normalmaps
//big formats
PTI_R16,
PTI_RGBA16,
//floating point formats
PTI_R16F,
PTI_R32F,
@ -188,8 +192,8 @@ typedef enum uploadfmt
//non-native formats (generally requiring weird palettes that are not supported by hardware)
TF_BGR24_FLIP, /*bgr byte order, no alpha channel nor pad, and bottom up*/
TF_MIP4_R8, /*8bit 4-mip greyscale image*/
TF_MIP4_SOLID8, /*8bit 4-mip image in default palette*/
TF_MIP4_P8, /*8bit 4-mip image in default palette, that will be loaded as an R8 texture.*/
TF_MIP4_SOLID8, /*8bit 4-mip image in default palette, that will be expanded to an RGB texture.*/
TF_MIP4_8PAL24, /*8bit 4-mip image with included palette*/
TF_MIP4_8PAL24_T255,/*8bit 4-mip image with included palette where index 255 is alpha 0*/
TF_SOLID8, /*8bit quake-palette image*/
@ -227,11 +231,9 @@ typedef enum uploadfmt
TF_BGRX32 = PTI_BGRX8, /*rgb byte order, with extra wasted byte after blue*/
TF_RGB24 = PTI_RGB8, /*rgb byte order, no alpha channel nor pad, and regular top down*/
TF_BGR24 = PTI_BGR8, /*bgr byte order, no alpha channel nor pad, and regular top down*/
TF_LUM8 = PTI_L8,
TF_R8 = PTI_R8
//these are emulated formats. this 'case' value allows drivers to easily ignore them
#define PTI_EMULATED TF_INVALID:case TF_BGR24_FLIP:case TF_MIP4_R8:case TF_MIP4_SOLID8:case TF_MIP4_8PAL24:case TF_MIP4_8PAL24_T255:case TF_SOLID8:case TF_TRANS8:case TF_TRANS8_FULLBRIGHT:case TF_HEIGHT8:case TF_HEIGHT8PAL:case TF_H2_T7G1:case TF_H2_TRANS8_0:case TF_H2_T4A4:case TF_8PAL24:case TF_8PAL32:case PTI_LLLX8:case PTI_LLLA8
#define PTI_EMULATED TF_INVALID:case TF_BGR24_FLIP:case TF_MIP4_P8:case TF_MIP4_SOLID8:case TF_MIP4_8PAL24:case TF_MIP4_8PAL24_T255:case TF_SOLID8:case TF_TRANS8:case TF_TRANS8_FULLBRIGHT:case TF_HEIGHT8:case TF_HEIGHT8PAL:case TF_H2_T7G1:case TF_H2_TRANS8_0:case TF_H2_T4A4:case TF_8PAL24:case TF_8PAL32:case PTI_LLLX8:case PTI_LLLA8
} uploadfmt_t;
qboolean SCR_ScreenShot (char *filename, enum fs_relative fsroot, void **buffer, int numbuffers, int bytestride, int width, int height, enum uploadfmt fmt, qboolean writemeta);

View file

@ -1593,6 +1593,9 @@ void Sys_Init (void)
vinfo.dwOSVersionInfoSize = sizeof(vinfo);
#if _MSC_VER >= 1600 //msvc2010 runtime does not work on 9x any more. get rid of the deprecation warnings in later versions.
WinNT = true;
#else
if (!GetVersionEx (&vinfo))
Sys_Error ("Couldn't get OS info");
@ -1606,6 +1609,7 @@ void Sys_Init (void)
WinNT = true;
else
WinNT = false;
#endif
qwinvermaj = vinfo.dwMajorVersion;
qwinvermin = vinfo.dwMinorVersion;
@ -3767,7 +3771,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
WinNT = vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT;
}
#if defined(_DEBUG) && defined(MULTITHREAD)
#if defined(_DEBUG) && defined(_MSC_VER) && defined(MULTITHREAD)
Sys_SetThreadName(-1, "main thread");
#endif

View file

@ -1257,6 +1257,13 @@ restart:
*y = CalcFov(afov, w, h);
}
break;
case 4: //wide 4:3
*y = tan(scr_fov.value * M_PI / 360.0) * (3.0 / 4.0);
*x = *y * (float)w / (float)h;
*x = atan(*x) * (360.0 / M_PI);
*y = atan(*y) * (360.0 / M_PI);
break;
}
}
void V_ApplyAFov(playerview_t *pv)

View file

@ -2700,13 +2700,14 @@ A complete command line has been parsed, so try to execute it
FIXME: lookupnoadd the token to speed search?
============
*/
void Cmd_ExecuteString (const char *text, int level)
static void Cmd_ExecuteStringGlobalsAreEvil (const char *text, int level)
{
//WARNING: PF_checkcommand should match the order.
cmd_function_t *cmd;
cmdalias_t *a;
char dest[8192];
Cmd_ExecLevel = level;
while (*text == ' ' || *text == '\n')
text++;
@ -2764,12 +2765,7 @@ void Cmd_ExecuteString (const char *text, int level)
Cmd_ForwardToServer ();
}
else
{
int olev = Cmd_ExecLevel;
Cmd_ExecLevel = level;
cmd->function ();
Cmd_ExecLevel = olev;
}
return;
}
}
@ -2875,7 +2871,6 @@ void Cmd_ExecuteString (const char *text, int level)
{
if (!strcmp(cmd_argv[0], tpcmds[level]))
{
int olev = Cmd_ExecLevel;
if (cmd->restriction && cmd->restriction > 0)
{ //warning, these commands would normally be considered to be run at restrict_local, but they're running at a much lower level
//which means that if there's ANY restriction on them then they'll fail.
@ -2888,7 +2883,6 @@ void Cmd_ExecuteString (const char *text, int level)
Cmd_ForwardToServer ();
else
cmd->function();
Cmd_ExecLevel = olev;
return;
}
}
@ -2904,13 +2898,7 @@ void Cmd_ExecuteString (const char *text, int level)
else if (!cmd->function)
Cmd_ForwardToServer ();
else
{
int olev = Cmd_ExecLevel;
Cmd_ExecLevel = level;
cmd->function ();
Cmd_ExecLevel = olev;
}
return;
}
@ -2962,7 +2950,14 @@ void Cmd_ExecuteString (const char *text, int level)
if ((cl_warncmd.value && level <= RESTRICT_LOCAL) || developer.value)
Con_TPrintf ("Unknown command \"%s\"\n", Cmd_Argv(0));
}
void Cmd_ExecuteString (const char *text, int level)
{ //inserted a small wrapper due to all the returns in the original function.
//a number of things check for seats if nothing else, and security says is safer to do this than to be in doubt.
int olev = Cmd_ExecLevel;
Cmd_ExecuteStringGlobalsAreEvil(text, level);
Cmd_ExecLevel = level;
Cmd_ExecLevel = olev;
}
/*

View file

@ -1224,6 +1224,7 @@ static const float *Alias_GetBoneInformation(galiasinfo_t *inf, framestate_t *fr
size_t numgroups;
size_t bone, endbone;
lerps[0].skeltype = SKEL_IDENTITY; //just in case.
#ifdef SKELETALOBJECTS
if (framestate->bonestate && framestate->bonecount >= inf->numbones)
{
@ -1613,7 +1614,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
if (!inf->numanimations)
{
#ifdef SKELETALMODELS
if (inf->ofs_skel_xyz && !inf->ofs_skel_weight)
if (inf->ofs_skel_xyz)
{}
else
#endif
@ -2015,11 +2016,12 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
#ifndef SERVERONLY
//used by the modelviewer.
void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader)
void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader, qboolean normals)
{
galiasinfo_t *mod;
scenetris_t *t;
vecV_t *posedata = NULL;
vec3_t *normdata = NULL;
int surfnum = 0, i;
#ifdef SKELETALMODELS
int cursurfnum = -1;
@ -2040,6 +2042,7 @@ void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader)
continue;
#ifdef SKELETALMODELS
normdata = mod->ofs_skel_norm;
if (mod->numbones)
{
if (!mod->ofs_skel_idx)
@ -2081,63 +2084,116 @@ void Mod_AddSingleSurface(entity_t *ent, int surfaceidx, shader_t *shader)
}
#endif
if (cl_numstris == cl_maxstris)
{
cl_maxstris+=8;
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
}
t = &cl_stris[cl_numstris++];
t->shader = shader;
t->flags = 0;//BEF_LINES;
t->firstidx = cl_numstrisidx;
t->firstvert = cl_numstrisvert;
if (t->flags&BEF_LINES)
t->numidx = mod->numindexes*2;
else
t->numidx = mod->numindexes;
t->numvert = mod->numverts;
if (cl_numstrisidx+t->numidx > cl_maxstrisidx)
{
cl_maxstrisidx=cl_numstrisidx+t->numidx;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
if (cl_numstrisvert+mod->numverts > cl_maxstrisvert)
{
cl_maxstrisvert=cl_numstrisvert+mod->numverts;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
for (i = 0; i < mod->numverts; i++)
{
VectorMA(ent->origin, posedata[i][0], ent->axis[0], cl_strisvertv[t->firstvert+i]);
VectorMA(cl_strisvertv[t->firstvert+i], posedata[i][1], ent->axis[1], cl_strisvertv[t->firstvert+i]);
VectorMA(cl_strisvertv[t->firstvert+i], posedata[i][2], ent->axis[2], cl_strisvertv[t->firstvert+i]);
// VectorAdd(ent->origin, posedata[i], cl_strisvertv[t->firstvert+i]);
Vector2Set(cl_strisvertt[t->firstvert+i], 0.5, 0.5);
Vector4Set(cl_strisvertc[t->firstvert+i], (mod->contents?1:0), 1, 1, 0.1);
}
if (t->flags&BEF_LINES)
{
for (i = 0; i < mod->numindexes; i+=3)
if (normals && normdata)
{ //pegs, one on each vertex.
vec3_t push;
if (cl_numstris == cl_maxstris)
{
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+0];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+1];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+1];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+2];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+2];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+0];
cl_maxstris+=8;
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
}
t = &cl_stris[cl_numstris++];
t->shader = shader;
t->flags = BEF_LINES;
t->firstidx = cl_numstrisidx;
t->firstvert = cl_numstrisvert;
t->numidx = t->numvert = mod->numverts*2;
if (cl_numstrisidx+t->numidx > cl_maxstrisidx)
{
cl_maxstrisidx=cl_numstrisidx+t->numidx;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
if (cl_numstrisvert+t->numvert > cl_maxstrisvert)
{
cl_maxstrisvert=cl_numstrisvert+t->numvert;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
for (i = 0; i < mod->numverts; i++)
{
VectorMA(ent->origin, posedata[i][0], ent->axis[0], cl_strisvertv[t->firstvert+i*2+0]);
VectorMA(cl_strisvertv[t->firstvert+i*2+0], posedata[i][1], ent->axis[1], cl_strisvertv[t->firstvert+i*2+0]);
VectorMA(cl_strisvertv[t->firstvert+i*2+0], posedata[i][2], ent->axis[2], cl_strisvertv[t->firstvert+i*2+0]);
VectorMA(posedata[i], 0.1, normdata[i], push);
VectorMA(ent->origin, push[0], ent->axis[0], cl_strisvertv[t->firstvert+i*2+1]);
VectorMA(cl_strisvertv[t->firstvert+i*2+1], push[1], ent->axis[1], cl_strisvertv[t->firstvert+i*2+1]);
VectorMA(cl_strisvertv[t->firstvert+i*2+1], push[2], ent->axis[2], cl_strisvertv[t->firstvert+i*2+1]);
Vector2Set(cl_strisvertt[t->firstvert+i*2+0], 0.0, 0.0);
Vector2Set(cl_strisvertt[t->firstvert+i*2+1], 1.0, 1.0);
Vector4Set(cl_strisvertc[t->firstvert+i*2+0], 0, 0, 1, 1);
Vector4Set(cl_strisvertc[t->firstvert+i*2+1], 0, 0, 1, 1);
cl_strisidx[cl_numstrisidx+i*2+0] = i*2+0;
cl_strisidx[cl_numstrisidx+i*2+1] = i*2+1;
}
cl_numstrisidx += i*2;
cl_numstrisvert += i*2;
}
else
{
for (i = 0; i < mod->numindexes; i++)
cl_strisidx[cl_numstrisidx+i] = mod->ofs_indexes[i];
cl_numstrisidx += mod->numindexes;
if (cl_numstris == cl_maxstris)
{
cl_maxstris+=8;
cl_stris = BZ_Realloc(cl_stris, sizeof(*cl_stris)*cl_maxstris);
}
t = &cl_stris[cl_numstris++];
t->shader = shader;
t->flags = 0;//BEF_LINES;
t->firstidx = cl_numstrisidx;
t->firstvert = cl_numstrisvert;
if (t->flags&BEF_LINES)
t->numidx = mod->numindexes*2;
else
t->numidx = mod->numindexes;
t->numvert = mod->numverts;
if (cl_numstrisidx+t->numidx > cl_maxstrisidx)
{
cl_maxstrisidx=cl_numstrisidx+t->numidx;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
if (cl_numstrisvert+mod->numverts > cl_maxstrisvert)
{
cl_maxstrisvert=cl_numstrisvert+mod->numverts;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(*cl_strisvertt)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(*cl_strisvertc)*cl_maxstrisvert);
}
for (i = 0; i < mod->numverts; i++)
{
VectorMA(ent->origin, posedata[i][0], ent->axis[0], cl_strisvertv[t->firstvert+i]);
VectorMA(cl_strisvertv[t->firstvert+i], posedata[i][1], ent->axis[1], cl_strisvertv[t->firstvert+i]);
VectorMA(cl_strisvertv[t->firstvert+i], posedata[i][2], ent->axis[2], cl_strisvertv[t->firstvert+i]);
// VectorAdd(ent->origin, posedata[i], cl_strisvertv[t->firstvert+i]);
Vector2Set(cl_strisvertt[t->firstvert+i], 0.5, 0.5);
Vector4Set(cl_strisvertc[t->firstvert+i], (mod->contents?1:0), 1, 1, 0.1);
}
if (t->flags&BEF_LINES)
{
for (i = 0; i < mod->numindexes; i+=3)
{
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+0];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+1];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+1];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+2];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+2];
cl_strisidx[cl_numstrisidx++] = mod->ofs_indexes[i+0];
}
}
else
{
for (i = 0; i < mod->numindexes; i++)
cl_strisidx[cl_numstrisidx+i] = mod->ofs_indexes[i];
cl_numstrisidx += mod->numindexes;
}
cl_numstrisvert += mod->numverts;
}
cl_numstrisvert += mod->numverts;
}
}
#endif

View file

@ -170,6 +170,9 @@ typedef struct galiasinfo_s
struct galiasinfo_s *nextsurf;
#ifdef SKELETALMODELS
// int *bonemap; //some models are horribly complicated, this provides a gpubone->cpubone table, reducing the number of gpu bones needed on a per-mesh basis.
// int mappedbones;
float *baseframeofs; /*non-heirachical*/
int numbones;
galiasbone_t *ofsbones;

View file

@ -4298,7 +4298,7 @@ skipwhite:
data++;
while (1)
{
if (len >= TOKENSIZE-1)
if (len >= tokenlen-1)
{
token[len] = '\0';
return (char*)data;
@ -4328,7 +4328,7 @@ skipwhite:
// parse a regular word
do
{
if (len >= TOKENSIZE-1)
if (len >= tokenlen-1)
break;
token[len] = c;
data++;

View file

@ -97,8 +97,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef _MSC_VER
#if _MSC_VER >= 1310
#define strtoull _strtoui64
#define strtoll _strtoi64
#else
#define strtoull strtoul //hopefully this won't cause too many issues
#define strtoll strtol //hopefully this won't cause too many issues
#define DWORD_PTR DWORD //32bit only
#define ULONG_PTR ULONG
#endif

View file

@ -88,6 +88,9 @@
//Image formats
#define IMAGEFMT_KTX //Khronos TeXture. common on gles3 devices for etc2 compression
#define IMAGEFMT_PKM //file format generally written by etcpack or android's etc1tool. doesn't support mips.
#define IMAGEFMT_PBM //pbm/ppm/pgm/pfm family formats.
#define IMAGEFMT_PSD //baselayer only.
#define IMAGEFMT_HDR //an RGBE format.
#define IMAGEFMT_DDS //.dds files embed mipmaps and texture compression. faster to load.
//#define IMAGEFMT_BLP //legacy crap
#define IMAGEFMT_BMP //windows bmp. yuck. also includes .ico for the luls

View file

@ -807,7 +807,9 @@ 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") || !Q_strcasecmp(link, "gltf") || !Q_strcasecmp(link, "glb") || !Q_strcasecmp(link, "ase") || !Q_strcasecmp(link, "lwo"))
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")
@ -818,7 +820,9 @@ static int QDECL COM_Dir_List(const char *name, qofs_t size, time_t mtime, void
|| !Q_strcasecmp(link, "vmt")
)
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") || !Q_strcasecmp(link, "ktx") || !Q_strcasecmp(link, "vtf"))
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, "ico") ||
!Q_strcasecmp(link, "pcx") || !Q_strcasecmp(link, "bmp") || !Q_strcasecmp(link, "dds") || !Q_strcasecmp(link, "ktx") || !Q_strcasecmp(link, "vtf") || !Q_strcasecmp(link, "psd") ||
!Q_strcasecmp(link, "pbm") || !Q_strcasecmp(link, "ppm") || !Q_strcasecmp(link, "pgm") || !Q_strcasecmp(link, "pam") || !Q_strcasecmp(link, "pfm") || !Q_strcasecmp(link, "hdr") )
{
//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);
@ -4514,7 +4518,7 @@ static qboolean FS_DirHasAPackage(char *basedir, ftemanifest_t *man)
}
//false stops the search (and returns that value to FS_DirHasGame)
int FS_DirDoesHaveGame(const char *fname, qofs_t fsize, time_t modtime, void *ctx, searchpathfuncs_t *subdir)
int QDECL FS_DirDoesHaveGame(const char *fname, qofs_t fsize, time_t modtime, void *ctx, searchpathfuncs_t *subdir)
{
return false;
}

View file

@ -149,8 +149,9 @@ enum addressscope_e
{
ASCOPE_PROCESS=0,
ASCOPE_HOST=1,
ASCOPE_LAN=2,
ASCOPE_NET=3
ASCOPE_LINK=2,
ASCOPE_LAN=3,
ASCOPE_NET=4
};
enum addressscope_e NET_ClassifyAddress(netadr_t *adr, char **outdesc);

View file

@ -39,8 +39,12 @@ cvar_t *tls_ignorecertificateerrors;
#define SCH_CRED_SNI_CREDENTIAL 0x00080000
#endif
#ifndef SEC_I_MESSAGE_FRAGMENT
#define SEC_I_MESSAGE_FRAGMENT 0x00090364L
#endif
#ifndef SEC_E_INVALID_PARAMETER
#define SEC_E_INVALID_PARAMETER 0x8009035DL
#endif
//hungarian ensures we hit no macros.

View file

@ -68,7 +68,7 @@ extern ftemanifest_t *fs_manifest;
#endif
#if defined(_WIN32) || defined(__linux__) && !defined(ANDROID)
#define USE_GETHOSTNAME_LOCALLISTING
#define USE_GETHOSTNAME_LOCALLISTING
#endif
netadr_t net_local_cl_ipadr; //still used to match local ui requests (quake/gamespy), and to generate ip reports for q3 servers (which is probably pointless).
@ -81,39 +81,28 @@ sizebuf_t net_message;
//emscripten can misalign stuff, which is a problem when the leading int is checked directly in a few places. gah.
FTE_ALIGN(4) qbyte net_message_buffer[MAX_OVERALLMSGLEN];
#if defined(_WIN32) && defined(HAVE_PACKET)
WSADATA winsockdata;
WSADATA winsockdata;
#endif
#ifdef HAVE_IPV6
#ifdef _WIN32
int (WINAPI *pgetaddrinfo) (
const char* nodename,
const char* servname,
const struct addrinfo* hints,
struct addrinfo** res
);
void (WSAAPI *pfreeaddrinfo) (struct addrinfo*);
#if defined(_WIN32)
int (WINAPI *pgetaddrinfo) (
const char* nodename,
const char* servname,
const struct addrinfo* hints,
struct addrinfo** res
);
void (WSAAPI *pfreeaddrinfo) (struct addrinfo*);
#else
#define pgetaddrinfo getaddrinfo
#define pfreeaddrinfo freeaddrinfo
/*int (*pgetaddrinfo)
(
const char* nodename,
const char* servname,
const struct addrinfo* hints,
struct addrinfo** res
);
void (*pfreeaddrinfo) (struct addrinfo*);
*/
#endif
#define pgetaddrinfo getaddrinfo
#define pfreeaddrinfo freeaddrinfo
#endif
#if defined(HAVE_IPV4) && defined(HAVE_SERVER)
#define HAVE_NATPMP
#define HAVE_NATPMP
#endif
#if defined(HAVE_SERVER) || defined(MASTERONLY)
#define HAVE_HTTPSV
#define HAVE_HTTPSV
#endif
void NET_GetLocalAddress (int socket, netadr_t *out);
@ -127,6 +116,8 @@ void IPX_CloseSocket (int socket);
cvar_t timeout = CVARD("timeout","65", "Connections will time out if no packets are received for this duration of time."); // seconds without any message
cvar_t net_hybriddualstack = CVARD("net_hybriddualstack", "1", "Uses hybrid ipv4+ipv6 sockets where possible. Not supported on xp or below.");
cvar_t net_fakeloss = CVARFD("net_fakeloss", "0", CVAR_CHEAT, "Simulates packetloss in both receiving and sending, on a scale from 0 to 1.");
static cvar_t net_dns_ipv4 = CVARD("net_dns_ipv4", "1", "If 0, disables dns resolution of names to ipv4 addresses (removing any associated error messages). Also hides ipv4 addresses in address:port listings.");
static cvar_t net_dns_ipv6 = CVARD("net_dns_ipv6", "1", "If 0, disables dns resolution of names to ipv6 addresses (removing any associated error messages). Also hides ipv6 addresses in address:port listings.");
cvar_t net_enabled = CVARD("net_enabled", "1", "If 0, disables all network access, including name resolution and socket creation. Does not affect loopback/internal connections.");
#if defined(TCPCONNECT) && (defined(HAVE_SERVER) || defined(HAVE_HTTPSV))
#ifdef HAVE_SERVER
@ -1040,10 +1031,32 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
{
struct sockaddr_un *sa = (struct sockaddr_un *)sadr;
int i;
//limit to known prefixes. this allows for sandboxing.
const char *allowedprefixes[] = {"@"DISTRIBUTION, "/tmp/"DISTRIBUTION".", "/tmp/qsock.", "@FTE", "@qtv", "@qsock"};
for (i = 0; i < countof(allowedprefixes); i++)
{
if (!Q_strncasecmp(s, allowedprefixes[i], strlen(allowedprefixes[i])))
break;
}
if (i == countof(allowedprefixes))
{
Con_DPrintf(CON_WARNING "\"%s\" is not an accepted prefix for a unix socket. Forcing prefix.\n", s);
i = 0;
sa->sun_path[i++] = 0;
sa->sun_path[i++] = 'q';
sa->sun_path[i++] = 's';
sa->sun_path[i++] = 'o';
sa->sun_path[i++] = 'c';
sa->sun_path[i++] = 'k';
}
else i = 0;
sa->sun_family = AF_UNIX;
//this parsing is so annoying because I want to support abstract sockets too.
for (i = 0; *s && i < countof(sa->sun_path); )
//this parsing is so annoying because I want to support abstract sockets too, which have nulls.
//we're using @ charsto represent nulls, to match 'lsof -U'
for ( ; *s && i < countof(sa->sun_path); )
{
if (*s == '@')
{
@ -1053,23 +1066,26 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
else if (*s == '\\')
{
if (s[1] == 0)
{
sa->sun_path[i++] = '\\';
break; //error.
}
else if (s[1] == '\\')
sa->sun_path[i++] = '\\';
else if (s[1] == '@')
sa->sun_path[i++] = '@';
else if (s[1] == 'n')
sa->sun_path[i++] = 'n';
sa->sun_path[i++] = '\n';
else if (s[1] == 'r')
sa->sun_path[i++] = 'r';
sa->sun_path[i++] = '\r';
else if (s[1] == 't')
sa->sun_path[i++] = 't';
sa->sun_path[i++] = '\t';
else if (s[1] == '1')
sa->sun_path[i++] = '1';
sa->sun_path[i++] = '\1';
else if (s[1] == '2')
sa->sun_path[i++] = '2';
sa->sun_path[i++] = '\2';
else if (s[1] == '3')
sa->sun_path[i++] = '3';
sa->sun_path[i++] = '\3';
else
sa->sun_path[i++] = '?';
s+=2;
@ -1077,6 +1093,8 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
else
sa->sun_path[i++] = *s++;
}
if (sa->sun_path[0]) //'pathname sockets should be null terminated'
sa->sun_path[i++] = 0;
if (i < countof(sa->sun_path))
sa->sun_path[i] = 'X';
if (addrsize)
@ -1185,6 +1203,10 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
}
else
{
#if defined(AI_ADDRCONFIG) && !defined(_WIN32)
udp6hint.ai_flags |= AI_ADDRCONFIG; //don't return ipv6 if we can't send to ipv6 hosts
#endif
port = strrchr(s, ':');
if (port)
@ -1218,12 +1240,16 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
switch(pos->ai_family)
{
case AF_INET6:
if (!net_dns_ipv6.ival)
continue;
if (result < addresses)
memcpy(&sadr[result++], pos->ai_addr, pos->ai_addrlen);
break;
#ifdef HAVE_IPV4
case AF_INET:
//ipv4 addresses have a higher priority than ipv6 ones.
if (!net_dns_ipv4.ival)
continue;
//ipv4 addresses have a higher priority than ipv6 ones (too few other quake engines support ipv6).
if (result && ((struct sockaddr_in *)&sadr[0])->sin_family == AF_INET6)
{
if (result < addresses)
@ -1262,7 +1288,7 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
else
#endif
{
#ifdef HAVE_IPV4
#if defined(HAVE_IPV4) && !defined(pgetaddrinfo) && !defined(HAVE_IPV6)
char copy[128];
char *colon;
@ -1272,6 +1298,8 @@ size_t NET_StringToSockaddr2 (const char *s, int defaultport, netadrtype_t afhin
if (strlen(s) >= sizeof(copy)-1)
return false;
if (!net_dns_ipv4.ival)
return false;
((struct sockaddr_in *)sadr)->sin_port = htons(defaultport);
@ -2931,71 +2959,15 @@ void FTENET_Generic_Close(ftenet_generic_connection_t *con)
int FTENET_GetLocalAddress(int port, qboolean ipx, qboolean ipv4, qboolean ipv6, unsigned int *adrflags, netadr_t *addresses, int maxaddresses)
{
//in win32, we can look up our own hostname to retrieve a list of local interface addresses.
#ifdef USE_GETHOSTNAME_LOCALLISTING
char adrs[MAX_ADR_SIZE];
int b;
#endif
int found = 0;
gethostname(adrs, sizeof(adrs));
#ifdef HAVE_IPV6
if (pgetaddrinfo)
#ifndef pgetaddrinfo
if (!pgetaddrinfo)
{
struct addrinfo hints, *result, *itr;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = 0; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
if (pgetaddrinfo(adrs, NULL, &hints, &result) == 0)
{
for (itr = result; itr; itr = itr->ai_next)
{
if ((itr->ai_addr->sa_family == AF_INET && ipv4)
|| (itr->ai_addr->sa_family == AF_INET6 && ipv6)
#ifdef HAVE_IPX
|| (itr->ai_addr->sa_family == AF_IPX && ipx)
#endif
)
if (maxaddresses)
{
SockadrToNetadr((struct sockaddr_qstorage*)itr->ai_addr, sizeof(struct sockaddr_qstorage), addresses);
addresses->port = port;
*adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
}
}
pfreeaddrinfo(result);
/*if none found, fill in the 0.0.0.0 or whatever*/
if (!found && maxaddresses)
{
memset(addresses, 0, sizeof(*addresses));
addresses->port = port;
if (ipv6)
addresses->type = NA_IPV6;
else if (ipv4)
addresses->type = NA_IP;
else if (ipx)
addresses->type = NA_IPX;
else
addresses->type = NA_INVALID;
*adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
}
}
}
else
#endif
{
struct hostent *h;
h = gethostbyname(adrs);
b = 0;
struct hostent *h = gethostbyname(adrs);
int b = 0;
#ifdef HAVE_IPV4
if(h && h->h_addrtype == AF_INET)
{
@ -3033,6 +3005,63 @@ int FTENET_GetLocalAddress(int port, qboolean ipx, qboolean ipv4, qboolean ipv6,
}
#endif
}
else
#endif
{
struct addrinfo hints, *result, *itr;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = 0; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_DGRAM; /* Datagram socket */
hints.ai_flags = 0;
hints.ai_protocol = 0; /* Any protocol */
if (pgetaddrinfo(adrs, NULL, &hints, &result) == 0)
{
for (itr = result; itr; itr = itr->ai_next)
{
if (0
#ifdef HAVE_IPV4
|| (itr->ai_addr->sa_family == AF_INET && ipv4)
#endif
#ifdef HAVE_IPV6
|| (itr->ai_addr->sa_family == AF_INET6 && ipv6)
#endif
#ifdef HAVE_IPX
|| (itr->ai_addr->sa_family == AF_IPX && ipx)
#endif
)
if (maxaddresses)
{
SockadrToNetadr((struct sockaddr_qstorage*)itr->ai_addr, sizeof(struct sockaddr_qstorage), addresses);
addresses->port = port;
*adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
}
}
pfreeaddrinfo(result);
/*if none found, fill in the 0.0.0.0 or whatever*/
if (!found && maxaddresses)
{
memset(addresses, 0, sizeof(*addresses));
addresses->port = port;
if (ipv6)
addresses->type = NA_IPV6;
else if (ipv4)
addresses->type = NA_IP;
else if (ipx)
addresses->type = NA_IPX;
else
addresses->type = NA_INVALID;
*adrflags++ = 0;
addresses++;
maxaddresses--;
found++;
}
}
}
return found;
}
@ -3051,6 +3080,10 @@ int FTENET_GetLocalAddress(int port, qboolean ipx, qboolean ipv4, qboolean ipv6,
int fam;
int idx = 0;
unsigned int time = Sys_Milliseconds();
ipv4 = ipv4 && net_dns_ipv4.ival;
ipv6 = ipv6 && net_dns_ipv6.ival;
if (time - iftime > 1000 && iflist)
{
freeifaddrs(iflist);
@ -3325,7 +3358,6 @@ neterr_t FTENET_Datagram_SendPacket(ftenet_generic_connection_t *con, int length
ret = sendto (con->thesocket, data, length, 0, (struct sockaddr*)&addr, size );
if (ret == -1)
{
const char *prot;
int ecode = neterrno();
// wouldblock is silent
if (ecode == NET_EWOULDBLOCK)
@ -3346,26 +3378,21 @@ neterr_t FTENET_Datagram_SendPacket(ftenet_generic_connection_t *con, int length
return NETERR_DISCONNECTED;
}
//network is unreachable scares the socks off people when IPv6 is non-functional despite ipv4 working fine.
//name the problem protocol in the error message.
switch(to->type)
{
case NA_IP: prot = "IPv4"; break;
case NA_IPV6: prot = "IPv6"; break;
case NA_IPX: prot = "IPX"; break;
default: prot = ""; break;
}
char adr[256];
#ifdef HAVE_CLIENT
if (ecode == NET_EADDRNOTAVAIL)
Con_DPrintf("NET_Send%sPacket Warning: %i\n", prot, ecode);
else
if (ecode == NET_EADDRNOTAVAIL)
Con_DPrintf("NET_SendPacket(%s) Warning: %i\n", NET_AdrToString (adr, sizeof(adr), to), ecode);
else
#endif
{
#ifdef _WIN32
Con_TPrintf ("NET_Send%sPacket ERROR: %i\n", prot, ecode);
Con_Printf ("NET_SendPacket(%s) ERROR: %i\n", NET_AdrToString (adr, sizeof(adr), to), ecode);
#else
Con_TPrintf ("NET_Send%sPacket ERROR: %s\n", prot, strerror(ecode));
Con_Printf ("NET_SendPacket(%s) ERROR: %s\n", NET_AdrToString (adr, sizeof(adr), to), strerror(ecode));
#endif
}
}
}
else if (ret < length)
return NETERR_MTU;
@ -3542,6 +3569,7 @@ ftenet_generic_connection_t *FTENET_Datagram_EstablishConnection(qboolean isserv
//and we can't re-bind to it while it still exists.
//so standard practise is to delete it before the bind.
//we do want to make sure the file is actually a socket before we remove it (so people can't abuse stuffcmds)
//FIXME: use lock-files
struct stat s;
if (stat(sa->sun_path, &s)!=-1)
{
@ -7147,7 +7175,7 @@ enum addressscope_e NET_ClassifyAddress(netadr_t *adr, char **outdesc)
else if (adr->type == NA_IPV6)
{
if ((*(int*)adr->address.ip6&BigLong(0xffc00000)) == BigLong(0xfe800000)) //fe80::/10
scope = ASCOPE_LAN, desc = "link-local";
scope = ASCOPE_LINK, desc = "link-local";
else if ((*(int*)adr->address.ip6&BigLong(0xfe000000)) == BigLong(0xfc00000)) //fc::/7
scope = ASCOPE_LAN, desc = "ULA/private";
else if (*(int*)adr->address.ip6 == BigLong(0x20010000)) //2001::/32
@ -7162,7 +7190,7 @@ enum addressscope_e NET_ClassifyAddress(netadr_t *adr, char **outdesc)
else if (adr->type == NA_IP)
{
if ((*(int*)adr->address.ip&BigLong(0xffff0000)) == BigLong(0xA9FE0000)) //169.254.x.x/16
scope = ASCOPE_LAN, desc = "link-local";
scope = ASCOPE_LINK, desc = "link-local";
else if ((*(int*)adr->address.ip&BigLong(0xff000000)) == BigLong(0x0a000000)) //10.x.x.x/8
scope = ASCOPE_LAN, desc = "private";
else if ((*(int*)adr->address.ip&BigLong(0xff000000)) == BigLong(0x7f000000)) //127.x.x.x/8
@ -7191,6 +7219,8 @@ void NET_PrintAddresses(ftenet_connections_t *collection)
struct ftenet_generic_connection_s *con[sizeof(addr)/sizeof(addr[0])];
int flags[sizeof(addr)/sizeof(addr[0])];
qboolean warn = true;
static const char *scopes[] = {"process", "local", "link", "lan", "net"};
char *desc;
if (!collection)
return;
@ -7201,23 +7231,20 @@ void NET_PrintAddresses(ftenet_connections_t *collection)
{
if (addr[i].type != NA_INVALID)
{
char *scopes[] = {NULL, "local", "lan", "net"};
char *scope;
char *desc;
scope = scopes[NET_ClassifyAddress(&addr[i], &desc)];
if (scope)
enum addressscope_e scope = NET_ClassifyAddress(&addr[i], &desc);
if (developer.ival || scope >= ASCOPE_LAN)
{
warn = false;
if (desc)
Con_Printf("%s address (%s): %s (%s)\n", scope, con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]), desc);
Con_Printf("%s address (%s): %s (%s)\n", scopes[scope], con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]), desc);
else
Con_Printf("%s address (%s): %s\n", scope, con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
Con_Printf("%s address (%s): %s\n", scopes[scope], con[i]->name, NET_AdrToString(adrbuf, sizeof(adrbuf), &addr[i]));
}
}
}
if (warn)
Con_Printf("net address: no addresses\n");
Con_Printf("net address: no public addresses\n");
}
void NET_PrintConnectionsStatus(ftenet_connections_t *collection)
@ -7298,7 +7325,7 @@ int TCP_OpenStream (netadr_t *remoteaddr)
{ //if its a unix socket, attempt to bind it to an unnamed address. linux should generate an ephemerial abstract address (otherwise the server will see an empty address).
struct sockaddr_un un;
memset(&un, 0, offsetof(struct sockaddr_un, sun_path));
bind(newsocket, &un, offsetof(struct sockaddr_un, sun_path));
bind(newsocket, (struct sockaddr*)&un, offsetof(struct sockaddr_un, sun_path));
}
else
#endif
@ -7815,6 +7842,8 @@ NET_Init
void NET_Init (void)
{
Cvar_Register(&net_enabled, "networking");
Cvar_Register(&net_dns_ipv4, "networking");
Cvar_Register(&net_dns_ipv6, "networking");
if (net_enabled.ival)
{
#if defined(_WIN32) && defined(HAVE_PACKET)
@ -7981,7 +8010,11 @@ void QDECL SV_PortUNIX_Callback(struct cvar_s *var, char *oldvalue)
{
FTENET_AddToCollection(svs.sockets, var->name, var->string, NA_UNIX, NP_DGRAM);
}
cvar_t sv_port_unix = CVARC("sv_port_unix", "/tmp/fte.sock", SV_PortUNIX_Callback);
#ifdef __linux //linux adds abstract sockets, which require no filesystem cleanup.
cvar_t sv_port_unix = CVARC("sv_port_unix", "@qsock.fte", SV_PortUNIX_Callback);
#else
cvar_t sv_port_unix = CVARC("sv_port_unix", "/tmp/qsock.fte", SV_PortUNIX_Callback);
#endif
#endif
#ifdef HAVE_NATPMP
static void QDECL SV_Port_NatPMP_Callback(struct cvar_s *var, char *oldvalue)

View file

@ -2156,12 +2156,12 @@ void Plug_CloseAll_f(void)
int QDECL Plug_List_Print(const char *fname, qofs_t fsize, time_t modtime, void *parm, searchpathfuncs_t *spath)
{
plugin_t *plug;
plugin_t *plug;
char plugname[MAX_QPATH];
//lots of awkward logic so we hide modules for other cpus.
size_t nl = strlen(fname);
size_t u;
const char *knownarch[] =
static const char *knownarch[] =
{
"x32", "x64", "amd64", "x86", //various x86 ABIs
"arm", "arm64", "armhf", //various arm ABIs

View file

@ -36,7 +36,7 @@ typedef enum {
#define PMF_JUMP_HELD 1
#define PMF_LADDER 2 //pmove flags. seperate from flags
#define MAX_PHYSENTS 128
#define MAX_PHYSENTS 2048
typedef struct
{
vec3_t origin;

View file

@ -97,10 +97,10 @@ qboolean QVM_LoadDLL(vm_t *vm, const char *name, qboolean binroot, void **vmMain
hVM=NULL;
*fname = 0;
Con_DPrintf("Attempting to load native library: %s\n", name);
if (binroot)
{
Con_DPrintf("Attempting to load native library: %s\n", name);
if (!hVM && FS_NativePath(dllname_arch, FS_BINARYPATH, fname, sizeof(fname)))
hVM = Sys_LoadLibrary(fname, funcs);
if (!hVM && FS_NativePath(dllname_anycpu, FS_BINARYPATH, fname, sizeof(fname)))
@ -130,20 +130,22 @@ qboolean QVM_LoadDLL(vm_t *vm, const char *name, qboolean binroot, void **vmMain
}
else
{
Con_DPrintf("Attempting to load (unsafe) native library: %s\n", name);
// run through the search paths
iterator = NULL;
while (!hVM && COM_IteratePaths(&iterator, gpath, sizeof(gpath), NULL, 0))
{
if (!hVM)
{
snprintf (fname, sizeof(fname), "%s/%s", gpath, dllname_arch);
snprintf (fname, sizeof(fname), "%s%s", gpath, dllname_arch);
Con_DLPrintf(2, "Loading native: %s\n", fname);
hVM = Sys_LoadLibrary(fname, funcs);
}
if (!hVM)
{
snprintf (fname, sizeof(fname), "%s/%s", gpath, dllname_anycpu);
snprintf (fname, sizeof(fname), "%s%s", gpath, dllname_anycpu);
Con_DLPrintf(2, "Loading native: %s\n", fname);
hVM = Sys_LoadLibrary(fname, funcs);
}

View file

@ -274,6 +274,13 @@ qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mi
tdesc.Format = DXGI_FORMAT_BC7_UNORM_SRGB;
break;
case PTI_R16:
tdesc.Format = DXGI_FORMAT_R16_UNORM;
break;
case PTI_RGBA16:
tdesc.Format = DXGI_FORMAT_R16G16B16A16_UNORM;
break;
case PTI_R16F:
tdesc.Format = DXGI_FORMAT_R16_FLOAT;
break;
@ -287,6 +294,7 @@ qboolean D3D11_LoadTextureMips(image_t *tex, const struct pendingtextureinfo *mi
tdesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
break;
case PTI_L8: //UNSUPPORTED
case PTI_P8: //R8, but different usage.
case PTI_R8:
tdesc.Format = DXGI_FORMAT_R8_UNORM;
break;

View file

@ -62,6 +62,9 @@
<data android:scheme="http" android:host="*" android:pathPattern=".*\\.dem" />
<data android:scheme="content" android:host="*" android:pathPattern=".*\\.dem" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.dem" />
<data android:scheme="http" android:host="*" android:pathPattern=".*\\.qwd" />
<data android:scheme="content" android:host="*" android:pathPattern=".*\\.qwd" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.qwd" />
<data android:scheme="http" android:host="*" android:pathPattern=".*\\.pak" />
<data android:scheme="content" android:host="*" android:pathPattern=".*\\.pak" />
<data android:scheme="file" android:host="*" android:pathPattern=".*\\.pak" />

View file

@ -1081,7 +1081,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
cm->texnum.paletted = R_LoadTexture(va("paletted$%x$%x$%i$%i$%i$%s", tc, bc, cm->skinnum, subframe, pc, cm->name),
scaled_width, scaled_height, PTI_R8, pixels8, IF_NEAREST|IF_NOMIPMAP);
scaled_width, scaled_height, PTI_P8, pixels8, IF_NEAREST|IF_NOMIPMAP);
}

View file

@ -218,6 +218,7 @@ void GL_SetupFormats(void)
glfmt(PTI_A2BGR10, GL_RGB10_A2, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV);
if (ver >= 3.0 || GL_CheckExtension("GL_ARB_texture_rg"))
{
glfmtc(PTI_P8, GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, tc_ru);
glfmtc(PTI_R8, GL_R8, GL_RED, GL_RED, GL_UNSIGNED_BYTE, tc_ru);
glfmtc(PTI_RG8, GL_RG8, GL_RG, GL_RG, GL_UNSIGNED_BYTE, tc_rs);
}
@ -229,6 +230,9 @@ void GL_SetupFormats(void)
if (ver >= 3.0)
{
glfmtc(PTI_R16, GL_R16, GL_RED, GL_RED, GL_UNSIGNED_SHORT, 0);
glfmtc(PTI_RGBA16, GL_RGBA16, GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT, 0);
glfmtc(PTI_R16F, GL_R16F, GL_RED, GL_RED, GL_HALF_FLOAT, 0);
glfmtc(PTI_R32F, GL_R32F, GL_RED, GL_RED, GL_FLOAT, 0);

View file

@ -6817,6 +6817,7 @@ void QCBUILTIN PF_brush_create(pubprogfuncs_t *prinst, struct globalvars_s *pr_g
brush.numplanes = numfaces;
brush.planes = planes;
brush.faces = faces;
brush.patch = NULL;
if (numfaces)
{
nb = Terr_Brush_Insert(mod, hm, &brush);
@ -7573,7 +7574,7 @@ qboolean Terr_ReformEntitiesLump(model_t *mod, heightmap_t *hm, char *entities)
p = 4; //we just managed to read an entire plane instead of 3 points.
break;
}
entities = COM_ParseTokenOut(entities, brushpunct, token, sizeof(token), NULL);
entities = COM_ParseTokenOut(entities, "()", token, sizeof(token), NULL);
}
if (p < 3)
{

View file

@ -294,6 +294,8 @@ static void Mod_BlockTextureColour_f (void)
#if defined(MULTITHREAD)
#ifdef _WIN32
#include <windows.h>
#elif defined(__linux__)
#include <unistd.h>
#endif
static void *relightthread[8];
static unsigned int relightthreads;
@ -349,7 +351,13 @@ void Mod_Think (void)
else
relightthreads--;
#elif defined(__GNUC__)
#ifdef __linux__
relightthreads = sysconf(_SC_NPROCESSORS_ONLN)-1;
if (relightthreads < 1)
relightthreads = 1;
#else
relightthreads = 2; //erm, lets hope...
#endif
#else
/*can't do atomics*/
relightthreads = 1;

View file

@ -388,7 +388,7 @@ void R_RenderDlights (void)
cscale = l->coronascale;
intensity = l->corona;// * 0.25;
if (coronastyle)
intensity *= r_coronas.value;
intensity *= r_coronas.value * r_coronas_intensity.value;
else
intensity *= r_flashblend.value;
if (intensity <= 0 || cscale <= 0)

View file

@ -756,6 +756,7 @@ void R_RenderScene (void)
{
GL_ForceDepthWritable();
qglClear (GL_DEPTH_BUFFER_BIT);
r_framecount++;
}
TRACE(("dbg: calling R_SetupGL\n"));
@ -1367,7 +1368,7 @@ void R_Clear (qboolean fbo)
//for performance, we clear the depth at the same time we clear colour, so we can skip clearing depth here the first time around each frame.
//but for multiple scenes, we do need to clear depth still.
//fbos always get cleared depth, just in case (colour fbos may contain junk, but hey).
if (fbo && r_clear.ival)
if ((fbo && r_clear.ival) || r_refdef.stereomethod==STEREO_RED_BLUE||r_refdef.stereomethod==STEREO_RED_GREEN)
qglClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
else
qglClear (GL_DEPTH_BUFFER_BIT);
@ -1744,6 +1745,8 @@ qboolean R_RenderScene_Cubemap(void)
GL_MTBind(0, GL_TEXTURE_CUBE_MAP_ARB, scenepp_postproc_cube);
qglCopyTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + i, 0, 0, 0, 0, vid.fbpheight - (prect.y + cmapsize), cmapsize, cmapsize);
}
r_framecount++;
}
if (usefbo)

View file

@ -5723,7 +5723,7 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
if (!TEXVALID(tex->paletted) && *mapname)
tex->paletted = R_LoadHiResTexture(va("%s_pal", mapname), NULL, imageflags|IF_NEAREST);
if (!TEXVALID(tex->paletted))
tex->paletted = Image_GetTexture(va("%s_pal", imagename), subpath, imageflags|IF_NEAREST|IF_NOSRGB, mipdata[0], palette, width, height, (basefmt==TF_MIP4_SOLID8)?TF_MIP4_R8:TF_R8);
tex->paletted = Image_GetTexture(va("%s_pal", imagename), subpath, imageflags|IF_NEAREST|IF_NOSRGB, mipdata[0], palette, width, height, (basefmt==TF_MIP4_SOLID8)?TF_MIP4_P8:PTI_P8);
}
imageflags |= IF_LOWPRIORITY;

View file

@ -709,7 +709,7 @@ static qboolean XRandR_Init(void)
xrandr.outputs = NULL;
//enable by default once this is properly tested, and supports hwgamma.
if (!X11_CheckFeature("xrandr", false))
if (!X11_CheckFeature("xrandr", true))
return false;
if (!xrandr.lib)
@ -877,6 +877,7 @@ static void XRandR_Shutdown(void)
}
static qboolean XRandR_FindOutput(const char *name)
{
XRROutputInfo *primary = NULL;
int i;
xrandr.output = NULL;
if (!xrandr.outputs)
@ -892,18 +893,18 @@ static qboolean XRandR_FindOutput(const char *name)
xrandr.crtcinfo = NULL;
for (i = 0; i < xrandr.res->noutput; i++)
{
if (xrandr.outputs[i]->connection != RR_Connected)
continue;
if (!xrandr.output || !strncmp(xrandr.outputs[i]->name, name, xrandr.outputs[i]->nameLen))
{
if (xrandr.outputs[i]->ncrtc) //should be able to use this one
{
xrandr.output = xrandr.outputs[i];
if (!strncmp(xrandr.outputs[i]->name, name, xrandr.outputs[i]->nameLen))
break;
}
if (xrandr.outputs[i]->connection != RR_Connected || !xrandr.outputs[i]->ncrtc)
continue; //not usable...
if (!primary || (xrandr.outputs[i]->npreferred && !primary->npreferred))
primary = xrandr.outputs[i];
if (*name && !strncmp(xrandr.outputs[i]->name, name, xrandr.outputs[i]->nameLen))
{ //this is the one they asked for
xrandr.output = xrandr.outputs[i];
break;
}
}
if (!xrandr.output)
xrandr.output = primary;
if (xrandr.output)
{
xrandr.crtc = xrandr.output->crtcs[0];
@ -3652,7 +3653,7 @@ static qboolean X_CheckWMFullscreenAvailable(void)
return success;
}
static Window X_CreateWindow(qboolean override, XVisualInfo *visinfo, int x, int y, unsigned int width, unsigned int height, qboolean fullscreen)
static Window X_CreateWindow(rendererstate_t *info, qboolean override, XVisualInfo *visinfo, int x, int y, unsigned int width, unsigned int height, qboolean fullscreen)
{
Window wnd, parent;
XSetWindowAttributes attr;
@ -3677,14 +3678,23 @@ static Window X_CreateWindow(qboolean override, XVisualInfo *visinfo, int x, int
}
memset(&szhints, 0, sizeof(szhints));
szhints.flags = PMinSize;
szhints.flags = PMinSize|PPosition|PSize;
szhints.min_width = 320;
szhints.min_height = 200;
szhints.x = x;
szhints.y = y;
szhints.width = width;
szhints.height = height;
if (!fullscreen)
{
#ifdef USE_XRANDR
int dx, dy, dw, dh;
if (*info->devicename && XRandr_PickScreen(info->devicename, &dx, &dy, &dw, &dh))
{
x += dx + (dw-width)/2;
y += dy + (dh-height)/2;
}
else
#endif
szhints.flags &= ~PPosition;
}
if (sys_parentwindow && !fullscreen)
{
@ -3695,6 +3705,11 @@ static Window X_CreateWindow(qboolean override, XVisualInfo *visinfo, int x, int
else
parent = vid_root;
szhints.x = x;
szhints.y = y;
szhints.width = width;
szhints.height = height;
wnd = x11.pXCreateWindow(vid_dpy, parent, x, y, width, height,
0, visinfo->depth, InputOutput,
visinfo->visual, mask, &attr);
@ -3889,11 +3904,11 @@ static qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int
vid.activeapp = false;
if (fullscreenflags & FULLSCREEN_LEGACY)
{
vid_decoywindow = X_CreateWindow(false, visinfo, x, y, 320, 200, false);
vid_window = X_CreateWindow(true, visinfo, x, y, width, height, fullscreen);
vid_decoywindow = X_CreateWindow(info, false, visinfo, x, y, 320, 200, false);
vid_window = X_CreateWindow(info, true, visinfo, x, y, width, height, fullscreen);
}
else
vid_window = X_CreateWindow(false, visinfo, x, y, width, height, fullscreen);
vid_window = X_CreateWindow(info, false, visinfo, x, y, width, height, fullscreen);
vid_x_eventmask |= X_InitUnicode();
x11.pXSelectInput(vid_dpy, vid_window, vid_x_eventmask);

View file

@ -683,6 +683,7 @@ typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei
#define GL_RG 0x8227
#define GL_RGB9_E5 0x8C3D /*opengl 3.0*/
#define GL_R8 0x8229 /*opengl 3.0*/
#define GL_R16 0x822A /*opengl 3.0*/
#define GL_RG8 0x822B /*opengl 3.0*/
#endif
#ifndef GL_RG8_SNORM

View file

@ -2982,7 +2982,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/skeletal.h\"\n"
"affine varying vec2 tc;\n"
"varying vec3 light;\n"
"varying vec4 light;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
"varying vec3 eyevector;\n"
"#endif\n"
@ -2998,6 +2998,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"{\n"
"vec3 n, s, t, w;\n"
"gl_Position = skeletaltransform_wnst(w,n,s,t);\n"
"n = normalize(n);\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
"vec3 eyeminusvertex = e_eyepos - w.xyz;\n"
"eyevector.x = dot(eyeminusvertex, s.xyz);\n"
@ -3015,7 +3016,11 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"float d = dot(n,e_light_dir);\n"
"if (d < 0.0) //vertex shader. this might get ugly, but I don't really want to make it per vertex.\n"
"d = 0.0; //this avoids the dark side going below the ambient level.\n"
"light = e_light_ambient + (d*e_light_mul);\n"
"light.rgb = e_light_ambient + (d*e_light_mul);\n"
"light.a = 1.0;\n"
"#ifdef VC\n"
"light *= v_colour;\n"
"#endif\n"
//FIXME: Software rendering imitation should possibly push out normals by half a pixel or something to approximate software's over-estimation of distant model sizes (small models are drawn using JUST their verticies using the nearest pixel, which results in larger meshes)
@ -3044,8 +3049,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"out vec3 t_normal[];\n"
"affine in vec2 tc[];\n"
"affine out vec2 t_tc[];\n"
"in vec3 light[];\n"
"out vec3 t_light[];\n"
"in vec4 light[];\n"
"out vec4 t_light[];\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
"in vec3 eyevector[];\n"
"out vec3 t_eyevector[];\n"
@ -3093,8 +3098,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"in vec3 t_normal[];\n"
"affine in vec2 t_tc[];\n"
"affine out vec2 tc;\n"
"in vec3 t_light[];\n"
"out vec3 light;\n"
"in vec4 t_light[];\n"
"out vec4 light;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
"in vec3 t_eyevector[];\n"
"out vec3 eyevector;\n"
@ -3157,7 +3162,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
"affine varying vec2 tc;\n"
"varying vec3 light;\n"
"varying vec4 light;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)\n"
"varying vec3 eyevector;\n"
"#endif\n"
@ -3214,8 +3219,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"col.rgb += texture2D(s_reflectmask, tc).rgb * textureCube(s_reflectcube, rtc).rgb;\n"
"#endif\n"
"col.rgb *= light;\n"
"col *= e_colourident;\n"
"col *= light * e_colourident;\n"
"#ifdef FULLBRIGHT\n"
"vec4 fb = texture2D(s_fullbright, tc);\n"
@ -6913,7 +6917,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"ts *= (texture2D(s_lightmap, lm0) * e_lmscale).rgb;\n"
"#endif\n"
"gl_FragColor = fog4(vec4(ts, USEALPHA) * e_colourident);\n"
"gl_FragColor = fog4blend(vec4(ts, USEALPHA) * e_colourident);\n"
"}\n"
"#endif\n"
},
@ -10452,9 +10456,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
{QR_OPENGL, 110, "terrain",
"!!permu FOG\n"
//t0-t3 are the diffusemaps, t4 is the blend factors
"!!samps 5\n"
"!!samps =PCF 6\n"
"!!samps =CUBE 7\n"
"!!samps 4\n"
"!!samps mix=4\n"
"!!samps =PCF shadowmap\n"
"!!samps =CUBE projectionmap\n"
//light levels
@ -10547,7 +10552,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"void main (void)\n"
"{\n"
"vec4 r;\n"
"vec4 m = texture2D(s_t4, lm);\n"
"vec4 m = texture2D(s_mix, lm);\n"
"r = texture2D(s_t0, tc)*m.r;\n"
"r += texture2D(s_t1, tc)*m.g;\n"
@ -10581,13 +10586,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"colorscale *= 1.0-(dot(spot,spot));\n"
"#endif\n"
"#ifdef PCF\n"
"colorscale *= ShadowmapFilter(s_t5, vtexprojcoord);\n"
"colorscale *= ShadowmapFilter(s_shadowmap, vtexprojcoord);\n"
"#endif\n"
"r.rgb *= colorscale * l_lightcolour;\n"
"#ifdef CUBE\n"
"r.rgb *= textureCube(s_t6, vtexprojcoord.xyz).rgb;\n"
"r.rgb *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb;\n"
"#endif\n"
"gl_FragColor = fog4additive(r);\n"
@ -10908,7 +10913,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvardf r_glsl_pcf\n"
"!!cvardf r_tessellation_level=5\n"
"!!samps shadowmap diffuse normalmap specular upper lower reflectcube reflectmask projectionmap\n"
"!!samps diffuse normalmap specular upper lower reflectcube reflectmask\n"
"!!samps =PCF shadowmap\n"
"!!samps =CUBE projectionmap\n"
"#include \"sys/defs.h\"\n"

View file

@ -363,6 +363,20 @@ iwboolean FTP_V4StringToAdr (const char *s, struct sockaddr_in *addr)
return true;
}
#if defined(_WIN32) && !defined(_WIN64) && !defined(WEBSVONLY)
int (WINAPI *pgetaddrinfo) (
const char* nodename,
const char* servname,
const struct addrinfo* hints,
struct addrinfo** res
);
void (WSAAPI *pfreeaddrinfo) (struct addrinfo*);
#else
#define qgetaddrinfo getaddrinfo
#define qfreeaddrinfo freeaddrinfo
#endif
iwboolean FTP_HostToSockaddr(int prot, char *host, int port, struct sockaddr_qstorage *addr, size_t *addrsize)
{
iwboolean r = false;
@ -383,7 +397,7 @@ iwboolean FTP_HostToSockaddr(int prot, char *host, int port, struct sockaddr_qst
break;
}
Q_snprintfz(service, sizeof(service), "%i", port);
if (getaddrinfo(host, service, &hint, &res))
if (qgetaddrinfo(host, service, &hint, &res))
return false;
if (res && res->ai_addr && res->ai_addrlen <= sizeof(*addr))
{
@ -391,7 +405,7 @@ iwboolean FTP_HostToSockaddr(int prot, char *host, int port, struct sockaddr_qst
memcpy(addr, res->ai_addr, res->ai_addrlen);
r = true;
}
freeaddrinfo(res);
qfreeaddrinfo(res);
return r;
#if 0
host = va("[%s]", host);

View file

@ -223,6 +223,22 @@ r_part +te_superspike
assoc gunshotsmoke
}
//simple slight trail, to show movement more than anything else.
r_part tr_spike
{
texture "particles/fteparticlefont.tga"
step 1.1
scale 4
die .4
rgb 20 20 20
alpha 1
blend add
spawnmode spiral 512
spawnvel 10
}
r_trail "progs/spike.mdl" tr_spike
r_trail "progs/s_spike.mdl" tr_spike
////////////////////////////////////////////////
//explosion

View file

@ -445,7 +445,7 @@ reeval:
ddef32_t *d = ED_GlobalAtOfs32(progfuncs, st->a);
#endif
fdef_t *f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->funcs.fieldadjust);
if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):NULL, f?f->name:NULL))
if (PR_ExecRunWarning(&progfuncs->funcs, st-pr_statements, "assignment to read-only entity %i in %s (%s.%s)\n", OPA->edict, PR_StringToNative(&progfuncs->funcs, pr_xfunction->s_name), d?PR_StringToNative(&progfuncs->funcs, d->s_name):"??", f?f->name:"??"))
return pr_xstatement;
OPC->_int = ~0;
break;

View file

@ -6454,17 +6454,6 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f
if (arg >= MAX_PARMS+MAX_EXTRA_PARMS)
QCC_PR_ParseErrorPrintSRef (ERR_TOOMANYTOTALPARAMETERS, func, "More than %i parameters", MAX_PARMS+MAX_EXTRA_PARMS);
else if (extraparms && arg >= MAX_PARMS && !t->vargcount)
{
//vararg builtins cannot accept more than 8 args. they can't tell if they got more, and wouldn't know where to read them.
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSVARARGS, "More than %i parameters on varargs function", MAX_PARMS);
QCC_PR_ParsePrintSRef(WARN_TOOMANYPARAMETERSVARARGS, func);
}
else if (!extraparms && arg >= t->num_parms && !p)
{
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters on call to %s", funcname);
QCC_PR_ParsePrintSRef(WARN_TOOMANYPARAMETERSFORFUNC, func);
}
if (QCC_PR_CheckToken("#"))
{
@ -6481,8 +6470,20 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f
e = QCC_DefToRef(&parambuf[arg], func.cast->params[arg].defltvalue);
}
else
e = QCC_PR_RefExpression(&parambuf[arg], TOP_PRIORITY, EXPR_DISALLOW_COMMA);
e = QCC_PR_RefExpression(&parambuf[arg], TOP_PRIORITY, EXPR_DISALLOW_COMMA);
if (extraparms && arg >= MAX_PARMS && !t->vargcount)
{
//vararg builtins cannot accept more than 8 args. they can't tell if they got more, and wouldn't know where to read them.
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSVARARGS, "More than %i parameters on varargs function", MAX_PARMS);
QCC_PR_ParsePrintSRef(WARN_TOOMANYPARAMETERSVARARGS, func);
}
else if (!extraparms && arg >= t->num_parms && !p)
{
char buf[256];
QCC_PR_ParseWarning (WARN_TOOMANYPARAMETERSFORFUNC, "too many parameters on call to %s, argument %s will be ignored", funcname, QCC_GetRefName(e, buf, sizeof(buf)));
QCC_PR_ParsePrintSRef(WARN_TOOMANYPARAMETERSFORFUNC, func);
}
//with vectorcalls, we store the vector into the args as individual floats
//this allows better reuse of vector constants.
@ -6600,7 +6601,10 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f
}
else*/
{
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s", QCC_GetSRefName(func));
if (func.cast->params[arg].paramname)
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s, %s will be UNDEFINED", QCC_GetSRefName(func), func.cast->params[arg].paramname);
else
QCC_PR_ParseWarning (WARN_TOOFEWPARAMS, "too few parameters on call to %s", QCC_GetSRefName(func));
QCC_PR_ParsePrintSRef (WARN_TOOFEWPARAMS, func);
}
}
@ -14098,7 +14102,7 @@ QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_functio
{
//this is a hack. droptofloor was wrongly declared in vanilla qc, which causes problems with replacement extensions.qc.
//yes, this is a selfish lazy hack for this, there's probably a better way, but at least we spit out a warning still.
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "%s builtin was wrongly defined as %s. ignoring later definition",name, TypeName(type, typebuf1, sizeof(typebuf1)));
QCC_PR_ParseWarning (WARN_COMPATIBILITYHACK, "%s builtin was wrongly redefined as %s. ignoring later definition",name, TypeName(type, typebuf1, sizeof(typebuf1)));
QCC_PR_ParsePrintDef(WARN_COMPATIBILITYHACK, def);
}
else

View file

@ -2596,7 +2596,7 @@ static void UpdateEditorTitle(editor_t *editor)
switch(editor->savefmt)
{
case UTF8_RAW:
encoding = "utf-8(raw)";
encoding = "utf-8";
break;
case UTF8_BOM:
encoding = "utf-8(bom)";

View file

@ -4725,7 +4725,7 @@ pbool QCC_main (int argc, const char **argv) //as part of the quake engine
MAX_STRINGS = 1<<21;
MAX_GLOBALS = 1<<17;
MAX_FIELDS = 1<<13;
MAX_STATEMENTS = 1<<21;
MAX_STATEMENTS = 1<<20;
MAX_FUNCTIONS = 1<<15;
maxtypeinfos = 1<<16;
MAX_CONSTANTS = 1<<12;

View file

@ -364,16 +364,18 @@ typedef enum {
emufield(maxspeed, F_FLOAT) \
emufield(movement, F_VECTOR) \
emufield(vw_index, F_FLOAT) \
emufield(isBot, F_INT)
// emufield(items2, F_FLOAT)
// emufield(brokenankle, F_FLOAT)
// emufield(mod_admin, F_INT)
// emufield(hideentity, F_INT)
// emufield(trackent, F_INT)
// emufield(hideplayers, F_INT)
// emufield(visclients, F_INT)
emufield(isBot, F_INT) \
emufield(items2, F_FLOAT) \
emufield(trackent, F_INT) /*network another player instead, but not entity because of an mvdsv bug. used during bloodfest.*/
// emufield(mod_admin, F_INT) /*enable 'cmd ban' etc when &2*/
// emufield(hideentity, F_INT) /*backward nodrawtoclient, used by race mode spectators*/
// emufield(hideplayers, F_INT) /*force other clients as invisible, for race mode*/
// emufield(visclients, F_INT) /*bitfield of clients that can see this entity (borked with playerslots>32). used for 'cmd tpmsg foo', and bots.*/
// emufield(teleported, F_INT) /*teleport angle twisting*/
// emufield(brokenankle, F_FLOAT) /*not actually in mvdsv after all*/
struct
static struct
{
#define emufield(n,t) int n;
emufields
@ -2554,6 +2556,10 @@ void Q1QVM_PostThink(void)
if (fofs.vw_index)
sv_player->xv->vw_index = ((float*)sv_player->v)[fofs.vw_index];
if (fofs.items2)
sv_player->xv->items2 = ((float*)sv_player->v)[fofs.items2];
if (fofs.trackent)
host_client->viewent = ((int*)sv_player->v)[fofs.trackent];
}
void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes)

View file

@ -78,7 +78,7 @@ void SV_SavegameComment (char *text, size_t textsize)
text[textsize-1] = '\0';
}
pbool SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const char **ptr)
pbool PDECL SV_ExtendedSaveData(pubprogfuncs_t *progfuncs, void *loadctx, const char **ptr)
{
char token[8192];
com_tokentype_t tt;

View file

@ -67,7 +67,7 @@ static int needcleanup;
//int fatbytes;
void SV_ExpandNackFrames(client_t *client, int require)
void SV_ExpandNackFrames(client_t *client, int require, client_frame_t **currentframeptr)
{
client_frame_t *newframes;
char *ptr;
@ -98,6 +98,10 @@ void SV_ExpandNackFrames(client_t *client, int require)
newframes[i].senttime = realtime;
}
Z_Free(client->frameunion.frames);
//if you're calling this then its because you're currently generating new frame data, and its a problem if that changes from under you. fix it up for the caller (so they can't forget to do so)
*currentframeptr = newframes+(*currentframeptr-client->frameunion.frames);
client->frameunion.frames = newframes;
}
@ -336,7 +340,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
if (lognum > maxlog)
{
SV_ExpandNackFrames(client, lognum+1);
SV_ExpandNackFrames(client, lognum+1, &frame);
break;
}
resend[lognum].entnum = entnum;
@ -389,7 +393,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
if (lognum > maxlog)
{
SV_ExpandNackFrames(client, lognum+1);
SV_ExpandNackFrames(client, lognum+1, &frame);
break;
}
resend[lognum].entnum = entnum;
@ -423,7 +427,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
if (lognum > maxlog)
{
SV_ExpandNackFrames(client, lognum+1);
SV_ExpandNackFrames(client, lognum+1, &frame);
break;
}
resend[lognum].entnum = entnum;
@ -459,7 +463,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg, qbyte svcnumber)
if (lognum > maxlog)
{
SV_ExpandNackFrames(client, lognum+1);
SV_ExpandNackFrames(client, lognum+1, &frame);
break;
}
resend[lognum].entnum = entnum;
@ -1512,7 +1516,7 @@ qboolean SVFTE_EmitPacketEntities(client_t *client, packet_entities_t *to, sizeb
}
if (outno >= outmax)
{ //expand the frames. may need some copying...
SV_ExpandNackFrames(client, outno+1);
SV_ExpandNackFrames(client, outno+1, &frame);
break;
}
@ -1985,7 +1989,7 @@ void SVDP_EmitEntitiesUpdate (client_t *client, client_frame_t *frame, packet_en
break; /*give up if it gets full. FIXME: bone data is HUGE.*/
if (outno >= outmax)
{ //expand the frames. may need some copying...
SV_ExpandNackFrames(client, outno+1);
SV_ExpandNackFrames(client, outno+1, &frame);
break;
}

View file

@ -1090,8 +1090,15 @@ dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
dllhandle_t *lib;
lib = dlopen (name, RTLD_LAZY);
if (!lib && !strstr(name, ".so"))
lib = dlopen (va("%s.so", name), RTLD_LAZY);
if (!lib)
{
const char *err = dlerror();
//I hate this string check
Con_DLPrintf(strstr(err, "No such file or directory")?2:0,"%s\n", err);
return NULL;
}
if (funcs)
{
@ -1103,6 +1110,7 @@ dllhandle_t *Sys_LoadLibrary(const char *name, dllfunction_t *funcs)
}
if (funcs[i].name)
{
Con_DPrintf("Unable to find symbol \"%s\" in \"%s\"\n", funcs[i].name, name);
Sys_CloseLibrary((dllhandle_t*)lib);
lib = NULL;
}

View file

@ -37,7 +37,7 @@
#include "sys/skeletal.h"
affine varying vec2 tc;
varying vec3 light;
varying vec4 light;
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
varying vec3 eyevector;
#endif
@ -53,6 +53,7 @@ void main ()
{
vec3 n, s, t, w;
gl_Position = skeletaltransform_wnst(w,n,s,t);
n = normalize(n);
#if defined(SPECULAR)||defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
vec3 eyeminusvertex = e_eyepos - w.xyz;
eyevector.x = dot(eyeminusvertex, s.xyz);
@ -70,7 +71,11 @@ void main ()
float d = dot(n,e_light_dir);
if (d < 0.0) //vertex shader. this might get ugly, but I don't really want to make it per vertex.
d = 0.0; //this avoids the dark side going below the ambient level.
light = e_light_ambient + (d*e_light_mul);
light.rgb = e_light_ambient + (d*e_light_mul);
light.a = 1.0;
#ifdef VC
light *= v_colour;
#endif
//FIXME: Software rendering imitation should possibly push out normals by half a pixel or something to approximate software's over-estimation of distant model sizes (small models are drawn using JUST their verticies using the nearest pixel, which results in larger meshes)
@ -99,8 +104,8 @@ in vec3 normal[];
out vec3 t_normal[];
affine in vec2 tc[];
affine out vec2 t_tc[];
in vec3 light[];
out vec3 t_light[];
in vec4 light[];
out vec4 t_light[];
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
in vec3 eyevector[];
out vec3 t_eyevector[];
@ -148,8 +153,8 @@ in vec3 t_vertex[];
in vec3 t_normal[];
affine in vec2 t_tc[];
affine out vec2 tc;
in vec3 t_light[];
out vec3 light;
in vec4 t_light[];
out vec4 light;
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
in vec3 t_eyevector[];
out vec3 eyevector;
@ -212,7 +217,7 @@ uniform float cvar_gl_specular;
#endif
affine varying vec2 tc;
varying vec3 light;
varying vec4 light;
#if defined(SPECULAR) || defined(OFFSETMAPPING) || defined(REFLECTCUBEMASK)
varying vec3 eyevector;
#endif
@ -269,8 +274,7 @@ void main ()
col.rgb += texture2D(s_reflectmask, tc).rgb * textureCube(s_reflectcube, rtc).rgb;
#endif
col.rgb *= light;
col *= e_colourident;
col *= light * e_colourident;
#ifdef FULLBRIGHT
vec4 fb = texture2D(s_fullbright, tc);

View file

@ -44,6 +44,6 @@ void main ()
ts *= (texture2D(s_lightmap, lm0) * e_lmscale).rgb;
#endif
gl_FragColor = fog4(vec4(ts, USEALPHA) * e_colourident);
gl_FragColor = fog4blend(vec4(ts, USEALPHA) * e_colourident);
}
#endif

View file

@ -9,7 +9,9 @@
!!cvarf r_glsl_offsetmapping_scale
!!cvardf r_glsl_pcf
!!cvardf r_tessellation_level=5
!!samps shadowmap diffuse normalmap specular upper lower reflectcube reflectmask projectionmap
!!samps diffuse normalmap specular upper lower reflectcube reflectmask
!!samps =PCF shadowmap
!!samps =CUBE projectionmap
#include "sys/defs.h"

View file

@ -1,8 +1,9 @@
!!permu FOG
//t0-t3 are the diffusemaps, t4 is the blend factors
!!samps 5
!!samps =PCF 6
!!samps =CUBE 7
!!samps 4
!!samps mix=4
!!samps =PCF shadowmap
!!samps =CUBE projectionmap
//light levels
@ -95,7 +96,7 @@ uniform vec4 e_lmscale;
void main (void)
{
vec4 r;
vec4 m = texture2D(s_t4, lm);
vec4 m = texture2D(s_mix, lm);
r = texture2D(s_t0, tc)*m.r;
r += texture2D(s_t1, tc)*m.g;
@ -129,13 +130,13 @@ void main (void)
colorscale *= 1.0-(dot(spot,spot));
#endif
#ifdef PCF
colorscale *= ShadowmapFilter(s_t5, vtexprojcoord);
colorscale *= ShadowmapFilter(s_shadowmap, vtexprojcoord);
#endif
r.rgb *= colorscale * l_lightcolour;
#ifdef CUBE
r.rgb *= textureCube(s_t6, vtexprojcoord.xyz).rgb;
r.rgb *= textureCube(s_projectionmap, vtexprojcoord.xyz).rgb;
#endif
gl_FragColor = fog4additive(r);

View file

@ -1300,12 +1300,15 @@ vk_image_t VK_CreateTexture2DArray(uint32_t width, uint32_t height, uint32_t lay
case PTI_ARGB4444: /*format = VK_FORMAT_A4R4G4B4_UNORM_PACK16;*/ break;
case PTI_RGBA5551: format = VK_FORMAT_R5G5B5A1_UNORM_PACK16; break;
case PTI_ARGB1555: format = VK_FORMAT_A1R5G5B5_UNORM_PACK16; break;
case PTI_R16: format = VK_FORMAT_R16_UNORM; break;
case PTI_RGBA16: format = VK_FORMAT_R16G16B16A16_UNORM; break;
//float formats
case PTI_R16F: format = VK_FORMAT_R16_SFLOAT; break;
case PTI_R32F: format = VK_FORMAT_R32_SFLOAT; break;
case PTI_RGBA16F: format = VK_FORMAT_R16G16B16A16_SFLOAT; break;
case PTI_RGBA32F: format = VK_FORMAT_R32G32B32A32_SFLOAT; break;
//weird formats
case PTI_P8:
case PTI_R8: format = VK_FORMAT_R8_UNORM; break;
case PTI_RG8: format = VK_FORMAT_R8G8_UNORM; break;
case PTI_R8_SNORM: format = VK_FORMAT_R8_SNORM; break;
@ -2395,6 +2398,7 @@ static qboolean VK_R_RenderScene_Cubemap(struct vk_rendertarg *fb)
Con_Printf("no flush\n");
VKBE_RT_End(&rtc->face[i]);
r_framecount++;
}
r_refdef.vrect = vrect;
@ -3887,6 +3891,7 @@ void VK_CheckTextureFormats(void)
{PTI_ARGB1555, VK_FORMAT_A1R5G5B5_UNORM_PACK16, VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT},
{PTI_RGBA16F, VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT},
{PTI_RGBA32F, VK_FORMAT_R32G32B32A32_SFLOAT, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT|VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT|VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT},
{PTI_P8, VK_FORMAT_R8_UNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_R8, VK_FORMAT_R8_UNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_RG8, VK_FORMAT_R8G8_UNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},
{PTI_R8_SNORM, VK_FORMAT_R8_SNORM, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT},

View file

@ -1143,7 +1143,6 @@ console.log("onerror: " + _url);
var gltex = GL.textures[texid];
img.onload = function()
{
console.log("Image Callback called!");
var oldtex = GLctx.getParameter(GLctx.TEXTURE_BINDING_2D); //blurgh, try to avoid breaking anything in this unexpected event.
GLctx.bindTexture(GLctx.TEXTURE_2D, gltex);
GLctx.texImage2D(GLctx.TEXTURE_2D, 0, GLctx.RGBA, GLctx.RGBA, GLctx.UNSIGNED_BYTE, img);

View file

@ -4,7 +4,7 @@
typedef struct cmdctxt_s cmdctxt_t;
struct cmdctxt_s {
cluster_t *cluster;
sv_t *qtv;
sv_t *qtv;
int streamid; //streamid, which is valid even if qtv is not, for specifying the streamid to use on connects
char *arg[MAX_ARGS];
int argc;
@ -16,7 +16,7 @@ struct cmdctxt_s {
typedef void (*consolecommand_t) (cmdctxt_t *ctx);
void Cmd_Printf(cmdctxt_t *ctx, char *fmt, ...);
void Cmd_Printf(cmdctxt_t *ctx, char *fmt, ...) PRINTFWARNING(2);
#define Cmd_Argc(ctx) ctx->argc
#define Cmd_Argv(ctx, num) (((unsigned int)ctx->argc <= (unsigned int)(num))?"": ctx->arg[num])
#define Cmd_IsLocal(ctx) ctx->localcommand

View file

@ -291,7 +291,7 @@ void Cluster_Run(cluster_t *cluster, qboolean dowait)
if (cluster->inputlength > 0)
{
Sys_Printf(cluster, "%c", c);
Sys_Printf(cluster, " ", c);
Sys_Printf(cluster, " ");
Sys_Printf(cluster, "%c", c);
cluster->inputlength--;
@ -466,12 +466,14 @@ int main(int argc, char **argv)
cluster = malloc(sizeof(*cluster));
if (cluster)
{
int j;
memset(cluster, 0, sizeof(*cluster));
cluster->qwdsocket[0] = INVALID_SOCKET;
cluster->qwdsocket[1] = INVALID_SOCKET;
cluster->tcpsocket[0] = INVALID_SOCKET;
cluster->tcpsocket[1] = INVALID_SOCKET;
for (j = 0; j < SOCKETGROUPS; j++)
{
cluster->qwdsocket[j] = INVALID_SOCKET;
cluster->tcpsocket[j] = INVALID_SOCKET;
}
cluster->anticheattime = 1*1000;
cluster->tooslowdelay = 100;
cluster->qwlistenportnum = 0;
@ -487,18 +489,19 @@ int main(int argc, char **argv)
if (!cluster->numservers)
{ //probably running on a home user's computer
if (cluster->qwdsocket[0] == INVALID_SOCKET && cluster->qwdsocket[1] == INVALID_SOCKET && !cluster->qwlistenportnum)
if (cluster->qwdsocket[SG_IPV4] == INVALID_SOCKET && cluster->qwdsocket[SG_IPV6] == INVALID_SOCKET && !cluster->qwlistenportnum)
{
cluster->qwlistenportnum = 27599;
NET_InitUDPSocket(cluster, cluster->qwlistenportnum, true);
NET_InitUDPSocket(cluster, cluster->qwlistenportnum, false);
NET_InitUDPSocket(cluster, cluster->qwlistenportnum, SG_IPV6);
NET_InitUDPSocket(cluster, cluster->qwlistenportnum, SG_IPV4);
}
if (cluster->tcpsocket[0] == INVALID_SOCKET && cluster->tcpsocket[1] == INVALID_SOCKET && !cluster->tcplistenportnum)
if (cluster->tcpsocket[SG_IPV4] == INVALID_SOCKET && cluster->tcpsocket[SG_IPV6] == INVALID_SOCKET && !cluster->tcplistenportnum)
{
cluster->tcplistenportnum = 27599;
Net_TCPListen(cluster, cluster->tcplistenportnum, true);
Net_TCPListen(cluster, cluster->tcplistenportnum, false);
Net_TCPListen(cluster, cluster->tcplistenportnum, SG_IPV6);
Net_TCPListen(cluster, cluster->tcplistenportnum, SG_IPV4);
}
Net_TCPListen(cluster, 1, SG_UNIX);
Sys_Printf(cluster, "\n"
"Welcome to FTEQTV\n"

View file

@ -122,7 +122,7 @@ void Fwd_ParseCommands(cluster_t *cluster, oproxy_t *prox)
bytes = NET_WebSocketRecv(prox->sock, &prox->websocket, prox->inbuffer+prox->inbuffersize, sizeof(prox->inbuffer)-prox->inbuffersize, NULL);
if (bytes < 0)
{
if (qerrno != EWOULDBLOCK && qerrno != EAGAIN) //not a problem, so long as we can flush it later.
if (qerrno != NET_EWOULDBLOCK && qerrno != NET_EAGAIN) //not a problem, so long as we can flush it later.
{
Sys_Printf(cluster, "network error from client proxy\n");
prox->drop = true; //drop them if we get any errors
@ -215,7 +215,7 @@ void Net_TryFlushProxyBuffer(cluster_t *cluster, oproxy_t *prox)
prox->flushing = false;
break;
case -1:
if (qerrno != EWOULDBLOCK && qerrno != EAGAIN) //not a problem, so long as we can flush it later.
if (qerrno != NET_EWOULDBLOCK && qerrno != NET_EAGAIN) //not a problem, so long as we can flush it later.
{
Sys_Printf(cluster, "network error from client proxy\n");
prox->drop = true; //drop them if we get any errors

View file

@ -7,7 +7,7 @@ size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *st
void tobase64(unsigned char *out, int outlen, unsigned char *in, int inlen)
{
static tab[64] =
static unsigned char tab[64] =
{
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
@ -730,7 +730,7 @@ static void HTTPSV_GenerateAdmin(cluster_t *cluster, oproxy_t *dest, int streami
static void HTTPSV_GenerateDemoListing(cluster_t *cluster, oproxy_t *dest, char *args)
{
int i;
char link[256];
char link[512];
char *s;
qboolean plugframe = false;
for (s=args; *s && *s != ' ';)

View file

@ -252,7 +252,7 @@ void WriteStringSelection(netmsg_t *b, qboolean selected, const char *str)
void Menu_Draw(cluster_t *cluster, viewer_t *viewer)
{
char buffer[2048];
char str[64];
char str[256];
sv_t *sv;
int i, min;
unsigned char *s;

View file

@ -239,7 +239,7 @@ void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, void *data, net
if (ret < 0)
{
int er = qerrno;
if (er == EWOULDBLOCK || er == EAGAIN)
if (er == NET_EWOULDBLOCK || er == NET_EAGAIN)
return;
Sys_Printf(cluster, "udp send error %i (%s)\n", er, strerror(er));

View file

@ -210,7 +210,7 @@ static void ParseServerData(sv_t *tv, netmsg_t *m, int to, unsigned int playerma
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FTE2 (%x) not supported\n", protocol & ~supported);
continue;
case PROTOCOL_VERSION_HUFFMAN:
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_HUFFMAN not supported\n", protocol);
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_HUFFMAN not supported\n");
ParseError(m);
return;
case PROTOCOL_VERSION_VARLENGTH:
@ -236,7 +236,7 @@ static void ParseServerData(sv_t *tv, netmsg_t *m, int to, unsigned int playerma
continue;
case PROTOCOL_VERSION_FRAGMENT:
protocol = ReadLong(m);
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FRAGMENT not supported\n", protocol);
Sys_Printf(tv->cluster, "ParseMessage: PROTOCOL_VERSION_FRAGMENT not supported\n");
ParseError(m);
return;
default:
@ -989,6 +989,7 @@ static void ParsePacketEntities(sv_t *tv, netmsg_t *m, int deltaframe)
tv->physicstime = tv->curtime;
if (tv->cluster->chokeonnotupdated)
{
for (v = tv->cluster->viewers; v; v = v->next)
{
if (v->server == tv)
@ -999,6 +1000,7 @@ static void ParsePacketEntities(sv_t *tv, netmsg_t *m, int deltaframe)
if (v->server == tv && v->netchan.isnqprotocol)
v->maysend = true;
}
}
if (deltaframe != -1)

View file

@ -118,14 +118,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#pragma comment (lib, "wsock32.lib")
#endif
#define qerrno WSAGetLastError()
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EINPROGRESS WSAEINPROGRESS
#define ECONNREFUSED WSAECONNREFUSED
#define ENOTCONN WSAENOTCONN
#define NET_EWOULDBLOCK WSAEWOULDBLOCK
#define NET_EINPROGRESS WSAEINPROGRESS
#define NET_ECONNREFUSED WSAECONNREFUSED
#define NET_ENOTCONN WSAENOTCONN
//we have special functions to properly terminate sprintf buffers in windows.
//we assume other systems are designed with even a minor thought to security.
#if !defined(__MINGW32_VERSION)
#if !defined(__MINGW32__)
#define unlink _unlink //why do MS have to be so awkward?
int snprintf(char *buffer, int buffersize, char *format, ...) PRINTFWARNING(3);
int vsnprintf(char *buffer, int buffersize, const char *format, va_list argptr);
@ -189,8 +189,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//try the cygwin ones
#endif
#ifndef EAGAIN
#define EAGAIN EWOULDBLOCK
#ifndef NET_EWOULDBLOCK
#define NET_EWOULDBLOCK EWOULDBLOCK
#define NET_EINPROGRESS EINPROGRESS
#define NET_ECONNREFUSED ECONNREFUSED
#define NET_ENOTCONN ENOTCONN
#endif
#ifndef NET_EAGAIN
#define NET_EAGAIN NET_EWOULDBLOCK
#endif
#ifndef IPV6_V6ONLY
#define IPV6_V6ONLY 27
@ -229,6 +236,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
size_t strlcpy(char *dst, const char *src, size_t siz);
#define SHA1 SHA1_quake
size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *string, size_t stringlen);
@ -236,8 +244,12 @@ size_t SHA1(unsigned char *digest, size_t maxdigestsize, const unsigned char *st
#define Sys_Printf QTVSys_Printf
#endif
#ifndef STRINGIFY
#define STRINGIFY2(s) #s
#define STRINGIFY(s) STRINGIFY2(s)
#endif
#ifdef SVNREVISION
#define QTV_VERSION_STRING SVNREVISION
#define QTV_VERSION_STRING STRINGIFY(SVNREVISION)
#else
//#include "../engine/common/bothdefs.h"
//#define QTV_VERSION_STRING STRINGIFY(FTE_VER_MAJOR)"."STRINGIFY(FTE_VER_MINOR)
@ -748,10 +760,16 @@ typedef struct {
int time, smalltime;
} availdemo_t;
#define SOCKETGROUPS 2
enum
{
SG_IPV4,
SG_IPV6,
SG_UNIX,
SOCKETGROUPS
};
struct cluster_s {
SOCKET qwdsocket[2]; //udp + quakeworld protocols
SOCKET tcpsocket[2]; //tcp listening socket (for mvd and listings and stuff)
SOCKET qwdsocket[SOCKETGROUPS]; //udp + quakeworld protocols
SOCKET tcpsocket[SOCKETGROUPS]; //tcp listening socket (for mvd and listings and stuff)
tcpconnect_t *tcpconnects; //'tcpconnect' qizmo-compatible quakeworld-over-tcp connection
char commandinput[512];
@ -881,12 +899,15 @@ void ParseMessage(sv_t *tv, void *buffer, int length, int to, int mask);
void BuildServerData(sv_t *tv, netmsg_t *msg, int servercount, viewer_t *spectatorflag);
void BuildNQServerData(sv_t *tv, netmsg_t *msg, qboolean mvd, int servercount);
void QW_UpdateUDPStuff(cluster_t *qtv);
void QW_TCPConnection(cluster_t *cluster, SOCKET sock, wsrbuf_t ws);
unsigned int Sys_Milliseconds(void);
void Prox_SendInitialEnts(sv_t *qtv, oproxy_t *prox, netmsg_t *msg);
qboolean QTV_ConnectStream(sv_t *qtv, char *serverurl);
void QTV_ShutdownStream(sv_t *qtv);
qboolean NET_StringToAddr (char *s, netadr_t *sadr, int defaultport);
void QTV_Printf(sv_t *qtv, char *format, ...) PRINTFWARNING(2);
void QTV_UpdatedServerInfo(sv_t *tv);
void QTV_CleanupMap(sv_t *qtv);
void SendBufferToViewer(viewer_t *v, const char *buffer, int length, qboolean reliable);
void QW_PrintfToViewer(viewer_t *v, char *format, ...) PRINTFWARNING(2);
@ -894,6 +915,11 @@ void QW_StuffcmdToViewer(viewer_t *v, char *format, ...) PRINTFWARNING(2);
void QW_StreamPrint(cluster_t *cluster, sv_t *server, viewer_t *allbut, char *message);
void QW_StreamStuffcmd(cluster_t *cluster, sv_t *server, char *fmt, ...) PRINTFWARNING(3);
void QTV_SayCommand(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *fullcommand); //execute a command from a view
void QW_SetViewersServer(cluster_t *cluster, viewer_t *viewer, sv_t *sv);
void QW_SetMenu(viewer_t *v, int menunum);
void QW_SetCommentator(cluster_t *cluster, viewer_t *v, viewer_t *commentator);
void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer);
void QW_ClearViewerState(viewer_t *viewer);
void PM_PlayerMove (pmove_t *pmove);
@ -924,14 +950,11 @@ qboolean BSP_Visible(bsp_t *bsp, int leafcount, unsigned short *list);
void BSP_SetupForPosition(bsp_t *bsp, float x, float y, float z);
const intermission_t *BSP_IntermissionSpot(bsp_t *bsp);
void QW_SetViewersServer(cluster_t *cluster, viewer_t *viewer, sv_t *sv);
unsigned short QCRC_Block (void *start, int count);
unsigned short QCRC_Value(unsigned short crcvalue);
void WriteDeltaUsercmd (netmsg_t *m, const usercmd_t *from, usercmd_t *move);
void SendClientCommand(sv_t *qtv, char *fmt, ...) PRINTFWARNING(2);
void QTV_Run(sv_t *qtv);
void QW_FreeViewer(cluster_t *cluster, viewer_t *viewer);
void QW_SetMenu(viewer_t *v, int menunum);
char *COM_ParseToken (char *data, char *out, int outsize, const char *punctuation);
char *Info_ValueForKey (char *s, const char *key, char *buffer, int buffersize);
@ -942,11 +965,13 @@ void Com_BlockFullChecksum (void *buffer, int len, unsigned char *outbuf);
void Cluster_BuildAvailableDemoList(cluster_t *cluster);
void Sys_Printf(cluster_t *cluster, char *fmt, ...) PRINTFWARNING(2);
//void Sys_mkdir(char *path);
void QTV_mkdir(char *path);
void Net_ProxySend(cluster_t *cluster, oproxy_t *prox, void *buffer, int length);
oproxy_t *Net_FileProxy(sv_t *qtv, char *filename);
sv_t *QTV_NewServerConnection(cluster_t *cluster, int streamid, char *server, char *password, qboolean force, enum autodisconnect_e autodisconnect, qboolean noduplicates, qboolean query);
void Net_TCPListen(cluster_t *cluster, int port, qboolean ipv6);
void Net_TCPListen(cluster_t *cluster, int port, int socketid);
qboolean Net_StopFileProxy(sv_t *qtv);
@ -954,18 +979,24 @@ void SV_FindProxies(SOCKET sock, cluster_t *cluster, sv_t *defaultqtv);
qboolean SV_ReadPendingProxy(cluster_t *cluster, oproxy_t *pend);
void SV_ForwardStream(sv_t *qtv, void *buffer, int length);
int SV_SayToUpstream(sv_t *qtv, char *message);
void SV_SayToViewers(sv_t *qtv, char *message);
unsigned char *FS_ReadFile(char *gamedir, char *filename, unsigned int *size);
void ChooseFavoriteTrack(sv_t *tv);
void DemoViewer_Update(sv_t *svtest);
void Fwd_SayToDownstream(sv_t *qtv, char *message);
//httpsv.c
void HTTPSV_GetMethod(cluster_t *cluster, oproxy_t *pend);
void HTTPSV_PostMethod(cluster_t *cluster, oproxy_t *pend, char *postdata);
//menu.c
void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum);
void Menu_Draw(cluster_t *cluster, viewer_t *viewer);
#ifdef __cplusplus
}

View file

@ -45,8 +45,6 @@ void QTV_DefaultMovevars(movevars_t *vars)
}
void Menu_Enter(cluster_t *cluster, viewer_t *viewer, int buttonnum);
const usercmd_t nullcmd = {0};
#define CM_ANGLE1 (1<<0)
@ -392,7 +390,7 @@ void SendNQSpawnInfoToViewer(cluster_t *cluster, viewer_t *viewer, netmsg_t *msg
int SendCurrentUserinfos(sv_t *tv, int cursize, netmsg_t *msg, int i, int thisplayer)
{
char name[MAX_QPATH];
char name[1024];
if (i < 0)
return i;
@ -2303,7 +2301,7 @@ void UpdateStats(sv_t *qtv, viewer_t *v)
netmsg_t msg;
char buf[6];
int i;
const static unsigned int nullstats[MAX_STATS] = {1000};
static const unsigned int nullstats[MAX_STATS] = {1000};
const unsigned int *stats;
@ -2467,6 +2465,7 @@ void QTV_SayCommand(cluster_t *cluster, sv_t *qtv, viewer_t *v, char *fullcomman
while(*args && *args <= ' ')
args++;
#pragma message("fixme: These all need testing")
if (!strcmp(command, "help"))
{
QW_PrintfToViewer(v, "Website: "PROXYWEBSITE"\n"
@ -2673,7 +2672,7 @@ I've removed the following from this function as it covered the menu (~Moodles):
if (!shownheader)
{
shownheader = true;
QW_StuffcmdToViewer(v, "menutext 72 %i \"Áãôéöå Çáíåóº\"\n", y);
QW_StuffcmdToViewer(v, "menutext 72 %i \"Áãôéöå Çáíåóº\"\n", y);
y+=8;
}
QW_StuffcmdToViewer(v, "menutext 32 %i \"%30s\" \"stream %i\"\n", y, *sv->map.hostname?sv->map.hostname:sv->server, sv->streamid);
@ -2902,7 +2901,7 @@ tuiadmin:
{
char buf[256];
snprintf(buf, sizeof(buf), "[QuakeTV] %s\n", qtv->serveraddress);
snprintf(buf, sizeof(buf), "[QuakeTV] %s\n", qtv->server);
// Print a short line with info about the server
QW_PrintfToViewer(v, buf);
}
@ -4206,7 +4205,6 @@ void SendViewerPackets(cluster_t *cluster, viewer_t *v)
void QW_ProcessUDPPacket(cluster_t *cluster, netmsg_t *m, netadr_t from)
{
char tempbuffer[256];
int fromsize = sizeof(from);
int qport;
viewer_t *v;
@ -4331,10 +4329,10 @@ void QW_ProcessUDPPacket(cluster_t *cluster, netmsg_t *m, netadr_t from)
if (ReadByte(m) == NQ_NETCHAN_VERSION)
{
//proquake extensions
int mod = ReadByte(m);
int modver = ReadByte(m);
int flags = ReadByte(m);
int passwd = ReadLong(m);
/*int mod =*/ ReadByte(m);
/*int modver =*/ ReadByte(m);
/*int flags =*/ ReadByte(m);
/*int passwd =*/ ReadLong(m);
//fte extension, sent so that dual-protocol servers will not create connections for dual-protocol clients
//the nqconnect command disables this (as well as the qw hand shake) if you really want to use nq protocols with fte clients
@ -4462,7 +4460,7 @@ void QW_UpdateUDPStuff(cluster_t *cluster)
tc->inbuffersize += read;
if (read == 0 || read < 0)
{
if (read == 0 || qerrno != EWOULDBLOCK)
if (read == 0 || qerrno != NET_EWOULDBLOCK)
{
*l = tc->next;
closesocket(tc->sock);

View file

@ -607,14 +607,12 @@ void Cmd_Status(cmdctxt_t *ctx)
Cmd_Printf(ctx, " Talking allowed\n");
if (ctx->cluster->nobsp)
Cmd_Printf(ctx, " No BSP loading\n");
if (ctx->cluster->tcpsocket[0] != INVALID_SOCKET || ctx->cluster->tcpsocket[1] != INVALID_SOCKET)
{
if (ctx->cluster->tcpsocket[SG_UNIX] != INVALID_SOCKET)
Cmd_Printf(ctx, " unix socket open\n");
if (ctx->cluster->tcpsocket[SG_IPV4] != INVALID_SOCKET || ctx->cluster->tcpsocket[SG_IPV6] != INVALID_SOCKET)
Cmd_Printf(ctx, " tcp port %i\n", ctx->cluster->tcplistenportnum);
}
if (ctx->cluster->qwdsocket[0] != INVALID_SOCKET || ctx->cluster->qwdsocket[1] != INVALID_SOCKET)
{
if (ctx->cluster->qwdsocket[SG_IPV4] != INVALID_SOCKET || ctx->cluster->qwdsocket[SG_IPV6] != INVALID_SOCKET)
Cmd_Printf(ctx, " udp port %i\n", ctx->cluster->qwlistenportnum);
}
Cmd_Printf(ctx, " user connections are %sallowed\n", ctx->cluster->nouserconnects?"NOT ":"");
Cmd_Printf(ctx, "\n");

View file

@ -62,6 +62,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <signal.h>
#endif
#include <stddef.h>
#ifdef UNIXSOCKETS
#include <sys/un.h>
#endif
#define RECONNECT_TIME (1000*30)
#define RECONNECT_TIME_DEMO (1000*5)
#define UDPRECONNECT_TIME (1000)
@ -238,13 +243,19 @@ qboolean Net_CompareAddress(netadr_t *s1, netadr_t *s2, int qp1, int qp2)
return false;
}
void Net_TCPListen(cluster_t *cluster, int port, qboolean ipv6)
void Net_TCPListen(cluster_t *cluster, int port, int socketid)
{
SOCKET sock;
struct sockaddr_in address4;
struct sockaddr_in6 address6;
struct sockaddr *address;
union
{
struct sockaddr s;
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
#ifdef UNIXSOCKETS
struct sockaddr_un un;
#endif
} address;
int prot;
int addrsize;
int _true = true;
@ -252,55 +263,69 @@ void Net_TCPListen(cluster_t *cluster, int port, qboolean ipv6)
unsigned long nonblocking = true;
unsigned long v6only = false;
const char *famname;
if (ipv6)
switch(socketid)
{
prot = PF_INET6;
memset(&address6, 0, sizeof(address6));
address6.sin6_family = AF_INET6;
address6.sin6_port = htons((u_short)port);
address = (struct sockaddr *)&address6;
#ifdef UNIXSOCKETS
case SG_UNIX:
prot = AF_UNIX;
memset(&address.un, 0, sizeof(address.un));
address.un.sun_family = prot;
memcpy(address.un.sun_path, "\0qtv", 4);
addrsize = offsetof(struct sockaddr_un, sun_path[4]);
famname = "unix";
break;
#endif
case SG_IPV6:
prot = AF_INET6;
memset(&address.ipv6, 0, sizeof(address.ipv6));
address.ipv6.sin6_family = prot;
address.ipv6.sin6_port = htons((u_short)port);
addrsize = sizeof(struct sockaddr_in6);
}
else
{
prot = PF_INET;
address4.sin_family = AF_INET;
address4.sin_addr.s_addr = INADDR_ANY;
address4.sin_port = htons((u_short)port);
address = (struct sockaddr *)&address4;
if (v6only)
famname = "tcp6";
else
famname = "tcp";
break;
case SG_IPV4:
prot = AF_INET;
address.ipv4.sin_family = prot;
address.ipv4.sin_addr.s_addr = INADDR_ANY;
address.ipv4.sin_port = htons((u_short)port);
addrsize = sizeof(struct sockaddr_in);
famname = "tcp4";
break;
default:
return; //some kind of error. avoid unintialised warnings.
}
if (!ipv6 && !v6only && cluster->tcpsocket[1] != INVALID_SOCKET)
{
if (socketid==SG_IPV4 && !v6only && cluster->tcpsocket[SG_IPV6] != INVALID_SOCKET)
{ //if we already have a hybrid ipv6 socket, don't bother with ipv4 too
int sz = sizeof(v6only);
if (getsockopt(cluster->tcpsocket[1], IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6only, &sz) == 0 && !v6only)
port = 0;
}
if (cluster->tcpsocket[ipv6] != INVALID_SOCKET)
if (cluster->tcpsocket[socketid] != INVALID_SOCKET)
{
closesocket(cluster->tcpsocket[ipv6]);
cluster->tcpsocket[ipv6] = INVALID_SOCKET;
closesocket(cluster->tcpsocket[socketid]);
cluster->tcpsocket[socketid] = INVALID_SOCKET;
if (v6only)
Sys_Printf(cluster, "closed tcp%i port\n", ipv6?6:4);
else
Sys_Printf(cluster, "closed tcp port\n");
Sys_Printf(cluster, "closed %s port\n", famname);
}
if (!port)
return;
if ((sock = socket (prot, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
if ((sock = socket (prot, SOCK_STREAM, 0)) == INVALID_SOCKET)
{
cluster->tcpsocket[ipv6] = INVALID_SOCKET;
cluster->tcpsocket[socketid] = INVALID_SOCKET;
return;
}
if (ioctlsocket (sock, FIONBIO, &nonblocking) == -1)
{
cluster->tcpsocket[ipv6] = INVALID_SOCKET;
cluster->tcpsocket[socketid] = INVALID_SOCKET;
closesocket(sock);
return;
}
@ -312,11 +337,17 @@ void Net_TCPListen(cluster_t *cluster, int port, qboolean ipv6)
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&_true, sizeof(_true));
if (prot == AF_INET6)
if (socketid == SG_IPV6)
{
if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6only, sizeof(v6only)) == -1)
v6only = true;
if (v6only)
famname = "tcp6";
else
famname = "tcp";
}
if (bind (sock, address, addrsize) == -1)
if (bind (sock, &address.s, addrsize) == -1)
{
printf("socket bind error %i (%s)\n", qerrno, strerror(qerrno));
closesocket(sock);
@ -325,12 +356,9 @@ void Net_TCPListen(cluster_t *cluster, int port, qboolean ipv6)
listen(sock, 2); //don't listen for too many clients at once.
if (v6only)
Sys_Printf(cluster, "opened tcp%i port %i\n", ipv6?6:4, port);
else
Sys_Printf(cluster, "opened tcp port %i\n", port);
Sys_Printf(cluster, "opened %s port %i\n", famname, port);
cluster->tcpsocket[ipv6] = sock;
cluster->tcpsocket[socketid] = sock;
}
char *strchrrev(char *str, char chr)
@ -533,7 +561,7 @@ qboolean Net_ConnectToTCPServer(sv_t *qtv, char *ip)
if (connect(qtv->sourcesock, (struct sockaddr *)&qtv->serveraddress.sockaddr, asz) == INVALID_SOCKET)
{
err = qerrno;
if (err != EINPROGRESS && err != EAGAIN && err != EWOULDBLOCK) //bsd sockets are meant to return EINPROGRESS, but some winsock drivers use EWOULDBLOCK instead. *sigh*...
if (err != NET_EINPROGRESS && err != NET_EAGAIN && err != NET_EWOULDBLOCK) //bsd sockets are meant to return EINPROGRESS, but some winsock drivers use EWOULDBLOCK instead. *sigh*...
{
closesocket(qtv->sourcesock);
qtv->sourcesock = INVALID_SOCKET;
@ -679,7 +707,7 @@ qboolean Net_ConnectToDemoServer(sv_t* qtv, char* ip, char* dir)
qtv->filelength = ftell(qtv->sourcefile);
//attempt to detect the end of the file
fseek(qtv->sourcefile, 0-sizeof(smallbuffer), SEEK_CUR);
fseek(qtv->sourcefile, 0-(long)sizeof(smallbuffer), SEEK_CUR);
fread(smallbuffer, 1, 17, qtv->sourcefile);
//0 is the time
if (smallbuffer[1] == dem_all || smallbuffer[1] == dem_read) //mvdsv changed it to read...
@ -718,106 +746,108 @@ qboolean Net_ConnectToDemoDirServer(sv_t* qtv, char *ip)
Sys_Printf(qtv->cluster, "Windows support coming soon!\n");
return false;
#else
DIR *dir;
struct dirent* ent;
dir = opendir(fullname);
if (dir)
{
char demoname[512];
int current_demo = 0;
int file_count = 0;
int random_number = 1; // always this value if the directory contains one file
DIR *dir;
struct dirent* ent;
// count the files, important for determining a random demo file
while ((ent = readdir(dir)) != NULL)
{
int len;
// only count files neding in .mvd
len = strlen(ent->d_name);
if (len < 5)
{
continue;
}
if (strcmp(ent->d_name+len-4, ".mvd"))
{
continue;
}
if (ent->d_type == DT_REG && *(ent->d_name) != '.')
file_count++; // only add non-hidden and regular files
}
if (file_count == 0)
{
// empty directory
Sys_Printf(qtv->cluster, "Stream %i: Error: Directory has no demos.\n", qtv->streamid);
closedir(dir);
return false;
}
closedir(dir);
dir = opendir(fullname);
// FIXME: not sure if srand should only be called once somewhere?
// FIXME: this is not really shuffling the demos, but does introduce some variety
if (file_count > 1)
if (dir)
{
//srand(time(NULL));
while ((random_number = rand()%file_count + 1) == qtv->last_random_number);
qtv->last_random_number = random_number;
}
char demoname[512];
int current_demo = 0;
int file_count = 0;
int random_number = 1; // always this value if the directory contains one file
while (1) {
int len;
ent = readdir(dir);
if (!ent)
// count the files, important for determining a random demo file
while ((ent = readdir(dir)) != NULL)
{
// reached the end of the directory, shouldn't happen
Sys_Printf(qtv->cluster, "Stream %i: Error: Reached end of directory (%s%s)\n", qtv->streamid, qtv->cluster->demodir, ip);
int len;
// only count files neding in .mvd
len = strlen(ent->d_name);
if (len < 5)
{
continue;
}
if (strcmp(ent->d_name+len-4, ".mvd"))
{
continue;
}
if (ent->d_type == DT_REG && *(ent->d_name) != '.')
file_count++; // only add non-hidden and regular files
}
if (file_count == 0)
{
// empty directory
Sys_Printf(qtv->cluster, "Stream %i: Error: Directory has no demos.\n", qtv->streamid);
closedir(dir);
return false;
}
if (ent->d_type != DT_REG || *(ent->d_name) == '.')
{
continue; // ignore hidden and non-regular files
}
//now make certain that the last four characters are '.mvd' and not something like '.cfg' perhaps
len = strlen(ent->d_name);
if (len < 5)
{
continue;
}
if (strcmp((ent->d_name)+len-4, ".mvd"))
{
continue;
}
if (++current_demo != random_number)
continue;
snprintf(demoname, sizeof(demoname), "%s/%s", ip, ent->d_name);
qtv->sourcefile = demoname;
closedir(dir);
if (Net_ConnectToDemoServer(qtv, ent->d_name, ip) == true)
dir = opendir(fullname);
// FIXME: not sure if srand should only be called once somewhere?
// FIXME: this is not really shuffling the demos, but does introduce some variety
if (file_count > 1)
{
return true;
//srand(time(NULL));
while ((random_number = rand()%file_count + 1) == qtv->last_random_number);
qtv->last_random_number = random_number;
}
else
{
return false;
while (1) {
int len;
ent = readdir(dir);
if (!ent)
{
// reached the end of the directory, shouldn't happen
Sys_Printf(qtv->cluster, "Stream %i: Error: Reached end of directory (%s%s)\n", qtv->streamid, qtv->cluster->demodir, ip);
closedir(dir);
return false;
}
if (ent->d_type != DT_REG || *(ent->d_name) == '.')
{
continue; // ignore hidden and non-regular files
}
//now make certain that the last four characters are '.mvd' and not something like '.cfg' perhaps
len = strlen(ent->d_name);
if (len < 5)
{
continue;
}
if (strcmp((ent->d_name)+len-4, ".mvd"))
{
continue;
}
if (++current_demo != random_number)
continue;
snprintf(demoname, sizeof(demoname), "%s/%s", ip, ent->d_name);
qtv->sourcefile = fopen(demoname, "rb");
closedir(dir);
if (Net_ConnectToDemoServer(qtv, ent->d_name, ip) == true)
{
return true;
}
else
{
return false;
}
}
closedir(dir);
}
else
{
Sys_Printf(qtv->cluster, "Stream %i: Unable to open directory %s\n", qtv->streamid, qtv->cluster->demodir);
return false;
}
closedir(dir);
}
else
{
Sys_Printf(qtv->cluster, "Stream %i: Unable to open directory %s\n", qtv->streamid, qtv->cluster->demodir);
return false;
}
#endif
@ -935,13 +965,11 @@ qboolean Net_WriteUpstream(sv_t *qtv)
if (len < 0)
{
int err = qerrno;
if (err != EWOULDBLOCK && err != EAGAIN && err != ENOTCONN)
if (err != NET_EWOULDBLOCK && err != NET_EAGAIN && err != NET_ENOTCONN)
{
int err;
err = qerrno;
if (qerrno)
if (err)
{
Sys_Printf(qtv->cluster, "Stream %i: Error: source socket error %i (%s)\n", qtv->streamid, qerrno, strerror(qerrno));
Sys_Printf(qtv->cluster, "Stream %i: Error: source socket error %i (%s)\n", qtv->streamid, err, strerror(err));
strcpy(qtv->status, "Network error\n");
}
else
@ -1091,7 +1119,7 @@ qboolean Net_ReadStream(sv_t *qtv)
errsize = sizeof(err);
err = 0;
getsockopt(qtv->sourcesock, SOL_SOCKET, SO_ERROR, (char*)&err, &errsize);
if (err == ECONNREFUSED)
if (err == NET_ECONNREFUSED)
{
Sys_Printf(qtv->cluster, "Stream %i: Error: server %s refused connection\n", qtv->streamid, qtv->server);
closesocket(qtv->sourcesock);
@ -1123,7 +1151,7 @@ qboolean Net_ReadStream(sv_t *qtv)
err = 0;
else
err = qerrno;
if (read == 0 || (err != EWOULDBLOCK && err != EAGAIN && err != ENOTCONN)) //ENOTCONN can be returned whilst waiting for a connect to finish.
if (read == 0 || (err != NET_EWOULDBLOCK && err != NET_EAGAIN && err != NET_ENOTCONN)) //ENOTCONN can be returned whilst waiting for a connect to finish.
{
if (qtv->sourcefile)
Sys_Printf(qtv->cluster, "Stream %i: Error: End of file\n", qtv->streamid);

View file

@ -1467,13 +1467,13 @@ static int sasl_oauth2_initial(struct sasl_ctx_s *ctx, char *buf, int bufsize)
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
//"Authorization: Basic %s\r\n"
"Content-length: %i\r\n"
"Content-length: %u\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"Connection: close\r\n"
"\r\n",
resource,
host,
strlen(body));
(unsigned)strlen(body));
sock = pNet_TCPConnect(host, 443);
pNet_SetTLSClient(sock, host);
@ -1541,12 +1541,12 @@ static int sasl_oauth2_initial(struct sasl_ctx_s *ctx, char *buf, int bufsize)
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
//"Authorization: Basic %s\r\n"
"Content-length: %i\r\n"
"Content-length: %u\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"user-agent: fteqw-plugin-xmpp\r\n"
"Connection: close\r\n"
"\r\n",
resource, host, strlen(body));
resource, host, (unsigned)strlen(body));
Con_Printf("XMPP: Requesting access token\n");
sock = pNet_TCPConnect(host, 443);
@ -1613,12 +1613,12 @@ static int sasl_oauth2_initial(struct sasl_ctx_s *ctx, char *buf, int bufsize)
"POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
//"Authorization: Basic %s\r\n"
"Content-length: %i\r\n"
"Content-length: %u\r\n"
"Content-Type: application/x-www-form-urlencoded\r\n"
"user-agent: fteqw-plugin-xmpp\r\n"
"Connection: close\r\n"
"\r\n",
resource, host, strlen(body));
resource, host, (unsigned)strlen(body));
Con_Printf("XMPP: Refreshing access token\n");
sock = pNet_TCPConnect(host, 443);

2160
plugins/models/gltf.c Normal file

File diff suppressed because it is too large Load diff

843
plugins/models/models.c Normal file
View file

@ -0,0 +1,843 @@
#ifndef GLQUAKE
#define GLQUAKE //this is shit.
#endif
#include "quakedef.h"
#include "../plugin.h"
#include "com_mesh.h"
modplugfuncs_t *modfuncs;
//#define ASEMODELS //FIXME: TEST TEST TEST. shold be working iiuc
//#define LWOMODELS //not working
#define GLTFMODELS //FIXME: not yet working properly.
#ifdef ASEMODELS
struct aseimport_s
{
char *file;
struct asematerial_s
{
char name[MAX_QPATH];
struct asemesh_s
{
struct asemesh_s *next;
struct asevert_s
{
vec3_t xyz;
vec3_t norm;
vec2_t st;
} *vert;
unsigned int numverts;
unsigned int maxverts;
index_t *index;
unsigned int numindexes;
unsigned int maxindexes;
} *meshes;
} *materials;
unsigned int nummaterials;
};
static char *ASE_GetToken(struct aseimport_s *ase, char *token, size_t tokensize)
{
char *ret = token;
tokensize--;
while(*ase->file == ' ' || *ase->file == '\t')
ase->file++;
if (*ase->file == '\n')
{
*ret = 0;
return ret;
}
if (*ase->file == '\"')
{
ase->file += 1;
while(tokensize-- > 0)
{
char i = *ase->file;
if (i == '\n')
break;
ase->file+=1;
if (i == '\"')
break;
*token++ = i;
}
}
else
{
while(tokensize-- > 0)
{
char i = *ase->file;
if (i == ' ' || i == '\t' || i == '\r' || i == '\n')
break;
ase->file+=1;
*token++ = i;
}
}
*token = 0;
return ret;
}
static void ASE_SkipLine(struct aseimport_s *ase)
{
while (*ase->file)
{
if (*ase->file == '\n')
{
ase->file += 1;
break;
}
ase->file += 1;
}
}
static void ASE_SkipBlock(struct aseimport_s *ase)
{
while (*ase->file)
{
if (*ase->file == '\n' || *ase->file == '{')
break;
ase->file += 1;
}
if (*ase->file == '{')
{
char token[1024];
ASE_SkipLine(ase);
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else
{
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
}
static void ASE_Material(struct aseimport_s *ase)
{
int idx;
char token[1024];
ASE_GetToken(ase, token, sizeof(token));
idx = atoi(token);
if (idx < 0 || idx >= ase->nummaterials)
{
Con_Printf("invalid material index: %s\n", token);
ASE_SkipBlock(ase);
return;
}
ASE_GetToken(ase, token, sizeof(token));
ASE_SkipLine(ase);
if (strcmp(token, "{"))
return;
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MATERIAL_NAME"))
{
ASE_GetToken(ase, token, sizeof(token));
Q_strlcpy(ase->materials[idx].name, token, sizeof(ase->materials[idx].name));
}
else if (!strcmp(token, "*MATERIAL_CLASS") || !strcmp(token, "*MATERIAL_DIFFUSE") || !strcmp(token, "*MATERIAL_SHADING") || !strcmp(token, "*MAP_DIFFUSE"))
ASE_SkipBlock(ase);
else
{
Con_Printf("Unknown top-level identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
static void ASE_MaterialList(struct aseimport_s *ase)
{
char token[1024];
ASE_GetToken(ase, token, sizeof(token));
ASE_SkipLine(ase);
if (strcmp(token, "{"))
return;
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MATERIAL_COUNT"))
{
ASE_GetToken(ase, token, sizeof(token));
if (!ase->materials)
{
ase->nummaterials = atoi(token);
ase->materials = malloc(sizeof(*ase->materials) * ase->nummaterials);
memset(ase->materials, 0, sizeof(*ase->materials) * ase->nummaterials);
}
}
else if (!strcmp(token, "*MATERIAL"))
{
ASE_Material(ase);
}
else
{
Con_Printf("Unknown top-level identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
static void ASE_GeomObject(struct aseimport_s *ase)
{
size_t materialidx = 0;
size_t numverts = 0;
size_t numtverts = 0;
size_t numtris = 0;
struct
{
vec3_t xyz;
vec3_t norm;
} *verts = NULL;
struct
{
vec3_t st;
} *tverts = NULL;
struct
{
index_t vidx[3];
index_t tidx[3];
} *tris = NULL;
size_t idx;
char token[1024];
ASE_GetToken(ase, token, sizeof(token));
ASE_SkipLine(ase);
if (strcmp(token, "{"))
return;
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MATERIAL_REF"))
{
ASE_GetToken(ase, token, sizeof(token));
materialidx = atoi(token);
}
else if (!strcmp(token, "*MESH"))
{
ASE_SkipLine(ase);
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*TIMEVALUE"))
ASE_SkipBlock(ase); //not useful
else if (!strcmp(token, "*MESH_NUMVERTEX"))
{
ASE_GetToken(ase, token, sizeof(token));
if (!verts)
{
numverts = atoi(token);
verts = malloc(sizeof(*verts) * numverts);
memset(verts, 0, sizeof(*verts) * numverts);
}
}
else if (!strcmp(token, "*MESH_NUMFACES"))
{
ASE_GetToken(ase, token, sizeof(token));
if (!tris)
{
numtris = atoi(token);
tris = malloc(sizeof(*tris) * numtris);
memset(tris, 0, sizeof(*tris) * numtris);
}
}
else if (!strcmp(token, "*COMMENT"))
ASE_SkipBlock(ase); //unused
else if (!strcmp(token, "*MESH_VERTEX_LIST"))
{
ASE_SkipLine(ase);
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MESH_VERTEX"))
{
ASE_GetToken(ase, token, sizeof(token));
idx = atoi(token);
if (idx >= 0 && idx < numverts)
{
ASE_GetToken(ase, token, sizeof(token));
verts[idx].xyz[0] = atof(token);
ASE_GetToken(ase, token, sizeof(token));
verts[idx].xyz[1] = atof(token);
ASE_GetToken(ase, token, sizeof(token));
verts[idx].xyz[2] = atof(token);
}
}
else
{
Con_Printf("Unknown MESH_VERTEX_LIST identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
else if (!strcmp(token, "*MESH_NORMALS"))
{
ASE_SkipLine(ase);
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MESH_FACENORMAL"))
ASE_SkipBlock(ase); //we don't give a fuck about these. its not usable for us. we'll calculate these if we actually need them, that way we're sure it actually matches the geometry and doesn't bug out.
else if (!strcmp(token, "*MESH_VERTEXNORMAL"))
{
ASE_GetToken(ase, token, sizeof(token));
idx = atoi(token);
if (idx >= 0 && idx < numverts)
{
ASE_GetToken(ase, token, sizeof(token));
verts[idx].norm[0] = atof(token);
ASE_GetToken(ase, token, sizeof(token));
verts[idx].norm[1] = atof(token);
ASE_GetToken(ase, token, sizeof(token));
verts[idx].norm[2] = atof(token);
}
}
else
{
Con_Printf("Unknown MESH_NORMALS identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
else if (!strcmp(token, "*MESH_FACE_LIST"))
{
ASE_SkipLine(ase);
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MESH_FACE"))
{
ASE_GetToken(ase, token, sizeof(token));
idx = atoi(token);
if (idx >= 0 && idx < numtris)
{
ASE_GetToken(ase, token, sizeof(token));
while(*token)
{
if (!strcmp(token, "A:"))
{
ASE_GetToken(ase, token, sizeof(token));
tris[idx].vidx[0] = atoi(token);
}
else if (!strcmp(token, "B:"))
{
ASE_GetToken(ase, token, sizeof(token));
tris[idx].vidx[1] = atoi(token);
}
else if (!strcmp(token, "C:"))
{
ASE_GetToken(ase, token, sizeof(token));
tris[idx].vidx[2] = atoi(token);
}
else if (!strcmp(token, "AB:") || !strcmp(token, "BC:") || !strcmp(token, "CA:") || !strcmp(token, "*MESH_SMOOTHING") || !strcmp(token, "*MESH_MTLID"))
{
ASE_GetToken(ase, token, sizeof(token));
}
else
{
Con_Printf("Unknown MESH_FACE identifier: %s\n", token);
ASE_GetToken(ase, token, sizeof(token));
}
ASE_GetToken(ase, token, sizeof(token));
}
tris[idx].tidx[0] = atoi(token);
ASE_GetToken(ase, token, sizeof(token));
tris[idx].tidx[1] = atoi(token);
ASE_GetToken(ase, token, sizeof(token));
tris[idx].tidx[2] = atoi(token);
}
}
else
{
Con_Printf("Unknown MESH_FACE_LIST identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
else if (!strcmp(token, "*MESH_NUMTVERTEX"))
{
ASE_GetToken(ase, token, sizeof(token));
if (!tverts)
{
numtverts = atoi(token);
tverts = malloc(sizeof(*tverts) * numtverts);
memset(tverts, 0, sizeof(*tverts) * numtverts);
}
}
else if (!strcmp(token, "*MESH_TVERTLIST"))
{
ASE_SkipLine(ase);
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MESH_TVERT"))
{
ASE_GetToken(ase, token, sizeof(token));
idx = atoi(token);
if (idx >= 0 && idx < numverts)
{
ASE_GetToken(ase, token, sizeof(token));
tverts[idx].st[0] = atof(token);
ASE_GetToken(ase, token, sizeof(token));
tverts[idx].st[1] = atof(token);
ASE_GetToken(ase, token, sizeof(token));
tverts[idx].st[2] = atof(token);
}
}
else
{
Con_Printf("Unknown MESH_TVERTLIST identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
else if (!strcmp(token, "*MESH_NUMTVFACES"))
ASE_SkipBlock(ase); //should be equal to MESH_NUMFACES
else if (!strcmp(token, "*MESH_TFACELIST"))
{
ASE_SkipLine(ase);
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "}"))
break;
else if (!strcmp(token, "*MESH_TFACE"))
{
ASE_GetToken(ase, token, sizeof(token));
idx = atoi(token);
if (idx >= 0 && idx < numtris)
{
ASE_GetToken(ase, token, sizeof(token));
tris[idx].tidx[0] = atoi(token);
ASE_GetToken(ase, token, sizeof(token));
tris[idx].tidx[1] = atoi(token);
ASE_GetToken(ase, token, sizeof(token));
tris[idx].tidx[2] = atoi(token);
}
}
else
{
Con_Printf("Unknown MESH_TFACELIST identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
else
{
Con_Printf("Unknown top-level identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
else if (!strcmp(token, "*NODE_NAME") || !strcmp(token, "*NODE_TM")
|| !strcmp(token, "*PROP_MOTIONBLUR")|| !strcmp(token, "*PROP_CASTSHADOW")|| !strcmp(token, "*PROP_RECVSHADOW"))
ASE_SkipBlock(ase);
else
{
Con_Printf("Unknown top-level identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
//merge into a mesh
if (materialidx >= 0 && materialidx < ase->nummaterials)
{
size_t v, tri, idx;
struct asemesh_s *mesh;
struct asevert_s asevert;
mesh = ase->materials[materialidx].meshes;
//don't let any single mesh exceed 65k verts. stuff bugs out then.
if (!mesh || mesh->numverts + numtris*3 > 0xffff)
{
mesh = malloc(sizeof(*mesh));
memset(mesh, 0, sizeof(*mesh));
mesh->next = ase->materials[materialidx].meshes;
ase->materials[materialidx].meshes = mesh;
}
//make sure there's going to be enough space
if (mesh->numverts + numtris*3 > mesh->maxverts)
{
mesh->maxverts = (mesh->maxverts+numtris*3)*2;
mesh->vert = realloc(mesh->vert, sizeof(*mesh->vert) * mesh->maxverts);
}
if (mesh->numindexes + numtris*3 > mesh->maxindexes)
{
mesh->maxindexes = (mesh->maxindexes+numtris*3)*2;
mesh->index = realloc(mesh->index, sizeof(*mesh->index) * mesh->maxindexes);
}
//insert each triangle into the mesh
for (tri = 0; tri < numtris; tri++)
{
for (v = 3; v --> 0; )
{
VectorCopy(verts[tris[tri].vidx[v]].xyz, asevert.xyz);
VectorCopy(verts[tris[tri].vidx[v]].norm, asevert.norm);
Vector2Copy(tverts[tris[tri].tidx[v]].st, asevert.st);
for (idx = 0; idx < mesh->numverts; idx++)
{
if (!memcmp(&mesh->vert[idx], &asevert, sizeof(asevert)))
break;
}
if (idx == mesh->numverts)
mesh->vert[mesh->numverts++] = asevert;
mesh->index[mesh->numindexes++] = idx;
}
}
}
free(verts);
free(tverts);
free(tris);
}
static void ASE_TopLevel(struct aseimport_s *ase)
{
char token[1024];
while (*ase->file)
{
ASE_GetToken(ase, token, sizeof(token));
if (!strcmp(token, "*3DSMAX_ASCIIEXPORT"))
{
ASE_GetToken(ase, token, sizeof(token)); //version
}
else if (!strcmp(token, "*COMMENT") || !strcmp(token, "*SCENE"))
ASE_SkipBlock(ase);
else if (!strcmp(token, "*MATERIAL_LIST"))
ASE_MaterialList(ase);
else if (!strcmp(token, "*GEOMOBJECT"))
ASE_GeomObject(ase);
else
{
Con_Printf("Unknown top-level identifier: %s\n", token);
ASE_SkipBlock(ase);
}
ASE_SkipLine(ase);
}
}
static qboolean QDECL Mod_LoadASEModel (struct model_s *mod, void *buffer, size_t fsize)
{
galiaspose_t *pose;
galiasinfo_t *surf;
size_t i, m;
struct aseimport_s ase;
memset(&ase, 0, sizeof(ase));
ase.file = buffer;
ASE_TopLevel(&ase);
//we need to generate engine meshes and clean up any dynamic memory
for (m = 0; m < ase.nummaterials; m++)
{
struct asemesh_s *mesh;
while(ase.materials[m].meshes)
{
mesh = ase.materials[m].meshes;
ase.materials[m].meshes = mesh->next;
surf = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*surf));
surf->nextsurf = mod->meshinfo;
mod->meshinfo = surf;
surf->numverts = mesh->numverts;
surf->numindexes = mesh->numindexes;
surf->ofs_indexes = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*surf->ofs_indexes) * mesh->numindexes);
for (i = 0; i < mesh->numindexes; i++)
surf->ofs_indexes[i] = mesh->index[i];
surf->numanimations = 1;
surf->ofsanimations = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*surf->ofsanimations));
surf->ofsanimations->poseofs = pose = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*pose));
surf->ofsanimations->loop = true;
surf->ofsanimations->numposes = 1;
surf->ofsanimations->rate = 10;
pose->ofsverts = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*pose->ofsverts) * mesh->numverts);
pose->ofsnormals = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*pose->ofsnormals) * mesh->numverts);
surf->ofs_st_array = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*surf->ofs_st_array) * mesh->numverts);
for (i = 0; i < mesh->numverts; i++)
{
VectorCopy(mesh->vert[i].xyz, pose->ofsverts[i]);
VectorCopy(mesh->vert[i].norm, pose->ofsnormals[i]);
Vector2Copy(mesh->vert[i].st, surf->ofs_st_array[i]);
}
surf->numskins = 1;
surf->ofsskins = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*surf->ofsskins));
surf->ofsskins->numframes = 1;
surf->ofsskins->skinspeed = 0.1;
surf->ofsskins->frame = modfuncs->ZG_Malloc(&mod->memgroup, sizeof(*surf->ofsskins->frame));
Q_strlcpy(surf->ofsskins->frame->shadername, ase.materials[m].name, sizeof(surf->ofsskins->frame->shadername));
Q_strlcpy(surf->ofsskins->name, ase.materials[m].name, sizeof(surf->ofsskins->name));
free(mesh->vert);
free(mesh->index);
free(mesh);
}
}
free(ase.materials);
mod->type = mod_alias;
return !!mod->meshinfo;
}
#endif
#ifdef LWOMODELS
static char *LWO_ReadString(unsigned char **file)
{ //strings are just null terminated.
//however, they may have an extra byte of padding. yay shorts...
//so skip the null and round up the length.
char *ret = *file;
size_t len = strlen(ret);
*file = *file + ((len + 2)&~1);
return ret;
}
static qboolean QDECL Mod_LoadLWOModel (struct model_s *mod, void *buffer, size_t fsize)
{
unsigned char *file = buffer, *fileend;
char *tags;
vec3_t *points;
size_t numpoints;
unsigned int tagssize;
size_t subsize;
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
if (strncmp(file, "FORM", 4) || subsize+8 != fsize)
return false; //not an lwo, or corrupt, or something
file += 8;
fileend = file + subsize;
if (strncmp(file, "LWO2", 4))
return false;
file += 4;
while (file < fileend)
{
if (!strncmp(file, "TAGS", 4))
{
tagssize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
tags = file+8;
file += 8+tagssize;
}
else if (!strncmp(file, "LAYR", 4))
{
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
//fixme:
file += 8+subsize;
}
else if (!strncmp(file, "PNTS", 4))
{
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
numpoints = subsize / sizeof(vec3_t);
points = (vec3_t*)(file+8);
file += 8+subsize;
}
else if (!strncmp(file, "BBOX", 4))
{
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
//we don't really care.
file += 8+subsize;
}
else if (!strncmp(file, "VMAP", 4))
{
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
if (!strcmp(file, "TXUV"))
{
}
// else if (!strcmp(file, "RGBA") || !strcmp(file, "RGB"))
// {
// }
file += 8+subsize;
}
else if (!strncmp(file, "POLS", 4))
{
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
file += 8;
if (!strcmp(file, "FACE") || !strcmp(file, "PTCH"))
{
}
file += subsize;
}
else if (!strncmp(file, "PTAG", 4))
{
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
//fixme:
file += 8+subsize;
}
else if (!strncmp(file, "VMAD", 4))
{
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
//fixme:
file += 8+subsize;
}
else if (!strncmp(file, "SURF", 4))
{
char *surfend;
char *surfname, *sourcename;
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
file += 8;
surfend = file + subsize;
surfname = LWO_ReadString(&file);
sourcename = LWO_ReadString(&file);
Con_Printf("surf=%s source=%s\n", surfname, sourcename);
while (file < surfend)
{
if (!strncmp(file, "COLR", 4))
{
subsize = file[5] | (file[4]<<8);
//fixme
file += 6+subsize;
}
else if (!strncmp(file, "DIFF", 4))
{
subsize = file[5] | (file[4]<<8);
//fixme
file += 6+subsize;
}
else if (!strncmp(file, "SMAN", 4))
{
subsize = file[5] | (file[4]<<8);
//fixme
file += 6+subsize;
}
else if (!strncmp(file, "BLOK", 4))
{
char *blokend;
subsize = file[5] | (file[4]<<8);
file += 6;
blokend = file + subsize;
while (file < blokend)
{
if (!strncmp(file, "IMAP", 4))
;
else if (!strncmp(file, "TMAP", 4))
;
else if (!strncmp(file, "PROJ", 4))
;
else if (!strncmp(file, "AXIS", 4))
;
else if (!strncmp(file, "IMAG", 4))
;
else if (!strncmp(file, "WRAP", 4))
;
else if (!strncmp(file, "WRPW", 4))
;
else if (!strncmp(file, "WRPH", 4))
;
else if (!strncmp(file, "VMAP", 4))
;
else if (!strncmp(file, "AAST", 4))
;
else if (!strncmp(file, "PIXB", 4))
;
else
Con_Printf("Unknown BLOK ID: %c%c%c%c\n", file[0], file[1], file[2], file[3]);
subsize = file[5] | (file[4]<<8);
file += 6+subsize;
}
file = blokend;
}
else
{
Con_Printf("Unknown SURF ID: %c%c%c%c\n", file[0], file[1], file[2], file[3]);
subsize = file[5] | (file[4]<<8);
file += 6+subsize;
}
}
file = surfend;
}
else
{
Con_Printf("Unknown ID: %c%c%c%c\n", file[0], file[1], file[2], file[3]);
subsize = file[7] | (file[6]<<8) | (file[5]<<16) | (file[4]<<24);
file += 8+subsize;
continue;
}
}
return false;
}
#endif
qboolean QDECL Mod_LoadGLTFModel (struct model_s *mod, void *buffer, size_t fsize);
qboolean QDECL Mod_LoadGLBModel (struct model_s *mod, void *buffer, size_t fsize);
qintptr_t Plug_Init(qintptr_t *args)
{
CHECKBUILTIN(Mod_GetPluginModelFuncs);
if (BUILTINISVALID(Mod_GetPluginModelFuncs))
{
modfuncs = pMod_GetPluginModelFuncs(sizeof(modplugfuncs_t));
if (modfuncs && modfuncs->version < MODPLUGFUNCS_VERSION)
modfuncs = NULL;
}
if (modfuncs)
{
#ifdef ASEMODELS
modfuncs->RegisterModelFormatText("ASE models (ase)", "*3DSMAX_ASCIIEXPORT", Mod_LoadASEModel);
#endif
#ifdef LWOMODELS
modfuncs->RegisterModelFormatMagic("LWO models (lwo)", (('M'<<24)+('R'<<16)+('O'<<8)+'F'), Mod_LoadLWOModel);
#endif
#ifdef GLTFMODELS
modfuncs->RegisterModelFormatText("glTF2 models (glTF)", ".gltf", Mod_LoadGLTFModel);
modfuncs->RegisterModelFormatMagic("glTF2 models (glb)", (('F'<<24)+('T'<<16)+('l'<<8)+'g'), Mod_LoadGLBModel);
#endif
return true;
}
return false;
}

View file

@ -144,12 +144,21 @@ extern "C" {
#define QDECL
#endif
#endif
#ifndef LIKEPRINTF
#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define LIKEPRINTF(x) __attribute__((format(printf,x,x+1)))
#else
#define LIKEPRINTF(x)
#endif
#endif
extern qintptr_t (QDECL *plugin_syscall)( qintptr_t arg, ... );
void Q_strlncpy(char *d, const char *s, int sizeofd, int lenofs);
void Q_strlcpy(char *d, const char *s, int n);
void Q_strlcat(char *d, const char *s, int n);
int Q_snprintf(char *buffer, size_t maxlen, const char *format, ...);
int Q_snprintf(char *buffer, size_t maxlen, const char *format, ...) LIKEPRINTF(3);
int Q_vsnprintf(char *buffer, size_t maxlen, const char *format, va_list vargs);
#endif
@ -366,7 +375,8 @@ EBUILTIN(int, Net_Send, (qhandle_t socket, void *buffer, int len));
EBUILTIN(void, Net_Close, (qhandle_t socket));
EBUILTIN(int, Net_SetTLSClient, (qhandle_t sock, const char *certhostname));
EBUILTIN(int, Net_GetTLSBinding, (qhandle_t sock, char *outdata, int *datalen));
#define N_WOULDBLOCK 0
#define N_WOULDBLOCK -1
#define N_FATALERROR -2
#define NET_CLIENTPORT -1
#define NET_SERVERPORT -2

View file

@ -6,14 +6,16 @@
//wmaker -display :1 (or xterm or whatever)
#include "../plugin.h"
#include "qux.h"
#include "../engine.h"
#include "qux.h"
#undef MULTITHREAD
int mousecursor_x, mousecursor_y;
float mousecursor_x, mousecursor_y;
static const int baseport = 6000;
static xclient_t *xclients;
static qhandle_t xlistensocket;
static qhandle_t xlistensocket = -1;
xwindow_t *xfocusedwindow;
@ -27,6 +29,7 @@ extern xwindow_t *xpgrabbedwindow;
int ctrldown, altdown;
#ifndef K_CTRL
int K_BACKSPACE;
int K_CTRL;
int K_ALT;
@ -35,9 +38,176 @@ int K_MOUSE2;
int K_MOUSE3;
int K_MOUSE4;
int K_MOUSE5;
#endif
int QKeyToScan(int qkey)
{ //X11 uses some variation of hardware scancodes.
//custom keymaps tend to ignore the server and use some other table instead.
//so we need to try to match what most servers expect
switch(qkey)
{
// case K_: return 1;
// case K_: return 2;
// case K_: return 3;
// case K_: return 4;
// case K_: return 5;
// case K_: return 6;
// case K_: return 7;
// case K_: return 8;
// case K_: return 9;
case '1': return 10;
case '2': return 11;
case '3': return 12;
case '4': return 13;
case '5': return 14;
case '6': return 15;
case '7': return 16;
case '8': return 17;
case '9': return 18;
case '-': return 19;
case '+': return 20;
case '=': return 21;
case K_BACKSPACE: return 22;
case K_TAB: return 23;
case 'q': return 24;
case 'w': return 25;
case 'e': return 26;
case 'r': return 27;
case 't': return 28;
case 'y': return 29;
case 'u': return 30;
case 'i': return 31;
case 'o': return 32;
case 'p': return 33;
case '[': return 34;
case ']': return 35;
case K_ENTER: return 36;
case K_LCTRL: return 37;
case 'a': return 38;
case 's': return 39;
case 'd': return 40;
case 'f': return 41;
case 'g': return 42;
case 'h': return 43;
case 'j': return 44;
case 'k': return 45;
case 'l': return 46;
case ';': return 47;
case '\'': return 48;
case '`': return 49;
case K_LSHIFT: return 50;
case '#': return 51;
case 'z': return 52;
case 'x': return 53;
case 'c': return 54;
case 'v': return 55;
case 'b': return 56;
case 'n': return 57;
case 'm': return 58;
case ',': return 59;
case '.': return 60;
case '/': return 61;
case K_RSHIFT: return 62;
case K_KP_STAR: return 63;
case K_LALT: return 64;
case K_SPACE: return 65;
case K_CAPSLOCK: return 66;
case K_F1: return 67;
case K_F2: return 68;
case K_F3: return 69;
case K_F4: return 70;
case K_F5: return 71;
case K_F6: return 72;
case K_F7: return 73;
case K_F8: return 74;
case K_F9: return 75;
case K_F10: return 76;
case K_KP_NUMLOCK: return 77;
case K_SCRLCK: return 78;
case K_KP_HOME: return 79;
case K_KP_UPARROW: return 80;
case K_KP_PGUP: return 81;
case K_KP_MINUS: return 82;
case K_KP_LEFTARROW:return 83;
case K_KP_5: return 84;
case K_KP_RIGHTARROW:return 85;
case K_KP_PLUS: return 86;
case K_KP_END: return 87;
case K_KP_DOWNARROW:return 88;
case K_KP_PGDN: return 89;
case K_KP_INS: return 90;
case K_KP_DEL: return 91;
// case K_L3SHIFT: return 92;
// case K_: return 93;
case '\\': return 94;
case K_F11: return 95;
case K_F12: return 96;
// case K_: return 97;
// case K_KATAKANA: return 98;
// case K_HIRAGANA: return 99;
// case K_HENKAN_MODE: return 100;
// case K_HIRAGANA_KATAKANA:return 101;
// case K_MUHENKAN: return 102;
// case K_: return 103;
case K_KP_ENTER: return 104;
case K_RCTRL: return 105;
case K_KP_SLASH: return 106;
case K_PRINTSCREEN: return 107;
// case K_L3SHIFT: return 108;
// case K_LINEFEED: return 109;
case K_HOME: return 110;
case K_UPARROW: return 111;
case K_PGUP: return 112;
case K_LEFTARROW: return 113;
case K_RIGHTARROW: return 114;
case K_END: return 115;
case K_DOWNARROW: return 116;
case K_PGDN: return 117;
case K_INS: return 118;
case K_DEL: return 119;
// case K_: return 120;
case K_MM_VOLUME_MUTE:return 121;
case K_VOLDOWN: return 122;
case K_VOLUP: return 123;
case K_POWER: return 124;
case K_KP_EQUALS: return 125;
// case K_PLUSMINUS: return 126;
case K_PAUSE: return 127;
// case K_LAUNCHA: return 128;
// case K_KP_DECIMAL: return 129;
// case K_HANGUL: return 130;
// case K_HANGUL_HANJA:return 131;
// case K_: return 132;
case K_LWIN: return 133;
case K_RWIN: return 134;
case K_APP: return 135;
// case K_CANCEL: return 136;
// case K_REDO: return 137;
// case K_SUNPROPS: return 138;
// case K_UNDO: return 139;
// case K_SUNFRONT: return 140;
// case K_COPY: return 141;
// case K_OPEN: return 142;
// case K_PASTE: return 143;
// case K_FIND: return 144;
// case K_CUT: return 145;
// case K_HELP: return 146;
// case K_MENUKB: return 147;
// case K_CALCULATOR: return 148;
default: return 0;
}
}
void X_SendData(xclient_t *cl, void *data, int datalen)
{
#ifdef MULTITHREADWIN32
@ -133,7 +303,7 @@ int X_SendNotificationMasked(xEvent *data, xwindow_t *window, unsigned int mask)
continue;
}
window = child->parent;
if (window)
// for (window = child; window; window = window->parent)
{
for (nm = window->notificationmask; nm; nm = nm->next)
@ -516,7 +686,6 @@ nextmessage:
if (inlen >= sizeof(xConnClientPrefix))
{
xConnClientPrefix *prefix = (xConnClientPrefix *)input;
input += sizeof(xConnClientPrefix);
cl->stillinitialising = false;
if (prefix->byteOrder != 'l') //egad no. horrible.
{
@ -539,7 +708,7 @@ nextmessage:
#endif
return true;
}
if (prefix->nbytesAuthProto != 0) //we can't handle this
/*if (prefix->nbytesAuthProto != 0) //we can't handle this
{
#ifdef MULTITHREADWIN32
LeaveCriticalSection(&cl->delecatesection);
@ -552,9 +721,14 @@ nextmessage:
LeaveCriticalSection(&cl->delecatesection);
#endif
return true;
}*/
if (inlen >= sizeof(*prefix) + ((prefix->nbytesAuthProto+3)&~3) + ((prefix->nbytesAuthString+3)&~3))
{
input += sizeof(*prefix) + ((prefix->nbytesAuthProto+3)&~3) + ((prefix->nbytesAuthString+3)&~3);
X_SendIntialResponse(cl);
goto nextmessage;
}
X_SendIntialResponse(cl);
goto nextmessage;
}
}
else if (inlen >= sizeof(xReq))
@ -763,15 +937,11 @@ void XWindows_TendToClients(void)
{
xclient_t *cl, *prev=NULL;
qhandle_t newclient;
#ifndef MULTITHREADWIN32
unsigned int _true = 1;
unsigned int _false = 0;
#endif
if (xlistensocket)
if (xlistensocket >= 0)
{
newclient = pNet_Accept(xlistensocket, NULL, 0);
if ((int)newclient != -1)
if (newclient >= 0)
{
cl = malloc(sizeof(xclient_t));
memset(cl, 0, sizeof(xclient_t));
@ -829,27 +999,66 @@ void XWindows_TendToClients(void)
}
}
void XWindows_Startup(void) //initialise the server socket and do any initial setup as required.
#ifdef UNIXSOCKETS
#include <unistd.h>
#include <fcntl.h>
#include <sys/file.h>
int XWindows_UnixListen(int x11display)
{
char buffer[64];
char lockfile[256];
char socketfile[256];
int lock_fd, ret;
int port = 6000;
Q_snprintf(lockfile, sizeof(lockfile), "/tmp/.X%i-lock", x11display);
Q_snprintf(socketfile, sizeof(socketfile), "/tmp/.X11-unix/X%i", x11display);
pCmd_Argv(1, buffer, sizeof(buffer));
port += atoi(buffer);
lock_fd = open(lockfile, O_RDONLY | O_CREAT, 0600);
if (lock_fd == -1)
return -1; //can't do it, jim
if (!xlistensocket)
// try to acquire lock
ret = flock(lock_fd, LOCK_EX | LOCK_NB);
if (ret != 0)
{
xlistensocket = pNet_TCPListen(NULL, port, 3);
close(lock_fd);
return -1;
}
// remove socket file
unlink(socketfile);
return pNet_TCPListen(va("unix://%s", socketfile), baseport+x11display, 3);
}
#endif
void XWindows_Startup(int x11display) //initialise the server socket and do any initial setup as required.
{
if (xlistensocket < 0)
{
#ifdef UNIXSOCKETS
if (x11display < 0)
{
while(xlistensocket < 0)
xlistensocket = XWindows_UnixListen(++x11display);
}
else
xlistensocket = XWindows_UnixListen(x11display);
#else
if (x11display < 0)
x11display = 0;
xlistensocket = pNet_TCPListen(NULL, baseport+x11display, 3);
#endif
if (xlistensocket < 0)
{
xlistensocket = 0;
xlistensocket = -1;
Con_Printf("Failed to create tcp listen socket\n");
return;
}
X_InitRequests();
XS_CreateInitialResources();
system(va("DISPLAY=:%i /usr/bin/x-terminal-emulator &", x11display));
}
XS_CheckResourceSentinals();
@ -1055,7 +1264,6 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
xwindow_t *nw = ew;
xwindow_t *oc[MAX_WINDOW_CHAIN];
xwindow_t *nc[MAX_WINDOW_CHAIN];
unsigned int curtime = pSys_Milliseconds();
if (!nw)
@ -1282,14 +1490,13 @@ void X_EvalutateCursorOwner(int movemode)
{
xEvent ev;
xwindow_t *cursorowner, *wnd, *use;
int mx, my;
float mx, my;
int wcx;
int wcy;
extern xwindow_t *xpconfinewindow;
{
extern int mousecursor_x, mousecursor_y;
mx = mousecursor_x;
my = mousecursor_y;
}
@ -1762,7 +1969,9 @@ void XWindows_KeyDown(int key)
else
{
ev.u.u.type = KeyPress;
ev.u.u.detail = key;
ev.u.u.detail = QKeyToScan(key);
if (!ev.u.u.detail)
return; //urm, never mind
ev.u.keyButtonPointer.state = 0;
ev.u.keyButtonPointer.child = x_windowwithfocus;
}
@ -1861,7 +2070,9 @@ void XWindows_Keyup(int key)
else
{
ev.u.u.type = KeyRelease;
ev.u.u.detail = key;
ev.u.u.detail = QKeyToScan(key);
if (!ev.u.u.detail)
return; //urm, never mind
ev.u.keyButtonPointer.child = x_windowwithfocus;
}
ev.u.u.sequenceNumber = 0;
@ -1899,7 +2110,7 @@ void XWindows_Keyup(int key)
XS_CheckResourceSentinals();
}
int Plug_MenuEvent(int *args)
/*static int X11_MenuEvent(int *args)
{
mousecursor_x = args[2];
mousecursor_y = args[3];
@ -1919,21 +2130,22 @@ int Plug_MenuEvent(int *args)
}
return 0;
}
}*/
qintptr_t Plug_ExecuteCommand(qintptr_t *args)
static qintptr_t X11_ExecuteCommand(qintptr_t *args)
{
char cmd[256];
pCmd_Argv(0, cmd, sizeof(cmd));
if (!strcmp("startx", cmd))
{
XWindows_Startup();
pCmd_Argv(1, cmd, sizeof(cmd));
XWindows_Startup(*cmd?atoi(cmd):-1);
return 1;
}
return 0;
}
qintptr_t Plug_Tick(qintptr_t *args)
static qintptr_t X11_Tick(qintptr_t *args)
{
XWindows_TendToClients();
return 0;
@ -1943,7 +2155,7 @@ static void *XWindows_Create(const char *medianame) //initialise the server sock
{
if (!strcmp(medianame, "x11"))
{
XWindows_Startup();
XWindows_Startup(-1);
return xscreen;
}
return NULL;
@ -1963,13 +2175,13 @@ static qboolean VARGS XWindows_DisplayFrame(void *ctx, qboolean nosound, qboolea
static void XWindows_Shutdown(void *ctx)
{
pNet_Close(xlistensocket);
xlistensocket = 0;
xlistensocket = -1;
}
static qboolean XWindows_SetSize (void *ctx, int width, int height)
{
qbyte *ns;
if (width < 64 || height < 64 || width > 2048 || height > 2048)
if (width < 64 || height < 64 || width > 16384 || height > 16384)
return false;
ns = realloc(xscreen, width*4*height);
@ -1980,8 +2192,11 @@ static qboolean XWindows_SetSize (void *ctx, int width, int height)
xscreenheight = height;
xscreenmodified = true;
//FIXME: resize root window + send notify
if (rootwindow)
{
X_Resize(rootwindow, 0, 0, width, height);
XW_ExposeWindow(rootwindow, 0, 0, rootwindow->width, rootwindow->height);
}
return true;
}
return false;
@ -2026,9 +2241,9 @@ media_decoder_funcs_t decoderfuncs =
qintptr_t Plug_Init(qintptr_t *args)
{
if (!Plug_Export("ExecuteCommand", Plug_ExecuteCommand) ||
// !Plug_Export("MenuEvent", Plug_MenuEvent) ||
!Plug_Export("Tick", Plug_Tick))
if (!Plug_Export("ExecuteCommand", X11_ExecuteCommand) ||
// !Plug_Export("MenuEvent", X11_MenuEvent) ||
!Plug_Export("Tick", X11_Tick))
{
Con_Printf("XServer plugin failed\n");
return false;
@ -2044,7 +2259,7 @@ qintptr_t Plug_Init(qintptr_t *args)
pCmd_AddCommand("startx");
#ifndef K_CTRL
K_CTRL = pKey_GetKeyCode("ctrl");
K_ALT = pKey_GetKeyCode("alt");
K_MOUSE1 = pKey_GetKeyCode("mouse1");
@ -2065,5 +2280,6 @@ qintptr_t Plug_Init(qintptr_t *args)
K_LEFTARROW = Key_GetKeyCode("leftarrow");
K_RIGHTARROW = Key_GetKeyCode("rightarrow");
*/
#endif
return true;
}

View file

@ -153,6 +153,7 @@ extern xwindow_t *rootwindow;
extern qboolean xrefreshed; //something onscreen changed.
int XS_GetResource(int id, void **data);
void *XS_GetResourceType(int id, int requiredtype);
void XS_SetProperty(xwindow_t *wnd, Atom atomid, Atom atomtype, char *data, int datalen, int format);
int XS_GetProperty(xwindow_t *wnd, Atom atomid, Atom *type, char *output, int maxlen, int offset, int *extrabytes, int *format);
void XS_DeleteProperty(xwindow_t *wnd, Atom atomid);
@ -161,8 +162,10 @@ Atom XS_FindAtom(char *name);
xgcontext_t *XS_CreateGContext(int id, xclient_t *owner, xresource_t *drawable);
int XS_NewResource(void);
xwindow_t *XS_CreateWindow(int wid, xclient_t *owner, xwindow_t *parent, short x, short y, short width, short height);
void X_Resize(xwindow_t *wnd, int newx, int newy, int neww, int newh);
void XS_SetParent(xwindow_t *wnd, xwindow_t *parent);
xpixmap_t *XS_CreatePixmap(int id, xclient_t *owner, int width, int height, int depth);
xfont_t *XS_CreateFont(int id, xclient_t *owner, char *fontname);
void XS_CreateInitialResources(void);
void XS_DestroyResource(xresource_t *res);
void XS_DestroyResourcesOfClient(xclient_t *cl);
@ -192,6 +195,7 @@ extern qbyte *xscreen;
extern short xscreenwidth;
extern short xscreenheight;
#ifndef K_CTRL
extern int K_BACKSPACE;
extern int K_CTRL;
extern int K_ALT;
@ -200,3 +204,4 @@ extern int K_MOUSE2;
extern int K_MOUSE3;
extern int K_MOUSE4;
extern int K_MOUSE5;
#endif

View file

@ -337,6 +337,7 @@ void XR_GetProperty (xclient_t *cl, xReq *request)
int format;
int trailing;
xGetPropertyReply *rep = (xGetPropertyReply*)buffer;
Atom proptype;
if (XS_GetResource(req->window, (void**)&wnd) != x_window)
{ //wait a minute, That's not a window!!!
@ -351,10 +352,12 @@ void XR_GetProperty (xclient_t *cl, xReq *request)
if (req->longLength > sizeof(buffer) - sizeof(req)/4)
req->longLength = sizeof(buffer) - sizeof(req)/4;
datalen = XS_GetProperty(wnd, req->property, &rep->propertyType, (char *)(rep+1), req->longLength*4, req->longOffset*4, &trailing, &format);
datalen = XS_GetProperty(wnd, req->property, &proptype, (char *)(rep+1), req->longLength*4, req->longOffset*4, &trailing, &format);
rep->type = X_Reply;
rep->format = format;
rep->propertyType = proptype;
rep->sequenceNumber = cl->requestnum;
rep->length = (datalen+3)/4;
//rep->propertyType = None;
@ -593,7 +596,38 @@ void XR_SetSelectionOwner (xclient_t *cl, xReq *request)
}
}
void XR_ConvertSelection (xclient_t *cl, xReq *request)
{
xConvertSelectionReq *req = (void*)request;
xatom_t *atom = XS_GetResourceType(req->selection, x_atom);
xEvent rep;
if (atom && atom->selectionownerwindowid)
{ //forward the request to the selection's owner
rep.u.u.type = SelectionRequest;
rep.u.u.detail = 0;
rep.u.u.sequenceNumber = 0;
rep.u.selectionRequest.time = req->time;
rep.u.selectionRequest.owner = atom->selectionownerwindowid;
rep.u.selectionRequest.target = req->target;
rep.u.selectionRequest.property = req->property;
rep.u.selectionRequest.requestor = req->requestor;
rep.u.selectionRequest.selection = req->selection;
X_SendData(atom->selectionownerclient, &rep, sizeof(rep));
}
else
{ //return it back to the sender, or so
rep.u.u.type = SelectionNotify;
rep.u.u.detail = 0;
rep.u.u.sequenceNumber = 0;
rep.u.selectionNotify.time = req->time;
rep.u.selectionNotify.target = req->target;
rep.u.selectionNotify.property = req->property;
rep.u.selectionNotify.requestor = req->requestor;
rep.u.selectionNotify.selection = req->selection;
X_SendData(cl, &rep, sizeof(rep));
}
}
extern int x_windowwithcursor;
@ -1063,7 +1097,7 @@ void XR_ChangeWindowAttributes (xclient_t *cl, xReq *request)
void XR_ConfigureWindow (xclient_t *cl, xReq *request)
{
int newx, newy, neww, newh, sibid, newbw;
int newx, newy, neww, newh, sibid, newbw, stackmode;
xConfigureWindowReq *req = (xConfigureWindowReq *)request;
xwindow_t *wnd;
@ -1112,22 +1146,22 @@ void XR_ConfigureWindow (xclient_t *cl, xReq *request)
if (req->mask & CWSibling)
sibid = *parm++;
else
sibid = 0;
sibid = None;
if (req->mask & CWStackMode)
*parm++;
stackmode = *parm++;
else
stackmode = Above;
if (!wnd->overrideredirect && X_NotifcationMaskPresent(wnd, SubstructureRedirectMask, cl))
{
xEvent ev;
ev.u.u.type = ConfigureRequest;
ev.u.u.detail = 0;
ev.u.u.detail = stackmode;
ev.u.u.sequenceNumber = 0;
ev.u.configureRequest.parent = wnd->parent->res.id;
ev.u.configureRequest.window = wnd->res.id;
ev.u.configureRequest.sibling = wnd->sibling?wnd->sibling->res.id:None;
ev.u.configureRequest.sibling = sibid;
ev.u.configureRequest.x = newx;
ev.u.configureRequest.y = newy;
ev.u.configureRequest.width = neww;
@ -1139,55 +1173,7 @@ void XR_ConfigureWindow (xclient_t *cl, xReq *request)
X_SendNotificationMasked(&ev, wnd, SubstructureRedirectMask);
}
else
{
xEvent ev;
/* if (wnd->xpos == newx && wnd->ypos == newy)
{
ev.u.u.type = ResizeRequest;
ev.u.u.detail = 0;
ev.u.u.sequenceNumber = 0;
ev.u.resizeRequest.window = wnd->res.id;
ev.u.resizeRequest.width = wnd->width;
ev.u.resizeRequest.height = wnd->height;
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
return;
}*/
wnd->xpos = newx;
wnd->ypos = newy;
if ((wnd->width != neww || wnd->height != newh) && wnd->buffer)
{
free(wnd->buffer);
wnd->buffer = NULL;
}
wnd->width = neww;
wnd->height = newh;
if (wnd->mapped)
xrefreshed = true;
ev.u.u.type = ConfigureNotify;
ev.u.u.detail = 0;
ev.u.u.sequenceNumber = 0;
ev.u.configureNotify.event = wnd->res.id;
ev.u.configureNotify.window = wnd->res.id;
ev.u.configureNotify.aboveSibling = None;
ev.u.configureNotify.x = wnd->xpos;
ev.u.configureNotify.y = wnd->ypos;
ev.u.configureNotify.width = wnd->width;
ev.u.configureNotify.height = wnd->height;
ev.u.configureNotify.borderWidth = 0;
ev.u.configureNotify.override = wnd->overrideredirect;
ev.u.configureNotify.bpad = 0;
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
}
X_Resize(wnd, newx, newy, neww, newh);
}
void XR_ReparentWindow (xclient_t *cl, xReq *request)
@ -1220,7 +1206,7 @@ void XR_ReparentWindow (xclient_t *cl, xReq *request)
ev.u.u.detail = 0;
ev.u.reparent.override = wnd->overrideredirect;
ev.u.reparent.window = wnd->res.id;
ev.u.reparent.parent = wnd->res.id;
ev.u.reparent.parent = wnd->parent->res.id;
ev.u.reparent.x = req->x;
ev.u.reparent.y = req->y;
@ -1344,17 +1330,280 @@ void XR_GetWindowAttributes (xclient_t *cl, xReq *request)
X_SendData(cl, &rep, sizeof(xGetWindowAttributesReply));
}
static struct
{
KeySym keysym[8];
} keyboardmapping[256] =
{
{{0}},
{{0}},
{{0}},
{{0}},
{{0}},
{{0}},
{{0}},
{{0}},
{{0}},
{{XK_Escape, NoSymbol, XK_Escape}}, //10
{{XK_1, XK_exclam, XK_1, XK_exclam, XK_onesuperior, XK_exclamdown, XK_onesuperior}}, //10 //11
{{XK_2, XK_quotedbl, XK_2, XK_quotedbl, XK_twosuperior}},//, XK_oneeighth, XK_twosuperior}}, //12
{{XK_3, XK_sterling, XK_3, XK_sterling, XK_threesuperior, XK_sterling, XK_threesuperior}}, //13
{{XK_4, XK_dollar, XK_4, XK_dollar}},//, XK_EuroSign, XK_onequarter, XK_EuroSign}}, //14
{{XK_5, XK_percent, XK_5, XK_percent, XK_onehalf}},//, XK_threeeighths, XK_onehalf}}, //15
{{XK_6, XK_asciicircum, XK_6, XK_asciicircum, XK_threequarters}},//, XK_fiveeighths, XK_threequarters}}, //16
{{XK_7, XK_ampersand, XK_7, XK_ampersand, XK_braceleft}},//, XK_seveneighths, XK_braceleft}}, //17
{{XK_8, XK_asterisk, XK_8, XK_asterisk, XK_bracketleft}},//, XK_trademark, XK_bracketleft}}, //18
{{XK_9, XK_parenleft, XK_9, XK_parenleft, XK_bracketright, XK_plusminus, XK_bracketright}}, //19
{{XK_0, XK_parenright, XK_0, XK_parenright, XK_braceright, XK_degree, XK_braceright}}, //10
{{XK_minus, XK_underscore, XK_minus, XK_underscore, XK_backslash, XK_questiondown, XK_backslash}}, //20
{{XK_equal, XK_plus, XK_equal, XK_plus}},//, XK_dead_cedilla, XK_dead_ogonek, XK_dead_cedilla}}, //21
{{XK_BackSpace, XK_BackSpace, XK_BackSpace, XK_BackSpace}}, //22
{{XK_Tab}},//, XK_ISO_Left_Tab, XK_Tab, XK_ISO_Left_Tab}}, //23
{{XK_q, XK_Q, XK_q, XK_Q, XK_at}},//, XK_Greek_OMEGA, XK_at}}, //24
{{XK_w, XK_W, XK_w, XK_W}},//, XK_lstroke, XK_Lstroke, XK_lstroke}}, //25
{{XK_e, XK_E, XK_e, XK_E, XK_e, XK_E, XK_e}}, //26
{{XK_r, XK_R, XK_r, XK_R, XK_paragraph, XK_registered, XK_paragraph}}, //27
{{XK_t, XK_T, XK_t, XK_T}},//, XK_tslash, XK_Tslash, XK_tslash}}, //28
{{XK_y, XK_Y, XK_y, XK_Y}},//, XK_leftarrow, XK_yen, XK_leftarrow}}, //29
{{XK_u, XK_U, XK_u, XK_U}},//, XK_downarrow, XK_uparrow, XK_downarrow}}, //30
{{XK_i, XK_I, XK_i, XK_I}},//, XK_rightarrow, XK_idotless, XK_rightarrow}}, //31
{{XK_o, XK_O, XK_o, XK_O, XK_oslash, XK_Oslash, XK_oslash}}, //32
{{XK_p, XK_P, XK_p, XK_P, XK_thorn, XK_THORN, XK_thorn}}, //33
{{XK_bracketleft, XK_braceleft, XK_bracketleft, XK_braceleft}},//, XK_dead_diaeresis, XK_dead_abovering, XK_dead_diaeresis}}, //34
{{XK_bracketright, XK_braceright, XK_bracketright, XK_braceright}},//, XK_dead_tilde, XK_dead_macron, XK_dead_tilde}}, //35
{{XK_Return, NoSymbol, XK_Return}}, //36
{{XK_Control_L, NoSymbol, XK_Control_L}}, //37
{{XK_a, XK_A, XK_a, XK_A, XK_ae, XK_AE, XK_ae}}, //38
{{XK_s, XK_S, XK_s, XK_S, XK_ssharp, XK_section, XK_ssharp}}, //39
{{XK_d, XK_D, XK_d, XK_D, XK_eth, XK_ETH, XK_eth}}, //40
{{XK_f, XK_F, XK_f, XK_F}},//, XK_dstroke, XK_ordfeminine, XK_dstroke}}, //41
{{XK_g, XK_G, XK_g, XK_G}},//, XK_eng, XK_ENG, XK_eng}}, //42
{{XK_h, XK_H, XK_h, XK_H}},//, XK_hstroke, XK_Hstroke, XK_hstroke}}, //43
{{XK_j, XK_J, XK_j, XK_J}},//, XK_dead_hook, XK_dead_horn, XK_dead_hook}}, //44
{{XK_k, XK_K, XK_k, XK_K}},//, XK_kra, XK_ampersand, XK_kra}}, //45
{{XK_l, XK_L, XK_l, XK_L}},//, XK_lstroke, XK_Lstroke, XK_lstroke}}, //46
{{XK_semicolon, XK_colon, XK_semicolon, XK_colon}},//, XK_dead_acute, XK_dead_doubleacute, XK_dead_acute}}, //47
{{XK_apostrophe, XK_at, XK_apostrophe, XK_at}},//, XK_dead_circumflex, XK_dead_caron, XK_dead_circumflex}}, //48
{{XK_grave, XK_notsign, XK_grave, XK_notsign, XK_bar, XK_bar, XK_bar}}, //49
{{XK_Shift_L, NoSymbol, XK_Shift_L}}, //50
{{XK_numbersign, XK_asciitilde, XK_numbersign, XK_asciitilde}},//, XK_dead_grave, XK_dead_breve, XK_dead_grave}}, //51
{{XK_z, XK_Z, XK_z, XK_Z, XK_guillemotleft, XK_less, XK_guillemotleft}}, //52
{{XK_x, XK_X, XK_x, XK_X, XK_guillemotright, XK_greater, XK_guillemotright}}, //53
{{XK_c, XK_C, XK_c, XK_C, XK_cent, XK_copyright, XK_cent}}, //54
{{XK_v, XK_V, XK_v, XK_V}},//, XK_leftdoublequotemark, XK_leftsinglequotemark, XK_leftdoublequotemark}}, //55
{{XK_b, XK_B, XK_b, XK_B}},//, XK_rightdoublequotemark, XK_rightsinglequotemark, XK_rightdoublequotemark}}, //56
{{XK_n, XK_N, XK_n, XK_N, XK_n, XK_N, XK_n}}, //57
{{XK_m, XK_M, XK_m, XK_M, XK_mu, XK_masculine, XK_mu}}, //58
{{XK_comma, XK_less, XK_comma, XK_less}},//, XK_horizconnector, XK_multiply, XK_horizconnector}}, //59
{{XK_period, XK_greater, XK_period, XK_greater, XK_periodcentered, XK_division, XK_periodcentered}}, //60
{{XK_slash, XK_question, XK_slash, XK_question}},//, XK_dead_belowdot, XK_dead_abovedot, XK_dead_belowdot}}, //61
{{XK_Shift_R, NoSymbol, XK_Shift_R}}, //62
{{XK_KP_Multiply, XK_KP_Multiply, XK_KP_Multiply, XK_KP_Multiply, XK_KP_Multiply, XK_KP_Multiply}},//, XK_XF86ClearGrab}}, //63
{{XK_Alt_L, XK_Meta_L, XK_Alt_L, XK_Meta_L}}, //64
{{XK_space, NoSymbol, XK_space}}, //65
{{XK_Caps_Lock, NoSymbol, XK_Caps_Lock}}, //66
{{XK_F1, XK_F1, XK_F1, XK_F1, XK_F1, XK_F1}},//, XK_XF86Switch_VT_1}}, //67
{{XK_F2, XK_F2, XK_F2, XK_F2, XK_F2, XK_F2}},//, XK_XF86Switch_VT_2}}, //68
{{XK_F3, XK_F3, XK_F3, XK_F3, XK_F3, XK_F3}},//, XK_XF86Switch_VT_3}}, //69
{{XK_F4, XK_F4, XK_F4, XK_F4, XK_F4, XK_F4}},//, XK_XF86Switch_VT_4}}, //70
{{XK_F5, XK_F5, XK_F5, XK_F5, XK_F5, XK_F5}},//, XK_XF86Switch_VT_5}}, //71
{{XK_F6, XK_F6, XK_F6, XK_F6, XK_F6, XK_F6}},//, XK_XF86Switch_VT_6}}, //72
{{XK_F7, XK_F7, XK_F7, XK_F7, XK_F7, XK_F7}},//, XK_XF86Switch_VT_7}}, //73
{{XK_F8, XK_F8, XK_F8, XK_F8, XK_F8, XK_F8}},//, XK_XF86Switch_VT_8}}, //74
{{XK_F9, XK_F9, XK_F9, XK_F9, XK_F9, XK_F9}},//, XK_XF86Switch_VT_9}}, //75
{{XK_F10, XK_F10, XK_F10, XK_F10, XK_F10, XK_F10}},//, XK_XF86Switch_VT_10}}, //76
{{XK_Num_Lock, NoSymbol, XK_Num_Lock}}, //77
{{XK_Scroll_Lock, NoSymbol, XK_Scroll_Lock}}, //78
{{XK_KP_Home, XK_KP_7, XK_KP_Home, XK_KP_7}}, //79
{{XK_KP_Up, XK_KP_8, XK_KP_Up, XK_KP_8}}, //80
{{XK_KP_Prior, XK_KP_9, XK_KP_Prior, XK_KP_9}}, //81
{{XK_KP_Subtract, XK_KP_Subtract, XK_KP_Subtract, XK_KP_Subtract, XK_KP_Subtract, XK_KP_Subtract}},//, XK_XF86Prev_VMode}}, //82
{{XK_KP_Left, XK_KP_4, XK_KP_Left, XK_KP_4}}, //83
{{XK_KP_Begin, XK_KP_5, XK_KP_Begin, XK_KP_5}}, //84
{{XK_KP_Right, XK_KP_6, XK_KP_Right, XK_KP_6}}, //85
{{XK_KP_Add, XK_KP_Add, XK_KP_Add, XK_KP_Add, XK_KP_Add, XK_KP_Add}},//, XK_XF86Next_VMode}}, //86
{{XK_KP_End, XK_KP_1, XK_KP_End, XK_KP_1}}, //87
{{XK_KP_Down, XK_KP_2, XK_KP_Down, XK_KP_2}}, //88
{{XK_KP_Next, XK_KP_3, XK_KP_Next, XK_KP_3}}, //89
{{XK_KP_Insert, XK_KP_0, XK_KP_Insert, XK_KP_0}}, //90
{{XK_KP_Delete, XK_KP_Decimal, XK_KP_Delete, XK_KP_Decimal}}, //91
{{0}},//XK_ISO_Level3_Shift, NoSymbol, XK_ISO_Level3_Shift}}, //92
{{0}}, //93
{{XK_backslash, XK_bar, XK_backslash, XK_bar, XK_bar, XK_brokenbar, XK_bar}}, //94
{{XK_F11, XK_F11, XK_F11, XK_F11, XK_F11, XK_F11}},//, XK_XF86Switch_VT_11}}, //95
{{XK_F12, XK_F12, XK_F12, XK_F12, XK_F12, XK_F12}},//, XK_XF86Switch_VT_12}}, //96
{{0}}, //97
{{XK_Katakana, NoSymbol, XK_Katakana}}, //98
{{XK_Hiragana, NoSymbol, XK_Hiragana}}, //99
{{XK_Henkan_Mode, NoSymbol, XK_Henkan_Mode}}, //100
{{XK_Hiragana_Katakana, NoSymbol, XK_Hiragana_Katakana}}, //101
{{XK_Muhenkan, NoSymbol, XK_Muhenkan}}, //102
{{0}}, //103
{{XK_KP_Enter, NoSymbol, XK_KP_Enter}}, //104
{{XK_Control_R, NoSymbol, XK_Control_R}}, //105
{{XK_KP_Divide, XK_KP_Divide, XK_KP_Divide, XK_KP_Divide, XK_KP_Divide, XK_KP_Divide}},//, XK_XF86Ungrab}}, //106
{{XK_Print, XK_Sys_Req, XK_Print, XK_Sys_Req}}, //107
{{0}},//XK_ISO_Level3_Shift, XK_Multi_key, XK_ISO_Level3_Shift, XK_Multi_key}}, //108
{{XK_Linefeed, NoSymbol, XK_Linefeed}}, //109
{{XK_Home, NoSymbol, XK_Home}}, //110
{{XK_Up, NoSymbol, XK_Up}}, //111
{{XK_Prior, NoSymbol, XK_Prior}}, //112
{{XK_Left, NoSymbol, XK_Left}}, //113
{{XK_Right, NoSymbol, XK_Right}}, //114
{{XK_End, NoSymbol, XK_End}}, //115
{{XK_Down, NoSymbol, XK_Down}}, //116
{{XK_Next, NoSymbol, XK_Next}}, //117
{{XK_Insert, NoSymbol, XK_Insert}}, //118
{{XK_Delete, NoSymbol, XK_Delete}}, //119
/*
120
121 0x1008ff12 (XF86AudioMute) 0x0000 (NoSymbol) 0x1008ff12 (XF86AudioMute)
122 0x1008ff11 (XF86AudioLowerVolume) 0x0000 (NoSymbol) 0x1008ff11 (XF86AudioLowerVolume)
123 0x1008ff13 (XF86AudioRaiseVolume) 0x0000 (NoSymbol) 0x1008ff13 (XF86AudioRaiseVolume)
124 0x1008ff2a (XF86PowerOff) 0x0000 (NoSymbol) 0x1008ff2a (XF86PowerOff)
125 0xffbd (KP_Equal) 0x0000 (NoSymbol) 0xffbd (KP_Equal)
126 0x00b1 (plusminus) 0x0000 (NoSymbol) 0x00b1 (plusminus)
127 0xff13 (Pause) 0xff6b (Break) 0xff13 (Pause) 0xff6b (Break)
128 0x1008ff4a (XF86LaunchA) 0x0000 (NoSymbol) 0x1008ff4a (XF86LaunchA)
129 0xffae (KP_Decimal) 0xffae (KP_Decimal) 0xffae (KP_Decimal) 0xffae (KP_Decimal)
130 0xff31 (Hangul) 0x0000 (NoSymbol) 0xff31 (Hangul)
131 0xff34 (Hangul_Hanja) 0x0000 (NoSymbol) 0xff34 (Hangul_Hanja)
132
133 0xffeb (Super_L) 0x0000 (NoSymbol) 0xffeb (Super_L)
134 0xffec (Super_R) 0x0000 (NoSymbol) 0xffec (Super_R)
135 0xff67 (Menu) 0x0000 (NoSymbol) 0xff67 (Menu)
136 0xff69 (Cancel) 0x0000 (NoSymbol) 0xff69 (Cancel)
137 0xff66 (Redo) 0x0000 (NoSymbol) 0xff66 (Redo)
138 0x1005ff70 (SunProps) 0x0000 (NoSymbol) 0x1005ff70 (SunProps)
139 0xff65 (Undo) 0x0000 (NoSymbol) 0xff65 (Undo)
140 0x1005ff71 (SunFront) 0x0000 (NoSymbol) 0x1005ff71 (SunFront)
141 0x1008ff57 (XF86Copy) 0x0000 (NoSymbol) 0x1008ff57 (XF86Copy)
142 0x1008ff6b (XF86Open) 0x0000 (NoSymbol) 0x1008ff6b (XF86Open)
143 0x1008ff6d (XF86Paste) 0x0000 (NoSymbol) 0x1008ff6d (XF86Paste)
144 0xff68 (Find) 0x0000 (NoSymbol) 0xff68 (Find)
145 0x1008ff58 (XF86Cut) 0x0000 (NoSymbol) 0x1008ff58 (XF86Cut)
146 0xff6a (Help) 0x0000 (NoSymbol) 0xff6a (Help)
147 0x1008ff65 (XF86MenuKB) 0x0000 (NoSymbol) 0x1008ff65 (XF86MenuKB)
148 0x1008ff1d (XF86Calculator) 0x0000 (NoSymbol) 0x1008ff1d (XF86Calculator)
149
150 0x1008ff2f (XF86Sleep) 0x0000 (NoSymbol) 0x1008ff2f (XF86Sleep)
151 0x1008ff2b (XF86WakeUp) 0x0000 (NoSymbol) 0x1008ff2b (XF86WakeUp)
152 0x1008ff5d (XF86Explorer) 0x0000 (NoSymbol) 0x1008ff5d (XF86Explorer)
153 0x1008ff7b (XF86Send) 0x0000 (NoSymbol) 0x1008ff7b (XF86Send)
154
155 0x1008ff8a (XF86Xfer) 0x0000 (NoSymbol) 0x1008ff8a (XF86Xfer)
156 0x1008ff41 (XF86Launch1) 0x0000 (NoSymbol) 0x1008ff41 (XF86Launch1)
157 0x1008ff42 (XF86Launch2) 0x0000 (NoSymbol) 0x1008ff42 (XF86Launch2)
158 0x1008ff2e (XF86WWW) 0x0000 (NoSymbol) 0x1008ff2e (XF86WWW)
159 0x1008ff5a (XF86DOS) 0x0000 (NoSymbol) 0x1008ff5a (XF86DOS)
160 0x1008ff2d (XF86ScreenSaver) 0x0000 (NoSymbol) 0x1008ff2d (XF86ScreenSaver)
161 0x1008ff74 (XF86RotateWindows) 0x0000 (NoSymbol) 0x1008ff74 (XF86RotateWindows)
162 0x1008ff7f (XF86TaskPane) 0x0000 (NoSymbol) 0x1008ff7f (XF86TaskPane)
163 0x1008ff19 (XF86Mail) 0x0000 (NoSymbol) 0x1008ff19 (XF86Mail)
164 0x1008ff30 (XF86Favorites) 0x0000 (NoSymbol) 0x1008ff30 (XF86Favorites)
165 0x1008ff33 (XF86MyComputer) 0x0000 (NoSymbol) 0x1008ff33 (XF86MyComputer)
166 0x1008ff26 (XF86Back) 0x0000 (NoSymbol) 0x1008ff26 (XF86Back)
167 0x1008ff27 (XF86Forward) 0x0000 (NoSymbol) 0x1008ff27 (XF86Forward)
168
169 0x1008ff2c (XF86Eject) 0x0000 (NoSymbol) 0x1008ff2c (XF86Eject)
170 0x1008ff2c (XF86Eject) 0x1008ff2c (XF86Eject) 0x1008ff2c (XF86Eject) 0x1008ff2c (XF86Eject)
171 0x1008ff17 (XF86AudioNext) 0x0000 (NoSymbol) 0x1008ff17 (XF86AudioNext)
172 0x1008ff14 (XF86AudioPlay) 0x1008ff31 (XF86AudioPause) 0x1008ff14 (XF86AudioPlay) 0x1008ff31 (XF86AudioPause)
173 0x1008ff16 (XF86AudioPrev) 0x0000 (NoSymbol) 0x1008ff16 (XF86AudioPrev)
174 0x1008ff15 (XF86AudioStop) 0x1008ff2c (XF86Eject) 0x1008ff15 (XF86AudioStop) 0x1008ff2c (XF86Eject)
175 0x1008ff1c (XF86AudioRecord) 0x0000 (NoSymbol) 0x1008ff1c (XF86AudioRecord)
176 0x1008ff3e (XF86AudioRewind) 0x0000 (NoSymbol) 0x1008ff3e (XF86AudioRewind)
177 0x1008ff6e (XF86Phone) 0x0000 (NoSymbol) 0x1008ff6e (XF86Phone)
178
179 0x1008ff81 (XF86Tools) 0x0000 (NoSymbol) 0x1008ff81 (XF86Tools)
180 0x1008ff18 (XF86HomePage) 0x0000 (NoSymbol) 0x1008ff18 (XF86HomePage)
181 0x1008ff73 (XF86Reload) 0x0000 (NoSymbol) 0x1008ff73 (XF86Reload)
182 0x1008ff56 (XF86Close) 0x0000 (NoSymbol) 0x1008ff56 (XF86Close)
183
184
185 0x1008ff78 (XF86ScrollUp) 0x0000 (NoSymbol) 0x1008ff78 (XF86ScrollUp)
186 0x1008ff79 (XF86ScrollDown) 0x0000 (NoSymbol) 0x1008ff79 (XF86ScrollDown)
187 0x0028 (parenleft) 0x0000 (NoSymbol) 0x0028 (parenleft)
188 0x0029 (parenright) 0x0000 (NoSymbol) 0x0029 (parenright)
189 0x1008ff68 (XF86New) 0x0000 (NoSymbol) 0x1008ff68 (XF86New)
190 0xff66 (Redo) 0x0000 (NoSymbol) 0xff66 (Redo)
191 0x1008ff81 (XF86Tools) 0x0000 (NoSymbol) 0x1008ff81 (XF86Tools)
192 0x1008ff45 (XF86Launch5) 0x0000 (NoSymbol) 0x1008ff45 (XF86Launch5)
193 0x1008ff46 (XF86Launch6) 0x0000 (NoSymbol) 0x1008ff46 (XF86Launch6)
194 0x1008ff47 (XF86Launch7) 0x0000 (NoSymbol) 0x1008ff47 (XF86Launch7)
195 0x1008ff48 (XF86Launch8) 0x0000 (NoSymbol) 0x1008ff48 (XF86Launch8)
196 0x1008ff49 (XF86Launch9) 0x0000 (NoSymbol) 0x1008ff49 (XF86Launch9)
197
198 0x1008ffb2 (XF86AudioMicMute) 0x0000 (NoSymbol) 0x1008ffb2 (XF86AudioMicMute)
199 0x1008ffa9 (XF86TouchpadToggle) 0x0000 (NoSymbol) 0x1008ffa9 (XF86TouchpadToggle)
200 0x1008ffb0 (XF86TouchpadOn) 0x0000 (NoSymbol) 0x1008ffb0 (XF86TouchpadOn)
201 0x1008ffb1 (XF86TouchpadOff) 0x0000 (NoSymbol) 0x1008ffb1 (XF86TouchpadOff)
202
203 0xff7e (Mode_switch) 0x0000 (NoSymbol) 0xff7e (Mode_switch)
204 0x0000 (NoSymbol) 0xffe9 (Alt_L) 0x0000 (NoSymbol) 0xffe9 (Alt_L)
205 0x0000 (NoSymbol) 0xffe7 (Meta_L) 0x0000 (NoSymbol) 0xffe7 (Meta_L)
206 0x0000 (NoSymbol) 0xffeb (Super_L) 0x0000 (NoSymbol) 0xffeb (Super_L)
207 0x0000 (NoSymbol) 0xffed (Hyper_L) 0x0000 (NoSymbol) 0xffed (Hyper_L)
208 0x1008ff14 (XF86AudioPlay) 0x0000 (NoSymbol) 0x1008ff14 (XF86AudioPlay)
209 0x1008ff31 (XF86AudioPause) 0x0000 (NoSymbol) 0x1008ff31 (XF86AudioPause)
210 0x1008ff43 (XF86Launch3) 0x0000 (NoSymbol) 0x1008ff43 (XF86Launch3)
211 0x1008ff44 (XF86Launch4) 0x0000 (NoSymbol) 0x1008ff44 (XF86Launch4)
212 0x1008ff4b (XF86LaunchB) 0x0000 (NoSymbol) 0x1008ff4b (XF86LaunchB)
213 0x1008ffa7 (XF86Suspend) 0x0000 (NoSymbol) 0x1008ffa7 (XF86Suspend)
214 0x1008ff56 (XF86Close) 0x0000 (NoSymbol) 0x1008ff56 (XF86Close)
215 0x1008ff14 (XF86AudioPlay) 0x0000 (NoSymbol) 0x1008ff14 (XF86AudioPlay)
216 0x1008ff97 (XF86AudioForward) 0x0000 (NoSymbol) 0x1008ff97 (XF86AudioForward)
217
218 0xff61 (Print) 0x0000 (NoSymbol) 0xff61 (Print)
219
220 0x1008ff8f (XF86WebCam) 0x0000 (NoSymbol) 0x1008ff8f (XF86WebCam)
221
222
223 0x1008ff19 (XF86Mail) 0x0000 (NoSymbol) 0x1008ff19 (XF86Mail)
224 0x1008ff8e (XF86Messenger) 0x0000 (NoSymbol) 0x1008ff8e (XF86Messenger)
225 0x1008ff1b (XF86Search) 0x0000 (NoSymbol) 0x1008ff1b (XF86Search)
226 0x1008ff5f (XF86Go) 0x0000 (NoSymbol) 0x1008ff5f (XF86Go)
227 0x1008ff3c (XF86Finance) 0x0000 (NoSymbol) 0x1008ff3c (XF86Finance)
228 0x1008ff5e (XF86Game) 0x0000 (NoSymbol) 0x1008ff5e (XF86Game)
229 0x1008ff36 (XF86Shop) 0x0000 (NoSymbol) 0x1008ff36 (XF86Shop)
230
231 0xff69 (Cancel) 0x0000 (NoSymbol) 0xff69 (Cancel)
232 0x1008ff03 (XF86MonBrightnessDown) 0x0000 (NoSymbol) 0x1008ff03 (XF86MonBrightnessDown)
233 0x1008ff02 (XF86MonBrightnessUp) 0x0000 (NoSymbol) 0x1008ff02 (XF86MonBrightnessUp)
234 0x1008ff32 (XF86AudioMedia) 0x0000 (NoSymbol) 0x1008ff32 (XF86AudioMedia)
235 0x1008ff59 (XF86Display) 0x0000 (NoSymbol) 0x1008ff59 (XF86Display)
236 0x1008ff04 (XF86KbdLightOnOff) 0x0000 (NoSymbol) 0x1008ff04 (XF86KbdLightOnOff)
237 0x1008ff06 (XF86KbdBrightnessDown) 0x0000 (NoSymbol) 0x1008ff06 (XF86KbdBrightnessDown)
238 0x1008ff05 (XF86KbdBrightnessUp) 0x0000 (NoSymbol) 0x1008ff05 (XF86KbdBrightnessUp)
239 0x1008ff7b (XF86Send) 0x0000 (NoSymbol) 0x1008ff7b (XF86Send)
240 0x1008ff72 (XF86Reply) 0x0000 (NoSymbol) 0x1008ff72 (XF86Reply)
241 0x1008ff90 (XF86MailForward) 0x0000 (NoSymbol) 0x1008ff90 (XF86MailForward)
242 0x1008ff77 (XF86Save) 0x0000 (NoSymbol) 0x1008ff77 (XF86Save)
243 0x1008ff5b (XF86Documents) 0x0000 (NoSymbol) 0x1008ff5b (XF86Documents)
244 0x1008ff93 (XF86Battery) 0x0000 (NoSymbol) 0x1008ff93 (XF86Battery)
245 0x1008ff94 (XF86Bluetooth) 0x0000 (NoSymbol) 0x1008ff94 (XF86Bluetooth)
246 0x1008ff95 (XF86WLAN) 0x0000 (NoSymbol) 0x1008ff95 (XF86WLAN)
247
248
249
250
251
*/
};
void XR_GetKeyboardMapping (xclient_t *cl, xReq *request)
{//fixme: send the XK equivelents.
xGetKeyboardMappingReq *req = (xGetKeyboardMappingReq *)request;
char buffer[8192];
xGetKeyboardMappingReply *rep = (xGetKeyboardMappingReply *)buffer;
int i;
int i, y, x;
int *syms = ((int *)(rep+1));
rep->type = X_Reply;
rep->keySymsPerKeyCode = 1;
rep->keySymsPerKeyCode = countof(keyboardmapping[0].keysym);
rep->sequenceNumber = cl->requestnum;
rep->length = req->count;
rep->length = 0;
rep->pad2 = 0;
rep->pad3 = 0;
rep->pad4 = 0;
@ -1364,71 +1613,54 @@ void XR_GetKeyboardMapping (xclient_t *cl, xReq *request)
for (i = 0; i < req->count; i++)
{
switch (req->firstKeyCode+i)
{
/*
case ' ': ((int *)(rep+1))[i] = XK_space; break;
case K_PGUP: ((int *)(rep+1))[i] = XK_Page_Up; break;
case K_PGDN: ((int *)(rep+1))[i] = XK_Page_Down; break;
case K_HOME: ((int *)(rep+1))[i] = XK_Home; break;
case K_END: ((int *)(rep+1))[i] = XK_End; break;
case K_LEFTARROW: ((int *)(rep+1))[i] = XK_Left; break;
case K_RIGHTARROW: ((int *)(rep+1))[i] = XK_Right; break;
case K_DOWNARROW: ((int *)(rep+1))[i] = XK_Down; break;
case K_UPARROW: ((int *)(rep+1))[i] = XK_Up; break;
case K_ENTER: ((int *)(rep+1))[i] = XK_Return; break;
case K_TAB: ((int *)(rep+1))[i] = XK_Tab; break;
case K_ESCAPE: ((int *)(rep+1))[i] = XK_Escape; break;
case K_F1: ((int *)(rep+1))[i] = XK_F1; break;
case K_F2: ((int *)(rep+1))[i] = XK_F2; break;
case K_F3: ((int *)(rep+1))[i] = XK_F3; break;
case K_F4: ((int *)(rep+1))[i] = XK_F4; break;
case K_F5: ((int *)(rep+1))[i] = XK_F5; break;
case K_F6: ((int *)(rep+1))[i] = XK_F6; break;
case K_F7: ((int *)(rep+1))[i] = XK_F7; break;
case K_F8: ((int *)(rep+1))[i] = XK_F8; break;
case K_F9: ((int *)(rep+1))[i] = XK_F9; break;
case K_F10: ((int *)(rep+1))[i] = XK_F10; break;
case K_F11: ((int *)(rep+1))[i] = XK_F11; break;
case K_F12: ((int *)(rep+1))[i] = XK_F12; break;
case K_BACKSPACE: ((int *)(rep+1))[i] = XK_BackSpace; break;
case K_DEL: ((int *)(rep+1))[i] = XK_Delete; break;
case K_INS: ((int *)(rep+1))[i] = XK_Insert; break;
case K_PAUSE: ((int *)(rep+1))[i] = XK_Pause; break;
case K_SHIFT: ((int *)(rep+1))[i] = XK_Shift_L; break;
case K_CTRL: ((int *)(rep+1))[i] = XK_Control_L; break;
case K_ALT: ((int *)(rep+1))[i] = XK_Alt_L; break;
case K_KP_HOME: ((int *)(rep+1))[i] = XK_Home; break;
case K_KP_UPARROW: ((int *)(rep+1))[i] = XK_Up; break;
case K_KP_PGUP: ((int *)(rep+1))[i] = XK_KP_Page_Up; break;
case K_KP_LEFTARROW: ((int *)(rep+1))[i] = XK_KP_Left; break;
case K_KP_5: ((int *)(rep+1))[i] = XK_KP_Space; break;
case K_KP_RIGHTARROW: ((int *)(rep+1))[i] = XK_KP_Right; break;
case K_KP_END: ((int *)(rep+1))[i] = XK_KP_End; break;
case K_KP_DOWNARROW: ((int *)(rep+1))[i] = XK_KP_Down; break;
case K_KP_PGDN: ((int *)(rep+1))[i] = XK_KP_Page_Down; break;
case K_KP_ENTER: ((int *)(rep+1))[i] = XK_KP_Enter; break;
case K_KP_INS: ((int *)(rep+1))[i] = XK_KP_Insert; break;
case K_KP_DEL: ((int *)(rep+1))[i] = XK_KP_Delete; break;
case K_KP_SLASH: ((int *)(rep+1))[i] = XK_KP_Divide; break;
case K_KP_MINUS: ((int *)(rep+1))[i] = XK_KP_Subtract; break;
case K_KP_PLUS: ((int *)(rep+1))[i] = XK_KP_Add; break;
case K_KP_STAR: ((int *)(rep+1))[i] = XK_KP_Multiply; break;
case K_KP_EQUALS: ((int *)(rep+1))[i] = XK_KP_Enter; break;
*/
default:
((int *)(rep+1))[i] = req->firstKeyCode+i;
y = req->firstKeyCode+i;
if (y >= countof(keyboardmapping))
break;
for (x = 0; x < rep->keySymsPerKeyCode; x++)
*syms++ = keyboardmapping[y].keysym[x];
}
rep->length = i*rep->keySymsPerKeyCode;
X_SendData(cl, rep, sizeof(*rep)+rep->length*4);
}
static struct
{
KEYCODE keysym[8];
} modifiermapping[] =
{ //these are scancodes
{{0x32, 0x32}},
{{0x42}},
{{0x24, 0x69}},
{{0x40, 0xcd}},
{{0x4d}},
{{0}},
{{0x85, 0x86, 0xce, 0xcf}},
{{0x5c, 0xcb}},
};
void XR_GetModifierMapping (xclient_t *cl, xReq *request)
{//fixme: send the XK equivelents.
// xReq *req = (xReq *)request;
char buffer[8192];
xGetModifierMappingReply *rep = (xGetModifierMappingReply *)buffer;
int x, y;
KEYCODE *syms = ((KEYCODE *)(rep+1));
rep->type = X_Reply;
rep->numKeyPerModifier = countof(modifiermapping[0].keysym);
rep->sequenceNumber = cl->requestnum;
rep->length = (8*rep->numKeyPerModifier * sizeof(KEYCODE) + 3)/4;
rep->pad2 = 0;
rep->pad3 = 0;
rep->pad4 = 0;
rep->pad5 = 0;
rep->pad6 = 0;
for (y = 0; y < countof(modifiermapping); y++)
{
for (x = 0; x < rep->numKeyPerModifier; x++)
{
*syms++ = modifiermapping[y].keysym[x];
}
}
@ -1470,13 +1702,14 @@ void XR_QueryPointer (xclient_t *cl, xReq *request)
void XR_CreateCursor (xclient_t *cl, xReq *request)
{
xCreateCursorReq *req = (xCreateCursorReq *)request;
// xCreateCursorReq *req = (xCreateCursorReq *)request;
// X_SendError(cl, BadImplementation, 0, req->reqType, 0);
}
void XR_CreateGlyphCursor (xclient_t *cl, xReq *request)
{
xCreateGlyphCursorReq *req = (xCreateGlyphCursorReq *)request;
// xCreateGlyphCursorReq *req = (xCreateGlyphCursorReq *)request;
// char buffer[8192];
// xGetKeyboardMappingReply *rep = (xGetKeyboardMappingReply *)buffer;
@ -1491,6 +1724,16 @@ void XR_FreeCursor (xclient_t *cl, xReq *request)
// X_SendError(cl, BadImplementation, 0, req->reqType, 0);
// X_SendError(cl, BadValue, req->id, X_DestroyWindow, 0);
}
void XR_RecolorCursor (xclient_t *cl, xReq *request)
{
}
void XR_GrabButton (xclient_t *cl, xReq *request)
{
}
void XR_UngrabButton (xclient_t *cl, xReq *request)
{
}
void XR_ChangeGCInternal(unsigned int mask, xgcontext_t *gc, CARD32 *param)
{
@ -1524,8 +1767,10 @@ void XR_ChangeGCInternal(unsigned int mask, xgcontext_t *gc, CARD32 *param)
param++;
if (mask & GCFont)
{
if (XS_GetResource(*param++, &gc->font) != x_font)
gc->font = NULL;
void *font = NULL;
if (XS_GetResource(*param++, &font) != x_font)
font = NULL;
gc->font = font;
}
if (mask & GCSubwindowMode)
param++;
@ -2364,14 +2609,12 @@ void XR_PutImage(xclient_t *cl, xReq *request)
}
void XR_GetImage(xclient_t *cl, xReq *request)
{
unsigned char *out;
unsigned char *out, *data;
unsigned char *in;
xGetImageReq *req = (xGetImageReq *)request;
xresource_t *drawable;
int i;
unsigned int buffer[65535];
xGetImageReply *rep = (xGetImageReply *)buffer;
xGetImageReply rep;
int drwidth;
int drheight;
@ -2398,7 +2641,7 @@ void XR_GetImage(xclient_t *cl, xReq *request)
drheight = wnd->height;
drbuffer = wnd->buffer;
rep->visual = 0x22;
rep.visual = 0x22;
}
else if (drawable->restype == x_pixmap)
{
@ -2414,7 +2657,7 @@ void XR_GetImage(xclient_t *cl, xReq *request)
drheight = pm->height;
drbuffer = pm->data;
rep->visual = 0;
rep.visual = 0;
}
else
{
@ -2445,18 +2688,22 @@ void XR_GetImage(xclient_t *cl, xReq *request)
return;
}
out = (qbyte *)(rep+1);
data = out = alloca(req->width*4*req->height);
if (req->format == 2) //32 bit network bandwidth (hideous)
{
while(req->height)
{
in = drbuffer + (req->x + req->y*drwidth)*4;
#if 1
memcpy(out, in, req->width*4);
#else
for (i = 0; i < req->width; i++)
{
out[i*4+0] = in[i*4+0];
out[i*4+1] = in[i*4+1];
out[i*4+2] = in[i*4+2];
}
#endif
out += req->width*4;
req->height--;
@ -2469,17 +2716,18 @@ void XR_GetImage(xclient_t *cl, xReq *request)
return;
}
rep->type = X_Reply;
rep->sequenceNumber = cl->requestnum;
rep->length = (out-(qbyte *)(rep+1)+3)/4;
rep->depth = 24;
rep->pad3 = 0;
rep->pad4 = 0;
rep->pad5 = 0;
rep->pad6 = 0;
rep->pad7 = 0;
rep.type = X_Reply;
rep.sequenceNumber = cl->requestnum;
rep.length = (out-data+3)/4;
rep.depth = 24;
rep.pad3 = 0;
rep.pad4 = 0;
rep.pad5 = 0;
rep.pad6 = 0;
rep.pad7 = 0;
X_SendData(cl, rep, sizeof(*rep)+rep->length*4);
X_SendData(cl, &rep, sizeof(rep));
X_SendData(cl, data, rep.length*4);
}
void XW_PolyLine(unsigned int *dbuffer, int dwidth, int dheight, int x1, int x2, int y1, int y2, xgcontext_t *gc)
@ -2715,6 +2963,7 @@ void XR_FillPoly(xclient_t *cl, xReq *request)
}
points+=2;
(void)drbuffer, (void)drwidth, (void)drheight;
// XW_PolyLine((unsigned int *)drbuffer, drwidth, drheight, start[0], start[1], end[0], end[1], gc);
points++;
@ -3026,7 +3275,7 @@ void Draw_CharToDrawable (int num, unsigned int *drawable, int x, int y, int wid
while (drawline-->=0)
{
for (i=s ; i<e ; i++)
if ((char*)(&source[i])[3] > 128 && source[i])
if (((qbyte*)(&source[i]))[3] > 128 && source[i])
// GCFunc(gc->fgcolour, drawable[i], gc->function, drawable[i], source[i]);
drawable[i] = source[i];
source += font->rowwidth;
@ -3157,6 +3406,14 @@ void XR_OpenFont(xclient_t *cl, xReq *request) //basically ignored. We only supp
XS_CreateFont(req->fid, cl, name);
}
void XR_CloseFont(xclient_t *cl, xReq *request) //basically ignored. We only support one font...
{
xResourceReq *req = (xResourceReq *)request;
void *font = XS_GetResourceType(req->id, x_font);
if (font)
XS_DestroyResource(font);
}
void XR_ListFonts(xclient_t *cl, xReq *request) //basically ignored. We only support one font...
{
// xListFontsReq *req = (xListFontsReq *)request;
@ -3178,8 +3435,8 @@ void XR_QueryFont(xclient_t *cl, xReq *request) //basically ignored. We only sup
int i;
xCharInfo *ci;
xQueryFontReply *rep = (xQueryFontReply *)buffer;
xfont_t *font;
if (XS_GetResource(req->id, &font) != x_font)
xfont_t *font = XS_GetResourceType(req->id, x_font);
if (!font)
{
X_SendError(cl, BadFont, req->id, req->reqType, 0);
return;
@ -3259,6 +3516,40 @@ void XR_AllocColor(xclient_t *cl, xReq *request)
X_SendData(cl, &rep, sizeof(rep));
}
void XR_QueryColors(xclient_t *cl, xReq *request)
{
xQueryColorsReq *req = (xQueryColorsReq *)request;
xQueryColorsReply rep;
xrgb rgb[65536];
int n;
int *pixel = (int*)(req+1);
rep.type = X_Reply;
rep.pad1 = 0;
rep.sequenceNumber = cl->requestnum;
rep.length = 0;
rep.nColors = 0;
rep.pad2 = 0;
rep.pad3 = 0;
rep.pad4 = 0;
rep.pad5 = 0;
rep.pad6 = 0;
rep.pad7 = 0;
for (n = 0; n < req->length - sizeof(*req)/4; n++)
{
rgb[n].red = ((pixel[n]>>16)&0xff)<<8;
rgb[n].green = ((pixel[n]>>8)&0xff)<<8;
rgb[n].blue = ((pixel[n]>>0)&0xff)<<8;
rgb[n].pad = 0;
}
rep.nColors = n;
rep.length = (sizeof(xrgb)*n+3)/4;
X_SendData(cl, &rep, sizeof(rep));
X_SendData(cl, rgb, rep.length*4);
}
void XR_LookupColor(xclient_t *cl, xReq *request)
{
typedef struct {
@ -3384,9 +3675,9 @@ void XR_SendEvent (xclient_t *cl, xReq *request)
{
int count;
xSendEventReq *req = (xSendEventReq *)request;
xwindow_t *wnd;
xwindow_t *wnd = XS_GetResourceType(req->destination, x_window);
if (XS_GetResource(req->destination, (void**)&wnd) != x_window)
if (!wnd)
{
X_SendError(cl, BadWindow, req->destination, X_SendEvent, 0);
return;
@ -3554,19 +3845,27 @@ void X_InitRequests(void)
XRequests[X_PolyLine] = XR_PolyLine;
XRequests[X_PolySegment] = XR_PolyLine;
XRequests[X_QueryPointer] = XR_QueryPointer;
// XRequests[X_ChangeKeyboardMapping] = XR_ChangeKeyboardMapping;
// XRequests[X_SetModifierMapping] = XR_ChangeKeyboardMapping;
XRequests[X_GetKeyboardMapping] = XR_GetKeyboardMapping;
XRequests[X_GetKeyboardControl] = XR_GetKeyboardControl;
XRequests[X_GetModifierMapping] = XR_GetModifierMapping;
XRequests[X_AllocColor] = XR_AllocColor;
XRequests[X_LookupColor] = XR_LookupColor;
XRequests[X_QueryColors] = XR_QueryColors;
XRequests[X_GetGeometry] = XR_GetGeometry;
XRequests[X_CreateCursor] = XR_CreateCursor;
XRequests[X_CreateGlyphCursor] = XR_CreateGlyphCursor;
XRequests[X_RecolorCursor] = XR_RecolorCursor;
XRequests[X_FreeCursor] = XR_FreeCursor;
XRequests[X_WarpPointer] = XR_WarpPointer;
XRequests[X_GrabButton] = XR_GrabButton;
XRequests[X_UngrabButton] = XR_UngrabButton;
XRequests[X_WarpPointer] = XR_WarpPointer;
XRequests[X_ListFonts] = XR_ListFonts;
XRequests[X_OpenFont] = XR_OpenFont;
XRequests[X_CloseFont] = XR_CloseFont;
XRequests[X_QueryFont] = XR_QueryFont;
XRequests[X_PolyText8] = XR_PolyText;
XRequests[X_PolyText16] = XR_PolyText;
@ -3585,6 +3884,7 @@ void X_InitRequests(void)
XRequests[X_SendEvent] = XR_SendEvent;
XRequests[X_ConvertSelection] = XR_ConvertSelection;
XRequests[X_GetSelectionOwner] = XR_GetSelectionOwner;
XRequests[X_SetSelectionOwner] = XR_SetSelectionOwner;

View file

@ -36,6 +36,18 @@ int XS_GetResource(int id, void **data)
}
return x_none;
}
void *XS_GetResourceType(int id, int requiredtype)
{
xresource_t *res;
if (id < 0)
return NULL;
res = Hash_GetKey(&restable, id);
if (res && res->restype == requiredtype)
return res;
return NULL;
}
Atom XS_FindAtom(char *name)
{
@ -83,8 +95,8 @@ void XS_DestroyResource(xresource_t *res)
}
if (res->restype == x_gcontext)
{
xgcontext_t *gc = (xgcontext_t *)res;
/*
/* xgcontext_t *gc = (xgcontext_t *)res;
gc->references--;
if (gc->references > 0)
return;
@ -341,8 +353,23 @@ void XS_RaiseWindow(xwindow_t *wnd)
bigger->sibling = wnd;
wnd->sibling = NULL;
}
static qboolean XS_IsAncestor(xwindow_t *w, xwindow_t *check)
{
xwindow_t *p;
if (w)
for (p = w->parent; p; p = p->parent)
{
if (p == check)
return true;
}
return false;
}
void XS_SetParent(xwindow_t *wnd, xwindow_t *parent)
{
if (XS_IsAncestor(parent, wnd))
parent = wnd==rootwindow?NULL:rootwindow;
if (wnd == parent)
parent = wnd==rootwindow?NULL:rootwindow;
XS_ClearParent(wnd);
if (parent)
{
@ -367,6 +394,57 @@ void XS_SetParent(xwindow_t *wnd, xwindow_t *parent)
XS_RaiseWindow(wnd);
}
void X_Resize(xwindow_t *wnd, int newx, int newy, int neww, int newh)
{
xEvent ev;
/* if (wnd->xpos == newx && wnd->ypos == newy)
{
ev.u.u.type = ResizeRequest;
ev.u.u.detail = 0;
ev.u.u.sequenceNumber = 0;
ev.u.resizeRequest.window = wnd->res.id;
ev.u.resizeRequest.width = wnd->width;
ev.u.resizeRequest.height = wnd->height;
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
return;
}*/
wnd->xpos = newx;
wnd->ypos = newy;
if ((wnd->width != neww || wnd->height != newh) && wnd->buffer)
{
free(wnd->buffer);
wnd->buffer = NULL;
}
wnd->width = neww;
wnd->height = newh;
if (wnd->mapped)
xrefreshed = true;
ev.u.u.type = ConfigureNotify;
ev.u.u.detail = 0;
ev.u.u.sequenceNumber = 0;
ev.u.configureNotify.event = wnd->res.id;
ev.u.configureNotify.window = wnd->res.id;
ev.u.configureNotify.aboveSibling = None;
ev.u.configureNotify.x = wnd->xpos;
ev.u.configureNotify.y = wnd->ypos;
ev.u.configureNotify.width = wnd->width;
ev.u.configureNotify.height = wnd->height;
ev.u.configureNotify.borderWidth = 0;
ev.u.configureNotify.override = wnd->overrideredirect;
ev.u.configureNotify.bpad = 0;
X_SendNotificationMasked(&ev, wnd, StructureNotifyMask);
X_SendNotificationMasked(&ev, wnd, SubstructureNotifyMask);
}
xwindow_t *XS_CreateWindow(int wid, xclient_t *owner, xwindow_t *parent, short x, short y, short width, short height)
{
xwindow_t *neww;
@ -488,22 +566,28 @@ xfont_t *XS_CreateFont(int id, xclient_t *owner, char *fontname)
unsigned char *in, *insrc;
f = fopen("xfont.raw", "rb");
if (!f)
return NULL;
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
if (f)
{
fseek(f, 0, SEEK_END);
len = ftell(f);
fseek(f, 0, SEEK_SET);
if (len == 256*256*3)
if (len == 256*256*3)
{
width = height = 256;
}
else if (len == 128*128*3)
width = height = 128;
else
{ //urm, no idea.
fclose(f);
return NULL;
}
}
else
{
width = height = 256;
}
else if (len == 128*128*3)
width = height = 128;
else
{ //urm, no idea.
fclose(f);
return NULL;
len = width*height*3;
}
newfont = malloc(sizeof(xfont_t) + (width*height*4));
@ -522,13 +606,16 @@ xfont_t *XS_CreateFont(int id, xclient_t *owner, char *fontname)
newfont->depth = 32;
in = insrc = malloc(len);
fread(in, len, 1, f);
fclose(f);
if (f)
{
fread(in, len, 1, f);
fclose(f);
}
out = newfont->data;
for (i = 0; i < width*height; i++)
{
*out = (in[0]) + (in[1]<<8) + (in[2]<<16) + (255<<24);
*out = (in[0]) + (in[1]<<8) + (in[2]<<16) + (255u<<24);
out++;
in+=3;
}