LOTS OF CHANGES. was hoping to get revision 5000 perfect, but really that's never going to happen. this has gone on for too long now.
vulkan, wasapi, quake injector features added. irc, avplug, cef plugins/drivers reworked/updated/added openal reverb, doppler effects added. 'dir' console command now attempts to view clicked files. lots of warning fixes, should now only be deprecation warnings for most targets (depending on compiler version anyway...). SendEntity finally reworked to use flags properly. effectinfo improved, other smc-targetted fixes. mapcluster stuff now has support for linux. .basebone+.baseframe now exist in ssqc. qcc: -Fqccx supports qccx syntax, including qccx hacks. don't expect these to work in fteqw nor dp though. qcc: rewrote function call handling to use refs rather than defs. this makes struct passing more efficient and makes the __out keyword usable with fields etc. qccgui: can cope a little better with non-unicode files. can now represent most quake chars. qcc: suppressed warnings from *extensions.qc git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5000 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
5920bf05fb
commit
27a59a0cbc
271 changed files with 101001 additions and 64352 deletions
139
plugins/Makefile
139
plugins/Makefile
|
@ -2,11 +2,13 @@
|
|||
#windows is special as always, but we don't support itanium, and microsoft don't support anything else (not even arm with the nt win32 api)
|
||||
ifeq ($(FTE_TARGET),win32)
|
||||
PLUG_NATIVE_EXT=_x86.dll
|
||||
PLUG_LDFLAGS=-Lavplug/lib32 -L../engine/libs/mingw-libs -lzlib
|
||||
PLUG_LDFLAGS=-L../engine/libs/mingw-libs -lzlib
|
||||
BITS=32
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),win64)
|
||||
PLUG_NATIVE_EXT=_amd.dll
|
||||
PLUG_LDFLAGS=-Lavplug/lib64 -L../engine/libs/mingw64-libs -lz -Wl,--support-old-code
|
||||
PLUG_NATIVE_EXT=_x64.dll
|
||||
PLUG_LDFLAGS=-L../engine/libs/mingw64-libs -lz -Wl,--support-old-code
|
||||
BITS=64
|
||||
endif
|
||||
|
||||
PLUG_LDFLAGS?=-L/usr/local/lib -Wl,-R/usr/local/lib -lz -lm
|
||||
|
@ -15,15 +17,14 @@ ifneq ($(PLUG_NATIVE_EXT),)
|
|||
#if we're on windows, we'll put our windows-specific hacks here.
|
||||
PLUG_DEFFILE=plugin.def
|
||||
PLUG_CFLAGS=
|
||||
|
||||
$(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT): avplug/libavformat/avformat.h
|
||||
PLUG_CXXFLAGS=
|
||||
endif
|
||||
|
||||
#cygwin uses dll naming.
|
||||
ifeq ($(FTE_TARGET),cygwin)
|
||||
ifeq ($(BITS),64)
|
||||
PLUG_DEFFILE=plugin.def
|
||||
PLUG_NATIVE_EXT=_amd.dll
|
||||
PLUG_NATIVE_EXT=_amd64.dll
|
||||
endif
|
||||
ifneq ($(BITS),64)
|
||||
PLUG_DEFFILE=plugin.def
|
||||
|
@ -36,7 +37,7 @@ endif
|
|||
ifeq ($(PLUG_NATIVE_EXT),)
|
||||
LIBRESOLV=-lresolv
|
||||
ifneq ($(shell echo|$(CC) -E -dM -|grep __amd64__),)
|
||||
PLUG_NATIVE_EXT=_amd.so
|
||||
PLUG_NATIVE_EXT=_amd64.so
|
||||
endif
|
||||
ifneq ($(shell echo|$(CC) -E -dM -|grep __i386__),)
|
||||
PLUG_NATIVE_EXT=_x86.so
|
||||
|
@ -53,12 +54,13 @@ endif
|
|||
PLUG_NATIVE_EXT?=_unk.so
|
||||
|
||||
PLUG_DEFFILE?=
|
||||
PLUG_CFLAGS?=-fPIC -Wl,--no-undefined -Bsymbolic
|
||||
PLUG_CFLAGS?=-fPIC -Wl,--no-undefined -Bsymbolic -fvisibility=hidden
|
||||
PLUG_CXXFLAGS?=-fPIC -Wl,--no-undefined -Bsymbolic -fvisibility=hidden
|
||||
PLUG_LDFLAGS?=
|
||||
|
||||
all: ezscript hud irc
|
||||
all: ezscript qi hud irc
|
||||
|
||||
clean: ezscript-clean hud-clean irc-clean
|
||||
clean: ezscript-clean qi-clean hud-clean irc-clean
|
||||
|
||||
.PHONY: all ezscript hud irc native distclean clean
|
||||
|
||||
|
@ -77,6 +79,12 @@ hud:
|
|||
hud-clean:
|
||||
$(MAKE) clean -C hud
|
||||
|
||||
qi:
|
||||
$(MAKE) -C qi
|
||||
|
||||
qi-clean:
|
||||
$(MAKE) clean -C qi
|
||||
|
||||
irc:
|
||||
$(MAKE) -C irc
|
||||
|
||||
|
@ -87,49 +95,108 @@ irc-clean:
|
|||
#linux users are expected to have the library installed locally already. If your version is too old or missing, run the following command to install it (to /usr/local), then delete the gz and directory.
|
||||
#wget http://ffmpeg.org/releases/ffmpeg-1.2.tar.gz && cd tar xvfz ffmpeg-1.2.tar.gz && cd ffmpeg-1.2/ && ./configure --disable-yasm --enable-shared && make && sudo make install
|
||||
#we use ffmpeg's version for some reason, as opposed to libav. not sure what the differences are meant to be, but libav seemed to have non-depricated functions defined, docs that say to use them, and these functions missing.
|
||||
AV7Z_VER=ffmpeg-1.2
|
||||
AV7Z_VER=ffmpeg-3.0.1
|
||||
AV7Z_W32=$(AV7Z_VER)-win32-dev.7z
|
||||
AV7Z_URL32=http://ffmpeg.zeranoe.com/builds/win32/dev/$(AV7Z_W32)
|
||||
AV7Z_PRE32=$(AV7Z_VER)-win32-dev/
|
||||
AV7Z_W64=$(AV7Z_VER)-win64-dev.7z
|
||||
AV7Z_URL64=http://ffmpeg.zeranoe.com/builds/win64/dev/$(AV7Z_W64)
|
||||
AV7Z_PRE64=$(AV7Z_VER)-win64-dev/
|
||||
avplug/libavformat/avformat.h:
|
||||
wget $(AV7Z_URL32)
|
||||
mkdir -p avplug/libavformat && cd avplug/libavformat && 7z e -y ../../$(AV7Z_W32) $(AV7Z_PRE32)include/libavformat/ && cd -
|
||||
mkdir -p avplug/libavcodec && cd avplug/libavcodec && 7z e -y ../../$(AV7Z_W32) $(AV7Z_PRE32)include/libavcodec/ && cd -
|
||||
mkdir -p avplug/libavutil && cd avplug/libavutil && 7z e -y ../../$(AV7Z_W32) $(AV7Z_PRE32)include/libavutil/ && cd -
|
||||
mkdir -p avplug/libswscale && cd avplug/libswscale && 7z e -y ../../$(AV7Z_W32) $(AV7Z_PRE32)include/libswscale/ && cd -
|
||||
mkdir -p avplug/lib32 && cd avplug/lib32 && 7z e -y ../../$(AV7Z_W32) $(AV7Z_PRE32)lib/avformat.lib $(AV7Z_PRE32)lib/avcodec.lib $(AV7Z_PRE32)lib/avutil.lib $(AV7Z_PRE32)lib/swscale.lib && cd -
|
||||
rm $(AV7Z_W32)
|
||||
wget $(AV7Z_URL64)
|
||||
mkdir -p avplug/lib64 && cd avplug/lib64 && 7z e -y ../../$(AV7Z_W64) $(AV7Z_PRE64)lib/avformat.lib $(AV7Z_PRE64)lib/avcodec.lib $(AV7Z_PRE64)lib/avutil.lib $(AV7Z_PRE64)lib/swscale.lib && cd -
|
||||
rm $(AV7Z_W64)
|
||||
AV_BASE=$(OUT_DIR)/../fte_libav_$(AV7Z_VER)/
|
||||
|
||||
|
||||
ifeq ($(FTE_TARGET),win32)
|
||||
#NATIVE_PLUGINS+=avplug
|
||||
endif
|
||||
ifeq ($(FTE_TARGET),win64)
|
||||
#NATIVE_PLUGINS+=avplug
|
||||
endif
|
||||
|
||||
$(AV_BASE)libavformat/avformat.h:
|
||||
mkdir -p $(AV_BASE)
|
||||
wget $(AV7Z_URL32) -O $(AV_BASE)$(AV7Z_W32)
|
||||
mkdir -p $(AV_BASE)libavformat && cd $(AV_BASE)libavformat && 7z e -y ../$(AV7Z_W32) $(AV7Z_PRE32)include/libavformat/ && cd -
|
||||
mkdir -p $(AV_BASE)libavcodec && cd $(AV_BASE)libavcodec && 7z e -y ../$(AV7Z_W32) $(AV7Z_PRE32)include/libavcodec/ && cd -
|
||||
mkdir -p $(AV_BASE)libavutil && cd $(AV_BASE)libavutil && 7z e -y ../$(AV7Z_W32) $(AV7Z_PRE32)include/libavutil/ && cd -
|
||||
mkdir -p $(AV_BASE)libswscale && cd $(AV_BASE)libswscale && 7z e -y ../$(AV7Z_W32) $(AV7Z_PRE32)include/libswscale/ && cd -
|
||||
mkdir -p $(AV_BASE)lib32 && cd $(AV_BASE)lib32 && 7z e -y ../$(AV7Z_W32) $(AV7Z_PRE32)lib/avformat.lib $(AV7Z_PRE32)lib/avcodec.lib $(AV7Z_PRE32)lib/avutil.lib $(AV7Z_PRE32)lib/swscale.lib && cd -
|
||||
rm $(AV_BASE)$(AV7Z_W32)
|
||||
wget $(AV7Z_URL64) -O $(AV_BASE)$(AV7Z_W64)
|
||||
mkdir -p $(AV_BASE)lib64 && cd $(AV_BASE)lib64 && 7z e -y ../$(AV7Z_W64) $(AV7Z_PRE64)lib/avformat.lib $(AV7Z_PRE64)lib/avcodec.lib $(AV7Z_PRE64)lib/avutil.lib $(AV7Z_PRE64)lib/swscale.lib && cd -
|
||||
rm $(AV_BASE)$(AV7Z_W64)
|
||||
distclean:
|
||||
rm avplug/libavformat/avformat.h
|
||||
rm $(AV_BASE)libavformat/avformat.h
|
||||
$(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT): $(AV_BASE)libavformat/avformat.h
|
||||
|
||||
$(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT): avplug/avencode.c avplug/avdecode.c plugin.c qvm_api.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -s -o $@ -shared $(PLUG_CFLAGS) -L$(AV_BASE)lib$(BITS) -I$(AV_BASE) $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) -lavcodec -lavformat -lavutil -lswscale
|
||||
|
||||
#small script for ode
|
||||
#FIXME: ode fails to compile under cygwin
|
||||
ODE_ARCH=$(FTE_TARGET)
|
||||
ifeq ($(ODE_ARCH),)
|
||||
ODE_ARCH=unknown
|
||||
endif
|
||||
ODE_VER=0.14
|
||||
ODE_URL=https://bitbucket.org/odedevs/ode/downloads/ode-$(ODE_VER).tar.gz
|
||||
ODE_BASE=$(OUT_DIR)/../ode-$(ODE_VER)_$(ODE_ARCH)/
|
||||
ODE_LIB=$(ODE_BASE)ode-$(ODE_VER)/ode/src/.libs/libode.a
|
||||
$(OUT_DIR)/../ode-$(ODE_VER).tar.gz:
|
||||
mkdir -p $(ODE_BASE)
|
||||
wget $(ODE_URL) -O $@
|
||||
$(ODE_LIB): $(OUT_DIR)/../ode-$(ODE_VER).tar.gz
|
||||
mkdir -p $(ODE_BASE) && cd $(ODE_BASE) && tar xvfz $<
|
||||
cd $(ODE_BASE)ode-$(ODE_VER)/ && ./bootstrap && ./configure --enable-double-precision --disable-demos --without-x --with-pic CC="$(CC) $(PLUG_CXXFLAGS)" CXX="$(CC) $(PLUG_CXXFLAGS)" --host=`$(CC) -dumpmachine` && make
|
||||
|
||||
ODE_FILES=../engine/common/com_phys_ode.c ../engine/common/mathlib.c plugin.c qvm_api.c $(ODE_LIB)
|
||||
$(OUT_DIR)/fteplug_ode$(PLUG_NATIVE_EXT): $(ODE_FILES)
|
||||
$(CC) -s $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -DODE_STATIC -o $@ -shared $(PLUG_CFLAGS) -I$(ODE_BASE)ode-$(ODE_VER)/include $(ODE_FILES) $(PLUG_DEFFILE) $(PLUG_LDFLAGS) -lstdc++ -lpthread
|
||||
#NATIVE_PLUGINS+=ode
|
||||
|
||||
|
||||
BULLET_VER=2.83.7
|
||||
BULLET_URL=https://github.com/bulletphysics/bullet3/archive/$(BULLET_VER).tar.gz
|
||||
BULLET_BASE=$(OUT_DIR)/../bullet3-$(ODE_VER)_$(FTE_TARGET)/
|
||||
BULLET_LIB=$(ODE_BASE)bullet3-$(ODE_VER)/ode/src/.libs/libode.a
|
||||
$(OUT_DIR)/../bullet3-$(BULLET_VER).tar.gz:
|
||||
mkdir -p $(BULLET_BASE)
|
||||
wget $(BULLET_URL) -O $@
|
||||
$(BULLET_LIB): $(OUT_DIR)/../bullet3-$(BULLET_VER).tar.gz
|
||||
mkdir -p $(BULLET_BASE) && cd $(BULLET_BASE) && tar xvfz $<
|
||||
cd $(BULLET_BASE)bullet3-$(BULLET_VER)/ && ./bootstrap && ./configure --enable-double-precision --disable-demos --without-x CXX="$(CC)" CFLAGS="$(PLUG_CFLAGS)" CXXFLAGS="$(PLUG_CXXFLAGS)" --host=`$(CC) -dumpmachine` && make
|
||||
|
||||
|
||||
$(OUT_DIR)/fteplug_bullet$(PLUG_NATIVE_EXT): bullet/bulletplug.c plugin.c qvm_api.c $(BULLET_LIB)
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
#NATIVE_PLUGINS+=bullet
|
||||
|
||||
|
||||
-include Makefile.private
|
||||
|
||||
$(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT): avplug/avencode.c avplug/avdecode.c plugin.c qvm_api.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -s -o $(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT) -shared $(PLUG_CFLAGS) -Iavplug/msvc_lib $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) -lavcodec -lavformat -lavutil -lswscale
|
||||
#native: $(OUT_DIR)/fteplug_avplug$(PLUG_NATIVE_EXT)
|
||||
|
||||
$(OUT_DIR)/fteplug_mpq$(PLUG_NATIVE_EXT): mpq/fs_mpq.c mpq/blast.c plugin.c qvm_api.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $(OUT_DIR)/fteplug_mpq$(PLUG_NATIVE_EXT) -shared $(PLUG_CFLAGS) -Impq $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
native: $(OUT_DIR)/fteplug_mpq$(PLUG_NATIVE_EXT)
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Impq $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
NATIVE_PLUGINS+=mpq
|
||||
|
||||
$(OUT_DIR)/fteplug_xmpp$(PLUG_NATIVE_EXT): jabber/jabberclient.c jabber/jingle.c jabber/sift.c jabber/xml.c plugin.c qvm_api.c ../engine/common/sha1.c emailnot/md5.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $(OUT_DIR)/fteplug_xmpp$(PLUG_NATIVE_EXT) -shared $(PLUG_CFLAGS) -Ijabber $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) $(LIBRESOLV)
|
||||
native: $(OUT_DIR)/fteplug_xmpp$(PLUG_NATIVE_EXT)
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Ijabber $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) $(LIBRESOLV)
|
||||
NATIVE_PLUGINS+=xmpp
|
||||
|
||||
$(OUT_DIR)/fteplug_qi$(PLUG_NATIVE_EXT): qi/qi.c jabber/xml.c plugin.c qvm_api.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Ijabber $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
NATIVE_PLUGINS+=qi
|
||||
|
||||
$(OUT_DIR)/fteplug_cef$(PLUG_NATIVE_EXT): cef/cef.c plugin.c qvm_api.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Icef/2623 $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS) -Wl,-rpath,. -ldl
|
||||
#NATIVE_PLUGINS+=cef
|
||||
|
||||
#irc plugin can still be built as a qvm.
|
||||
$(OUT_DIR)/fteplug_irc$(PLUG_NATIVE_EXT): irc/ircclient.c plugin.c qvm_api.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $(OUT_DIR)/fteplug_irc$(PLUG_NATIVE_EXT) -shared $(PLUG_CFLAGS) -Iirc $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
native: $(OUT_DIR)/fteplug_irc$(PLUG_NATIVE_EXT)
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Iirc $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
NATIVE_PLUGINS+=irc
|
||||
|
||||
#for compat with ezquake
|
||||
$(OUT_DIR)/fteplug_ezhud$(PLUG_NATIVE_EXT): ezhud/ezquakeisms.c ezhud/hud.c ezhud/hud_common.c ezhud/hud_editor.c plugin.c qvm_api.c
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $(OUT_DIR)/fteplug_ezhud$(PLUG_NATIVE_EXT) -shared $(PLUG_CFLAGS) -Iezhud $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
native: $(OUT_DIR)/fteplug_ezhud$(PLUG_NATIVE_EXT)
|
||||
$(CC) $(BASE_CFLAGS) $(CFLAGS) -DFTEPLUGIN -o $@ -shared $(PLUG_CFLAGS) -Iezhud $^ $(PLUG_DEFFILE) $(PLUG_LDFLAGS)
|
||||
NATIVE_PLUGINS+=ezhud
|
||||
|
||||
native:
|
||||
native: $(foreach FOO,$(NATIVE_PLUGINS), $(OUT_DIR)/fteplug_$(FOO)$(PLUG_NATIVE_EXT))
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "libavcodec/avcodec.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
|
||||
//between av 52.31 and 54.35, lots of constants etc got renamed to gain an extra AV_ prefix.
|
||||
/*
|
||||
|
@ -44,18 +45,18 @@ struct decctx
|
|||
AVCodecContext *pVCodecCtx;
|
||||
AVFrame *pVFrame;
|
||||
int64_t num, denum;
|
||||
int64_t lasttime;
|
||||
|
||||
AVPicture pFrameRGB;
|
||||
uint8_t *rgb_data;
|
||||
int rgb_linesize;
|
||||
struct SwsContext *pScaleCtx;
|
||||
|
||||
unsigned int starttime;
|
||||
unsigned int lastframe;
|
||||
};
|
||||
|
||||
static qboolean AVDec_SetSize (void *vctx, int width, int height)
|
||||
{
|
||||
struct decctx *ctx = (struct decctx*)vctx;
|
||||
AVPicture newscaled;
|
||||
uint8_t *rgb_data[1];
|
||||
int rgb_linesize[1];
|
||||
|
||||
//colourspace conversions will be fastest if we
|
||||
// if (width > ctx->pCodecCtx->width)
|
||||
|
@ -67,15 +68,16 @@ static qboolean AVDec_SetSize (void *vctx, int width, int height)
|
|||
if (width == ctx->width && height == ctx->height && ctx->pScaleCtx)
|
||||
return true;
|
||||
|
||||
if (avpicture_alloc(&newscaled, AV_PIX_FMT_BGRA, width, height) >= 0)
|
||||
if (av_image_alloc(rgb_data, rgb_linesize, width, height, AV_PIX_FMT_BGRA, 16) >= 0)
|
||||
{
|
||||
//update the scale context as required
|
||||
//clear the old stuff out
|
||||
avpicture_free(&ctx->pFrameRGB);
|
||||
av_free(ctx->rgb_data);
|
||||
|
||||
ctx->width = width;
|
||||
ctx->height = height;
|
||||
ctx->pFrameRGB = newscaled;
|
||||
ctx->rgb_data = rgb_data[0];
|
||||
ctx->rgb_linesize = rgb_linesize[0];
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse; //unsupported
|
||||
|
@ -93,12 +95,12 @@ static int AVIO_Read(void *opaque, uint8_t *buf, int buf_size)
|
|||
static int64_t AVIO_Seek(void *opaque, int64_t offset, int whence)
|
||||
{
|
||||
struct decctx *ctx = opaque;
|
||||
int64_t ret = ctx->fileofs;
|
||||
whence &= ~AVSEEK_FORCE;
|
||||
switch(whence)
|
||||
{
|
||||
case SEEK_SET:
|
||||
default:
|
||||
return -1;
|
||||
case SEEK_SET:
|
||||
ctx->fileofs = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
|
@ -119,7 +121,7 @@ static void AVDec_Destroy(void *vctx)
|
|||
struct decctx *ctx = (struct decctx*)vctx;
|
||||
|
||||
// Free the video stuff
|
||||
avpicture_free(&ctx->pFrameRGB);
|
||||
av_free(ctx->rgb_data);
|
||||
if (ctx->pVCodecCtx)
|
||||
avcodec_close(ctx->pVCodecCtx);
|
||||
av_free(ctx->pVFrame);
|
||||
|
@ -138,7 +140,7 @@ static void AVDec_Destroy(void *vctx)
|
|||
free(ctx);
|
||||
}
|
||||
|
||||
static void *AVDec_Create(char *medianame)
|
||||
static void *AVDec_Create(const char *medianame)
|
||||
{
|
||||
struct decctx *ctx;
|
||||
|
||||
|
@ -163,16 +165,13 @@ static void *AVDec_Create(char *medianame)
|
|||
ctx = malloc(sizeof(*ctx));
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
|
||||
//so we always decode the first frame instantly.
|
||||
|
||||
ctx->starttime = pSys_Milliseconds();
|
||||
|
||||
ctx->lasttime = -1;
|
||||
ctx->file = -1;
|
||||
if (useioctx)
|
||||
{
|
||||
// Create internal Buffer for FFmpeg:
|
||||
const int iBufSize = 32 * 1024;
|
||||
char *pBuffer = malloc(iBufSize);
|
||||
char *pBuffer = av_malloc(iBufSize);
|
||||
AVIOContext *ioctx;
|
||||
|
||||
ctx->filelen = pFS_Open(medianame, &ctx->file, 1);
|
||||
|
@ -180,7 +179,7 @@ static void *AVDec_Create(char *medianame)
|
|||
{
|
||||
Con_Printf("Unable to open %s\n", medianame);
|
||||
free(ctx);
|
||||
free(pBuffer);
|
||||
av_free(pBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -230,7 +229,7 @@ having them tied to the libavformat network IO.
|
|||
ctx->pACodecCtx=ctx->pFormatCtx->streams[ctx->audioStream]->codec;
|
||||
pCodec=avcodec_find_decoder(ctx->pACodecCtx->codec_id);
|
||||
|
||||
ctx->pAFrame=avcodec_alloc_frame();
|
||||
ctx->pAFrame=av_frame_alloc();
|
||||
if(pCodec!=NULL && ctx->pAFrame && avcodec_open2(ctx->pACodecCtx, pCodec, NULL) >= 0)
|
||||
{
|
||||
|
||||
|
@ -260,7 +259,7 @@ having them tied to the libavformat network IO.
|
|||
if(pCodec!=NULL && avcodec_open2(ctx->pVCodecCtx, pCodec, NULL) >= 0)
|
||||
{
|
||||
// Allocate video frame
|
||||
ctx->pVFrame=avcodec_alloc_frame();
|
||||
ctx->pVFrame=av_frame_alloc();
|
||||
if(ctx->pVFrame!=NULL)
|
||||
{
|
||||
if (AVDec_SetSize(ctx, ctx->pVCodecCtx->width, ctx->pVCodecCtx->height))
|
||||
|
@ -276,30 +275,27 @@ having them tied to the libavformat network IO.
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void *AVDec_DisplayFrame(void *vctx, qboolean nosound, uploadfmt_t *fmt, int *width, int *height)
|
||||
static qboolean VARGS AVDec_DisplayFrame(void *vctx, qboolean nosound, qboolean forcevideo, double mediatime, void (QDECL *uploadtexture)(void *ectx, uploadfmt_t fmt, int width, int height, void *data, void *palette), void *ectx)
|
||||
{
|
||||
struct decctx *ctx = (struct decctx*)vctx;
|
||||
AVPacket packet;
|
||||
int frameFinished;
|
||||
qboolean repainted = false;
|
||||
int64_t curtime, lasttime;
|
||||
int64_t curtime;
|
||||
|
||||
curtime = ((pSys_Milliseconds() - ctx->starttime) * ctx->denum);
|
||||
curtime /= (ctx->num * 1000);
|
||||
curtime = (mediatime * ctx->denum) / ctx->num;
|
||||
|
||||
*fmt = TF_BGRA32;
|
||||
while (1)
|
||||
{
|
||||
lasttime = av_frame_get_best_effort_timestamp(ctx->pVFrame);
|
||||
|
||||
if (lasttime > curtime)
|
||||
if (ctx->lasttime > curtime)
|
||||
break;
|
||||
|
||||
// We're ahead of the previous frame. try and read the next.
|
||||
if (av_read_frame(ctx->pFormatCtx, &packet) < 0)
|
||||
{
|
||||
*fmt = TF_INVALID;
|
||||
break;
|
||||
if (repainted)
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Is this a packet from the video stream?
|
||||
|
@ -314,10 +310,11 @@ static void *AVDec_DisplayFrame(void *vctx, qboolean nosound, uploadfmt_t *fmt,
|
|||
ctx->pScaleCtx = sws_getCachedContext(ctx->pScaleCtx, ctx->pVCodecCtx->width, ctx->pVCodecCtx->height, ctx->pVCodecCtx->pix_fmt, ctx->width, ctx->height, AV_PIX_FMT_BGRA, SWS_POINT, 0, 0, 0);
|
||||
|
||||
// Convert the image from its native format to RGB
|
||||
sws_scale(ctx->pScaleCtx, (void*)ctx->pVFrame->data, ctx->pVFrame->linesize, 0, ctx->pVCodecCtx->height, ctx->pFrameRGB.data, ctx->pFrameRGB.linesize);
|
||||
sws_scale(ctx->pScaleCtx, (void*)ctx->pVFrame->data, ctx->pVFrame->linesize, 0, ctx->pVCodecCtx->height, &ctx->rgb_data, &ctx->rgb_linesize);
|
||||
|
||||
repainted = true;
|
||||
}
|
||||
ctx->lasttime = av_frame_get_best_effort_timestamp(ctx->pVFrame);
|
||||
}
|
||||
else if(packet.stream_index==ctx->audioStream && !nosound)
|
||||
{
|
||||
|
@ -335,6 +332,7 @@ static void *AVDec_DisplayFrame(void *vctx, qboolean nosound, uploadfmt_t *fmt,
|
|||
if (okay)
|
||||
{
|
||||
int width = 2;
|
||||
int channels = ctx->pACodecCtx->channels;
|
||||
unsigned int auddatasize = av_samples_get_buffer_size(NULL, ctx->pACodecCtx->channels, ctx->pAFrame->nb_samples, ctx->pACodecCtx->sample_fmt, 1);
|
||||
void *auddata = ctx->pAFrame->data[0];
|
||||
switch(ctx->pACodecCtx->sample_fmt)
|
||||
|
@ -342,13 +340,24 @@ static void *AVDec_DisplayFrame(void *vctx, qboolean nosound, uploadfmt_t *fmt,
|
|||
default:
|
||||
auddatasize = 0;
|
||||
break;
|
||||
case AV_SAMPLE_FMT_U8P:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
width = 1;
|
||||
break;
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
width = 2;
|
||||
break;
|
||||
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
//FIXME: support float audio internally.
|
||||
{
|
||||
float *in = (void*)auddata;
|
||||
signed short *out = (void*)auddata;
|
||||
|
@ -366,23 +375,43 @@ static void *AVDec_DisplayFrame(void *vctx, qboolean nosound, uploadfmt_t *fmt,
|
|||
auddatasize/=2;
|
||||
width = 2;
|
||||
}
|
||||
|
||||
case AV_SAMPLE_FMT_DBLP:
|
||||
auddatasize /= channels;
|
||||
channels = 1;
|
||||
case AV_SAMPLE_FMT_DBL:
|
||||
{
|
||||
double *in = (double*)auddata;
|
||||
signed short *out = (void*)auddata;
|
||||
int v;
|
||||
unsigned int i;
|
||||
for (i = 0; i < auddatasize/sizeof(*in); i++)
|
||||
{
|
||||
v = (short)(in[i]*32767);
|
||||
if (v < -32767)
|
||||
v = -32767;
|
||||
else if (v > 32767)
|
||||
v = 32767;
|
||||
out[i] = v;
|
||||
}
|
||||
auddatasize/=4;
|
||||
width = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pS_RawAudio(-1, auddata, ctx->pACodecCtx->sample_rate, auddatasize/(ctx->pACodecCtx->channels*width), ctx->pACodecCtx->channels, width, 1);
|
||||
pS_RawAudio(-1, auddata, ctx->pACodecCtx->sample_rate, auddatasize/(channels*width), channels, width, 1);
|
||||
}
|
||||
}
|
||||
packet.data = odata;
|
||||
}
|
||||
|
||||
// Free the packet that was allocated by av_read_frame
|
||||
av_free_packet(&packet);
|
||||
av_packet_unref(&packet);
|
||||
}
|
||||
|
||||
*width = ctx->width;
|
||||
*height = ctx->height;
|
||||
if (!repainted)
|
||||
return NULL;
|
||||
return ctx->pFrameRGB.data[0];
|
||||
if (forcevideo || repainted)
|
||||
uploadtexture(ectx, TF_BGRA32, ctx->width, ctx->height, ctx->rgb_data, NULL);
|
||||
return true;
|
||||
}
|
||||
static void AVDec_GetSize (void *vctx, int *width, int *height)
|
||||
{
|
||||
|
@ -407,11 +436,16 @@ static void AVDec_Rewind(void *vctx)
|
|||
{
|
||||
struct decctx *ctx = (struct decctx*)vctx;
|
||||
if (ctx->videoStream >= 0)
|
||||
av_seek_frame(ctx->pFormatCtx, ctx->videoStream, 0, AVSEEK_FLAG_BACKWARD);
|
||||
{
|
||||
av_seek_frame(ctx->pFormatCtx, ctx->videoStream, 0, AVSEEK_FLAG_FRAME|AVSEEK_FLAG_BACKWARD);
|
||||
avcodec_flush_buffers(ctx->pVCodecCtx);
|
||||
}
|
||||
if (ctx->audioStream >= 0)
|
||||
av_seek_frame(ctx->pFormatCtx, ctx->audioStream, 0, AVSEEK_FLAG_BACKWARD);
|
||||
|
||||
ctx->starttime = pSys_Milliseconds();
|
||||
{
|
||||
av_seek_frame(ctx->pFormatCtx, ctx->audioStream, 0, AVSEEK_FLAG_FRAME|AVSEEK_FLAG_BACKWARD);
|
||||
avcodec_flush_buffers(ctx->pACodecCtx);
|
||||
}
|
||||
ctx->lasttime = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -424,10 +458,10 @@ static qintptr_t AVDec_Shutdown(qintptr_t *args)
|
|||
|
||||
static media_decoder_funcs_t decoderfuncs =
|
||||
{
|
||||
sizeof(media_decoder_funcs_t),
|
||||
"avplug",
|
||||
AVDec_Create,
|
||||
AVDec_DisplayFrame,
|
||||
NULL,//doneframe
|
||||
AVDec_Destroy,
|
||||
AVDec_Rewind,
|
||||
|
||||
|
@ -452,6 +486,15 @@ static qboolean AVDec_Init(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void AVLogCallback(void *avcl, int level, const char *fmt, va_list vl)
|
||||
{ //needs to be reenterant
|
||||
#ifdef _DEBUG
|
||||
char string[1024];
|
||||
Q_vsnprintf (string, sizeof(string), fmt, vl);
|
||||
pCon_Print(string);
|
||||
#endif
|
||||
}
|
||||
|
||||
//get the encoder/decoders to register themselves with the engine, then make sure avformat/avcodec have registered all they have to give.
|
||||
qboolean AVEnc_Init(void);
|
||||
qintptr_t Plug_Init(qintptr_t *args)
|
||||
|
@ -464,6 +507,9 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
{
|
||||
av_register_all();
|
||||
avcodec_register_all();
|
||||
|
||||
av_log_set_level(AV_LOG_WARNING);
|
||||
av_log_set_callback(AVLogCallback);
|
||||
}
|
||||
return okay;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "libavformat/avio.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/opt.h"
|
||||
//#include <libavutil/channel_layout.h>
|
||||
|
||||
/*
|
||||
|
@ -14,6 +16,7 @@ http://svn.gnumonks.org/tags/21c3-video/upstream/ffmpeg-0.4.9-pre1/output_exampl
|
|||
|
||||
struct encctx
|
||||
{
|
||||
char abspath[MAX_OSPATH];
|
||||
AVFormatContext *fc;
|
||||
qboolean doneheaders;
|
||||
|
||||
|
@ -25,27 +28,33 @@ struct encctx
|
|||
|
||||
AVStream *audio_st;
|
||||
AVFrame *audio;
|
||||
uint8_t *audio_outbuf;
|
||||
uint32_t audio_outcount;
|
||||
int64_t audio_pts;
|
||||
};
|
||||
|
||||
#define VARIABLE_AUDIO_FRAME_MIN_SIZE 512 //audio frames smaller than a certain size are just wasteful
|
||||
#define VARIABLE_AUDIO_FRAME_MAX_SIZE 1024
|
||||
|
||||
static void AVEnc_End (void *ctx);
|
||||
|
||||
static AVFrame *alloc_frame(enum PixelFormat pix_fmt, int width, int height)
|
||||
static AVFrame *alloc_frame(enum AVPixelFormat pix_fmt, int width, int height)
|
||||
{
|
||||
AVFrame *picture;
|
||||
uint8_t *picture_buf;
|
||||
int size;
|
||||
|
||||
picture = avcodec_alloc_frame();
|
||||
picture = av_frame_alloc();
|
||||
if(!picture)
|
||||
return NULL;
|
||||
size = avpicture_get_size(pix_fmt, width, height);
|
||||
size = av_image_get_buffer_size(pix_fmt, width, height, 1);
|
||||
picture_buf = (uint8_t*)(av_malloc(size));
|
||||
if (!picture_buf)
|
||||
{
|
||||
av_free(picture);
|
||||
return NULL;
|
||||
}
|
||||
avpicture_fill((AVPicture *) picture, picture_buf, pix_fmt, width, height);
|
||||
av_image_fill_arrays(picture->data, picture->linesize, picture_buf, pix_fmt, width, height, 1/*fixme: align*/);
|
||||
picture->width = width;
|
||||
picture->height = height;
|
||||
return picture;
|
||||
|
@ -61,10 +70,7 @@ AVStream *add_video_stream(struct encctx *ctx, AVCodec *codec, int fps, int widt
|
|||
|
||||
st = avformat_new_stream(ctx->fc, codec);
|
||||
if (!st)
|
||||
{
|
||||
fprintf(stderr, "Could not alloc stream\n");
|
||||
exit(1);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
c = st->codec;
|
||||
c->codec_id = codec->id;
|
||||
|
@ -78,14 +84,14 @@ AVStream *add_video_stream(struct encctx *ctx, AVCodec *codec, int fps, int widt
|
|||
/* frames per second */
|
||||
c->time_base.num = 1;
|
||||
c->time_base.den = fps;
|
||||
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
||||
c->pix_fmt = PIX_FMT_YUV420P;
|
||||
if (c->codec_id == CODEC_ID_MPEG2VIDEO)
|
||||
//c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO)
|
||||
{
|
||||
/* just for testing, we also add B frames */
|
||||
c->max_b_frames = 2;
|
||||
}
|
||||
if (c->codec_id == CODEC_ID_MPEG1VIDEO)
|
||||
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO)
|
||||
{
|
||||
/* needed to avoid using macroblocks in which some coeffs overflow
|
||||
this doesnt happen with normal video, it just happens here as the
|
||||
|
@ -96,9 +102,13 @@ AVStream *add_video_stream(struct encctx *ctx, AVCodec *codec, int fps, int widt
|
|||
if (ctx->fc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
*prof = 0;
|
||||
pCvar_GetString("avplug_format", prof, sizeof(prof));
|
||||
// av_opt_set(c->priv_data, "profile", prof, AV_OPT_SEARCH_CHILDREN);
|
||||
pCvar_GetString("avplug_videopreset", prof, sizeof(prof));
|
||||
if (*prof)
|
||||
av_opt_set(c->priv_data, "preset", prof, AV_OPT_SEARCH_CHILDREN);
|
||||
pCvar_GetString("avplug_video_crf", prof, sizeof(prof));
|
||||
if (*prof)
|
||||
av_opt_set(c->priv_data, "crf", prof, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
|
||||
return st;
|
||||
}
|
||||
|
@ -124,6 +134,7 @@ static void AVEnc_Video (void *vctx, void *data, int frame, int width, int heigh
|
|||
AVPacket pkt;
|
||||
int avpfmt;
|
||||
int inbpp;
|
||||
int err;
|
||||
|
||||
if (!ctx->video_st)
|
||||
return;
|
||||
|
@ -146,28 +157,39 @@ static void AVEnc_Video (void *vctx, void *data, int frame, int width, int heigh
|
|||
|
||||
//convert RGB to whatever the codec needs (ie: yuv...).
|
||||
//also rescales, but only if the user resizes the video while recording. which is a stupid thing to do.
|
||||
ctx->scale_ctx = sws_getCachedContext(ctx->scale_ctx, width, height, qpfmt, ctx->picture->width, ctx->picture->height, ctx->video_st->codec->pix_fmt, SWS_POINT, 0, 0, 0);
|
||||
ctx->scale_ctx = sws_getCachedContext(ctx->scale_ctx, width, height, avpfmt, ctx->picture->width, ctx->picture->height, ctx->video_st->codec->pix_fmt, SWS_POINT, 0, 0, 0);
|
||||
sws_scale(ctx->scale_ctx, srcslices, srcstride, 0, height, ctx->picture->data, ctx->picture->linesize);
|
||||
|
||||
av_init_packet(&pkt);
|
||||
ctx->picture->pts = av_rescale_q(frame, ctx->video_st->codec->time_base, ctx->video_st->time_base);
|
||||
ctx->picture->pts = frame;
|
||||
success = 0;
|
||||
pkt.data = ctx->video_outbuf;
|
||||
pkt.size = ctx->video_outbuf_size;
|
||||
if (avcodec_encode_video2(ctx->video_st->codec, &pkt, ctx->picture, &success) == 0 && success)
|
||||
ctx->picture->format = ctx->video_st->codec->pix_fmt;
|
||||
err = avcodec_encode_video2(ctx->video_st->codec, &pkt, ctx->picture, &success);
|
||||
if (err)
|
||||
{
|
||||
pkt.pts = ctx->video_st->codec->coded_frame->pts;
|
||||
if(ctx->video_st->codec->coded_frame->key_frame)
|
||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
char buf[512];
|
||||
Con_Printf("avcodec_encode_video2: error: %s\n", av_make_error_string(buf, sizeof(buf), err));
|
||||
}
|
||||
else if (err == 0 && success)
|
||||
{
|
||||
// pkt.pts = ctx->video_st->codec->coded_frame->pts;
|
||||
// if(ctx->video_st->codec->coded_frame->key_frame)
|
||||
// pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
av_packet_rescale_ts(&pkt, ctx->video_st->codec->time_base, ctx->video_st->time_base);
|
||||
pkt.stream_index = ctx->video_st->index;
|
||||
pkt.data = ctx->video_outbuf;
|
||||
// pkt.size = psize;
|
||||
|
||||
av_write_frame(ctx->fc, &pkt);
|
||||
err = av_interleaved_write_frame(ctx->fc, &pkt);
|
||||
|
||||
if (err)
|
||||
{
|
||||
char buf[512];
|
||||
Con_Printf("av_interleaved_write_frame: error: %s\n", av_make_error_string(buf, sizeof(buf), err));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AVStream *add_audio_stream(struct encctx *ctx, AVCodec *codec, int samplerate, int bits, int channels)
|
||||
AVStream *add_audio_stream(struct encctx *ctx, AVCodec *codec, int samplerate, int *bits, int channels)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
AVStream *st;
|
||||
|
@ -175,11 +197,9 @@ AVStream *add_audio_stream(struct encctx *ctx, AVCodec *codec, int samplerate, i
|
|||
|
||||
st = avformat_new_stream(ctx->fc, codec);
|
||||
if (!st)
|
||||
{
|
||||
fprintf(stderr, "Could not alloc stream\n");
|
||||
exit(1);
|
||||
}
|
||||
return NULL;
|
||||
|
||||
st->id = ctx->fc->nb_streams-1;
|
||||
c = st->codec;
|
||||
c->codec_id = codec->id;
|
||||
c->codec_type = codec->type;
|
||||
|
@ -187,25 +207,46 @@ AVStream *add_audio_stream(struct encctx *ctx, AVCodec *codec, int samplerate, i
|
|||
/* put sample parameters */
|
||||
c->bit_rate = bitrate;
|
||||
/* frames per second */
|
||||
c->sample_fmt = ((bits==16)?AV_SAMPLE_FMT_S16:AV_SAMPLE_FMT_U8);
|
||||
c->time_base.num = 1;
|
||||
c->time_base.den = samplerate;
|
||||
c->sample_rate = samplerate;
|
||||
c->channels = channels;
|
||||
#if 0
|
||||
switch(channels)
|
||||
{
|
||||
case 1:
|
||||
c->channel_layout = AV_CH_FRONT_CENTER;
|
||||
c->channel_layout = AV_CH_LAYOUT_MONO;
|
||||
break;
|
||||
case 2:
|
||||
c->channel_layout = AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT;
|
||||
c->channel_layout = AV_CH_LAYOUT_STEREO;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#else
|
||||
c->channel_layout = av_get_default_channel_layout(c->channels);
|
||||
#endif
|
||||
|
||||
c->channel_layout = av_get_default_channel_layout(c->channels);
|
||||
c->sample_fmt = codec->sample_fmts[0];
|
||||
|
||||
// if (c->sample_fmt == AV_SAMPLE_FMT_FLTP || c->sample_fmt == AV_SAMPLE_FMT_FLT)
|
||||
// *bits = 32; //get the engine to mix 32bit audio instead of whatever its currently set to.
|
||||
// else if (c->sample_fmt == AV_SAMPLE_FMT_U8P || c->sample_fmt == AV_SAMPLE_FMT_U8)
|
||||
// *bits = 8; //get the engine to mix 32bit audio instead of whatever its currently set to.
|
||||
// else if (c->sample_fmt == AV_SAMPLE_FMT_S16P || c->sample_fmt == AV_SAMPLE_FMT_S16)
|
||||
// *bits = 16;
|
||||
// else
|
||||
*bits = 32;
|
||||
|
||||
c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||
|
||||
// some formats want stream headers to be seperate
|
||||
if (ctx->fc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
|
||||
|
||||
// avcodec_parameters_from_context(st->codecpar, c);
|
||||
|
||||
return st;
|
||||
}
|
||||
void close_audio(struct encctx *ctx)
|
||||
|
@ -220,25 +261,159 @@ static void AVEnc_Audio (void *vctx, void *data, int bytes)
|
|||
struct encctx *ctx = vctx;
|
||||
int success;
|
||||
AVPacket pkt;
|
||||
int err;
|
||||
|
||||
ctx->audio->nb_samples = ctx->audio_st->codec->frame_size;
|
||||
if (avcodec_fill_audio_frame(ctx->audio, ctx->audio_st->codec->channels, ctx->audio_st->codec->sample_fmt, data, bytes, 0) < 0)
|
||||
if (!ctx->audio_st)
|
||||
return;
|
||||
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
success = 0;
|
||||
if (avcodec_encode_audio2(ctx->audio_st->codec, &pkt, ctx->audio, &success) == 0 && success)
|
||||
while (bytes)
|
||||
{
|
||||
pkt.pts = ctx->audio_st->codec->coded_frame->pts;
|
||||
if(ctx->audio_st->codec->coded_frame->key_frame)
|
||||
pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
pkt.stream_index = ctx->audio_st->index;
|
||||
// pkt.data = ctx->video_outbuf;
|
||||
// pkt.size = psize;
|
||||
int i, p, chans = ctx->audio_st->codec->channels;
|
||||
int blocksize = sizeof(float)*chans;
|
||||
int count = bytes / blocksize;
|
||||
int planesize = ctx->audio_st->codec->frame_size;
|
||||
float *in;
|
||||
int offset;
|
||||
|
||||
av_write_frame(ctx->fc, &pkt);
|
||||
if (!planesize) //variable-sized frames. yay
|
||||
{
|
||||
planesize = count;
|
||||
if (count > VARIABLE_AUDIO_FRAME_MAX_SIZE - ctx->audio_outcount)
|
||||
count = VARIABLE_AUDIO_FRAME_MAX_SIZE - ctx->audio_outcount;
|
||||
}
|
||||
else if (count > ctx->audio_st->codec->frame_size - ctx->audio_outcount)
|
||||
count = ctx->audio_st->codec->frame_size - ctx->audio_outcount;
|
||||
|
||||
in = (float*)data;
|
||||
offset = ctx->audio_outcount;
|
||||
ctx->audio_outcount += count;
|
||||
data = (qbyte*)data + count * blocksize;
|
||||
bytes -= count * blocksize;
|
||||
|
||||
//input is always float audio, because I'm lazy.
|
||||
//output is whatever the codec needs (may be packed or planar, gah).
|
||||
//the engine's mixer will do all rate scaling for us, as well as channel selection
|
||||
switch(ctx->audio_st->codec->sample_fmt)
|
||||
{
|
||||
case AV_SAMPLE_FMT_DBL:
|
||||
offset *= chans;
|
||||
count *= chans;
|
||||
planesize *= chans;
|
||||
chans = 1;
|
||||
case AV_SAMPLE_FMT_DBLP:
|
||||
for (p = 0; p < chans; p++)
|
||||
{
|
||||
double *f = (double*)ctx->audio_outbuf + p*planesize + offset;
|
||||
for (i = 0; i < count*chans; i+=chans)
|
||||
*f++ = in[i];
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_FLT:
|
||||
offset *= chans;
|
||||
count *= chans;
|
||||
planesize *= chans;
|
||||
chans = 1;
|
||||
case AV_SAMPLE_FMT_FLTP:
|
||||
for (p = 0; p < chans; p++)
|
||||
{
|
||||
float *f = (float *)ctx->audio_outbuf + p*planesize + offset;
|
||||
for (i = 0; i < count*chans; i+=chans)
|
||||
*f++ = in[i];
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_S32:
|
||||
offset *= chans;
|
||||
count *= chans;
|
||||
planesize *= chans;
|
||||
chans = 1;
|
||||
case AV_SAMPLE_FMT_S32P:
|
||||
for (p = 0; p < chans; p++)
|
||||
{
|
||||
int32_t *f = (int32_t *)ctx->audio_outbuf + p*planesize + offset;
|
||||
for (i = 0; i < count*chans; i+=chans)
|
||||
*f++ = bound(0x80000000, (in[i] * 0x7fffffff), 0x7fffffff);
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
offset *= chans;
|
||||
count *= chans;
|
||||
planesize *= chans;
|
||||
chans = 1;
|
||||
case AV_SAMPLE_FMT_S16P:
|
||||
for (p = 0; p < chans; p++)
|
||||
{
|
||||
int16_t *f = (int16_t *)ctx->audio_outbuf + p*planesize + offset;
|
||||
for (i = 0; i < count*chans; i+=chans)
|
||||
*f++ = bound(-32768, (int)(in[i] * 32767), 32767);
|
||||
|
||||
//sin((ctx->audio_pts+ctx->audio_outcount-count+i/chans)*0.1) * 32767;//
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
offset *= chans;
|
||||
count *= chans;
|
||||
planesize *= chans;
|
||||
chans = 1;
|
||||
case AV_SAMPLE_FMT_U8P:
|
||||
for (p = 0; p < chans; p++)
|
||||
{
|
||||
uint8_t *f = (uint8_t*)ctx->audio_outbuf + p*planesize + offset;
|
||||
for (i = 0; i < count*chans; i+=chans)
|
||||
*f++ = bound(0, 128+(int)(in[i] * 127), 255);
|
||||
in++;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->audio_st->codec->frame_size)
|
||||
{
|
||||
if (ctx->audio_outcount < ctx->audio_st->codec->frame_size)
|
||||
break; //not enough data yet.
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctx->audio_outcount < VARIABLE_AUDIO_FRAME_MIN_SIZE)
|
||||
break; //not enough data yet.
|
||||
}
|
||||
|
||||
ctx->audio->nb_samples = ctx->audio_outcount;
|
||||
avcodec_fill_audio_frame(ctx->audio, ctx->audio_st->codec->channels, ctx->audio_st->codec->sample_fmt, ctx->audio_outbuf, av_get_bytes_per_sample(ctx->audio_st->codec->sample_fmt)*ctx->audio_outcount*ctx->audio_st->codec->channels, 1);
|
||||
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = NULL;
|
||||
pkt.size = 0;
|
||||
success = 0;
|
||||
ctx->audio->pts = ctx->audio_pts;
|
||||
ctx->audio_pts += ctx->audio_outcount;
|
||||
ctx->audio_outcount = 0;
|
||||
err = avcodec_encode_audio2(ctx->audio_st->codec, &pkt, ctx->audio, &success);
|
||||
|
||||
if (err)
|
||||
{
|
||||
char buf[512];
|
||||
Con_Printf("avcodec_encode_audio2: error: %s\n", av_make_error_string(buf, sizeof(buf), err));
|
||||
}
|
||||
else if (success)
|
||||
{
|
||||
// pkt.pts = ctx->audio_st->codec->coded_frame->pts;
|
||||
// if(ctx->audio_st->codec->coded_frame->key_frame)
|
||||
// pkt.flags |= AV_PKT_FLAG_KEY;
|
||||
|
||||
av_packet_rescale_ts(&pkt, ctx->audio_st->codec->time_base, ctx->audio_st->time_base);
|
||||
pkt.stream_index = ctx->audio_st->index;
|
||||
err = av_interleaved_write_frame(ctx->fc, &pkt);
|
||||
if (err)
|
||||
{
|
||||
char buf[512];
|
||||
Con_Printf("av_interleaved_write_frame: error: %s\n", av_make_error_string(buf, sizeof(buf), err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,8 +424,9 @@ static void *AVEnc_Begin (char *streamname, int videorate, int width, int height
|
|||
AVCodec *videocodec = NULL;
|
||||
AVCodec *audiocodec = NULL;
|
||||
char formatname[64];
|
||||
int err;
|
||||
formatname[0] = 0;
|
||||
pCvar_GetString("avplug_format", formatname, sizeof(formatname));
|
||||
pCvar_GetString("avplug_format_force", formatname, sizeof(formatname));
|
||||
|
||||
if (*formatname)
|
||||
{
|
||||
|
@ -349,49 +525,56 @@ static void *AVEnc_Begin (char *streamname, int videorate, int width, int height
|
|||
//pick default codecs
|
||||
ctx->video_st = NULL;
|
||||
if (videocodec)
|
||||
{
|
||||
ctx->video_st = add_video_stream(ctx, videocodec, videorate, width, height);
|
||||
|
||||
if (ctx->video_st)
|
||||
{
|
||||
AVCodecContext *c = ctx->video_st->codec;
|
||||
if (avcodec_open2(c, videocodec, NULL) < 0)
|
||||
{
|
||||
Con_Printf("avplug: Could not init codec instance \"%s\". Maybe try a different framerate/resolution/bitrate\n", videocodec->name);
|
||||
AVEnc_End(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->picture = alloc_frame(c->pix_fmt, c->width, c->height);
|
||||
|
||||
ctx->video_outbuf_size = 200000;
|
||||
ctx->video_outbuf = av_malloc(ctx->video_outbuf_size);
|
||||
if (!ctx->video_outbuf)
|
||||
ctx->video_outbuf_size = 0;
|
||||
}
|
||||
}
|
||||
if (audiocodec)
|
||||
{
|
||||
ctx->audio_st = add_audio_stream(ctx, audiocodec, *sndkhz, *sndbits, *sndchannels);
|
||||
if (ctx->audio_st)
|
||||
{
|
||||
AVCodecContext *c = ctx->audio_st->codec;
|
||||
if (avcodec_open2(c, audiocodec, NULL) < 0)
|
||||
{
|
||||
Con_Printf("avplug: Could not init codec instance \"%s\".\n", audiocodec->name);
|
||||
AVEnc_End(ctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx->audio_st = add_audio_stream(ctx, audiocodec, *sndkhz, sndbits, *sndchannels);
|
||||
|
||||
ctx->audio = avcodec_alloc_frame();
|
||||
if (ctx->video_st)
|
||||
{
|
||||
AVCodecContext *c = ctx->video_st->codec;
|
||||
err = avcodec_open2(c, videocodec, NULL);
|
||||
if (err < 0)
|
||||
{
|
||||
char buf[512];
|
||||
Con_Printf("avplug: Could not init codec instance \"%s\" - %s\nMaybe try a different framerate/resolution/bitrate\n", videocodec->name, av_make_error_string(buf, sizeof(buf), err));
|
||||
AVEnc_End(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->picture = alloc_frame(c->pix_fmt, c->width, c->height);
|
||||
|
||||
ctx->video_outbuf_size = 200000;
|
||||
ctx->video_outbuf = av_malloc(ctx->video_outbuf_size);
|
||||
if (!ctx->video_outbuf)
|
||||
ctx->video_outbuf_size = 0;
|
||||
}
|
||||
if (ctx->audio_st)
|
||||
{
|
||||
int sz;
|
||||
AVCodecContext *c = ctx->audio_st->codec;
|
||||
err = avcodec_open2(c, audiocodec, NULL);
|
||||
if (err < 0)
|
||||
{
|
||||
char buf[512];
|
||||
Con_Printf("avplug: Could not init codec instance \"%s\" - %s\n", audiocodec->name, av_make_error_string(buf, sizeof(buf), err));
|
||||
AVEnc_End(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->audio = av_frame_alloc();
|
||||
sz = ctx->audio_st->codec->frame_size;
|
||||
if (!sz)
|
||||
sz = VARIABLE_AUDIO_FRAME_MAX_SIZE;
|
||||
sz *= av_get_bytes_per_sample(ctx->audio_st->codec->sample_fmt) * ctx->audio_st->codec->channels;
|
||||
ctx->audio_outbuf = av_malloc(sz);
|
||||
}
|
||||
|
||||
av_dump_format(ctx->fc, 0, streamname, 1);
|
||||
|
||||
if (!(fmt->flags & AVFMT_NOFILE))
|
||||
{
|
||||
if (avio_open(&ctx->fc->pb, streamname, AVIO_FLAG_WRITE) < 0)
|
||||
//okay, this is annoying, but I'm too lazy to figure out the issue I was having with avio stuff.
|
||||
if (!pFS_NativePath(streamname, FS_GAMEONLY, ctx->abspath, sizeof(ctx->abspath)) || avio_open(&ctx->fc->pb, ctx->abspath, AVIO_FLAG_WRITE) < 0)
|
||||
{
|
||||
Con_Printf("Could not open '%s'\n", streamname);
|
||||
AVEnc_End(ctx);
|
||||
|
@ -400,7 +583,14 @@ static void *AVEnc_Begin (char *streamname, int videorate, int width, int height
|
|||
}
|
||||
|
||||
//nearly complete, can make the file dirty now.
|
||||
avformat_write_header(ctx->fc, NULL);
|
||||
err = avformat_write_header(ctx->fc, NULL);
|
||||
if (err < 0)
|
||||
{
|
||||
char buf[512];
|
||||
Con_Printf("avformat_write_header: failed %s\n", av_make_error_string(buf, sizeof(buf), err));
|
||||
AVEnc_End(ctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx->doneheaders = true;
|
||||
return ctx;
|
||||
}
|
||||
|
@ -413,18 +603,26 @@ static void AVEnc_End (void *vctx)
|
|||
|
||||
//don't write trailers if this is an error case and we never even wrote the headers.
|
||||
if (ctx->doneheaders)
|
||||
{
|
||||
av_write_trailer(ctx->fc);
|
||||
if (*ctx->abspath)
|
||||
Con_Printf("Finished writing %s\n", ctx->abspath);
|
||||
}
|
||||
|
||||
for(i = 0; i < ctx->fc->nb_streams; i++)
|
||||
av_freep(&ctx->fc->streams[i]);
|
||||
// if (!(fmt->flags & AVFMT_NOFILE))
|
||||
avio_close(ctx->fc->pb);
|
||||
av_free(ctx->audio_outbuf);
|
||||
av_free(ctx->fc);
|
||||
free(ctx);
|
||||
}
|
||||
static media_encoder_funcs_t encoderfuncs =
|
||||
{
|
||||
sizeof(media_encoder_funcs_t),
|
||||
"avplug",
|
||||
"Use ffmpeg's various codecs. Various settings are configured with the avplug_* cvars.",
|
||||
".mp4",
|
||||
AVEnc_Begin,
|
||||
AVEnc_Video,
|
||||
AVEnc_Audio,
|
||||
|
@ -457,22 +655,28 @@ menutext 0 24 "Cancel"
|
|||
|
||||
qboolean AVEnc_Init(void)
|
||||
{
|
||||
pCvar_Register("avplug_format", "mp4", 0, "avplug");
|
||||
|
||||
pCvar_Register("avplug_videocodec", "mpeg4", 0, "avplug");
|
||||
pCvar_Register("avplug_videocodecprofile", "", 0, "avplug");
|
||||
pCvar_Register("avplug_videobitrate", "4000000", 0, "avplug");
|
||||
pCvar_Register("avplug_videoforcewidth", "", 0, "avplug");
|
||||
pCvar_Register("avplug_videoforceheight", "", 0, "avplug");
|
||||
pCvar_Register("avplug_audiocodec", "libmp3lame", 0, "avplug");
|
||||
pCvar_Register("avplug_audiobitrate", "64000", 0, "avplug");
|
||||
|
||||
CHECKBUILTIN(FS_NativePath);
|
||||
if (!BUILTINISVALID(FS_NativePath))
|
||||
{
|
||||
Con_Printf("avplug: Engine too old\n");
|
||||
return false;
|
||||
}
|
||||
if (!pPlug_ExportNative("Media_VideoEncoder", &encoderfuncs))
|
||||
{
|
||||
Con_Printf("avplug: Engine doesn't support media encoder plugins\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
pCvar_Register("avplug_format_force", "", 0, "avplug");
|
||||
|
||||
pCvar_Register("avplug_videocodec", "", 0, "avplug");
|
||||
pCvar_Register("avplug_videobitrate", "4000000", 0, "avplug");
|
||||
pCvar_Register("avplug_videoforcewidth", "", 0, "avplug");
|
||||
pCvar_Register("avplug_videoforceheight", "", 0, "avplug");
|
||||
pCvar_Register("avplug_videopreset", "veryfast", 0, "avplug");
|
||||
pCvar_Register("avplug_audiocodec", "", 0, "avplug");
|
||||
pCvar_Register("avplug_audiobitrate", "64000", 0, "avplug");
|
||||
|
||||
// if (Plug_Export("ExecuteCommand", AVEnc_ExecuteCommand))
|
||||
// Cmd_AddCommand("avcapture");
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="berkelium/berkelium.lib"
|
||||
OutputFile="../../fteplug_berkeliumx86.dll"
|
||||
OutputFile="../../fteplug_berkelium_x86.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
|
|
|
@ -181,7 +181,7 @@ public:
|
|||
MyDelegate(decctx *_ctx) : ctx(_ctx) {};
|
||||
};
|
||||
|
||||
static void *Dec_Create(char *medianame)
|
||||
static void *Dec_Create(const char *medianame)
|
||||
{
|
||||
/*only respond to berkelium: media prefixes*/
|
||||
if (!strncmp(medianame, "berkelium:", 10))
|
||||
|
@ -220,19 +220,17 @@ static void *Dec_Create(char *medianame)
|
|||
return ctx;
|
||||
}
|
||||
|
||||
static void *Dec_DisplayFrame(void *vctx, qboolean nosound, enum uploadfmt_e *fmt, int *width, int *height)
|
||||
static qboolean VARGS Dec_DisplayFrame(void *vctx, qboolean nosound, qboolean forcevideo, double mediatime, void (QDECL *uploadtexture)(void *ectx, uploadfmt_t fmt, int width, int height, void *data, void *palette), void *ectx)
|
||||
{
|
||||
decctx *ctx = (decctx*)vctx;
|
||||
*fmt = TF_BGRA32;
|
||||
*width = ctx->width;
|
||||
*height = ctx->height;
|
||||
|
||||
if (!ctx->repainted)
|
||||
return NULL;
|
||||
ctx->paintedwidth = ctx->width;
|
||||
ctx->paintedheight = ctx->height;
|
||||
ctx->repainted = false;
|
||||
return ctx->buffer;
|
||||
if (forcevideo || ctx->repainted)
|
||||
{
|
||||
uploadtexture(ectx, TF_BGRA32, ctx->width, ctx->height, ctx->buffer, NULL);
|
||||
ctx->paintedwidth = ctx->width;
|
||||
ctx->paintedheight = ctx->height;
|
||||
ctx->repainted = false;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
static void Dec_Destroy(void *vctx)
|
||||
{
|
||||
|
@ -340,7 +338,7 @@ static void Dec_Key (void *vctx, int code, int unicode, int isup)
|
|||
}
|
||||
}
|
||||
|
||||
static void Dec_ChangeStream(void *vctx, char *newstream)
|
||||
static void Dec_ChangeStream(void *vctx, const char *newstream)
|
||||
{
|
||||
decctx *ctx = (decctx*)vctx;
|
||||
|
||||
|
@ -413,10 +411,11 @@ static qintptr_t Dec_Shutdown(qintptr_t *args)
|
|||
|
||||
static media_decoder_funcs_t decoderfuncs =
|
||||
{
|
||||
sizeof(media_decoder_funcs_t),
|
||||
|
||||
"berkelium",
|
||||
Dec_Create,
|
||||
Dec_DisplayFrame,
|
||||
NULL,//doneframe
|
||||
Dec_Destroy,
|
||||
NULL,//rewind
|
||||
|
||||
|
|
1969
plugins/cef/cef.c
Normal file
1969
plugins/cef/cef.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,37 +1,46 @@
|
|||
#ifndef FTEPLUGIN
|
||||
#ifndef VARGS
|
||||
#define VARGS QDECL
|
||||
#endif
|
||||
typedef enum uploadfmt_e
|
||||
{
|
||||
TF_INVALID,
|
||||
TF_RGBA32,
|
||||
TF_BGRA32,
|
||||
TF_RGBX32,
|
||||
TF_BGRX32
|
||||
TF_BGRX32,
|
||||
TF_RGB24,
|
||||
TF_BGR24
|
||||
} uploadfmt_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *drivername;
|
||||
void *(QDECL *createdecoder)(char *name); //needed
|
||||
void *(QDECL *decodeframe)(void *ctx, qboolean nosound, uploadfmt_t *fmt, int *width, int *height); //needed
|
||||
void (QDECL *doneframe)(void *ctx, void *img); //basically a free()
|
||||
void (QDECL *shutdown)(void *ctx); //probably needed...
|
||||
void (QDECL *rewind)(void *ctx);
|
||||
size_t structsize;
|
||||
const char *drivername;
|
||||
void *(VARGS *createdecoder)(const char *name);
|
||||
qboolean (VARGS *decodeframe)(void *ctx, qboolean nosound, qboolean forcevideo, double mediatime, void (QDECL *uploadtexture)(void *ectx, uploadfmt_t fmt, int width, int height, void *data, void *palette), void *ectx);
|
||||
void (VARGS *shutdown)(void *ctx);
|
||||
void (VARGS *rewind)(void *ctx);
|
||||
|
||||
//these are any interactivity functions you might want...
|
||||
void (QDECL *cursormove) (void *ctx, float posx, float posy); //pos is 0-1
|
||||
void (QDECL *key) (void *ctx, int code, int unicode, int event); //key event! event=1=down
|
||||
qboolean (QDECL *setsize) (void *ctx, int width, int height); //updates the desired screen-space size
|
||||
void (QDECL *getsize) (void *ctx, int *width, int *height); //retrieves the screen-space size
|
||||
void (QDECL *changestream) (void *ctx, char *streamname); //can be used to accept commands from qc
|
||||
} media_decoder_funcs_t;
|
||||
void (VARGS *cursormove) (void *ctx, float posx, float posy); //pos is 0-1
|
||||
void (VARGS *key) (void *ctx, int code, int unicode, int event);
|
||||
qboolean (VARGS *setsize) (void *ctx, int width, int height);
|
||||
void (VARGS *getsize) (void *ctx, int *width, int *height);
|
||||
void (VARGS *changestream) (void *ctx, const char *streamname);
|
||||
|
||||
size_t (VARGS *gettext) (void *ctx, const char *field, char *out, size_t outlen); //if out is null, returns required buffer size. returns 0 on failure / buffer too small
|
||||
} media_decoder_funcs_t;
|
||||
typedef struct
|
||||
{
|
||||
char *drivername;
|
||||
void *(QDECL *capture_begin) (char *streamname, int videorate, int width, int height, int *sndkhz, int *sndchannels, int *sndbits);
|
||||
void (QDECL *capture_video) (void *ctx, void *data, int frame, int width, int height);
|
||||
void (QDECL *capture_audio) (void *ctx, void *data, int bytes);
|
||||
void (QDECL *capture_end) (void *ctx);
|
||||
size_t structsize;
|
||||
const char *drivername;
|
||||
const char *description;
|
||||
const char *defaultextension;
|
||||
void *(VARGS *capture_begin) (char *streamname, int videorate, int width, int height, int *sndkhz, int *sndchannels, int *sndbits);
|
||||
void (VARGS *capture_video) (void *ctx, void *data, int frame, int width, int height, enum uploadfmt fmt);
|
||||
void (VARGS *capture_audio) (void *ctx, void *data, int bytes);
|
||||
void (VARGS *capture_end) (void *ctx);
|
||||
} media_encoder_funcs_t;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -127,7 +127,8 @@ char *TP_ItemName(unsigned int itbit);
|
|||
#define Util_SkipEZColors(src,dst,dstlen) strlcpy(dst,src,dstlen)
|
||||
|
||||
void Replace_In_String(char *string, size_t strsize, char leadchar, int patterns, ...);
|
||||
static qbool Utils_RegExpMatch(char *regexp, char *term) {return true;}
|
||||
//static qbool Utils_RegExpMatch(char *regexp, char *term) {return true;}
|
||||
#define Utils_RegExpMatch(regexp,term) (true)
|
||||
|
||||
#define clamp(v,min,max) v=bound(min,v,max)
|
||||
#define strlen_color(line) (pDraw_StringWidth(8, 0, line)/8.0)
|
||||
|
|
|
@ -793,12 +793,18 @@ void HUD_Export_f(void)
|
|||
cvar_t *var;
|
||||
int i;
|
||||
|
||||
char *fname = "foo";
|
||||
char *fdesc = "OMG ITS FOO";
|
||||
char fname[64];
|
||||
char fdesc[256];
|
||||
|
||||
pCmd_Argv(1, fname, sizeof(fname));
|
||||
pCmd_Argv(2, fdesc, sizeof(fdesc));
|
||||
|
||||
if (!*fdesc)
|
||||
snprintf(fdesc, sizeof(fdesc), "%s", fname);
|
||||
|
||||
snprintf(line, sizeof(line), "configs/hud_%s.cfg", fname);
|
||||
|
||||
if (pFS_Open(line, &handle, 0) < 0)
|
||||
if (pFS_Open(line, &handle, 2) < 0)
|
||||
Com_Printf("Couldn't open %s\n", line);
|
||||
else
|
||||
{
|
||||
|
@ -1353,7 +1359,7 @@ hud_t * HUD_Register(char *name, char *var_alias, char *description,
|
|||
|
||||
void HUD_ParamsCleanup(void)
|
||||
{
|
||||
int i = 0;
|
||||
// int i = 0;
|
||||
hud_t *hud = hud_huds;
|
||||
|
||||
while (hud)
|
||||
|
|
|
@ -510,10 +510,12 @@ void SCR_HUD_DrawMouserate(hud_t *hud)
|
|||
|
||||
void SCR_HUD_DrawTracking(hud_t *hud)
|
||||
{
|
||||
#ifdef HAXX
|
||||
static char tracked_strings[MV_VIEWS][MAX_TRACKING_STRING];
|
||||
static int tracked[MV_VIEWS] = {-1, -1, -1, -1};
|
||||
int views = 1;
|
||||
int view = 0;
|
||||
#endif
|
||||
int views = 1;
|
||||
int x = 0, y = 0, width = 0, height = 0;
|
||||
char track_string[MAX_TRACKING_STRING];
|
||||
|
||||
|
@ -847,8 +849,9 @@ void SCR_HUD_DrawGameClock(hud_t *hud)
|
|||
*hud_gameclock_style,
|
||||
*hud_gameclock_blink,
|
||||
*hud_gameclock_countdown,
|
||||
*hud_gameclock_scale,
|
||||
*hud_gameclock_offset;
|
||||
*hud_gameclock_scale
|
||||
// *hud_gameclock_offset
|
||||
;
|
||||
|
||||
if (hud_gameclock_big == NULL) // first time
|
||||
{
|
||||
|
@ -857,7 +860,7 @@ void SCR_HUD_DrawGameClock(hud_t *hud)
|
|||
hud_gameclock_blink = HUD_FindVar(hud, "blink");
|
||||
hud_gameclock_countdown = HUD_FindVar(hud, "countdown");
|
||||
hud_gameclock_scale = HUD_FindVar(hud, "scale");
|
||||
hud_gameclock_offset = HUD_FindVar(hud, "offset");
|
||||
// hud_gameclock_offset = HUD_FindVar(hud, "offset");
|
||||
// gameclockoffset = &hud_gameclock_offset->ival;
|
||||
}
|
||||
|
||||
|
@ -1170,7 +1173,7 @@ void SCR_HUD_DrawSpeed2(hud_t *hud)
|
|||
int x, y;
|
||||
|
||||
static cvar_t *hud_speed2_xyz = NULL,
|
||||
*hud_speed2_opacity,
|
||||
// *hud_speed2_opacity,
|
||||
*hud_speed2_color_stopped,
|
||||
*hud_speed2_color_normal,
|
||||
*hud_speed2_color_fast,
|
||||
|
@ -1183,7 +1186,7 @@ void SCR_HUD_DrawSpeed2(hud_t *hud)
|
|||
if (hud_speed2_xyz == NULL) // first time
|
||||
{
|
||||
hud_speed2_xyz = HUD_FindVar(hud, "xyz");
|
||||
hud_speed2_opacity = HUD_FindVar(hud, "opacity");
|
||||
// hud_speed2_opacity = HUD_FindVar(hud, "opacity");
|
||||
hud_speed2_color_stopped = HUD_FindVar(hud, "color_stopped");
|
||||
hud_speed2_color_normal = HUD_FindVar(hud, "color_normal");
|
||||
hud_speed2_color_fast = HUD_FindVar(hud, "color_fast");
|
||||
|
@ -1418,6 +1421,13 @@ void SCR_HUD_DrawSpeed2(hud_t *hud)
|
|||
|
||||
// Draw the speed needle.
|
||||
Draw_AlphaLineRGB (needle_start_x, needle_start_y, needle_end_x, needle_end_y, 1, RGBA_TO_COLOR(250, 250, 250, 255 * hud_speed2_opacity->value));
|
||||
#else
|
||||
(void)color1;
|
||||
(void)color2;
|
||||
(void)needle_start_x;
|
||||
(void)needle_start_y;
|
||||
(void)needle_end_x;
|
||||
(void)needle_end_y;
|
||||
#endif
|
||||
|
||||
// Draw the speed.
|
||||
|
@ -2268,7 +2278,6 @@ void Amf_Reset_DamageStats(void)
|
|||
void Draw_AMFStatLoss (int stat, hud_t* hud) {
|
||||
//fixme: should reset these on pov change
|
||||
int * vxdmgcnt, * vxdmgcnt_t, * vxdmgcnt_o;
|
||||
int x;
|
||||
float alpha;
|
||||
int elem;
|
||||
|
||||
|
@ -2276,13 +2285,11 @@ void Draw_AMFStatLoss (int stat, hud_t* hud) {
|
|||
vxdmgcnt = &vxdamagecount;
|
||||
vxdmgcnt_t = &vxdamagecount_time;
|
||||
vxdmgcnt_o = &vxdamagecount_oldhealth;
|
||||
x = 136;
|
||||
elem = 0;
|
||||
} else {
|
||||
vxdmgcnt = &vxdamagecountarmour;
|
||||
vxdmgcnt_t = &vxdamagecountarmour_time;
|
||||
vxdmgcnt_o = &vxdamagecountarmour_oldhealth;
|
||||
x = 24;
|
||||
elem = 1;
|
||||
}
|
||||
|
||||
|
@ -5102,9 +5109,9 @@ static void SCR_HUD_DrawTeamHoldBar(hud_t *hud)
|
|||
|
||||
void TeamHold_OnChangeItemFilterInfo(cvar_t *var, char *oldvalue)
|
||||
{
|
||||
char *start = var->string;
|
||||
char *end = start;
|
||||
int order = 0;
|
||||
// char *start = var->string;
|
||||
// char *end = start;
|
||||
// int order = 0;
|
||||
|
||||
// Parse the item filter.
|
||||
teamhold_show_rl = Utils_RegExpMatch("RL", var->string);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -55,7 +55,7 @@
|
|||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="../../fteplug_$(ProjectName)x86.dll"
|
||||
OutputFile="../../fteplug_xmpp_x86.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
|
|
|
@ -90,15 +90,6 @@ enum
|
|||
|
||||
#define Q_strncpyz(o, i, l) do {strncpy(o, i, l-1);o[l-1]='\0';}while(0)
|
||||
|
||||
|
||||
#define ARGNAMES ,sock,certhostname
|
||||
BUILTINR(int, Net_SetTLSClient, (qhandle_t sock, const char *certhostname));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,funcname
|
||||
BUILTINR(void *, Plug_GetNativePointer, (const char *funcname));
|
||||
#undef ARGNAMES
|
||||
|
||||
void (*Con_TrySubPrint)(const char *conname, const char *message);
|
||||
void Fallback_ConPrint(const char *conname, const char *message)
|
||||
{
|
||||
|
@ -252,7 +243,6 @@ static VOID (WINAPI *pDnsRecordListFree)(PDNS_RECORD pRecordList, DNS_FREE_TYPE
|
|||
static HMODULE dnsapi_lib;
|
||||
qboolean NET_DNSLookup_SRV(char *host, char *out, int outlen)
|
||||
{
|
||||
HRESULT hr;
|
||||
DNS_RECORD *result = NULL;
|
||||
if (!dnsapi_lib)
|
||||
{
|
||||
|
@ -264,7 +254,7 @@ qboolean NET_DNSLookup_SRV(char *host, char *out, int outlen)
|
|||
if (!pDnsQuery_UTF8 || !pDnsRecordListFree)
|
||||
return false;
|
||||
//do lookup
|
||||
hr = pDnsQuery_UTF8(host, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &result, NULL);
|
||||
pDnsQuery_UTF8(host, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &result, NULL);
|
||||
if (result)
|
||||
{
|
||||
Q_snprintf(out, outlen, "[%s]:%i", result->Data.SRV.pNameTarget, result->Data.SRV.wPort);
|
||||
|
@ -283,10 +273,9 @@ qboolean NET_DNSLookup_SRV(char *host, char *out, int outlen)
|
|||
qbyte answer[512];
|
||||
qbyte dname[512];
|
||||
int len, i;
|
||||
static qboolean inited;
|
||||
qbyte *msg, *eom, *cp;
|
||||
qbyte *msg, *eom;
|
||||
|
||||
len = res_query(host, C_IN, T_SRV, &answer, sizeof(answer));
|
||||
len = res_query(host, C_IN, T_SRV, answer, sizeof(answer));
|
||||
if (len < 12)
|
||||
{
|
||||
Con_Printf("srv lookup failed for %s\n", host);
|
||||
|
@ -569,7 +558,6 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
Plug_Export("Shutdown", JCL_Shutdown) &&
|
||||
Plug_Export("ExecuteCommand", JCL_ExecuteCommand))
|
||||
{
|
||||
CHECKBUILTIN(Net_SetTLSClient);
|
||||
if (!BUILTINISVALID(Net_SetTLSClient))
|
||||
Con_Printf("XMPP Plugin Loaded ^1without^7 TLS\n"); //most servers REQUIRE tls now
|
||||
else
|
||||
|
@ -609,7 +597,6 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
pCvar_Register("xmpp_debug", "0", 0, "xmpp");
|
||||
|
||||
#ifdef JINGLE
|
||||
CHECKBUILTIN(Plug_GetNativePointer);
|
||||
if (BUILTINISVALID(Plug_GetNativePointer))
|
||||
piceapi = pPlug_GetNativePointer(ICE_API_CURRENT);
|
||||
#endif
|
||||
|
@ -1345,7 +1332,7 @@ qintptr_t JCL_ConsoleLinkMouseOver(qintptr_t *args)
|
|||
char which[256];
|
||||
char *actiontext;
|
||||
int i;
|
||||
buddy_t *b, *me;
|
||||
buddy_t *b, *me = NULL;
|
||||
bresource_t *br;
|
||||
float x = *(float*)&args[0];
|
||||
float y = *(float*)&args[1];
|
||||
|
@ -1751,6 +1738,16 @@ qintptr_t JCL_ConExecuteCommand(qintptr_t *args)
|
|||
{
|
||||
case ACT_NONE:
|
||||
break;
|
||||
case ACT_OAUTH:
|
||||
jcl = jclient_action_cl;
|
||||
if (jcl)
|
||||
{
|
||||
free(jcl->oauth2.authtoken);
|
||||
jcl->oauth2.authtoken = strdup(args);
|
||||
if (jcl->status == JCL_INACTIVE)
|
||||
jcl->status = JCL_DEAD;
|
||||
}
|
||||
break;
|
||||
case ACT_NEWACCOUNT:
|
||||
if (!*args)
|
||||
break; //they didn't enter anything! oh well.
|
||||
|
@ -2789,7 +2786,7 @@ static qboolean JCL_BuddyVCardReply(jclient_t *jcl, xmltree_t *tree, struct iq_s
|
|||
const char *nickname;
|
||||
const char *photomime;
|
||||
|
||||
buddy_t *b;
|
||||
buddy_t *b = NULL;
|
||||
char *from = iq->to;
|
||||
|
||||
if (!*from)
|
||||
|
@ -2923,11 +2920,8 @@ static qboolean JCL_MyVCardReply(jclient_t *jcl, xmltree_t *tree, struct iq_s *i
|
|||
}
|
||||
else
|
||||
{
|
||||
char *hex = "0123456789abcdef";
|
||||
int photosize;
|
||||
int digestsize;
|
||||
photosize = Base64_Decode(photodata, sizeof(photodata), photobinval->body, strlen(photobinval->body));
|
||||
digestsize = SHA1(digest, sizeof(digest), photodata, photosize);
|
||||
int photosize = Base64_Decode(photodata, sizeof(photodata), photobinval->body, strlen(photobinval->body));
|
||||
SHA1(digest, sizeof(digest), photodata, photosize);
|
||||
if (jcl->vcardphotohashstatus != VCP_KNOWN || memcmp(jcl->vcardphotohash, digest, sizeof(jcl->vcardphotohash)))
|
||||
{
|
||||
memcpy(jcl->vcardphotohash, digest, sizeof(jcl->vcardphotohash));
|
||||
|
@ -3148,13 +3142,13 @@ char *buildcapsvcardpresence(jclient_t *jcl, char *caps, size_t sizeofcaps)
|
|||
}
|
||||
else if (jcl->vcardphotohashstatus == VCP_KNOWN)
|
||||
{
|
||||
char *hex = "0123456789abcdef";
|
||||
unsigned char *hex = "0123456789abcdef";
|
||||
char inhex[41];
|
||||
int i, o;
|
||||
for (i = 0, o = 0; i < sizeof(jcl->vcardphotohash); i++)
|
||||
{
|
||||
inhex[o++] = hex[jcl->vcardphotohash[(i>>4) & 0xf]];
|
||||
inhex[o++] = hex[jcl->vcardphotohash[(i>>0) & 0xf]];
|
||||
inhex[o++] = hex[(jcl->vcardphotohash[i]>>4) & 0xf];
|
||||
inhex[o++] = hex[(jcl->vcardphotohash[i]>>0) & 0xf];
|
||||
}
|
||||
inhex[o] = 0;
|
||||
|
||||
|
@ -4857,8 +4851,8 @@ static void JCL_RegenerateBuddyList(qboolean force)
|
|||
|
||||
for (c2c = jcl->c2c; c2c; c2c = c2c->next)
|
||||
{
|
||||
buddy_t *peer;
|
||||
qboolean voice = false, video = false, server = false, client = false;
|
||||
buddy_t *peer = NULL;
|
||||
qboolean voice = false, video = false, server = false;
|
||||
int c;
|
||||
JCL_FindBuddy(jcl, c2c->with, &peer, NULL, true);
|
||||
if (peer == b)
|
||||
|
@ -4867,10 +4861,11 @@ static void JCL_RegenerateBuddyList(qboolean force)
|
|||
{
|
||||
switch(c2c->content[c].mediatype)
|
||||
{
|
||||
case ICEP_INVALID: break;
|
||||
case ICEP_VOICE: voice = true; break;
|
||||
case ICEP_VIDEO: video = true; break;
|
||||
case ICEP_QWSERVER: server = true; break;
|
||||
case ICEP_QWCLIENT: client = true; break;
|
||||
case ICEP_QWCLIENT: /*client = true;*/ break;
|
||||
}
|
||||
}
|
||||
if (server)
|
||||
|
@ -4883,7 +4878,7 @@ static void JCL_RegenerateBuddyList(qboolean force)
|
|||
JCL_GenLink(jcl, convolink, sizeof(convolink), "jdeny", c2c->with, NULL, c2c->sid, "%s", "Hang Up");
|
||||
voiceres = NULL;
|
||||
}
|
||||
else
|
||||
else /*if (client)*/
|
||||
{
|
||||
JCL_GenLink(jcl, convolink, sizeof(convolink), "jdeny", c2c->with, NULL, c2c->sid, "%s", "Disconnect");
|
||||
gameres = NULL;
|
||||
|
@ -4979,6 +4974,7 @@ static void JCL_PrintBuddyList(char *console, jclient_t *jcl, qboolean all)
|
|||
{
|
||||
switch(c2c->content[c].mediatype)
|
||||
{
|
||||
case ICEP_INVALID: break;
|
||||
case ICEP_VOICE: voice = true; break;
|
||||
case ICEP_VIDEO: video = true; break;
|
||||
case ICEP_QWSERVER: server = true; break;
|
||||
|
@ -5588,7 +5584,7 @@ void JCL_Command(int accid, char *console)
|
|||
msg = JCL_ParseOut(msg, arg[0], sizeof(arg[0]));
|
||||
msg = JCL_ParseOut(msg, arg[1], sizeof(arg[1]));
|
||||
while(*msg == ' ')
|
||||
*msg++;
|
||||
msg++;
|
||||
|
||||
JCL_SendMessage(jcl, jcl->defaultdest, msg);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
1459
plugins/jabber/xml.c
1459
plugins/jabber/xml.c
File diff suppressed because it is too large
Load diff
1789
plugins/mpq/fs_mpq.c
1789
plugins/mpq/fs_mpq.c
File diff suppressed because it is too large
Load diff
|
@ -62,7 +62,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="zlib.lib"
|
||||
OutputFile="../../fteplug_mpqx86.dll"
|
||||
OutputFile="../../fteplug_mpq_x86.dll"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../..\engine\libs"
|
||||
ModuleDefinitionFile="../plugin.def"
|
||||
|
|
204
plugins/odeplug/odeplug.vcproj
Normal file
204
plugins/odeplug/odeplug.vcproj
Normal file
|
@ -0,0 +1,204 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="odeplug"
|
||||
ProjectGUID="{ED16B405-BDCD-4EB8-BF70-761964301368}"
|
||||
RootNamespace="odeplug"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../engine/server;../../engine/gl;../../engine/qclib;../../engine/client;../../engine/common;."
|
||||
PreprocessorDefinitions="FTEPLUGIN;ODE_STATIC"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
BrowseInformation="1"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ode/ode_doubled.lib"
|
||||
OutputFile="../../fteplug_ode_x86.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
GenerateDebugInformation="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../engine/server;../../engine/gl;../../engine/qclib;../../engine/client;../../engine/common"
|
||||
PreprocessorDefinitions="FTEPLUGIN"
|
||||
CallingConvention="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ode/ode_double.lib"
|
||||
OutputFile="../../fteplug_odex86.dll"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\..\engine\common\com_phys_ode.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\engine\common\mathlib.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\plugin.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\qvm_api.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\plugin.def"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -49,6 +49,10 @@ BUILTINR(int, Plug_ExportToEngine, (const char *funcname, int expnum));
|
|||
#define ARGNAMES ,funcname,func
|
||||
BUILTINR(qboolean, Plug_ExportNative, (const char *funcname, void *func));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,funcname
|
||||
BUILTINR(void *, Plug_GetNativePointer, (const char *funcname));
|
||||
#undef ARGNAMES
|
||||
#endif
|
||||
|
||||
#define ARGNAMES ,text
|
||||
|
@ -159,6 +163,20 @@ BUILTINR(int, GetLastInputFrame, (int seat, usercmd_t *playercmd));
|
|||
BUILTINR(float, GetTrackerOwnFrags, (int seat, char *text, size_t textsize));
|
||||
#undef ARGNAMES
|
||||
|
||||
#ifndef Q3_VM
|
||||
#define ARGNAMES ,vmid
|
||||
BUILTINR(struct pubprogfuncs_s*, PR_GetVMInstance, (int vmid/*0=ss,1=cs,2=m*/));
|
||||
#undef ARGNAMES
|
||||
#ifdef MULTITHREAD
|
||||
#define ARGNAMES ,threadingsize
|
||||
BUILTINR(struct threading_s*, Sys_GetThreadingFuncs, (int threadingsize));
|
||||
#undef ARGNAMES
|
||||
#endif
|
||||
#define ARGNAMES ,version
|
||||
BUILTINR(struct modplugfuncs_s*, Mod_GetPluginModelFuncs, (int version));
|
||||
#undef ARGNAMES
|
||||
#endif
|
||||
|
||||
|
||||
#define ARGNAMES ,pos,buffer,bufferlen
|
||||
BUILTIN(void, GetLocationName, (const float *pos, char *buffer, int bufferlen));
|
||||
|
@ -233,7 +251,7 @@ BUILTIN(void, Draw_Colour4f, (float r, float g, float b, float a));
|
|||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,s
|
||||
BUILTIN(void, SCR_CenterPrint, (char *s));
|
||||
BUILTIN(void, SCR_CenterPrint, (const char *s));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,mnum
|
||||
|
@ -241,16 +259,19 @@ BUILTIN(void, Menu_Control, (int mnum));
|
|||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,keyname
|
||||
BUILTINR(int, Key_GetKeyCode, (char *keyname));
|
||||
BUILTINR(int, Key_GetKeyCode, (const char *keyname));
|
||||
#undef ARGNAMES
|
||||
|
||||
#if !defined(Q3_VM) && defined(FTEPLUGIN)
|
||||
#define ARGNAMES ,name,handle,mode
|
||||
BUILTINR(qboolean, VFS_Open, (char *name, vfsfile_t **handle, char *mode));//opens a direct vfs file. no access checks, and so can be used in threaded plugins
|
||||
BUILTINR(qboolean, VFS_Open, (const char *name, vfsfile_t **handle, const char *mode));//opens a direct vfs file. no access checks, and so can be used in threaded plugins
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,name,relativeto,out,outlen
|
||||
BUILTINR(qboolean, FS_NativePath, (const char *name, enum fs_relative relativeto, char *out, int outlen));
|
||||
#undef ARGNAMES
|
||||
#endif
|
||||
#define ARGNAMES ,name,handle,mode
|
||||
BUILTINR(int, FS_Open, (char *name, qhandle_t *handle, int mode));
|
||||
BUILTINR(int, FS_Open, (const char *name, qhandle_t *handle, int mode));
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,handle
|
||||
BUILTIN(void, FS_Close, (qhandle_t handle));
|
||||
|
@ -264,7 +285,9 @@ BUILTINR(int, FS_Read, (qhandle_t handle, void *data, int len));
|
|||
#define ARGNAMES ,handle,offsetlow,offsethigh
|
||||
BUILTINR(int, FS_Seek, (qhandle_t handle, unsigned int offsetlow, unsigned int offsethigh));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,handle,sizelow,sizehigh
|
||||
BUILTINR(qboolean, FS_GetLen, (qhandle_t handle, unsigned int *sizelow, unsigned int *sizehigh));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,ip,port
|
||||
BUILTINR(qhandle_t, Net_TCPConnect, (char *ip, int port));
|
||||
|
@ -284,6 +307,9 @@ BUILTINR(int, Net_Send, (qhandle_t socket, void *buffer, int len));
|
|||
#define ARGNAMES ,socket
|
||||
BUILTIN(void, Net_Close, (qhandle_t socket));
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,sock,certhostname
|
||||
BUILTINR(int, Net_SetTLSClient, (qhandle_t sock, const char *certhostname));
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,inputbuffer,buffersize
|
||||
BUILTINR(int, ReadInputBuffer, (void *inputbuffer, int buffersize));
|
||||
|
@ -382,6 +408,7 @@ void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(Plug_ExportToEngine);
|
||||
#ifndef Q3_VM
|
||||
CHECKBUILTIN(Plug_ExportNative);
|
||||
CHECKBUILTIN(Plug_GetNativePointer);
|
||||
#endif
|
||||
CHECKBUILTIN(Sys_Error);
|
||||
|
||||
|
@ -422,6 +449,8 @@ void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(FS_Read);
|
||||
CHECKBUILTIN(FS_Write);
|
||||
CHECKBUILTIN(FS_Close);
|
||||
CHECKBUILTIN(FS_Seek);
|
||||
CHECKBUILTIN(FS_GetLen);
|
||||
|
||||
//networking
|
||||
CHECKBUILTIN(Net_TCPConnect);
|
||||
|
@ -430,6 +459,7 @@ void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(Net_Recv);
|
||||
CHECKBUILTIN(Net_Send);
|
||||
CHECKBUILTIN(Net_Close);
|
||||
CHECKBUILTIN(Net_SetTLSClient);
|
||||
|
||||
//random things
|
||||
CHECKBUILTIN(CL_GetStats);
|
||||
|
@ -450,6 +480,10 @@ void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(GetWeaponStats);
|
||||
CHECKBUILTIN(GetNetworkInfo);
|
||||
|
||||
#ifndef Q3_VM
|
||||
CHECKBUILTIN(PR_GetVMInstance);
|
||||
#endif
|
||||
|
||||
//drawing routines
|
||||
CHECKBUILTIN(Draw_LoadImageData);
|
||||
CHECKBUILTIN(Draw_LoadImageShader);
|
||||
|
|
|
@ -74,7 +74,7 @@ void BadBuiltin(void);
|
|||
#include <math.h>
|
||||
|
||||
#ifndef _VM_H
|
||||
#if __STDC_VERSION__ >= 199901L
|
||||
#if __STDC_VERSION__ >= 199901L || defined(__GNUC__)
|
||||
//C99 has a stdint header which hopefully contains an intptr_t
|
||||
//its optional... but if its not in there then its unlikely you'll actually be able to get the engine to a stage where it *can* load anything
|
||||
#include <stdint.h>
|
||||
|
@ -129,7 +129,7 @@ extern "C" {
|
|||
#define BUILTINR(t, n, args) qintptr_t BUILTIN_##n; t n args {qintptr_t res = plugin_syscall(BUILTIN_##n ARGNAMES); return *(t*)&res;}
|
||||
#define BUILTIN(t, n, args) qintptr_t BUILTIN_##n; t n args {plugin_syscall(BUILTIN_##n ARGNAMES);}
|
||||
#endif
|
||||
#define CHECKBUILTIN(n) BUILTIN_##n = (qintptr_t)pPlug_GetEngineFunction(#n);
|
||||
#define CHECKBUILTIN(n) ((BUILTIN_##n = (qintptr_t)pPlug_GetEngineFunction(#n)))
|
||||
#define BUILTINISVALID(n) (BUILTIN_##n != 0)
|
||||
#ifndef QDECL
|
||||
#ifdef _WIN32
|
||||
|
@ -138,7 +138,7 @@ extern "C" {
|
|||
#define QDECL
|
||||
#endif
|
||||
#endif
|
||||
extern qintptr_t (*plugin_syscall)( qintptr_t arg, ... );
|
||||
extern qintptr_t (QDECL *plugin_syscall)( qintptr_t arg, ... );
|
||||
|
||||
void Q_strlcpy(char *d, const char *s, int n);
|
||||
void Q_strlcat(char *d, const char *s, int n);
|
||||
|
@ -181,8 +181,8 @@ typedef struct {
|
|||
int starttime;
|
||||
int userid;
|
||||
int spectator;
|
||||
char userinfo[1024];
|
||||
char team[8];
|
||||
char userinfo[2048];
|
||||
char team[64];
|
||||
} plugclientinfo_t;
|
||||
|
||||
|
||||
|
@ -194,6 +194,7 @@ EBUILTIN(funcptr_t, Plug_GetEngineFunction, (const char *funcname)); //set up in
|
|||
#else
|
||||
#ifndef Q3_VM
|
||||
EBUILTIN(qboolean, Plug_ExportNative, (const char *funcname, void *func)); //set up in vmMain, use this to get all other builtins
|
||||
EBUILTIN(void *, Plug_GetNativePointer, (const char *funcname));
|
||||
#endif
|
||||
EBUILTIN(void, Con_Print, (const char *text)); //on to main console.
|
||||
|
||||
|
@ -240,6 +241,17 @@ EBUILTIN(int, GetLastInputFrame, (int seat, usercmd_t *playercmd));
|
|||
#endif
|
||||
EBUILTIN(float, GetTrackerOwnFrags, (int seat, char *text, size_t textsize));
|
||||
|
||||
#ifndef Q3_VM
|
||||
struct pubprogfuncs_s;
|
||||
EBUILTIN(struct pubprogfuncs_s*, PR_GetVMInstance, (int vmid/*0=ss,1=cs,2=m*/));
|
||||
struct modplugfuncs_s;
|
||||
EBUILTIN(struct modplugfuncs_s*, Mod_GetPluginModelFuncs, (int version));
|
||||
#ifdef MULTITHREAD
|
||||
struct threading_s;
|
||||
EBUILTIN(struct threading_s*, Sys_GetThreadingFuncs, (int threadingsize));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int client;
|
||||
|
@ -299,7 +311,7 @@ EBUILTIN(int, GetNetworkInfo, (vmnetinfo_t *ni, unsigned int sizeofni));
|
|||
EBUILTIN(void, Menu_Control, (int mnum));
|
||||
#define MENU_CLEAR 0
|
||||
#define MENU_GRAB 1
|
||||
EBUILTIN(int, Key_GetKeyCode, (char *keyname));
|
||||
EBUILTIN(int, Key_GetKeyCode, (const char *keyname));
|
||||
|
||||
EBUILTIN(qhandle_t, Draw_LoadImageData, (const char *name, const char *mime, const void *data, unsigned int datasize)); //load/replace a named texture
|
||||
EBUILTIN(qhandle_t, Draw_LoadImageShader, (const char *name, const char *defaultshader)); //loads a shader.
|
||||
|
@ -317,7 +329,7 @@ EBUILTIN(void, Draw_Colourpa, (int palcol, float a));
|
|||
EBUILTIN(void, Draw_Colourp, (int palcol));
|
||||
EBUILTIN(void, Draw_Colour3f, (float r, float g, float b));
|
||||
EBUILTIN(void, Draw_Colour4f, (float r, float g, float b, float a));
|
||||
EBUILTIN(void, SCR_CenterPrint, (char *s));
|
||||
EBUILTIN(void, SCR_CenterPrint, (const char *s));
|
||||
|
||||
EBUILTIN(void, S_RawAudio, (int sourceid, void *data, int speed, int samples, int channels, int width, float volume));
|
||||
|
||||
|
@ -325,13 +337,15 @@ EBUILTIN(int, ReadInputBuffer, (void *inputbuffer, int buffersize));
|
|||
EBUILTIN(int, UpdateInputBuffer, (void *inputbuffer, int bytes));
|
||||
|
||||
#if !defined(Q3_VM) && defined(FTEPLUGIN)
|
||||
EBUILTIN(qboolean, VFS_Open, (char *name, vfsfile_t **handle, char *mode));//opens a direct vfs file. no access checks, and so can be used in threaded plugins
|
||||
EBUILTIN(qboolean, VFS_Open, (const char *name, vfsfile_t **handle, const char *mode));//opens a direct vfs file. no access checks, and so can be used in threaded plugins
|
||||
EBUILTIN(qboolean, FS_NativePath, (const char *name, enum fs_relative relativeto, char *out, int outlen));
|
||||
#endif
|
||||
EBUILTIN(int, FS_Open, (char *name, qhandle_t *handle, int mode));
|
||||
EBUILTIN(int, FS_Open, (const char *name, qhandle_t *handle, int mode));
|
||||
EBUILTIN(void, FS_Close, (qhandle_t handle));
|
||||
EBUILTIN(int, FS_Write, (qhandle_t handle, void *data, int len));
|
||||
EBUILTIN(int, FS_Read, (qhandle_t handle, void *data, int len));
|
||||
EBUILTIN(int, FS_Seek, (qhandle_t handle, unsigned int offsetlow, unsigned int offsethigh));
|
||||
EBUILTIN(qboolean, FS_GetLen, (qhandle_t handle, unsigned int *sizelow, unsigned int *sizehigh));
|
||||
|
||||
EBUILTIN(qhandle_t, Net_TCPConnect, (char *ip, int port));
|
||||
EBUILTIN(qhandle_t, Net_TCPListen, (char *ip, int port, int maxcount));
|
||||
|
@ -339,6 +353,7 @@ EBUILTIN(qhandle_t, Net_Accept, (qhandle_t socket, char *address, int addresssiz
|
|||
EBUILTIN(int, Net_Recv, (qhandle_t socket, void *buffer, int len));
|
||||
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));
|
||||
#define N_WOULDBLOCK 0
|
||||
#define NET_CLIENTPORT -1
|
||||
#define NET_SERVERPORT -2
|
||||
|
@ -415,7 +430,7 @@ extern vmvideo_t pvid;
|
|||
#ifndef MAX_INFO_KEY
|
||||
#define MAX_INFO_KEY 64
|
||||
#endif
|
||||
char *Info_ValueForKey (const char *s, const char *key);
|
||||
char *Plug_Info_ValueForKey (const char *s, const char *key, char *out, size_t outsize);
|
||||
void Info_RemoveKey (char *s, const char *key);
|
||||
void Info_RemovePrefixedKeys (char *start, char prefix);
|
||||
void Info_RemoveNonStarKeys (char *start);
|
||||
|
|
680
plugins/qi/qi.c
Normal file
680
plugins/qi/qi.c
Normal file
|
@ -0,0 +1,680 @@
|
|||
#include "../plugin.h"
|
||||
|
||||
#include "../jabber/xml.h"
|
||||
|
||||
#define DATABASEURL "https://www.quaddicted.com/reviews/quaddicted_database.xml"
|
||||
#define FILEIMAGEURL "https://www.quaddicted.com/reviews/screenshots/%s_injector.jpg"
|
||||
#define FILEDOWNLOADURL "https://www.quaddicted.com/filebase/%s.zip"
|
||||
#define WINDOWTITLE "Quaddicted Map+Mod Archive"
|
||||
#define WINDOWNAME "QI"
|
||||
|
||||
/*
|
||||
<file id="downloadname" type="1=map. 2=mod" rating="5-star-rating">
|
||||
<author>meh</author>
|
||||
<title>some readable name</title>
|
||||
<md5sum>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</md5sum>
|
||||
<size>size-in-kb</size>
|
||||
<date>dd.mm.yy</date>
|
||||
<description>HTML-encoded text. just to be awkward</description>
|
||||
<techinfo>
|
||||
<zipbasedir>additional path needed to make it relative to the quake directory</zipbasedir>
|
||||
<requirements>
|
||||
<file id="quoth" />
|
||||
</requirements>
|
||||
</techinfo>
|
||||
</file>
|
||||
*/
|
||||
|
||||
xmltree_t *thedatabase;
|
||||
qhandle_t dlcontext = -1;
|
||||
|
||||
struct
|
||||
{
|
||||
char namefilter[256];
|
||||
int minrating;
|
||||
int maxrating;
|
||||
int type;
|
||||
} filters;
|
||||
|
||||
void Con_SubPrintf(const char *subname, char *format, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
static char string[8192];
|
||||
|
||||
va_start (argptr, format);
|
||||
Q_vsnprintf (string, sizeof(string), format,argptr);
|
||||
va_end (argptr);
|
||||
|
||||
pCon_SubPrint(subname, string);
|
||||
}
|
||||
|
||||
|
||||
qintptr_t QI_Shutdown(qintptr_t *args)
|
||||
{
|
||||
if (dlcontext != -1)
|
||||
{ //we're still downloading something? :o
|
||||
pFS_Close(dlcontext);
|
||||
dlcontext = -1;
|
||||
}
|
||||
if (thedatabase)
|
||||
XML_Destroy(thedatabase);
|
||||
thedatabase = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
qboolean QI_SetupWindow(const char *console, qboolean force)
|
||||
{
|
||||
if (!BUILTINISVALID(Con_GetConsoleFloat))
|
||||
return false;
|
||||
|
||||
//only redraw the window if it actually exists. if they closed it, then don't mess things up.
|
||||
if (!force && pCon_GetConsoleFloat(console, "iswindow") <= 0)
|
||||
return false;
|
||||
|
||||
if (pCon_GetConsoleFloat(console, "iswindow") != true)
|
||||
{
|
||||
pCon_SetConsoleString(console, "title", WINDOWTITLE);
|
||||
pCon_SetConsoleFloat(console, "iswindow", true);
|
||||
pCon_SetConsoleFloat(console, "forceutf8", true);
|
||||
pCon_SetConsoleFloat(console, "linebuffered", false);
|
||||
pCon_SetConsoleFloat(console, "maxlines", 16384); //the line limit is more a sanity thing than anything else. so long as we explicitly clear before spamming more, then its not an issue...
|
||||
pCon_SetConsoleFloat(console, "wnd_x", 8);
|
||||
pCon_SetConsoleFloat(console, "wnd_y", 8);
|
||||
pCon_SetConsoleFloat(console, "wnd_w", pvid.width-16);
|
||||
pCon_SetConsoleFloat(console, "wnd_h", pvid.height-16);
|
||||
pCon_SetConsoleString(console, "footer", "");
|
||||
}
|
||||
pCon_SetConsoleFloat(console, "linecount", 0); //clear it
|
||||
if (force)
|
||||
pCon_SetActive(console);
|
||||
return true;
|
||||
}
|
||||
void QI_DeHTML(const char *in, char *out, size_t outsize)
|
||||
{
|
||||
outsize--;
|
||||
while(*in && outsize > 0)
|
||||
{
|
||||
if (*in == '\r' || *in == '\n')
|
||||
in++;
|
||||
else if (*in == '<')
|
||||
{
|
||||
char tag[256];
|
||||
int i;
|
||||
qboolean open = false;
|
||||
qboolean close = false;
|
||||
in++;
|
||||
if (*in == '/')
|
||||
{
|
||||
in++;
|
||||
close = true;
|
||||
}
|
||||
else
|
||||
open = true;
|
||||
while (*in == ' ' || *in == '\n' || *in == '\t' || *in == '\r')
|
||||
in++;
|
||||
for (i = 0; i < countof(tag)-1; )
|
||||
{
|
||||
if (*in == '>')
|
||||
break;
|
||||
if (!*in || *in == ' ' || *in == '\n' || *in == '\t' || *in == '\r' || (in[0] == '/' && in[1] == '>'))
|
||||
break;
|
||||
tag[i++] = *in++;
|
||||
}
|
||||
tag[i] = 0;
|
||||
while (*in && *in)
|
||||
{
|
||||
if (*in == '/' && in[1] == '>')
|
||||
{
|
||||
in += 2;
|
||||
close = true;
|
||||
break;
|
||||
}
|
||||
if (*in++ == '>')
|
||||
break;
|
||||
}
|
||||
if (!strcmp(tag, "br") && open && outsize > 0)
|
||||
{ //new lines!
|
||||
*out++ = '\n';
|
||||
outsize--;
|
||||
}
|
||||
else if (!strcmp(tag, "b") && open != close && outsize > 1)
|
||||
{ //bold
|
||||
*out++ = '^';
|
||||
outsize--;
|
||||
*out++ = 'a';
|
||||
outsize--;
|
||||
}
|
||||
else if (!strcmp(tag, "i") && open != close && outsize > 1)
|
||||
{ //italics
|
||||
*out++ = '^';
|
||||
outsize--;
|
||||
*out++ = 'b';
|
||||
outsize--;
|
||||
}
|
||||
}
|
||||
else if (*in == '^')
|
||||
{
|
||||
if (outsize > 1)
|
||||
{
|
||||
*out++ = *in;
|
||||
outsize--;
|
||||
*out++ = *in++;
|
||||
outsize--;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*out++ = *in++;
|
||||
outsize--;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
}
|
||||
|
||||
static char *QI_strcasestr(const char *haystack, const char *needle)
|
||||
{
|
||||
int c1, c2, c2f;
|
||||
int i;
|
||||
c2f = *needle;
|
||||
if (c2f >= 'a' && c2f <= 'z')
|
||||
c2f -= ('a' - 'A');
|
||||
if (!c2f)
|
||||
return (char*)haystack;
|
||||
while (1)
|
||||
{
|
||||
c1 = *haystack;
|
||||
if (!c1)
|
||||
return NULL;
|
||||
if (c1 >= 'a' && c1 <= 'z')
|
||||
c1 -= ('a' - 'A');
|
||||
if (c1 == c2f)
|
||||
{
|
||||
for (i = 1; ; i++)
|
||||
{
|
||||
c1 = haystack[i];
|
||||
c2 = needle[i];
|
||||
if (c1 >= 'a' && c1 <= 'z')
|
||||
c1 -= ('a' - 'A');
|
||||
if (c2 >= 'a' && c2 <= 'z')
|
||||
c2 -= ('a' - 'A');
|
||||
if (!c2)
|
||||
return (char*)haystack; //end of needle means we found a complete match
|
||||
if (!c1) //end of haystack means we can't possibly find needle in it any more
|
||||
return NULL;
|
||||
if (c1 != c2) //mismatch means no match starting at haystack[0]
|
||||
break;
|
||||
}
|
||||
}
|
||||
haystack++;
|
||||
}
|
||||
return NULL; //didn't find it
|
||||
}
|
||||
|
||||
void QI_RefreshMapList(qboolean forcedisplay)
|
||||
{
|
||||
xmltree_t *file;
|
||||
const char *console = WINDOWNAME;
|
||||
char descbuf[1024];
|
||||
if (!QI_SetupWindow(console, forcedisplay))
|
||||
return;
|
||||
|
||||
if (!thedatabase)
|
||||
{
|
||||
if (dlcontext != -1)
|
||||
Con_SubPrintf(console, "Downloading database...\n");
|
||||
else
|
||||
Con_SubPrintf(console, "Unable to download HTTP database\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!thedatabase->child)
|
||||
{
|
||||
Con_SubPrintf(console, "No maps in database... SPIRIT! YOU BROKE IT!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (file = thedatabase->child; file; file = file->sibling)
|
||||
{
|
||||
char *id = XML_GetParameter(file, "id", "unnamed");
|
||||
char *rating = XML_GetParameter(file, "rating", "");
|
||||
int ratingnum = atoi(rating);
|
||||
char *author = XML_GetChildBody(file, "author", "unknown");
|
||||
char *desc = XML_GetChildBody(file, "description", "<NO DESCRIPTION>");
|
||||
char *type;
|
||||
char *date;
|
||||
int year, month, day;
|
||||
int startmapnum, i;
|
||||
char ratingtext[65];
|
||||
xmltree_t *tech;
|
||||
xmltree_t *startmap;
|
||||
if (strcmp(file->name, "file"))
|
||||
continue; //erk?
|
||||
if (atoi(XML_GetParameter(file, "hide", "")) || atoi(XML_GetParameter(file, "fte_hide", "")))
|
||||
continue;
|
||||
type = XML_GetParameter(file, "type", "");
|
||||
if (filters.type && atoi(type) != filters.type)
|
||||
continue;
|
||||
switch(atoi(type))
|
||||
{
|
||||
case 1:
|
||||
type = "map";
|
||||
break;
|
||||
case 2:
|
||||
type = "mod";
|
||||
break;
|
||||
case 5:
|
||||
type = "otr";
|
||||
break;
|
||||
default:
|
||||
type = "???";
|
||||
break;
|
||||
}
|
||||
|
||||
if (filters.maxrating>=0 && ratingnum > filters.maxrating)
|
||||
continue;
|
||||
if (filters.minrating>=0 && ratingnum < filters.minrating)
|
||||
continue;
|
||||
|
||||
tech = XML_ChildOfTree(file, "techinfo", 0);
|
||||
//if the filter isn't contained in the id/desc then don't display it.
|
||||
if (filters.namefilter)
|
||||
{
|
||||
if (!QI_strcasestr(id, filters.namefilter) && !QI_strcasestr(desc, filters.namefilter) && !QI_strcasestr(author, filters.namefilter))
|
||||
{
|
||||
//check map list too
|
||||
for (startmapnum = 0; ; startmapnum++)
|
||||
{
|
||||
startmap = XML_ChildOfTree(tech, "startmap", startmapnum);
|
||||
if (!startmap)
|
||||
break;
|
||||
if (QI_strcasestr(startmap->body, filters.namefilter))
|
||||
break;
|
||||
}
|
||||
if (!startmap)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ratingnum > (sizeof(ratingtext)-5)/6)
|
||||
ratingnum = (sizeof(ratingtext)-5)/6;
|
||||
if (ratingnum)
|
||||
{
|
||||
Q_snprintf(ratingtext, sizeof(ratingtext), "^a");
|
||||
for (i = 0; i < ratingnum; i++)
|
||||
Q_snprintf(ratingtext + i+2, sizeof(ratingtext)-i*2+2, "*");
|
||||
Q_snprintf(ratingtext + i+2, sizeof(ratingtext)-i*2+2, "^a");
|
||||
}
|
||||
else if (*rating)
|
||||
Q_snprintf(ratingtext, sizeof(ratingtext), "%s", rating);
|
||||
else
|
||||
Q_snprintf(ratingtext, sizeof(ratingtext), "%s", "unrated");
|
||||
|
||||
|
||||
date = XML_GetChildBody(file, "date", "1.1.1990");
|
||||
day = atoi(date?date:"1");
|
||||
date = date?strchr(date, '.'):NULL;
|
||||
month = atoi(date?date+1:"1");
|
||||
date = date?strchr(date, '.'):NULL;
|
||||
year = atoi(date?date+1:"1990");
|
||||
if (year < 90)
|
||||
year += 2000;
|
||||
else if (year < 1900)
|
||||
year += 1900;
|
||||
Q_snprintf(descbuf, sizeof(descbuf), "Id: %s\nAuthor: %s\nDate: %04u-%02u-%02u\nRating: %s\n\n", id, author, year, month, day, ratingtext);
|
||||
|
||||
QI_DeHTML(desc, descbuf + strlen(descbuf), sizeof(descbuf) - strlen(descbuf));
|
||||
desc = descbuf;
|
||||
|
||||
for (startmapnum = 0; ; startmapnum++)
|
||||
{
|
||||
startmap = XML_ChildOfTree(tech, "startmap", startmapnum);
|
||||
if (!startmap)
|
||||
break;
|
||||
Con_SubPrintf(console, "%s ^[%s (%s)\\tip\\%s\\tipimg\\"FILEIMAGEURL"\\id\\%s\\startmap\\%s^]\n", type, XML_GetChildBody(file, "title", "<NO TITLE>"), startmap->body, desc, id, id, startmap->body);
|
||||
}
|
||||
if (!startmapnum)
|
||||
Con_SubPrintf(console, "%s ^[%s\\tip\\%s\\tipimg\\"FILEIMAGEURL"\\id\\%s^]\n", type, XML_GetChildBody(file, "title", "<NO TITLE>"), desc, id, id);
|
||||
}
|
||||
|
||||
Con_SubPrintf(console, "\nFilter:\n");
|
||||
if (*filters.namefilter)
|
||||
Con_SubPrintf(console, "Contains: %s ", filters.namefilter);
|
||||
Con_SubPrintf(console, "^[Change Filter^]\n");
|
||||
Con_SubPrintf(console, "^[Maps^] %s\n", (filters.type!=2)?"shown":"hidden");
|
||||
Con_SubPrintf(console, "^[Mods^] %s\n", (filters.type!=1)?"shown":"hidden");
|
||||
if (filters.minrating == filters.maxrating)
|
||||
{
|
||||
char *gah[] = {"Any Rating", "Unrated", "1","2","3","4","5"};
|
||||
int i;
|
||||
Con_SubPrintf(console, "Rating");
|
||||
for (i = 0; i < countof(gah); i++)
|
||||
{
|
||||
if (i == filters.minrating+1)
|
||||
Con_SubPrintf(console, " %s", gah[i]);
|
||||
else
|
||||
Con_SubPrintf(console, " ^[%s^]", gah[i]);
|
||||
}
|
||||
Con_SubPrintf(console, "\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filters.minrating)
|
||||
Con_SubPrintf(console, "Min Rating: %i stars\n", filters.minrating);
|
||||
if (filters.maxrating)
|
||||
Con_SubPrintf(console, "Max Rating: %i stars\n", filters.maxrating);
|
||||
}
|
||||
}
|
||||
|
||||
static void QI_UpdateFilter(char *filtertext)
|
||||
{
|
||||
if (!strcmp(filtertext, "all"))
|
||||
{
|
||||
filters.type = 0;
|
||||
filters.minrating = filters.maxrating = -1;
|
||||
Q_strlcpy(filters.namefilter, "", sizeof(filters.namefilter));
|
||||
}
|
||||
else if (*filtertext == '>')
|
||||
filters.minrating = atoi(filtertext+1);
|
||||
else if (*filtertext == '<')
|
||||
filters.maxrating = atoi(filtertext+1);
|
||||
else if (*filtertext == '=')
|
||||
filters.minrating = filters.maxrating = atoi(filtertext+1);
|
||||
else if (!strcmp(filtertext, "any"))
|
||||
{
|
||||
filters.type = 0;
|
||||
filters.minrating = filters.maxrating = -1;
|
||||
}
|
||||
else if (!strcmp(filtertext, "maps"))
|
||||
filters.type = 1;
|
||||
else if (!strcmp(filtertext, "mods"))
|
||||
filters.type = 2;
|
||||
else
|
||||
Q_strlcpy(filters.namefilter, filtertext, sizeof(filters.namefilter));
|
||||
}
|
||||
|
||||
static xmltree_t *QI_FindArchive(const char *name)
|
||||
{
|
||||
xmltree_t *file;
|
||||
for (file = thedatabase->child; file; file = file->sibling)
|
||||
{
|
||||
char *id = XML_GetParameter(file, "id", "unnamed");
|
||||
if (strcmp(file->name, "file"))
|
||||
continue; //erk?
|
||||
|
||||
if (!strcmp(id, name))
|
||||
return file;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static void QI_AddPackages(xmltree_t *qifile)
|
||||
{
|
||||
char *id;
|
||||
char extra[1024];
|
||||
char clean[512];
|
||||
unsigned int i;
|
||||
|
||||
xmltree_t *tech;
|
||||
const char *basedir;
|
||||
xmltree_t *requires;
|
||||
xmltree_t *req;
|
||||
//quaddicted's database contains various zips that are meant to be extracted to various places.
|
||||
//this can either be the quake root (no path), a mod directory (typically the name of the mod), or the maps directory (id1/maps or some such)
|
||||
//unfortunately, quake files are relative to the subdir, so we need to strip the first subdir. anyone that tries to put dlls in there is evil. and if there isn't one, we need to get the engine to compensate.
|
||||
//we also need to clean up the paths so they're not badly formed
|
||||
tech = XML_ChildOfTree(qifile, "techinfo", 0);
|
||||
basedir = XML_GetChildBody(tech, "zipbasedir", "");
|
||||
|
||||
//skip any dodgy leading slashes
|
||||
while (*basedir == '/' || *basedir == '\\')
|
||||
basedir++;
|
||||
if (!*basedir)
|
||||
strcpy(clean, ".."); //err, there wasn't a directory... we still need to 'strip' it though.
|
||||
else
|
||||
{
|
||||
//skip the gamedir
|
||||
while (*basedir && *basedir != '/' && *basedir != '\\')
|
||||
basedir++;
|
||||
//skip any trailing
|
||||
while (*basedir == '/' || *basedir == '\\')
|
||||
basedir++;
|
||||
for (i = 0; *basedir; i++)
|
||||
{
|
||||
if (i >= sizeof(clean)-1)
|
||||
break;
|
||||
if (*basedir == '\\') //sigh
|
||||
clean[i] = '/';
|
||||
else
|
||||
clean[i] = *basedir;
|
||||
basedir++;
|
||||
}
|
||||
while (i > 0 && clean[i-1] == '/')
|
||||
i--;
|
||||
clean[i] = 0;
|
||||
}
|
||||
|
||||
requires = XML_ChildOfTree(tech, "requirements", 0);
|
||||
if (requires)
|
||||
{
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
req = XML_ChildOfTree(requires, "file", i);
|
||||
if (!req)
|
||||
break;
|
||||
id = XML_GetParameter(req, "id", "unknown");
|
||||
QI_AddPackages(QI_FindArchive(id));
|
||||
}
|
||||
}
|
||||
|
||||
id = XML_GetParameter(qifile, "id", "unknown");
|
||||
if (strchr(clean, '\\') || strchr(clean, '\"') || strchr(clean, '\n') || strchr(clean, ';'))
|
||||
return;
|
||||
if (strchr(id, '\\') || strchr(id, '\"') || strchr(id, '\n') || strchr(id, ';'))
|
||||
return;
|
||||
|
||||
|
||||
Q_snprintf(extra, sizeof(extra), " package \""FILEDOWNLOADURL"\" prefix \"%s\"", id, clean);
|
||||
pCmd_AddText(extra, false);
|
||||
}
|
||||
static void QI_RunMap(xmltree_t *qifile, const char *map)
|
||||
{
|
||||
if (!qifile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//type 1 (maps) often don't list any map names
|
||||
if (!*map)// && atoi(XML_GetParameter(qifile, "type", "0")) == 1)
|
||||
map = XML_GetParameter(qifile, "id", "unknown");
|
||||
if (!*map || strchr(map, '\\') || strchr(map, '\"') || strchr(map, '\n') || strchr(map, ';'))
|
||||
map = "";
|
||||
|
||||
|
||||
pCmd_AddText("fs_changemod map \"", false);
|
||||
pCmd_AddText(map, false);
|
||||
pCmd_AddText("\"", false);
|
||||
QI_AddPackages(qifile);
|
||||
// Con_Printf("Command: %s\n", cmd);
|
||||
pCmd_AddText("\n", false);
|
||||
}
|
||||
|
||||
qintptr_t QI_ConsoleLink(qintptr_t *args)
|
||||
{
|
||||
xmltree_t *file;
|
||||
char *map;
|
||||
char *id;
|
||||
char *e;
|
||||
char text[2048];
|
||||
char link[8192];
|
||||
pCmd_Argv(0, text, sizeof(text));
|
||||
pCmd_Argv(1, link, sizeof(link));
|
||||
|
||||
if (!strcmp(text, "Change Filter") && !*link)
|
||||
{
|
||||
const char *console = WINDOWNAME;
|
||||
pCon_SetConsoleFloat(console, "linebuffered", true);
|
||||
pCon_SetConsoleString(console, "footer", "Please enter filter:");
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(text, "Maps") && !*link)
|
||||
{
|
||||
filters.type = (filters.type==2)?0:2;
|
||||
QI_RefreshMapList(true);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(text, "Mods") && !*link)
|
||||
{
|
||||
filters.type = (filters.type==1)?0:1;
|
||||
QI_RefreshMapList(true);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(text, "Any Rating") && !*link)
|
||||
{
|
||||
filters.minrating = filters.maxrating = -1;
|
||||
QI_RefreshMapList(true);
|
||||
return true;
|
||||
}
|
||||
if ((atoi(text) || !strcmp(text, "Unrated")) && !*link)
|
||||
{
|
||||
filters.minrating = filters.maxrating = atoi(text);
|
||||
QI_RefreshMapList(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
id = strstr(link, "\\id\\");
|
||||
map = strstr(link, "\\startmap\\");
|
||||
if (id)
|
||||
{
|
||||
id+=4;
|
||||
e = strchr(id, '\\');
|
||||
if (e)
|
||||
*e = 0;
|
||||
if (map)
|
||||
{
|
||||
map += 10;
|
||||
e = strchr(map, '\\');
|
||||
if (e)
|
||||
*e = 0;
|
||||
}
|
||||
else
|
||||
map = "";
|
||||
|
||||
file = QI_FindArchive(id);
|
||||
if (!file)
|
||||
{
|
||||
Con_Printf("Unknown file \"%s\"\n", id);
|
||||
return true;
|
||||
}
|
||||
QI_RunMap(file, map);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
qintptr_t QI_Tick(qintptr_t *args)
|
||||
{
|
||||
if (dlcontext != -1)
|
||||
{
|
||||
unsigned int flen;
|
||||
if (pFS_GetLen(dlcontext, &flen, NULL))
|
||||
{
|
||||
int ofs = 0;
|
||||
char *file;
|
||||
qboolean archive = true;
|
||||
if (flen == 0)
|
||||
{
|
||||
pFS_Close(dlcontext);
|
||||
flen = pFS_Open("**plugconfig", &dlcontext, 1);
|
||||
if (dlcontext == -1)
|
||||
{
|
||||
QI_RefreshMapList(false);
|
||||
return false;
|
||||
}
|
||||
archive = false;
|
||||
}
|
||||
file = malloc(flen+1);
|
||||
file[flen] = 0;
|
||||
pFS_Read(dlcontext, file, flen);
|
||||
pFS_Close(dlcontext);
|
||||
if (archive)
|
||||
{
|
||||
pFS_Open("**plugconfig", &dlcontext, 2);
|
||||
if (dlcontext != -1)
|
||||
{
|
||||
pFS_Write(dlcontext, file, flen);
|
||||
pFS_Close(dlcontext);
|
||||
}
|
||||
}
|
||||
dlcontext = -1;
|
||||
do
|
||||
{
|
||||
if (thedatabase)
|
||||
XML_Destroy(thedatabase);
|
||||
thedatabase = XML_Parse(file, &ofs, flen, false, "");
|
||||
} while(thedatabase && !thedatabase->child);
|
||||
free(file);
|
||||
|
||||
QI_RefreshMapList(false);
|
||||
|
||||
// XML_ConPrintTree(thedatabase, "quadicted_xml", 0);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
qintptr_t QI_ConExecuteCommand(qintptr_t *args)
|
||||
{
|
||||
char console[256];
|
||||
char filter[256];
|
||||
pCmd_Argv(0, console, sizeof(console));
|
||||
pCmd_Args(filter, sizeof(filter));
|
||||
QI_UpdateFilter(filter);
|
||||
|
||||
QI_RefreshMapList(true);
|
||||
pCon_SetConsoleFloat(console, "linebuffered", false);
|
||||
pCon_SetConsoleString(console, "footer", "");
|
||||
return true;
|
||||
}
|
||||
|
||||
qintptr_t QI_ExecuteCommand(qintptr_t *args)
|
||||
{
|
||||
char cmd[256];
|
||||
pCmd_Argv(0, cmd, sizeof(cmd));
|
||||
if (!strcmp(cmd, "qi") || !strcmp(cmd, "quaddicted"))
|
||||
{
|
||||
if (pCmd_Argc() > 1)
|
||||
{
|
||||
pCmd_Args(cmd, sizeof(cmd));
|
||||
QI_UpdateFilter(cmd);
|
||||
}
|
||||
else if (QI_SetupWindow(WINDOWNAME, false))
|
||||
{
|
||||
pCon_SetActive(WINDOWNAME);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!thedatabase && dlcontext == -1)
|
||||
pFS_Open(DATABASEURL, &dlcontext, 1);
|
||||
|
||||
QI_RefreshMapList(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
extern void (*Con_TrySubPrint)(const char *conname, const char *message);
|
||||
qintptr_t Plug_Init(qintptr_t *args)
|
||||
{
|
||||
filters.minrating = filters.maxrating = -1;
|
||||
Con_TrySubPrint = pCon_SubPrint;
|
||||
if (Plug_Export("Tick", QI_Tick) &&
|
||||
Plug_Export("Shutdown", QI_Shutdown) &&
|
||||
Plug_Export("ExecuteCommand", QI_ExecuteCommand) &&
|
||||
Plug_Export("ConExecuteCommand", QI_ConExecuteCommand) &&
|
||||
Plug_Export("ConsoleLink", QI_ConsoleLink))
|
||||
{
|
||||
pCmd_AddCommand("qi");
|
||||
pCmd_AddCommand("quaddicted");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
362
plugins/qi/qi.vcproj
Normal file
362
plugins/qi/qi.vcproj
Normal file
|
@ -0,0 +1,362 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="qi"
|
||||
ProjectGUID="{909E9AE0-0617-469C-954E-1ED09367F90E}"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
<Platform
|
||||
Name="x64"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../engine/server;../../engine/gl;../../engine/qclib;../../engine/client;../../engine/common"
|
||||
PreprocessorDefinitions="FTEPLUGIN"
|
||||
EnableFunctionLevelLinking="true"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="../../fteplug_$(ProjectName)_x86.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
GenerateDebugInformation="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../engine/server;../../engine/gl;../../engine/qclib;../../engine/client;../../engine/common"
|
||||
PreprocessorDefinitions="FTEPLUGIN"
|
||||
EnableFunctionLevelLinking="true"
|
||||
BrowseInformation="1"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="../../fteplug_$(ProjectName)x86.dll"
|
||||
LinkIncremental="2"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
GenerateDebugInformation="true"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
EmbedManifest="false"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../engine/server;../../engine/gl;../../engine/qclib;../../engine/client;../../engine/common"
|
||||
PreprocessorDefinitions="FTEPLUGIN"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="../../fteplug_$(ProjectName)x86.dll"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|x64"
|
||||
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
|
||||
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
TargetEnvironment="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../engine/server;../../engine/gl;../../engine/qclib;../../engine/client;../../engine/common"
|
||||
PreprocessorDefinitions="FTEPLUGIN"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="../../fteplug_$(ProjectName)_x64.dll"
|
||||
GenerateManifest="false"
|
||||
ModuleDefinitionFile="..\plugin.def"
|
||||
TargetMachine="17"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\emailnot\md5.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\plugin.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\qi.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\qvm_api.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\jabber\xml.c"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\plugin.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\jabber\xml.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\plugin.def"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
|
@ -105,6 +105,10 @@ retry:
|
|||
*buffer++ = _int;
|
||||
tokens++;
|
||||
break;
|
||||
case 'p':
|
||||
if (1)
|
||||
_uint = (size_t)va_arg(vargs, void*);
|
||||
else
|
||||
case 'x':
|
||||
_uint = va_arg(vargs, unsigned int);
|
||||
i = sizeof(tempbuffer)-2;
|
||||
|
@ -590,3 +594,50 @@ void Q_strlcat(char *d, const char *s, int n)
|
|||
d[n - 1] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
char *Plug_Info_ValueForKey (const char *s, const char *key, char *out, size_t outsize)
|
||||
{
|
||||
int isvalue = 0;
|
||||
const char *start;
|
||||
char *oout = out;
|
||||
*out = 0;
|
||||
if (*s != '\\')
|
||||
return out; //gah, get lost with your corrupt infostrings.
|
||||
|
||||
start = ++s;
|
||||
while(1)
|
||||
{
|
||||
while(s[0] == '\\' && s[1] == '\\')
|
||||
s+=2;
|
||||
if (s[0] != '\\' && *s)
|
||||
{
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
|
||||
//okay, it terminates here
|
||||
isvalue = !isvalue;
|
||||
if (isvalue)
|
||||
{
|
||||
if (strlen(key) == s - start && !strncmp(start, key, s - start))
|
||||
{
|
||||
s++;
|
||||
while (outsize --> 1)
|
||||
{
|
||||
if (s[0] == '\\' && s[1] == '\\')
|
||||
s++;
|
||||
else if (s[0] == '\\' || !s[0])
|
||||
break;
|
||||
*out++ = *s++;
|
||||
}
|
||||
*out++ = 0;
|
||||
return oout;
|
||||
}
|
||||
}
|
||||
if (*s)
|
||||
start = ++s;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return oout;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
int mousecursor_x, mousecursor_y;
|
||||
|
||||
static xclient_t *xclients;
|
||||
static qhandle_t xlistensocket=NULL;
|
||||
static qhandle_t xlistensocket;
|
||||
|
||||
xwindow_t *xfocusedwindow;
|
||||
|
||||
|
@ -479,7 +479,7 @@ qboolean XWindows_TendToClient(xclient_t *cl) //true says drop
|
|||
}
|
||||
len = cl->inbuffermaxlen - cl->inbufferlen;
|
||||
//Con_Printf("recving\n");
|
||||
len = Net_Recv(cl->socket, cl->inbuffer + cl->inbufferlen, len);
|
||||
len = pNet_Recv(cl->socket, cl->inbuffer + cl->inbufferlen, len);
|
||||
//Con_Printf("recved %i\n", len);
|
||||
if (len == 0) //connection was closed. bummer.
|
||||
{
|
||||
|
@ -632,7 +632,7 @@ nextmessage:
|
|||
len = cl->outbufferlen;
|
||||
if (len > 8000)
|
||||
len = 8000;
|
||||
len = Net_Send(cl->socket, cl->outbuffer, len);
|
||||
len = pNet_Send(cl->socket, cl->outbuffer, len);
|
||||
if (len>0)
|
||||
{
|
||||
memmove(cl->outbuffer, cl->outbuffer+len, cl->outbufferlen - len);
|
||||
|
@ -768,9 +768,9 @@ void XWindows_TendToClients(void)
|
|||
unsigned int _false = 0;
|
||||
#endif
|
||||
|
||||
if (xlistensocket != NULL)
|
||||
if (xlistensocket)
|
||||
{
|
||||
newclient = Net_Accept(xlistensocket, NULL, 0);
|
||||
newclient = pNet_Accept(xlistensocket, NULL, 0);
|
||||
if ((int)newclient != -1)
|
||||
{
|
||||
cl = malloc(sizeof(xclient_t));
|
||||
|
@ -816,7 +816,7 @@ void XWindows_TendToClients(void)
|
|||
break;
|
||||
}
|
||||
#endif
|
||||
Net_Close(cl->socket);
|
||||
pNet_Close(cl->socket);
|
||||
if (cl->inbuffer)
|
||||
free(cl->inbuffer);
|
||||
if (cl->outbuffer)
|
||||
|
@ -835,15 +835,15 @@ void XWindows_Startup(void) //initialise the server socket and do any initial se
|
|||
|
||||
int port = 6000;
|
||||
|
||||
Cmd_Argv(1, buffer, sizeof(buffer));
|
||||
pCmd_Argv(1, buffer, sizeof(buffer));
|
||||
port += atoi(buffer);
|
||||
|
||||
if (xlistensocket == NULL)
|
||||
if (!xlistensocket)
|
||||
{
|
||||
xlistensocket = Net_TCPListen(NULL, port, 3);
|
||||
if ((int)xlistensocket < 0)
|
||||
xlistensocket = pNet_TCPListen(NULL, port, 3);
|
||||
if (xlistensocket < 0)
|
||||
{
|
||||
xlistensocket = NULL;
|
||||
xlistensocket = 0;
|
||||
Con_Printf("Failed to create tcp listen socket\n");
|
||||
return;
|
||||
}
|
||||
|
@ -1055,7 +1055,7 @@ 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 = Sys_Milliseconds();
|
||||
unsigned int curtime = pSys_Milliseconds();
|
||||
|
||||
|
||||
if (!nw)
|
||||
|
@ -1101,7 +1101,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
//LeaveNotify with detail Inferior is generated on A.
|
||||
ev.u.u.type = LeaveNotify;
|
||||
ev.u.u.detail = NotifyInferior;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = oc[0]->res.id;
|
||||
ev.u.enterLeave.child = None;
|
||||
|
@ -1119,7 +1119,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
{
|
||||
ev.u.u.type = EnterNotify;
|
||||
ev.u.u.detail = NotifyVirtual;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = oc[i]->res.id;
|
||||
ev.u.enterLeave.child = oc[i-1]->res.id;
|
||||
|
@ -1136,7 +1136,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
//EnterNotify with detail Ancestor is generated on B.
|
||||
ev.u.u.type = EnterNotify;
|
||||
ev.u.u.detail = NotifyInferior;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = nc[0]->res.id;
|
||||
ev.u.enterLeave.child = None;
|
||||
|
@ -1155,7 +1155,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
//LeaveNotify with detail Ancestor is generated on A.
|
||||
ev.u.u.type = LeaveNotify;
|
||||
ev.u.u.detail = NotifyAncestor;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = oc[0]->res.id;
|
||||
ev.u.enterLeave.child = None;
|
||||
|
@ -1173,7 +1173,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
{
|
||||
ev.u.u.type = LeaveNotify;
|
||||
ev.u.u.detail = NotifyVirtual;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = nc[i]->res.id;
|
||||
ev.u.enterLeave.child = nc[i-1]->res.id;
|
||||
|
@ -1190,7 +1190,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
//EnterNotify with detail Inferior is generated on B.
|
||||
ev.u.u.type = EnterNotify;
|
||||
ev.u.u.detail = NotifyInferior;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = nc[0]->res.id;
|
||||
ev.u.enterLeave.child = None;
|
||||
|
@ -1210,7 +1210,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
//LeaveNotify with detail Nonlinear is generated on A.
|
||||
ev.u.u.type = LeaveNotify;
|
||||
ev.u.u.detail = NotifyNonlinear;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = oc[0]->res.id;
|
||||
ev.u.enterLeave.child = None;
|
||||
|
@ -1228,7 +1228,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
{
|
||||
ev.u.u.type = LeaveNotify;
|
||||
ev.u.u.detail = NotifyNonlinearVirtual;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = nc[i]->res.id;
|
||||
ev.u.enterLeave.child = nc[i-1]->res.id;
|
||||
|
@ -1246,7 +1246,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
{
|
||||
ev.u.u.type = EnterNotify;
|
||||
ev.u.u.detail = NotifyNonlinearVirtual;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = oc[i]->res.id;
|
||||
ev.u.enterLeave.child = oc[i-1]->res.id;
|
||||
|
@ -1263,7 +1263,7 @@ void X_MoveCursorWindow(xwindow_t *ew, int mx, int my, int movemode)
|
|||
//EnterNotify with detail Nonlinear is generated on B.
|
||||
ev.u.u.type = EnterNotify;
|
||||
ev.u.u.detail = NotifyNonlinear;
|
||||
ev.u.enterLeave.time = Sys_Milliseconds();
|
||||
ev.u.enterLeave.time = pSys_Milliseconds();
|
||||
ev.u.enterLeave.root = rootwindow->res.id;
|
||||
ev.u.enterLeave.event = nc[0]->res.id;
|
||||
ev.u.enterLeave.child = None;
|
||||
|
@ -1394,7 +1394,7 @@ void X_EvalutateCursorOwner(int movemode)
|
|||
ev.u.u.type = MotionNotify;
|
||||
ev.u.u.detail = 0;
|
||||
ev.u.u.sequenceNumber = 0;
|
||||
ev.u.keyButtonPointer.time = Sys_Milliseconds();
|
||||
ev.u.keyButtonPointer.time = pSys_Milliseconds();
|
||||
ev.u.keyButtonPointer.root = rootwindow->res.id;
|
||||
ev.u.keyButtonPointer.event = cursorowner->res.id;
|
||||
ev.u.keyButtonPointer.child = (x_windowwithcursor == cursorowner->res.id)?None:x_windowwithcursor;
|
||||
|
@ -1767,7 +1767,7 @@ void XWindows_KeyDown(int key)
|
|||
ev.u.keyButtonPointer.child = x_windowwithfocus;
|
||||
}
|
||||
ev.u.u.sequenceNumber = 0;
|
||||
ev.u.keyButtonPointer.time = Sys_Milliseconds();
|
||||
ev.u.keyButtonPointer.time = pSys_Milliseconds();
|
||||
ev.u.keyButtonPointer.rootX = x_mousex;
|
||||
ev.u.keyButtonPointer.rootY = x_mousey;
|
||||
ev.u.keyButtonPointer.sameScreen= true;
|
||||
|
@ -1865,7 +1865,7 @@ void XWindows_Keyup(int key)
|
|||
ev.u.keyButtonPointer.child = x_windowwithfocus;
|
||||
}
|
||||
ev.u.u.sequenceNumber = 0;
|
||||
ev.u.keyButtonPointer.time = Sys_Milliseconds();
|
||||
ev.u.keyButtonPointer.time = pSys_Milliseconds();
|
||||
ev.u.keyButtonPointer.rootX = x_mousex;
|
||||
ev.u.keyButtonPointer.rootY = x_mousey;
|
||||
ev.u.keyButtonPointer.state = 0;
|
||||
|
@ -1924,7 +1924,7 @@ int Plug_MenuEvent(int *args)
|
|||
qintptr_t Plug_ExecuteCommand(qintptr_t *args)
|
||||
{
|
||||
char cmd[256];
|
||||
Cmd_Argv(0, cmd, sizeof(cmd));
|
||||
pCmd_Argv(0, cmd, sizeof(cmd));
|
||||
if (!strcmp("startx", cmd))
|
||||
{
|
||||
XWindows_Startup();
|
||||
|
@ -1939,7 +1939,7 @@ qintptr_t Plug_Tick(qintptr_t *args)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void *XWindows_Create(char *medianame) //initialise the server socket and do any initial setup as required.
|
||||
static void *XWindows_Create(const char *medianame) //initialise the server socket and do any initial setup as required.
|
||||
{
|
||||
if (!strcmp(medianame, "x11"))
|
||||
{
|
||||
|
@ -1949,24 +1949,21 @@ static void *XWindows_Create(char *medianame) //initialise the server socket and
|
|||
return NULL;
|
||||
}
|
||||
|
||||
qbyte *XWindows_DisplayFrame(void *ctx, qboolean nosound, enum uploadfmt *fmt, int *width, int *height)
|
||||
static qboolean VARGS XWindows_DisplayFrame(void *ctx, qboolean nosound, qboolean forcevideo, double mediatime, void (QDECL *uploadtexture)(void *ectx, uploadfmt_t fmt, int width, int height, void *data, void *palette), void *ectx)
|
||||
{
|
||||
XWindows_Draw();
|
||||
|
||||
*fmt = TF_BGRX32;
|
||||
*width = xscreenwidth;
|
||||
*height = xscreenheight;
|
||||
|
||||
if (!xscreenmodified)
|
||||
return NULL;
|
||||
if (forcevideo || xscreenmodified)
|
||||
uploadtexture(ectx, TF_BGRX32, xscreenwidth, xscreenheight, xscreen, NULL);
|
||||
xscreenmodified = false;
|
||||
return xscreen;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void XWindows_Shutdown(void *ctx)
|
||||
{
|
||||
Net_Close(xlistensocket);
|
||||
xlistensocket = NULL;
|
||||
pNet_Close(xlistensocket);
|
||||
xlistensocket = 0;
|
||||
}
|
||||
|
||||
static qboolean XWindows_SetSize (void *ctx, int width, int height)
|
||||
|
@ -2012,9 +2009,10 @@ static void XWindows_Key (void *ctx, int code, int unicode, int isup)
|
|||
|
||||
media_decoder_funcs_t decoderfuncs =
|
||||
{
|
||||
sizeof(media_decoder_funcs_t),
|
||||
"x11",
|
||||
XWindows_Create,
|
||||
XWindows_DisplayFrame,
|
||||
NULL,//doneframe
|
||||
XWindows_Shutdown,
|
||||
NULL,//rewind
|
||||
|
||||
|
@ -2036,7 +2034,7 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!Plug_ExportNative("Media_VideoDecoder", &decoderfuncs))
|
||||
if (!pPlug_ExportNative("Media_VideoDecoder", &decoderfuncs))
|
||||
{
|
||||
Con_Printf("XServer plugin failed: Engine doesn't support media decoder plugins\n");
|
||||
return false;
|
||||
|
@ -2044,17 +2042,17 @@ qintptr_t Plug_Init(qintptr_t *args)
|
|||
|
||||
Con_Printf("XServer plugin started\n");
|
||||
|
||||
Cmd_AddCommand("startx");
|
||||
pCmd_AddCommand("startx");
|
||||
|
||||
|
||||
K_CTRL = Key_GetKeyCode("ctrl");
|
||||
K_ALT = Key_GetKeyCode("alt");
|
||||
K_MOUSE1 = Key_GetKeyCode("mouse1");
|
||||
K_MOUSE2 = Key_GetKeyCode("mouse2");
|
||||
K_MOUSE3 = Key_GetKeyCode("mouse3");
|
||||
K_MOUSE4 = Key_GetKeyCode("mouse4");
|
||||
K_MOUSE5 = Key_GetKeyCode("mouse5");
|
||||
K_BACKSPACE = Key_GetKeyCode("backspace");
|
||||
K_CTRL = pKey_GetKeyCode("ctrl");
|
||||
K_ALT = pKey_GetKeyCode("alt");
|
||||
K_MOUSE1 = pKey_GetKeyCode("mouse1");
|
||||
K_MOUSE2 = pKey_GetKeyCode("mouse2");
|
||||
K_MOUSE3 = pKey_GetKeyCode("mouse3");
|
||||
K_MOUSE4 = pKey_GetKeyCode("mouse4");
|
||||
K_MOUSE5 = pKey_GetKeyCode("mouse5");
|
||||
K_BACKSPACE = pKey_GetKeyCode("backspace");
|
||||
/*
|
||||
K_UPARROW = Key_GetKeyCode("uparrow");
|
||||
K_DOWNARROW = Key_GetKeyCode("downarrow");
|
||||
|
|
|
@ -380,7 +380,7 @@ void XR_GetProperty (xclient_t *cl, xReq *request)
|
|||
ev.u.u.sequenceNumber = 0;
|
||||
ev.u.property.window = req->window;
|
||||
ev.u.property.atom = req->property;
|
||||
ev.u.property.time = Sys_Milliseconds();
|
||||
ev.u.property.time = pSys_Milliseconds();
|
||||
ev.u.property.state = PropertyDelete;
|
||||
|
||||
ev.u.property.pad1 = 0;
|
||||
|
@ -485,7 +485,7 @@ void XR_ChangeProperty (xclient_t *cl, xReq *request)
|
|||
ev.u.u.sequenceNumber = 0;
|
||||
ev.u.property.window = req->window;
|
||||
ev.u.property.atom = req->property;
|
||||
ev.u.property.time = Sys_Milliseconds();
|
||||
ev.u.property.time = pSys_Milliseconds();
|
||||
ev.u.property.state = PropertyNewValue;
|
||||
|
||||
ev.u.property.pad1 = 0;
|
||||
|
@ -523,7 +523,7 @@ void XR_DeleteProperty(xclient_t *cl, xReq *request)
|
|||
ev.u.u.sequenceNumber = 0;
|
||||
ev.u.property.window = req->window;
|
||||
ev.u.property.atom = req->property;
|
||||
ev.u.property.time = Sys_Milliseconds();
|
||||
ev.u.property.time = pSys_Milliseconds();
|
||||
ev.u.property.state = PropertyDelete;
|
||||
|
||||
ev.u.property.pad1 = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue